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

Re: visualmode(0) now indicates visualmode is recent

Expand Messages
  • Benji Fisher
    ... Clarification: - means not recent and + means recent, right? ... I would count the first op as a Visual-mode operator, not a Normal-mode one, but I
    Message 1 of 4 , Dec 4, 2003
    • 0 Attachment
      On Thu, Dec 04, 2003 at 12:36:05PM -0500, Charles E. Campbell, Jr. wrote:
      > Hello! (apologies if this message is duplicated)
      >
      > The visualmode() function returns blank, v, V, or ctrl-v, reflecting
      > the last visual mode that was selected. Unfortunately that selection
      > can have already been "used" quite a bit ago and not be intended
      > for the current activity, and so can be misleading.
      >
      > The mode() function isn't of much help when functions/scripts are
      > being invoked and need to know if they're to handle a visually-selected
      > area or not.
      >
      > Thus these patches to visualmode():
      >
      > visualmode() returns " ", "v", "V", "ctrl-v" as now
      > visualmode(1) clears visual mode, returning last mode, as now
      > visualmode(0) will now return a leading - or + to indicate
      > that visual mode was selected recently:
      > "- " "-v" "-V" or "-ctrl-v"
      > "+ " "+v" "+V" or "+ctrl-v"

      Clarification: - means "not recent" and + means "recent," right?

      > visualmode(0) itself will clear the "recently" indicator.
      >
      > Two or more toplevel normal-mode commands will clear the "recently"
      > indicator;
      > thus a visualmode..motion..op will leave the "recently" indicator on,
      > but the very next toplevel normal mode command will clear it.

      I would count the first op as a Visual-mode operator, not a
      Normal-mode one, but I think I get the idea. Does the : (go from Normal
      to Command-line mode) count as a Normal-mode operator?

      > Terminating visual mode with an <Esc> will clear the "recently" indicator.

      So there is a difference between

      :vmap <F5> :<C-U>call MyGreatFun()<CR>

      and

      :vmap <F5> <Esc>:call MyGreatFun()<CR>

      if MyGreatFun() invokes visualmode(0), right? I am not sure I like
      this twist, but maybe it is useful. Is this a special case of the rule
      above, with <Esc> being the first (Visual? Normal?) operator, and :
      being the second?

      > Note that a simple :'<,'>call Test() with
      >
      > fun! Test()
      > echomsg "[".visualmode(0)."]"
      > endfun
      >
      > ends up invoking Test() twice, hence the first invocation will echo [+v]
      > and the second one will echo [-v].

      You are assuming a Visual range including exactly two lines, I
      think. I am still getting the hang of this. It took me a minute to
      realize that the second time echos [-v] because calling visualmode(0)
      clears it, not because Visual mode is no longer recent.

      I guess the advantage of all this is that if I define a function to
      comment out code, or quote/unquote mail messages, etc., then instead of

      :nmap \q :call Sherpa("n")<CR>
      :vmap \q :call Sherpa("v")<CR>

      (where the argument tells the function whether it was called from Normal
      or Visual mode) the Sherpa() function (which does all the work ... it
      must be late ...) can test visualmode(0) and decide for itself. What
      about MyMotionFunction(), which might be called from Normal, Visual, or
      Operator-pending mode and needs to know which?

      --Benji Fisher
    • Charles E. Campbell, Jr.
      ... Yes, sorry bout not mentioning that! ... Normal-mode one, ... Command-line mode) ... Apparently it does -- it goes tbrough normal_cmd(). ... indicator.
      Message 2 of 4 , Dec 5, 2003
      • 0 Attachment
        Benji Fisher wrote:
        >On Thu, Dec 04, 2003 at 12:36:05PM -0500, Charles E. Campbell, Jr. wrote:
        >> visualmode() returns " ", "v", "V", "ctrl-v" as now
        >> visualmode(1) clears visual mode, returning last mode, as now
        >> visualmode(0) will now return a leading - or + to indicate
        >> that visual mode was selected recently:
        >> "- " "-v" "-V" or "-ctrl-v"
        >> "+ " "+v" "+V" or "+ctrl-v"
        >
        > Clarification: - means "not recent" and + means "recent," right?

        Yes, sorry 'bout not mentioning that!

        > I would count the first op as a Visual-mode operator, not a
        Normal-mode one,
        > but I think I get the idea. Does the : (go from Normal to
        Command-line mode)
        > count as a Normal-mode operator?

        Apparently it does -- it goes tbrough normal_cmd().

        >>Terminating visual mode with an <Esc> will clear the "recently"
        indicator.
        >
        > So there is a difference between
        >
        >:vmap <F5> :<C-U>call MyGreatFun()<CR>
        >
        >and
        >
        >:vmap <F5> <Esc>:call MyGreatFun()<CR>

        Yes, because the <Esc> will internally call end_visual_mode();
        ie. it explicitly terminates visual mode.

        > if MyGreatFun() invokes visualmode(0), right? I am not sure I like
        > this twist, but maybe it is useful. Is this a special case of the rule
        > above, with <Esc> being the first (Visual? Normal?) operator, and :
        > being the second?

        The problem is that the internal variable "VIsual_active", obviously which
        indicates that visual mode is active, gets turned off before any user
        function gets called (either by the : or <Esc> methods you mentioned above).
        So, to know if visual mode is intended for that function call I have to make
        vim remember that visual mode status a little longer.

        >>Note that a simple :'<,'>call Test() with
        >>
        >> fun! Test()
        >> echomsg "[".visualmode(0)."]"
        >> endfun
        >>
        >>ends up invoking Test() twice, hence the first invocation will echo [+v]
        >>and the second one will echo [-v].
        >
        > You are assuming a Visual range including exactly two lines, I
        >think.

        As an example of how to operate with a range...

        fun! Test() range
        echomsg "[".visualmode(0)."]"
        let i=a:firstline
        while i < a:lastline
        echo "doing something on the range: ".i
        let i=i+1
        endwhile
        endfun

        > I am still getting the hang of this. It took me a minute to
        > realize that the second time echos [-v] because calling visualmode(0)
        > clears it, not because Visual mode is no longer recent.

        Actually at first I too was thinking it was due to multiple calls
        to Test(). Perhaps the clearing of the active mode could be put
        into visualmode(1) (which is already available with 6.2). OK, I've
        made another patch. You'll want to remove the old patch first,
        then apply the new one. The new patch won't clear old_VIsual_active
        (the "recent visual mode indicator") when visualmode(0) is called,
        but will when visualmode(1) is called.

        > I guess the advantage of all this is that if I define a function to
        >comment out code, or quote/unquote mail messages, etc., then instead of
        >
        >:nmap \q :call Sherpa("n")<CR>
        >:vmap \q :call Sherpa("v")<CR>
        >
        >(where the argument tells the function whether it was called from Normal
        >or Visual mode) the Sherpa() function (which does all the work ... it
        >must be late ...) can test visualmode(0) and decide for itself. What
        >about MyMotionFunction(), which might be called from Normal, Visual, or
        >Operator-pending mode and needs to know which?

        normal: visualmode(0) will yield "-"
        visual: visualmode(0) will yield "+v" "+V" "+ctrl-v", whichever
        op-pend: visualmode(0) will yield "-"

        I've never used operator-pending mode myself; ok, here's a small
        example:

        -------------------------------
        omap <silent> { :call Tst()<CR>

        fun! Tst()
        echomsg "[".visualmode(0)."]"
        norm! yiw
        endfun
        -------------------------------
        (exercise it with y{ )

        I've written some functions (in <vis.vim> and <Align.vim>) that try to
        detect if visualmode is on or not, but sadly its unreliable with 6.2.
        Looks like more would need to be done to detect if operator-pending
        mode is on.

        Regards,
        Chip Campbell
      • Charles E. Campbell, Jr.
        Hello! I ve put two patches up on my website (http://www.erols.com/astronaut/vim/index.html#Patch): startreplace which starts replace mode, akin to
        Message 3 of 4 , Dec 5, 2003
        • 0 Attachment
          Hello!

          I've put two patches up on my website
          (http://www.erols.com/astronaut/vim/index.html#Patch):

          startreplace which starts replace mode, akin to :startinsert)

          visualmode(0) which returns
          - -v -^V : indicating visualmode and that its not
          currently active
          + +v +^V : indicating visualmode and that it is
          currently active
          Regards,
          Chip Campbell
        Your message has been successfully submitted and would be delivered to recipients shortly.