Loading ...
Sorry, an error occurred while loading the content.
 

omap with 'f' and 't' and getchar() and nr2char()

Expand Messages
  • dfishburn.vim@gmail.com
    ... VIM - Vi IMproved 7.1 (2007 May 12, compiled Feb 6 2008 14:53:08) MS-Windows 32 bit GUI version with OLE support Included patches: 1-243 I have run into
    Message 1 of 18 , Feb 11, 2008
      :ver
      VIM - Vi IMproved 7.1 (2007 May 12, compiled Feb 6 2008 14:53:08)
      MS-Windows 32 bit GUI version with OLE support
      Included patches: 1-243

      I have run into an off by 1 error that I was hoping someone could
      explain.

      Start Vim using:
      gvim --noplugin -U none -U NONE omap_cf.vim

      Save the following into this file.
      "********
      function! MyOp(op)
      let c = getchar()
      echoerr "Executing ".a:op.nr2char(c)
      exec "normal! ".a:op.nr2char(c)
      endfunction

      onoremap f :call MyOp('f')<CR>

      " Now run:
      "********

      If you place your cursor at the beginning of the Now run line run the
      following command:
      cfw

      This changes up to and including the w, so you end up with:
      " Now run:
      run:

      <Esc> and undo the change.
      Source the file :so %
      Try the same command (cfw).
      This time you end up with:
      " Now run:
      w run:

      Notice the "w" was not included in the change.
      If you did this using 't', same thing happens, you are one character
      back.

      This function works fine if you do not use the getchar() function to
      ask the user what character they want to change up to.

      Comments?

      TIA,
      Dave


      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_use" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Ben Schmidt
      ... This is expected behaviour. Because :call is part of an Ex command, it behaves as described at ... (the fifth of the dot points ), i.e. it is always
      Message 2 of 18 , Feb 12, 2008
        dfishburn.vim@... wrote:
        >
        > :ver
        > VIM - Vi IMproved 7.1 (2007 May 12, compiled Feb 6 2008 14:53:08)
        > MS-Windows 32 bit GUI version with OLE support
        > Included patches: 1-243
        >
        > I have run into an off by 1 error that I was hoping someone could
        > explain.
        >
        > Start Vim using:
        > gvim --noplugin -U none -U NONE omap_cf.vim
        >
        > Save the following into this file.
        > "********
        > function! MyOp(op)
        > let c = getchar()
        > echoerr "Executing ".a:op.nr2char(c)
        > exec "normal! ".a:op.nr2char(c)
        > endfunction
        >
        > onoremap f :call MyOp('f')<CR>
        >
        > " Now run:
        > "********
        >
        > If you place your cursor at the beginning of the Now run line run the
        > following command:
        > cfw
        >
        > This changes up to and including the w, so you end up with:
        > " Now run:
        > run:
        >
        > <Esc> and undo the change.
        > Source the file :so %
        > Try the same command (cfw).
        > This time you end up with:
        > " Now run:
        > w run:
        >
        > Notice the "w" was not included in the change.
        > If you did this using 't', same thing happens, you are one character
        > back.
        >
        > This function works fine if you do not use the getchar() function to
        > ask the user what character they want to change up to.
        >
        > Comments?

        This is expected behaviour.

        Because :call is part of an Ex command, it behaves as described at

        :help {motion}

        (the fifth of the 'dot points'), i.e. it is always characterwise exclusive. A way
        to solve it is to use an <expr> map to avoid an Ex command altogether. Idea
        implementation:

        function! MyOp(op)
        let c = getchar()
        echoerr "Executing ".a:op.nr2char(c)
        return a:op.nr2char(c)
        endfunction

        onoremap <expr> f MyOp('f')

        Ben.




        Send instant messages to your online friends http://au.messenger.yahoo.com


        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_use" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Andy Wokula
        ... The only change is inserting a v in the mapping. -- Andy --~--~---------~--~----~------------~-------~--~----~ You received this message from the
        Message 3 of 18 , Feb 12, 2008
          Ben Schmidt schrieb:
          > dfishburn.vim@... wrote:
          >> I have run into an off by 1 error that I was hoping someone could
          >> explain.
          >>
          >> Start Vim using:
          >> gvim --noplugin -U none -U NONE omap_cf.vim
          >>
          >> Save the following into this file.
          >> "********
          >> function! MyOp(op)
          >> let c = getchar()
          >> echoerr "Executing ".a:op.nr2char(c)
          >> exec "normal! ".a:op.nr2char(c)
          >> endfunction
          >>
          >> onoremap f :call MyOp('f')<CR>
          >>
          >> " Now run:
          >> "********
          >>
          >> If you place your cursor at the beginning of the Now run line run the
          >> following command:
          >> cfw
          >>
          >> This changes up to and including the w, so you end up with:
          >> " Now run:
          >> run:
          >>
          >> <Esc> and undo the change.
          >> Source the file :so %
          >> Try the same command (cfw).
          >> This time you end up with:
          >> " Now run:
          >> w run:
          >>
          >> Notice the "w" was not included in the change.
          >> If you did this using 't', same thing happens, you are one character
          >> back.
          >>
          >> This function works fine if you do not use the getchar() function to
          >> ask the user what character they want to change up to.
          >>
          >> Comments?
          >
          > This is expected behaviour.
          >
          > Because :call is part of an Ex command, it behaves as described at
          >
          > :help {motion}
          >
          > (the fifth of the 'dot points'), i.e. it is always characterwise exclusive. A way
          > to solve it is to use an <expr> map [...]

          Another way:
          :h o_v

          :onoremap f v:call MyOp('f')<CR>

          The only change is inserting a "v" in the mapping.

          --
          Andy


          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_use" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • Charles E Campbell Jr
          ... I m probably doing something incorrectly. Instead of off-by-one or whatever, I get: gvim --noplugin -U none -U NONE omap_cf.vim /Now run/ cf ... the
          Message 4 of 18 , Feb 12, 2008
            dfishburn.vim@... wrote:

            >I have run into an off by 1 error that I was hoping someone could
            >explain.
            >
            >Start Vim using:
            >gvim --noplugin -U none -U NONE omap_cf.vim
            >
            >Save the following into this file.
            >"********
            >function! MyOp(op)
            > let c = getchar()
            > echoerr "Executing ".a:op.nr2char(c)
            > exec "normal! ".a:op.nr2char(c)
            >endfunction
            >
            >onoremap f :call MyOp('f')<CR>
            >
            >" Now run:
            >"********
            >
            >If you place your cursor at the beginning of the Now run line run the
            >following command:
            >cfw
            >
            >This changes up to and including the w, so you end up with:
            >" Now run:
            > run:
            >
            ><Esc> and undo the change.
            >Source the file :so %
            >Try the same command (cfw).
            >This time you end up with:
            >" Now run:
            >w run:
            >
            >Notice the "w" was not included in the change.
            >If you did this using 't', same thing happens, you are one character
            >back.
            >
            >This function works fine if you do not use the getchar() function to
            >ask the user what character they want to change up to.
            >
            >Comments?
            >
            >
            I'm probably doing something incorrectly. Instead of off-by-one or
            whatever, I get:

            gvim --noplugin -U none -U NONE omap_cf.vim
            /Now run/
            cf

            :call MyOp('f')<CR>[] <---- this shows up on the display where [] marks
            the cursor position

            now type that w...
            :call MyOp('f')<CR>w[]

            Beyond the directions: I then typed a <cr>. I got a half-height cursor
            at the : on the command line, but nothing was otherwise happening.
            I then pressed yet another <cr> on in:

            Error detected while processing function MyOp:
            line 2:
            Executing f^M
            E488: Trailing characters
            Press ENTER or type command to continue

            (I have a huge version of vim, 7.1.245)

            Regards,
            Chip Campbell


            I'm using a huge version

            --~--~---------~--~----~------------~-------~--~----~
            You received this message from the "vim_use" maillist.
            For more information, visit http://www.vim.org/maillist.php
            -~----------~----~----~----~------~----~------~--~---
          • David Fishburn
            ... Thanks Ben and Andy. I keep getting closer and closer, I can almost taste it. Using v: has got me almost where I need to be, but yet again I find a minor
            Message 5 of 18 , Feb 15, 2008
              On Feb 12, 2008 9:55 AM, Andy Wokula <anwoku@...> wrote:
              > Ben Schmidt schrieb:
              > > dfishburn.vim@... wrote:
              >
              > >> I have run into an off by 1 error that I was hoping someone could
              > >> explain.
              > >>
              > >> Start Vim using:
              > >> gvim --noplugin -U none -U NONE omap_cf.vim
              > >>
              > >> Save the following into this file.
              > >> "********
              > >> function! MyOp(op)
              > >> let c = getchar()
              > >> echoerr "Executing ".a:op.nr2char(c)
              > >> exec "normal! ".a:op.nr2char(c)
              > >> endfunction
              > >>
              > >> onoremap f :call MyOp('f')<CR>
              > >>
              > >> " Now run:
              > >> "********
              > >>
              > >> If you place your cursor at the beginning of the Now run line run the
              > >> following command:
              > >> cfw
              > >>
              > >> This changes up to and including the w, so you end up with:
              > >> " Now run:
              > >> run:
              > >>
              > >> <Esc> and undo the change.
              > >> Source the file :so %
              > >> Try the same command (cfw).
              > >> This time you end up with:
              > >> " Now run:
              > >> w run:
              > >>
              > >> Notice the "w" was not included in the change.
              > >> If you did this using 't', same thing happens, you are one character
              > >> back.
              > >>
              > >> This function works fine if you do not use the getchar() function to
              > >> ask the user what character they want to change up to.
              > >>
              > >> Comments?
              > >
              > > This is expected behaviour.
              > >
              > > Because :call is part of an Ex command, it behaves as described at
              > >
              > > :help {motion}
              > >
              > > (the fifth of the 'dot points'), i.e. it is always characterwise exclusive. A way
              > > to solve it is to use an <expr> map [...]
              >
              > Another way:
              > :h o_v
              >
              > :onoremap f v:call MyOp('f')<CR>
              >
              > The only change is inserting a "v" in the mapping.

              Thanks Ben and Andy.

              I keep getting closer and closer, I can almost taste it.

              Using v: has got me almost where I need to be, but yet again I find a
              minor discrepancy.

              I have the following text:
              foo(1,2)

              Placing the cursor on foo and hitting cw changes up to and including
              the "(". It should only include "foo".

              Looking at :h o_v it says:
              *o_v*
              v When used after an operator, before the motion command: Force
              the operator to work characterwise, also when the motion is
              linewise. If the motion was linewise, it will become
              |exclusive|.
              If the motion already was characterwise, toggle
              inclusive/exclusive. This can be used to make an exclusive
              motion inclusive and an inclusive motion exclusive.

              :h w
              <S-Right> or *<S-Right>* *w*
              w [count] words forward. |exclusive| motion.

              :h e
              *e*
              e Forward to the end of word [count] |inclusive|.

              So, using v:, can change an exclusive motion into an inclusive one.
              So if anything that should result in basically "cw" becoming the same
              as "ce" (if I interpret this correctly).

              ce works as expected and only changes "foo".

              Here is the script you can execute to demonstrate the issue. Just
              source this script.
              *****
              set nocompatible

              function! MyOp(op)
              let op_motion = a:op
              " Check if we are in operator-pending mode
              if op_motion =~? '\(f\|t\)'
              " If the operator pending mode is f or t
              " request the final character from the user
              let c = getchar()
              let op_motion = op_motion . nr2char(c)
              endif

              let v_count = ((v:count > 0)?(v:count):'')
              echoerr "Executing ".v_count.op_motion
              exec "normal! ".v_count.op_motion
              " return a:op.nr2char(c)
              endfunction

              onoremap f v:call MyOp('f')<CR>
              onoremap t v:call MyOp('t')<CR>
              onoremap w v:call MyOp('w')<CR>
              onoremap e v:call MyOp('e')<CR>

              " Now run:
              " foo(1,2)
              *****

              Comments?

              Thanks,
              Dave

              --~--~---------~--~----~------------~-------~--~----~
              You received this message from the "vim_use" maillist.
              For more information, visit http://www.vim.org/maillist.php
              -~----------~----~----~----~------~----~------~--~---
            • Andy Wokula
              ... For t and w the v is to be omitted. ... The builtin w motion is exclusive. If you omap w to an Ex command you ll get an exclusive motion, per
              Message 6 of 18 , Feb 16, 2008
                David Fishburn schrieb:
                > On Feb 12, 2008 9:55 AM, Andy Wokula <anwoku@...> wrote:
                >> Ben Schmidt schrieb:
                >>> dfishburn.vim@... wrote:
                >>>> I have run into an off by 1 error that I was hoping someone could
                >>>> explain.
                >>>>
                >>>> Start Vim using:
                >>>> gvim --noplugin -U none -U NONE omap_cf.vim
                >>>>
                >>>> Save the following into this file.
                >>>> "********
                >>>> function! MyOp(op)
                >>>> let c = getchar()
                >>>> echoerr "Executing ".a:op.nr2char(c)
                >>>> exec "normal! ".a:op.nr2char(c)
                >>>> endfunction
                >>>>
                >>>> onoremap f :call MyOp('f')<CR>
                >>>>
                >>>> " Now run:
                >>>> "********
                >>>>
                >>>> If you place your cursor at the beginning of the Now run line run
                >>>> the following command:
                >>>> cfw
                >>>>
                >>>> This changes up to and including the w, so you end up with:
                >>>> " Now run:
                >>>> run:
                >>>>
                >>>> <Esc> and undo the change.
                >>>> Source the file :so %
                >>>> Try the same command (cfw).
                >>>> This time you end up with:
                >>>> " Now run:
                >>>> w run:
                >>>>
                >>>> Notice the "w" was not included in the change.
                >>>> If you did this using 't', same thing happens, you are one
                >>>> character back.
                >>>>
                >>>> This function works fine if you do not use the getchar() function
                >>>> to ask the user what character they want to change up to.
                >>>>
                >>>> Comments?
                >>> This is expected behaviour.
                >>>
                >>> Because :call is part of an Ex command, it behaves as described at
                >>>
                >>> :help {motion}
                >>>
                >>> (the fifth of the 'dot points'), i.e. it is always characterwise
                >>> exclusive. A way to solve it is to use an <expr> map [...]
                >> Another way:
                >> :h o_v
                >>
                >> :onoremap f v:call MyOp('f')<CR>
                >>
                >> The only change is inserting a "v" in the mapping.
                >
                > Thanks Ben and Andy.
                >
                > I keep getting closer and closer, I can almost taste it.
                >
                > Using v: has got me almost where I need to be, but yet again I find a
                > minor discrepancy.
                >
                > I have the following text:
                > foo(1,2)
                >
                > Placing the cursor on foo and hitting cw changes up to and including
                > the "(". It should only include "foo".
                >
                > Looking at :h o_v it says:
                > *o_v*
                > v When used after an operator, before the motion command:
                > Force the operator to work characterwise, also when the
                > motion is linewise. If the motion was linewise, it will
                > become |exclusive|.
                > If the motion already was characterwise, toggle
                > inclusive/exclusive. This can be used to make an
                > exclusive motion inclusive and an inclusive motion
                > exclusive.
                >
                > :h w
                > <S-Right> or *<S-Right>* *w*
                > w [count] words forward. |exclusive| motion.
                >
                > :h e
                > *e*
                > e Forward to the end of word [count] |inclusive|.
                >
                > So, using v:, can change an exclusive motion into an inclusive one.
                > So if anything that should result in basically "cw" becoming the same
                > as "ce" (if I interpret this correctly).
                >
                > ce works as expected and only changes "foo".
                >
                > Here is the script you can execute to demonstrate the issue. Just
                > source this script.
                > *****
                > set nocompatible
                >
                > function! MyOp(op)
                > let op_motion = a:op
                > " Check if we are in operator-pending mode
                > if op_motion =~? '\(f\|t\)'
                > " If the operator pending mode is f or t
                > " request the final character from the user
                > let c = getchar()
                > let op_motion = op_motion . nr2char(c)
                > endif
                >
                > let v_count = ((v:count > 0)?(v:count):'')
                > echoerr "Executing ".v_count.op_motion
                > exec "normal! ".v_count.op_motion
                > " return a:op.nr2char(c)
                > endfunction
                >
                > onoremap f v:call MyOp('f')<CR>
                > onoremap t v:call MyOp('t')<CR>
                > onoremap w v:call MyOp('w')<CR>

                For "t" and "w" the "v" is to be omitted.

                > onoremap e v:call MyOp('e')<CR>
                >
                > " Now run:
                > " foo(1,2)
                > *****
                >
                > Comments?
                >
                > Thanks,
                > Dave

                The builtin "w" motion is exclusive. If you omap "w" to an Ex command
                you'll get an exclusive motion, per default. That's just what you want;
                prepending "v" to the Ex command makes your "w" motion inclusive (not
                wanted).

                "cw" is a confusing example, because it is an exception (works like
                "ce").
                :h cw
                Indeed, "e" is inclusive, but it stops earlier than an inclusive "w"
                would do:
                "foo bar" -- ce --> "| bar"
                "foo bar" -- cw --> "|ar"

                v:operator can help to detect the "c" operator. Maybe you could try
                this mapping:
                :ono <expr> w v:operator=="c" ? "v:call MyOp('e')<cr>"
                \ : ":call MyOp('w')<cr>"

                What are you going to do?
                Is it still for the yankring plugin, where you need the omap-motion to
                yank what it moves over (AIUI), as a side effect? In this case you
                cannot use :map-<expr> (see Ben's post) -- although I'd also prefer it,
                because it is more reliable. Remapping all the motions your way is
                difficult because of the subtle exceptions -- there is not only "cw".

                Minor:
                - I'd rename "MyOp" into "MyOmap" or "MyMotion" ...

                --
                Andy


                --~--~---------~--~----~------------~-------~--~----~
                You received this message from the "vim_use" maillist.
                For more information, visit http://www.vim.org/maillist.php
                -~----------~----~----~----~------~----~------~--~---
              • Andy Wokula
                ... Ah, wrong, it was a little different. You want to cancel Omap-mode and then execute v:operator + motion argument in MyOp(). I just looked up ... Some day
                Message 7 of 18 , Feb 17, 2008
                  Andy Wokula schrieb:
                  > Minor:
                  > - I'd rename "MyOp" into "MyOmap" or "MyMotion" ...

                  Ah, wrong, it was a little different. You want to cancel
                  Omap-mode and then execute v:operator + motion argument in
                  MyOp(). I just looked up
                  :h v:operator
                  Some day I'll get it ;-)

                  --
                  Andy

                  --~--~---------~--~----~------------~-------~--~----~
                  You received this message from the "vim_use" maillist.
                  For more information, visit http://www.vim.org/maillist.php
                  -~----------~----~----~----~------~----~------~--~---
                • dfishburn.vim@gmail.com
                  ... Thanks for the response Andy. I tried to use maps, but had to bail on them. So I have tried a few techniques at this point: 1. omap - simply
                  Message 8 of 18 , Apr 9, 2008
                    ...

                    > "cw" is a confusing example, because it is an exception (works like
                    > "ce").
                    >     :h cw
                    > Indeed, "e" is inclusive, but it stops earlier than an inclusive "w"
                    > would do:
                    >     "foo bar"     -- ce -->      "| bar"
                    >     "foo bar"     -- cw -->      "|ar"
                    >
                    > v:operator can help to detect the "c" operator.  Maybe you could try
                    > this mapping:
                    >     :ono <expr> w  v:operator=="c" ? "v:call MyOp('e')<cr>"
                    >                                  \ : ":call MyOp('w')<cr>"
                    >
                    > What are you going to do?
                    > Is it still for the yankring plugin, where you need theomap-motion to
                    > yank what it moves over (AIUI), as a side effect?  In this case you
                    > cannot use :map-<expr> (see Ben's post) -- although I'd also prefer it,
                    > because it is more reliable.  Remapping all the motions your way is
                    > difficult because of the subtle exceptions -- there is not only "cw".

                    Thanks for the response Andy.

                    I tried to use <expr> maps, but had to bail on them.

                    So I have tried a few techniques at this point:
                    1. omap - simply execute "normal! motion" that the user typed
                    2. omap <ESC>... redo the whole operation using v:operator and the
                    motion passed in
                    3. omap <expr> ... return exactly what the user typed

                    Each has its own flaws.

                    The expr seemed to generate the most consistent results (re inclusive
                    vs exclusive) and I would use it if I could only solve this problem.
                    Any suggestions are very welcome.

                    The problem
                    -----------------
                    The goal, after the operation completes, I want to record the register
                    changes.
                    So, dw, I want to record the word just deleted.

                    Since the registers do not change until the function completes, the
                    function itself cannot record the change. I worked around this in 1.
                    by using feedkeys() to call my function to record the change. This
                    function gets called after the omap completes. This does not work for
                    change operators (cw), so I record that using an autocmd, InsertLeave.

                    It seems when using <expr> feedkeys() does not work the same way. So
                    really, I have no way to telling my plugin to record the register
                    changes once the function completes. I thought about using CursorHold
                    to do it, but a user could hit:
                    dw
                    dw
                    dw
                    dw
                    Very quickly and I am doubt that would record them all.

                    Any possibilities?

                    Thanks,
                    Dave

                    --~--~---------~--~----~------------~-------~--~----~
                    You received this message from the "vim_use" maillist.
                    For more information, visit http://www.vim.org/maillist.php
                    -~----------~----~----~----~------~----~------~--~---
                  • Andy Wokula
                    ... I just got a simple idea. Works even for cw . nn yy yy cr ono w w cr copy register nn cr :call cr()
                    Message 9 of 18 , Apr 10, 2008
                      dfishburn.vim@... schrieb:
                      > ...
                      >
                      >> "cw" is a confusing example, because it is an exception (works like
                      >> "ce").
                      >> :h cw
                      >> Indeed, "e" is inclusive, but it stops earlier than an inclusive "w"
                      >> would do:
                      >> "foo bar" -- ce --> "| bar"
                      >> "foo bar" -- cw --> "|ar"
                      >>
                      >> v:operator can help to detect the "c" operator. Maybe you could try
                      >> this mapping:
                      >> :ono <expr> w v:operator=="c" ? "v:call MyOp('e')<cr>"
                      >> \ : ":call MyOp('w')<cr>"
                      >>
                      >> What are you going to do?
                      >> Is it still for the yankring plugin, where you need theomap-motion to
                      >> yank what it moves over (AIUI), as a side effect? In this case you
                      >> cannot use :map-<expr> (see Ben's post) -- although I'd also prefer it,
                      >> because it is more reliable. Remapping all the motions your way is
                      >> difficult because of the subtle exceptions -- there is not only "cw".
                      >
                      > Thanks for the response Andy.
                      >
                      > I tried to use <expr> maps, but had to bail on them.
                      >
                      > So I have tried a few techniques at this point:
                      > 1. omap - simply execute "normal! motion" that the user typed
                      > 2. omap <ESC>... redo the whole operation using v:operator and the
                      > motion passed in
                      > 3. omap <expr> ... return exactly what the user typed
                      >
                      > Each has its own flaws.
                      >
                      > The expr seemed to generate the most consistent results (re inclusive
                      > vs exclusive) and I would use it if I could only solve this problem.
                      > Any suggestions are very welcome.
                      >
                      > The problem
                      > -----------------
                      > The goal, after the operation completes, I want to record the register
                      > changes.
                      > So, dw, I want to record the word just deleted.
                      >
                      > Since the registers do not change until the function completes, the
                      > function itself cannot record the change. I worked around this in 1.
                      > by using feedkeys() to call my function to record the change. This
                      > function gets called after the omap completes. This does not work for
                      > change operators (cw), so I record that using an autocmd, InsertLeave.
                      >
                      > It seems when using <expr> feedkeys() does not work the same way. So
                      > really, I have no way to telling my plugin to record the register
                      > changes once the function completes. I thought about using CursorHold
                      > to do it, but a user could hit:
                      > dw
                      > dw
                      > dw
                      > dw
                      > Very quickly and I am doubt that would record them all.
                      >
                      > Any possibilities?
                      >
                      > Thanks,
                      > Dave

                      I just got a simple idea. Works even for "cw".

                      nn <script> yy yy<sid>cr
                      ono <script> w w<sid>cr

                      " copy register
                      nn <silent> <sid>cr :call <sid>cr()<cr>
                      ino <script> <sid>cr <c-o><sid>cr

                      func! <sid>cr()
                      let reg = getreg(v:register)
                      echo reg
                      endfunc

                      --
                      Andy


                      --~--~---------~--~----~------------~-------~--~----~
                      You received this message from the "vim_use" maillist.
                      For more information, visit http://www.vim.org/maillist.php
                      -~----------~----~----~----~------~----~------~--~---
                    • Andy Wokula
                      ... return ... -- Andy --~--~---------~--~----~------------~-------~--~----~ You received this message from the vim_use maillist. For more information,
                      Message 10 of 18 , Apr 10, 2008
                        Andy Wokula schrieb:
                        > nn <script> yy yy<sid>cr
                        > ono <script> w w<sid>cr
                        >
                        > " copy register
                        > nn <silent> <sid>cr :call <sid>cr()<cr>

                        > ino <script> <sid>cr <c-o><sid>cr
                        Hmm, this breaks the redo command "." after "cw", therefore:

                        :ino <silent> <sid>cr <c-r>=<sid>cr()<cr>

                        > func! <sid>cr()
                        > let reg = getreg(v:register)
                        > echo reg
                        return ""
                        > endfunc

                        --
                        Andy

                        --~--~---------~--~----~------------~-------~--~----~
                        You received this message from the "vim_use" maillist.
                        For more information, visit http://www.vim.org/maillist.php
                        -~----------~----~----~----~------~----~------~--~---
                      • dfishburn.vim@gmail.com
                        ... Hot Diggity Dog! Andy, I had run into the exact redo issue after you last post and was attempting to come up with a work around. I doubt I would have
                        Message 11 of 18 , Apr 11, 2008
                          On Apr 10, 7:43 am, Andy Wokula <anw...@...> wrote:
                          > Andy Wokula schrieb:
                          >
                          > > nn <script> yy yy<sid>cr
                          > > ono <script> w w<sid>cr
                          >
                          > > " copy register
                          > > nn <silent> <sid>cr :call <sid>cr()<cr>
                          > > ino <script> <sid>cr <c-o><sid>cr
                          >
                          > Hmm, this breaks the redo command "." after "cw", therefore:
                          >
                          > :ino <silent> <sid>cr <c-r>=<sid>cr()<cr>

                          Hot Diggity Dog!

                          Andy, I had run into the exact "redo" issue after you last post and
                          was attempting to come up with a work around. I doubt I would have
                          tried this and it works perfectly.

                          Using . mapped the same way will also record future redos.

                          I have all motions and all text objects working as well.

                          I have one remaining issue, that I was hoping you might have an idea
                          for.

                          Mapping f and t, these require and additional character specified. I
                          was able to do this:
                          omap f :<C-U>call RepeatMotion('f')<CR>

                          This function basically did this:

                          function! RepeatMotion(op_motion) range
                          if a:op_motion =~? '\(f\|t\)'
                          let op_motion = op_motion . s:YRGetChar()
                          endif

                          let cmd = 'normal! '.a:op_motion
                          exec cmd
                          endfunction

                          This works, it prompts the user for an additional character.

                          On a redo, this function is called again, but unfortunately, it
                          prompts the user again. So I can't get a seemless redo.

                          Based on your previous posts I have tried a few options listed here:
                          ************
                          set nocompatible

                          nn <script> yy yy<sid>cr
                          ono <script> w w<sid>cr
                          ono <script> t t<sid>motion
                          ono <script> t t<sid>cr
                          " ono <script> <expr> t <sid>motion
                          " ono <script> <expr> t <sid>motion<sid>cr
                          " ono <script> <expr> t Motion()
                          " ono <script> <expr> t Motion()<bar><sid>cr
                          " ono <script> <expr> t Motion()<bar>CR()
                          " ono <script> <expr> t Motion()<bar>CR()<CR>

                          " copy register
                          nn <silent> <sid>cr :call <sid>cr()<cr>
                          " This breaks the redo feature
                          " ino <script> <sid>cr <c-o><sid>cr
                          ino <script> <sid>cr <c-r>=<sid>cr()<CR>
                          nn <silent> <sid>motion :call <sid>motion()<cr>
                          " This breaks the redo feature
                          " ino <script> <sid>motion <c-o><sid>motion
                          ino <script> <sid>motion <c-r>=<sid>motion()<CR>

                          func! <sid>cr()
                          let reg = getreg(v:register)
                          echo "reg:".v:register.':'.reg
                          return "t"
                          endfunc

                          func! CR()
                          let reg = getreg(v:register)
                          echo "reg:".v:register.':'.reg
                          return ""
                          endfunc

                          func! <sid>motion()
                          return 't'
                          endfunc

                          func! Motion()
                          " doautocmd User
                          return 'tt'
                          endfunc

                          augroup YankRingTest
                          autocmd User * :echo "YRT:".@"
                          augroup END

                          " test is a
                          " test line
                          " test testing
                          ************

                          I was hoping I could use another <c-r> function call to return the
                          character, I was also tried additional <expr> maps, but had the usual
                          issue is no additonal functions are called after the first function.

                          Do you have any other suggestions that I might try out?

                          Thanks for all your help so far.
                          Dave


                          --~--~---------~--~----~------------~-------~--~----~
                          You received this message from the "vim_use" maillist.
                          For more information, visit http://www.vim.org/maillist.php
                          -~----------~----~----~----~------~----~------~--~---
                        • Andy Wokula
                          ... Current try (works well for me :-) : ono f getzapchar( f ). cr ono F getzapchar( F ). cr func!
                          Message 12 of 18 , Apr 11, 2008
                            dfishburn.vim@... schrieb:
                            > I have one remaining issue, that I was hoping you might have an idea
                            > for.
                            >
                            > Mapping f and t, these require and additional character specified. I
                            > was able to do this:
                            > omap f :<C-U>call RepeatMotion('f')<CR>
                            >
                            > This function basically did this:
                            >
                            > function! RepeatMotion(op_motion) range
                            > if a:op_motion =~? '\(f\|t\)'
                            > let op_motion = op_motion . s:YRGetChar()
                            > endif
                            >
                            > let cmd = 'normal! '.a:op_motion
                            > exec cmd
                            > endfunction
                            >
                            > This works, it prompts the user for an additional character.
                            >
                            > On a redo, this function is called again, but unfortunately, it
                            > prompts the user again. So I can't get a seemless redo.
                            >
                            > Based on your previous posts I have tried a few options listed here:
                            > ************
                            > set nocompatible
                            >
                            > nn <script> yy yy<sid>cr
                            > ono <script> w w<sid>cr
                            > ono <script> t t<sid>motion
                            > ono <script> t t<sid>cr
                            > " ono <script> <expr> t <sid>motion
                            > " ono <script> <expr> t <sid>motion<sid>cr
                            > " ono <script> <expr> t Motion()
                            > " ono <script> <expr> t Motion()<bar><sid>cr
                            > " ono <script> <expr> t Motion()<bar>CR()
                            > " ono <script> <expr> t Motion()<bar>CR()<CR>
                            >
                            > " copy register
                            > nn <silent> <sid>cr :call <sid>cr()<cr>
                            > " This breaks the redo feature
                            > " ino <script> <sid>cr <c-o><sid>cr
                            > ino <script> <sid>cr <c-r>=<sid>cr()<CR>
                            > nn <silent> <sid>motion :call <sid>motion()<cr>
                            > " This breaks the redo feature
                            > " ino <script> <sid>motion <c-o><sid>motion
                            > ino <script> <sid>motion <c-r>=<sid>motion()<CR>
                            >
                            > func! <sid>cr()
                            > let reg = getreg(v:register)
                            > echo "reg:".v:register.':'.reg
                            > return "t"
                            > endfunc
                            >
                            > func! CR()
                            > let reg = getreg(v:register)
                            > echo "reg:".v:register.':'.reg
                            > return ""
                            > endfunc
                            >
                            > func! <sid>motion()
                            > return 't'
                            > endfunc
                            >
                            > func! Motion()
                            > " doautocmd User
                            > return 'tt'
                            > endfunc
                            >
                            > augroup YankRingTest
                            > autocmd User * :echo "YRT:".@"
                            > augroup END
                            >
                            > " test is a
                            > " test line
                            > " test testing
                            > ************
                            >
                            > I was hoping I could use another <c-r> function call to return the
                            > character, I was also tried additional <expr> maps, but had the usual
                            > issue is no additonal functions are called after the first function.
                            >
                            > Do you have any other suggestions that I might try out?
                            >
                            > Thanks for all your help so far.
                            > Dave

                            " Current try (works well for me :-) :

                            ono <expr><script> f <sid>getzapchar("f"). "<sid>cr"
                            ono <expr><script> F <sid>getzapchar("F"). "<sid>cr"

                            func! <sid>getzapchar(fcmd)
                            return a:fcmd. s:Getchar()
                            endfunc

                            func! s:Getchar()
                            let c = getchar()
                            if c != 0
                            let c = nr2char(c)
                            endif
                            return c
                            endfunc


                            Looks like "." doesn't repeat the expr-eval, only the result.

                            --
                            Andy


                            --~--~---------~--~----~------------~-------~--~----~
                            You received this message from the "vim_use" maillist.
                            For more information, visit http://www.vim.org/maillist.php
                            -~----------~----~----~----~------~----~------~--~---
                          • David Fishburn
                            ... Thanks for the response Andy. I tried this out when you originally posted it (sometime ago) and have tried a few work arounds. ... Yes, what you provided
                            Message 13 of 18 , May 28, 2008
                              > " Current try (works well for me :-) :
                              >
                              > ono <expr><script> f <sid>getzapchar("f"). "<sid>cr"
                              > ono <expr><script> F <sid>getzapchar("F"). "<sid>cr"
                              >
                              > func! <sid>getzapchar(fcmd)
                              > return a:fcmd. s:Getchar()
                              > endfunc
                              >
                              > func! s:Getchar()
                              > let c = getchar()
                              > if c != 0
                              > let c = nr2char(c)
                              > endif
                              > return c
                              > endfunc
                              >
                              >
                              > Looks like "." doesn't repeat the expr-eval, only the result.

                              Thanks for the response Andy.

                              I tried this out when you originally posted it (sometime ago) and have
                              tried a few work arounds.

                              > " Current try (works well for me :-) :

                              Yes, what you provided works but not in the original case.

                              Your map:
                              > ono <expr><script> F <sid>getzapchar("F"). "<sid>cr"

                              Successfully calls getzapchar(), but once getzapchar() completes, it
                              does not call "<sid>cr" which is the reason I cannot use <expr> maps.

                              Not sure why this limitation exists, but everything else is working
                              great except the f and t maps.

                              Unforutnately, I use this religiously and have to have them working
                              and repeatable before I release the next version of the YankRing.

                              Any other possible suggestions?

                              TIA,
                              Dave

                              --~--~---------~--~----~------------~-------~--~----~
                              You received this message from the "vim_use" maillist.
                              For more information, visit http://www.vim.org/maillist.php
                              -~----------~----~----~----~------~----~------~--~---
                            • John Little
                              Like Dr Chip, I didn t know where you guys are at, but I m getting there. ... AFAICT, -U none is being overridden by -U NONE . If vim running without any
                              Message 14 of 18 , May 29, 2008
                                Like Dr Chip, I didn't know where you guys are at, but I'm getting
                                there.

                                > gvim --noplugin -U none -U NONE omap_cf.vim

                                AFAICT, "-U none" is being overridden by "-U NONE". If vim running
                                without any customization is intended, "-u NONE" is needed. However,
                                the use of <CR> in the script implies :set nocp, and you get cp with "-
                                u NONE". I think that explains Dr Chip's first result, "<CR>" shown
                                on the command line.

                                My next mistake was to cut and paste the example from firefox (or
                                Konqueror). I get an extra space on the end of the omap line. I think
                                Dr Chip got this too.

                                Regards, John
                                --~--~---------~--~----~------------~-------~--~----~
                                You received this message from the "vim_use" maillist.
                                For more information, visit http://www.vim.org/maillist.php
                                -~----------~----~----~----~------~----~------~--~---
                              • Tony Mechelynck
                                ... For no vimrc, no gvimrc, no plugins, but nocompatible mode, use: vim -N -u NONE for the same, but with global plugins, use vim -N -u NORC This, however,
                                Message 15 of 18 , May 30, 2008
                                  On 30/05/08 07:21, John Little wrote:
                                  > Like Dr Chip, I didn't know where you guys are at, but I'm getting
                                  > there.
                                  >
                                  >> gvim --noplugin -U none -U NONE omap_cf.vim
                                  >
                                  > AFAICT, "-U none" is being overridden by "-U NONE". If vim running
                                  > without any customization is intended, "-u NONE" is needed. However,
                                  > the use of<CR> in the script implies :set nocp, and you get cp with "-
                                  > u NONE". I think that explains Dr Chip's first result, "<CR>" shown
                                  > on the command line.
                                  >
                                  > My next mistake was to cut and paste the example from firefox (or
                                  > Konqueror). I get an extra space on the end of the omap line. I think
                                  > Dr Chip got this too.
                                  >
                                  > Regards, John

                                  For no vimrc, no gvimrc, no plugins, but 'nocompatible' mode, use:

                                  vim -N -u NONE

                                  for the same, but with global plugins, use

                                  vim -N -u NORC

                                  This, however, will also load any additional global plugins in
                                  $HOME/.vim/plugin (Unix), $HOME/vimfiles/plugin (Windows),
                                  $VIM/vimfiles/plugin (all). To avoid these, you may want to temporarily
                                  rename their .vim and vimfiles parents to something where Vim won't look
                                  into.

                                  To avoid sourcing your own vimrc and gvimrc, and still enable (among
                                  others) syntax highlighting in a way that Bram can reproduce, you can use:
                                  (Windows)
                                  gvim -u C:\PROGRA~1\vim\vim71\vimrc_example.vim -U NONE
                                  (Unix)
                                  gvim -u /usr/local/share/vim/vim71/vimrc_example.vim -U NONE

                                  assuming default install paths in both cases, and 8.3 dirnames on
                                  Windows to avoid the problems sometimes caused by spaces in them. "-N"
                                  can be omitted in this case because the vimrc_example.vim sets
                                  'nocompatible' as it starts.

                                  The same remarks about own-installed plugins applies; see under -u NORC
                                  above.


                                  Best regards,
                                  Tony.
                                  --
                                  There were the Scots
                                  Who kept the Sabbath
                                  And everything else they could lay their hands on.
                                  Then there were the Welsh
                                  Who prayed on their knees and their neighbors.
                                  Thirdly there were the Irish
                                  Who never knew what they wanted
                                  But were willing to fight for it anyway.
                                  Lastly there were the English
                                  Who considered themselves a self-made nation
                                  Thus relieving the Almighty of a dreadful responsibility.

                                  --~--~---------~--~----~------------~-------~--~----~
                                  You received this message from the "vim_use" maillist.
                                  For more information, visit http://www.vim.org/maillist.php
                                  -~----------~----~----~----~------~----~------~--~---
                                • David Fishburn
                                  Sorry, this went to Andy only, sorry. ... Okay, here is a recap. Goal: For every operation in Vim that effects a register, record the changed value in the
                                  Message 16 of 18 , May 31, 2008
                                    Sorry, this went to Andy only, sorry.

                                    ---------- Forwarded message ----------

                                    Okay, here is a recap.

                                    Goal:
                                    For every operation in Vim that effects a register, record the changed
                                    value in the YankRing plugin for later use.

                                    The current version of the YankRing (3.0) does this but not for all
                                    motions and text objects. I also does not handle any changes (like
                                    cw).

                                    The new version handles everything (including all text objects :h
                                    text-objects), changes, clipboard.
                                    It has been accomplished using this technique for the maps:
                                    nnoremap <script> w w<SID>YRRecord2

                                    Since the above is an "omap", if I issue a dw, cw, yw it triggers the
                                    map. Thanks to Andy, it executes the 'w' to complete the motion, then
                                    calls a function in the YankRing plugin to record the changed
                                    register. This technique also supports "." (repeat). Hot diggidy
                                    dog!

                                    This works for all motions and text-objects _except_ 't' and 'f'.

                                    t and f are special cases since we must ask the user for the character
                                    to perform the motion up to.
                                    If you have this word in your buffer: my_word_with_underscores
                                    df_ will delete up to and including the first _, resulting in:
                                    word_with_underscores
                                    dt_ will delete up to the first _, resulting in: _word_with_underscores

                                    Handling these 2 special cases has been troublesome.

                                    Andy and Ben suggested using a <expr> map.
                                    This works great. My function knows it is a 't' or 'f' map and
                                    prompts for the following character. And it is executed.

                                    The problem with the above is for some reason when an <expr> map is
                                    used, any command following the function call is not called by Vim.
                                    So with the previous technique:
                                    nnoremap <script> w w<SID>YRRecord2

                                    We execute w, the omap simply returns 'w', telling Vim to do the usual
                                    operation and once it finishes, it calls the YRRecord2 function.

                                    The same approach with the <expr> map, execute the f motion but will
                                    NOT call YRRecord2.

                                    The YRRecord2 function must be called _after_ the map (or function
                                    completes) since the registers are _not_ updated until the function
                                    completes. Hence I cannot record any changed registers.


                                    Ben had another suggested approach. Instead of using an <expr> map,
                                    use an omap, but cancel the omap first and then execute the command in
                                    your own function. Something like this:
                                    onoremap w <Esc>:<C-U>call TestOMap()<CR>

                                    TestOMap() will execute the v:operator.w and attempt to record the changes made.
                                    This fails for a number of reasons:
                                    - The registers are not updated until the function completes
                                    - Cancelling the omap with <Esc> and re-executing it runs into
                                    inclusive vs exclusive problems (which <expr> maps avoid entirely)

                                    I attempted to solve this by using feedkeys(). So in the TestOMap
                                    function, after executing the command I did this:
                                    call feedkeys(":silent! :call YRRecord('".user_register."')\<CR>", 't')

                                    So, when the function completed, I "fed" a call to my function. This
                                    only partially worked.



                                    Some of the test cases when starting Vim using:
                                    gvim -u NONE -U NONE --noplugin omap_cf.vim
                                    ***** omap_cf.vim *****
                                    set nocompatible
                                    set hidden

                                    function! MyOp(op)
                                    let op_motion = a:op
                                    " Check if we are in operator-pending mode
                                    if op_motion =~? '\(f\|t\)'
                                    " If the operator pending mode is f or t
                                    " request the final character from the user
                                    let c = getchar()
                                    let op_motion = op_motion . nr2char(c)
                                    endif

                                    let v_count = ((v:count > 0)?(v:count):'')
                                    " echoerr "Executing ".v:count.op_motion
                                    exec "normal! ".v:count.op_motion
                                    " return a:op.nr2char(c)
                                    endfunction

                                    function! MyDisplay()
                                    echo 'reg:'.@"
                                    let @a = @"
                                    endfunction

                                    function! MyExprOp(op)
                                    let c = getchar()
                                    return a:op.nr2char(c)
                                    endfunction

                                    onoremap f v:call MyOp('f')<CR>
                                    onoremap t v:call MyOp('t')<CR>
                                    onoremap w :call MyOp('w')<CR>
                                    " onoremap e v:call MyOp('e')<CR>
                                    " onoremap iw v:call MyOp('iw')<CR>

                                    onoremap f v:call MyOp('f')<CR>
                                    onoremap t v:call MyOp('t')<bar>:call MyDisplay()<CR>
                                    onoremap w :call MyOp('w')<CR>

                                    onoremap f v:call MyOp('f')<CR>
                                    onoremap t v:call MyOp('t')<bar>:call MyDisplay()<CR>
                                    onoremap <expr> f MyExprOp('f') |:call MyDisplay()<CR>
                                    onoremap <expr> f MyExprOp('f')<bar>:call MyDisplay()<CR>


                                    onoremap w :call MyOp('w')<CR>
                                    " Now run:
                                    " foo(1,2)

                                    **********


                                    I am happy to use expression maps if I can somehow get a function to
                                    be called after them using the technique (or otherwise) above:
                                    onoremap <expr> f MyExprOp('f')<bar>:call MyDisplay()<CR>

                                    Just wondering if there is anyway how this might be accomplished.

                                    TIA,
                                    Dave

                                    --~--~---------~--~----~------------~-------~--~----~
                                    You received this message from the "vim_use" maillist.
                                    For more information, visit http://www.vim.org/maillist.php
                                    -~----------~----~----~----~------~----~------~--~---
                                  • Ben Schmidt
                                    ... The :call MyDisplay() should either be part of the expression that MyExprOp returns, or appended to it with the . operator. So far you ve tried
                                    Message 17 of 18 , May 31, 2008
                                      > I am happy to use expression maps if I can somehow get a function to
                                      > be called after them using the technique (or otherwise) above:
                                      > onoremap <expr> f MyExprOp('f')<bar>:call MyDisplay()<CR>
                                      >
                                      > Just wondering if there is anyway how this might be accomplished.

                                      The ":call MyDisplay()<CR>" should either be part of the expression that MyExprOp
                                      returns, or appended to it with the "." operator. So far you've tried including it
                                      as for a regular map, not an <expr> map. Try (roughly)

                                      func! MyExprOp(arg)
                                      let char=getchar()
                                      return "f".char.":call MyDisplay()\<CR>"
                                      endfunc

                                      or

                                      onoremap <expr> f MyExprOp('f').":call MyDisplay()\<CR>"

                                      and let me know how you go...

                                      Ben.



                                      --~--~---------~--~----~------------~-------~--~----~
                                      You received this message from the "vim_use" maillist.
                                      For more information, visit http://www.vim.org/maillist.php
                                      -~----------~----~----~----~------~----~------~--~---
                                    • David Fishburn
                                      ... YES! That works like a charm and it makes sense too! --~--~---------~--~----~------------~-------~--~----~ You received this message from the vim_use
                                      Message 18 of 18 , Jun 2, 2008
                                        ...
                                        > The ":call MyDisplay()<CR>" should either be part of the expression that MyExprOp
                                        > returns, or appended to it with the "." operator. So far you've tried including it
                                        > as for a regular map, not an <expr> map. Try (roughly)
                                        >
                                        > func! MyExprOp(arg)
                                        > let char=getchar()
                                        > return "f".char.":call MyDisplay()\<CR>"
                                        > endfunc
                                        >
                                        > or
                                        >
                                        > onoremap <expr> f MyExprOp('f').":call MyDisplay()\<CR>"

                                        YES!

                                        That works like a charm and it makes sense too!

                                        --~--~---------~--~----~------------~-------~--~----~
                                        You received this message from the "vim_use" maillist.
                                        For more information, visit http://www.vim.org/maillist.php
                                        -~----------~----~----~----~------~----~------~--~---
                                      Your message has been successfully submitted and would be delivered to recipients shortly.