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

visualmode(0) now indicates visualmode is recent

Expand Messages
  • Charles E. Campbell, Jr.
    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.
    Message 1 of 4 , Dec 4, 2003
    • 0 Attachment
      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"

      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.

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

      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].

      Regards,
      Chip Campbell
    • 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 2 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 3 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 4 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.