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

Re: How to determine the start of a visual block (C-V) when it starts in the void?

Expand Messages
  • John Little
    ... (Sorry, I thought the $ characters were part of the text. And I was moving right, not up.) The result depends on the setting of the virtualedit option.
    Message 1 of 17 , Jan 29, 2013
    • 0 Attachment
      On Tuesday, January 29, 2013 8:13:59 PM UTC+13, Axel Bender wrote:
      > virtcol(...) doesn't "work" in the example given. Please note that the end/start - depending from where you start to select - of the block is in the "void", i.e. after the line's end (as indicated by "$"). Here even virtcol(...) returns 1.
      (Sorry, I thought the $ characters were part of the text. And I was moving right, not up.)
      The result depends on the setting of the 'virtualedit' option. If this is "" (the default) or "block", by the time the echo command is executing, vim is out of visual mode and the cursor can no longer be positioned "where there is no actual character", to quote :help 've'.

      If I set ve=all, then :echo virtcol("'<") does indeed say 4. I think you've got ve=block.

      Regards, John

      --
      --
      You received this message from the "vim_use" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php

      ---
      You received this message because you are subscribed to the Google Groups "vim_use" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Axel Bender
      @John Thanks for the answer. You re right, I ve actually set virtualedit to block . Nevertheless I would have assumed (hoped), that - whatever mode I m in -
      Message 2 of 17 , Jan 29, 2013
      • 0 Attachment
        @John

        Thanks for the answer. You're right, I've actually set 'virtualedit' to 'block'. Nevertheless I would have assumed (hoped), that - whatever mode I'm in - 'block', or 'all' - virtcol("'<") would reflect the actual start column.

        One can - of course - argue in favor or against that, but I would consider this more logical: If(!) I'm able to create a block with corners in the void using 'block' mode, then why should virtcol() not adapt to that?

        --
        --
        You received this message from the "vim_use" maillist.
        Do not top-post! Type your reply below the text you are replying to.
        For more information, visit http://www.vim.org/maillist.php

        ---
        You received this message because you are subscribed to the Google Groups "vim_use" group.
        To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.
      • Axel Bender
        Addendum: It s obviously sufficient to set virtualedit to block just before retrieving from virtcol(), and resetting it thereafter. I m using this in a
        Message 3 of 17 , Jan 29, 2013
        • 0 Attachment
          Addendum: It's obviously sufficient to set virtualedit to 'block' just before retrieving from virtcol(), and resetting it thereafter. I'm using this in a plugin mapping that operates on a visual area or on a motion.

          --
          --
          You received this message from the "vim_use" maillist.
          Do not top-post! Type your reply below the text you are replying to.
          For more information, visit http://www.vim.org/maillist.php

          ---
          You received this message because you are subscribed to the Google Groups "vim_use" group.
          To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
          For more options, visit https://groups.google.com/groups/opt_out.
        • John Little
          ... It does, the point in your example is the observation affecting the result. By going to the command line, vim has gone out of visual block mode. If your
          Message 4 of 17 , Jan 29, 2013
          • 0 Attachment
            On Wednesday, January 30, 2013 3:08:04 AM UTC+13, Axel Bender wrote:

            >If(!) I'm able to create a block with corners in the void using 'block' mode, >then why should virtcol() not adapt to that?

            It does, the point in your example is the observation affecting the result. By going to the command line, vim has gone out of visual block mode. If your plug-in is careful, it can avoid this. For example,

            :vmap <expr> z Col()
            :fun! Col()
            echo virtcol("'<")
            return ""
            endf

            Select a block and press z. If ve=block, when virtcol is called vim is still in visual block mode.

            Regards, John

            --
            --
            You received this message from the "vim_use" maillist.
            Do not top-post! Type your reply below the text you are replying to.
            For more information, visit http://www.vim.org/maillist.php

            ---
            You received this message because you are subscribed to the Google Groups "vim_use" group.
            To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
            For more options, visit https://groups.google.com/groups/opt_out.
          • Axel Bender
            Hi John, unfortunately this approach doesn t work in my situation. I m using the same function in a mapping operating either on visuals, or on motions
            Message 5 of 17 , Jan 30, 2013
            • 0 Attachment
              Hi John,

              unfortunately this approach doesn't work in my situation. I'm using the same function in a mapping operating either on visuals, or on motions (:map-operator).

              Also, I think that if a visual block is displayed (set virtualedit=block, upper left corner in the void), then when switching to the command line and issuing :<C-U>echo virtcol("'<"), the function should return the "correct" left column, as this selection is perfectly legal in "block" mode...


              --
              --
              You received this message from the "vim_use" maillist.
              Do not top-post! Type your reply below the text you are replying to.
              For more information, visit http://www.vim.org/maillist.php

              ---
              You received this message because you are subscribed to the Google Groups "vim_use" group.
              To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
              For more options, visit https://groups.google.com/groups/opt_out.
            • Ben Fritz
              ... I think you are missing the point. By pressing the : key, you are no longer in visual mode. Visual mode ends the moment you enter command line mode. John
              Message 6 of 17 , Jan 30, 2013
              • 0 Attachment
                On Wednesday, January 30, 2013 8:06:36 AM UTC-6, Axel Bender wrote:
                > Hi John,
                >
                > unfortunately this approach doesn't work in my situation. I'm using the same function in a mapping operating either on visuals, or on motions (:map-operator).
                >
                > Also, I think that if a visual block is displayed (set virtualedit=block, upper left corner in the void), then when switching to the command line and issuing :<C-U>echo virtcol("'<"), the function should return the "correct" left column, as this selection is perfectly legal in "block" mode...

                I think you are missing the point.

                By pressing the : key, you are no longer in visual mode. Visual mode ends the moment you enter command line mode.

                John was trying to demonstrate that you can use <expr> mappings to perform an action in visual mode *without leaving visual mode*. Why exactly doesn't this method apply in your case? You can continue using the same function in both modes.

                --
                --
                You received this message from the "vim_use" maillist.
                Do not top-post! Type your reply below the text you are replying to.
                For more information, visit http://www.vim.org/maillist.php

                ---
                You received this message because you are subscribed to the Google Groups "vim_use" group.
                To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                For more options, visit https://groups.google.com/groups/opt_out.
              • Axel Bender
                Hi Ben, try this: xnoremap _C : call SomeFunc() My current mapping xnoremap _D SomeFunc() John s
                Message 7 of 17 , Jan 30, 2013
                • 0 Attachment
                  Hi Ben,

                  try this:

                  xnoremap <silent> _C :<C-U>call SomeFunc()<CR> " My current mapping
                  xnoremap <silent><expr>_D SomeFunc()<CR> " John's proposal
                  xnoremap <silent> _E SomeFunc()<CR> " same w/o <expr>

                  fun! SomeFunc()
                  let col = virtcol("'<") - 1
                  let ecol = virtcol("'>")

                  for l in range(line("'<"), line("'>"))
                  call setline(l, strpart(getline(l), col, ecol - col))
                  endfor
                  endf

                  Select (ve=block) a visual block from "Fun" down to "ol ", the press _C, _D, and _E. Repeat the same (_C, _E) with an extended block (one line further down - in the void).

                  --
                  --
                  You received this message from the "vim_use" maillist.
                  Do not top-post! Type your reply below the text you are replying to.
                  For more information, visit http://www.vim.org/maillist.php

                  ---
                  You received this message because you are subscribed to the Google Groups "vim_use" group.
                  To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                  For more options, visit https://groups.google.com/groups/opt_out.
                • Ben Fritz
                  ... This should be: xnoremap _C : call SomeFunc() xnoremap _D SomeFunc() Your third mapping will never work, why do you
                  Message 8 of 17 , Jan 30, 2013
                  • 0 Attachment
                    On Wednesday, January 30, 2013 9:49:52 AM UTC-6, Axel Bender wrote:
                    > Hi Ben,
                    >
                    > try this:
                    >
                    > xnoremap <silent> _C :<C-U>call SomeFunc()<CR> " My current mapping
                    > xnoremap <silent><expr>_D SomeFunc()<CR> " John's proposal
                    > xnoremap <silent> _E SomeFunc()<CR> " same w/o <expr>
                    >

                    This should be:
                    xnoremap <silent> _C :<C-U>call SomeFunc()<CR>
                    xnoremap <silent><expr>_D SomeFunc()

                    Your third mapping will never work, why do you expect it to? It is like pressing the keys S o m e F u n c ( ) and then <CR> in sequence, in visual mode. The S will replace the entire visual selection and enter the rest of the text in insert mode.

                    > fun! SomeFunc()
                    > let col = virtcol("'<") - 1
                    > let ecol = virtcol("'>")
                    >
                    > for l in range(line("'<"), line("'>"))
                    > call setline(l, strpart(getline(l), col, ecol - col))
                    > endfor
                    > endf
                    >

                    I modified this to echo the columns instead of doing whatever the for loop does.

                    > Select (ve=block) a visual block from "Fun" down to "ol ", the press _C, _D, and _E. Repeat the same (_C, _E) with an extended block (one line further down - in the void).

                    The first mapping clears visual mode and echos 1 on empty lines, as you reported, and as I and John expect, BECAUSE THE : ENDS VISUAL MODE. There is nothing you can do about this. There is nothing Vim SHOULD do about this. Visual mode is over. Done. Complete. You are no longer in visual block mode so the cursor can no longer be outside the real text.

                    The second mapping works as expected, getting the virtual column of the visual block selection, because IT NEVER LEAVES VISUAL MODE.

                    Note to call a function in a visual mode <expr> mapping, the function should return the text desired for the RHS of the mapping. In this case, adding:

                    return ""

                    to the end of the mapping lets it do no further action on the visual selection.

                    --
                    --
                    You received this message from the "vim_use" maillist.
                    Do not top-post! Type your reply below the text you are replying to.
                    For more information, visit http://www.vim.org/maillist.php

                    ---
                    You received this message because you are subscribed to the Google Groups "vim_use" group.
                    To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                    For more options, visit https://groups.google.com/groups/opt_out.
                  • Axel Bender
                    Please try it again w/o commenting out the stuff. -- -- You received this message from the vim_use maillist. Do not top-post! Type your reply below the text
                    Message 9 of 17 , Jan 30, 2013
                    • 0 Attachment
                      Please try it again w/o commenting out the stuff.

                      --
                      --
                      You received this message from the "vim_use" maillist.
                      Do not top-post! Type your reply below the text you are replying to.
                      For more information, visit http://www.vim.org/maillist.php

                      ---
                      You received this message because you are subscribed to the Google Groups "vim_use" group.
                      To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                      For more options, visit https://groups.google.com/groups/opt_out.
                    • Christian Brabandt
                      ... For expression mappings, you don t need the trailing , because they don t execute the rhs of the mapping, but rather evaluate it. ... Not sure, what
                      Message 10 of 17 , Jan 30, 2013
                      • 0 Attachment
                        On Wed, January 30, 2013 16:49, Axel Bender wrote:
                        > Hi Ben,
                        >
                        > try this:
                        >
                        > xnoremap <silent> _C :<C-U>call SomeFunc()<CR> " My current
                        > mapping
                        > xnoremap <silent><expr>_D SomeFunc()<CR> " John's proposal

                        For expression mappings, you don't need the trailing <CR>, because
                        they don't execute the rhs of the mapping, but rather evaluate it.

                        > xnoremap <silent> _E SomeFunc()<CR> " same w/o <expr>

                        Not sure, what you are expecting here. This won't work.

                        >
                        > fun! SomeFunc()
                        > let col = virtcol("'<") - 1
                        > let ecol = virtcol("'>")
                        >
                        > for l in range(line("'<"), line("'>"))
                        > call setline(l, strpart(getline(l), col, ecol - col))
                        > endfor
                        > endf
                        >
                        > Select (ve=block) a visual block from "Fun" down to "ol ", the press _C,
                        > _D, and _E. Repeat the same (_C, _E) with an extended block (one line
                        > further down - in the void).

                        The problem is, expression-mappings are not allowed to change the
                        text, therefore they can't work exactly the same. To work around this
                        issue, they need to return what the user would type, which would then
                        be executed. E.g. for your usecase, use this function (there might
                        actually be better ways to achieve what you want, I haven't thought
                        about it):

                        xnoremap <silent> _C :<C-U>call SomeFunc()<CR> " My current mapping
                        xnoremap <silent><expr>_D SomeFunc1() " John's proposal

                        [匽

                        fun! SomeFunc1()
                        let col = virtcol("'<") - 1
                        let ecol = virtcol("'>")
                        let range= range(line("'<"), line("'>"))

                        let result=printf(": for l in %s|".
                        \ "call setline(l, strpart(getline(l), %d, %d))|".
                        \ "endfor", string(range), col, ecol-col)
                        return result
                        endf

                        regards,
                        Christian

                        --
                        --
                        You received this message from the "vim_use" maillist.
                        Do not top-post! Type your reply below the text you are replying to.
                        For more information, visit http://www.vim.org/maillist.php

                        ---
                        You received this message because you are subscribed to the Google Groups "vim_use" group.
                        To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                        For more options, visit https://groups.google.com/groups/opt_out.
                      • Axel Bender
                        Hi Christian, thanks for the answer. I completely go with you concerning , but this was not my original problem. In fact, I already have a solution for
                        Message 11 of 17 , Jan 30, 2013
                        • 0 Attachment
                          Hi Christian,

                          thanks for the answer. I completely go with you concerning <expr>, but this was not my original problem.

                          In fact, I already have a solution for it (temporarily setting ve to "all"), which doesn't require me to change any mapping.

                          However the inconsistency remains: when - with ve=block - I select a visual block and one corner is in the void, :<C-U>echo virtcol("'<") returns 1, while with ve set to "all" - the same command correctly(?) returns the start of the block.

                          If - as Ben said - by moving into the command line - I've ended visual mode, then why doesn't this hold for both settings?

                          --
                          --
                          You received this message from the "vim_use" maillist.
                          Do not top-post! Type your reply below the text you are replying to.
                          For more information, visit http://www.vim.org/maillist.php

                          ---
                          You received this message because you are subscribed to the Google Groups "vim_use" group.
                          To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                          For more options, visit https://groups.google.com/groups/opt_out.
                        • Ben Fritz
                          ... Because with ve=all, the cursor is allowed to be outside the real text lines even when not in visual mode. -- -- You received this message from the
                          Message 12 of 17 , Jan 30, 2013
                          • 0 Attachment
                            On Wednesday, January 30, 2013 10:35:21 AM UTC-6, Axel Bender wrote:
                            > Hi Christian,
                            >
                            > thanks for the answer. I completely go with you concerning <expr>, but this was not my original problem.
                            >
                            > In fact, I already have a solution for it (temporarily setting ve to "all"), which doesn't require me to change any mapping.
                            >
                            > However the inconsistency remains: when - with ve=block - I select a visual block and one corner is in the void, :<C-U>echo virtcol("'<") returns 1, while with ve set to "all" - the same command correctly(?) returns the start of the block.
                            >
                            > If - as Ben said - by moving into the command line - I've ended visual mode, then why doesn't this hold for both settings?

                            Because with ve=all, the cursor is allowed to be outside the real text lines even when not in visual mode.

                            --
                            --
                            You received this message from the "vim_use" maillist.
                            Do not top-post! Type your reply below the text you are replying to.
                            For more information, visit http://www.vim.org/maillist.php

                            ---
                            You received this message because you are subscribed to the Google Groups "vim_use" group.
                            To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                            For more options, visit https://groups.google.com/groups/opt_out.
                          • John Little
                            ... Yes, but it is still showing in the window. Not that I d want it not to, but the situation is a little murky, in that what you see is not what you get.
                            Message 13 of 17 , Jan 30, 2013
                            • 0 Attachment
                              On Thursday, January 31, 2013 5:02:56 AM UTC+13, Ben Fritz wrote:
                              >...BECAUSE THE : ENDS VISUAL MODE. ... Visual mode is over. Done. Complete...

                              Yes, but it is still showing in the window. Not that I'd want it not to, but the situation is a little murky, in that what you see is not what you get.

                              Regards, John

                              --
                              --
                              You received this message from the "vim_use" maillist.
                              Do not top-post! Type your reply below the text you are replying to.
                              For more information, visit http://www.vim.org/maillist.php

                              ---
                              You received this message because you are subscribed to the Google Groups "vim_use" group.
                              To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@....
                              For more options, visit https://groups.google.com/groups/opt_out.
                            Your message has been successfully submitted and would be delivered to recipients shortly.