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

vim: map a key to "conditionally" override built-in behavior

Expand Messages
  • ping
    this looks weird at first glance. but sometime, I want to give the existing keystroke (like h ) a new behavior, at a very certain circumstance. for example,
    Message 1 of 5 , Feb 18, 2013
    • 0 Attachment
      this looks weird at first glance.
      but sometime, I want to give the existing keystroke (like 'h') a new
      behavior, at a very certain circumstance.
      for example, if you use ranger (file manager), by default it will end up
      with opening the text file in vim, if you keep press "l" towards the
      file. now you disconnect (temporarily ) with range and you are with vim.
      then to go back you have to type vim's keystroke (:q) to exit vim and
      turn control back to ranger.

      I'm thinking if I want to make it real consistent , I need to have a "h"
      key that can exit vim and go back to ranger, just opposite what a "l"
      key does in ranger.
      but if I map it (absolute map) this way:

      map h :q

      it will be obviously a disaster.

      so , how can I map the 'h', to ":q", if , and only if, say, my cursor is
      in the left/top corner of the file?

      --
      --
      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.
    • Paul Isambert
      ... You can use to define a mapping with a function: function! Map() if line( . ) == 1 && wincol( . ) == 1 return :q r else return h endif
      Message 2 of 5 , Feb 19, 2013
      • 0 Attachment
        ping <songpingemail@...> a écrit:
        > this looks weird at first glance.
        > but sometime, I want to give the existing keystroke (like 'h') a new
        > behavior, at a very certain circumstance.
        > for example, if you use ranger (file manager), by default it will end up
        > with opening the text file in vim, if you keep press "l" towards the
        > file. now you disconnect (temporarily ) with range and you are with vim.
        > then to go back you have to type vim's keystroke (:q) to exit vim and
        > turn control back to ranger.
        >
        > I'm thinking if I want to make it real consistent , I need to have a "h"
        > key that can exit vim and go back to ranger, just opposite what a "l"
        > key does in ranger.
        > but if I map it (absolute map) this way:
        >
        > map h :q
        >
        > it will be obviously a disaster.
        >
        > so , how can I map the 'h', to ":q", if , and only if, say, my cursor is
        > in the left/top corner of the file?

        You can use <expr> to define a mapping with a function:

        function! <SID>Map()
        if line(".") == 1 && wincol(".") == 1
        return ":q\r"
        else
        return "h"
        endif
        endfunction

        nnoremap <expr> h <SID>Map()

        If you meant the “topleft corner of the window” rather than “of the
        file”, replace “line(".")” with “winline()” and “col(".")” with
        “wincol()”. However, the latter might be surprising because it takes
        into account the width of the linenumbers column (if you use it),
        which you can factor out with “numberwidth”:

        function! <SID>Map()
        if winline() == 1 && wincol() - (&number ? &numberwidth : 0) == 1
        return ":q\r"
        else
        return "h"
        endif
        endfunction

        Best,
        Paul

        --
        --
        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.
      • ping
        ... thanks! I still don t fully understand the theory of this thing (even read ... but per my test this doesn t work well. it s weird that echo wincol()
        Message 3 of 5 , Feb 19, 2013
        • 0 Attachment
          On 2/19/2013 4:20 AM, Paul Isambert wrote:
          > You can use <expr> to define a mapping with a function:
          >
          > function! <SID>Map()
          > if line(".") == 1 && wincol(".") == 1
          > return ":q\r"
          > else
          > return "h"
          > endif
          > endfunction
          >
          > nnoremap <expr> h <SID>Map()
          thanks!

          I still don't fully understand the theory of this <SID> thing (even read
          : help <SID>)
          but per my test this doesn't work well.
          it's weird that echo wincol() starting from 7, instead of 1, when I move
          my cursor to the leftmost column.

          regards
          ping

          --
          --
          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.
        • ping
          ... this works, thanks! if line( . ) == 1 && virtcol( . ) == 1 ... -- -- You received this message from the vim_use maillist. Do not top-post! Type your
          Message 4 of 5 , Feb 19, 2013
          • 0 Attachment
            On 2/19/2013 5:50 PM, ping wrote:
            > On 2/19/2013 4:20 AM, Paul Isambert wrote:
            >> You can use <expr> to define a mapping with a function:
            >>
            >> function! <SID>Map()
            >> if line(".") == 1 && wincol(".") == 1
            "this works, thanks!
            if line(".") == 1 && virtcol(".") == 1
            >> return ":q\r"
            >> else
            >> return "h"
            >> endif
            >> endfunction
            >>
            >> nnoremap <expr> h <SID>Map()
            > thanks!
            >
            > I still don't fully understand the theory of this <SID> thing (even
            > read : help <SID>)
            > but per my test this doesn't work well.
            > it's weird that echo wincol() starting from 7, instead of 1, when I
            > move my cursor to the leftmost column.
            >
            > regards
            > ping

            --
            --
            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.
          • Paul Isambert
            ... Quite normal it doesn’t work, I made a mistake and mixed two versions. The conditional should be either (to trigger the special mapping when in the upper
            Message 5 of 5 , Feb 20, 2013
            • 0 Attachment
              ping <songpingemail@...> a écrit:
              > On 2/19/2013 4:20 AM, Paul Isambert wrote:
              > > You can use <expr> to define a mapping with a function:
              > >
              > > function! <SID>Map()
              > > if line(".") == 1 && wincol(".") == 1
              > > return ":q\r"
              > > else
              > > return "h"
              > > endif
              > > endfunction
              > >
              > > nnoremap <expr> h <SID>Map()
              > thanks!
              >
              > I still don't fully understand the theory of this <SID> thing (even read
              > : help <SID>)
              > but per my test this doesn't work well.

              Quite normal it doesn’t work, I made a mistake and mixed two versions.
              The conditional should be either (to trigger the special mapping when
              in the upper left corner of the window):

              if winline() == 1 && wincol() - (&number ? &numberwidth : 0) == 1

              or (to trigger the mapping in the upper left corner of the file):

              if line(".") == 1 && col(".") == 1

              As for <SID>: the “real name” of a <SID>-prefixed function is that
              function’s name with a prefix unique to the script, so that in script
              Foo “<SID>MyFunc()” is e.g. “<SNR>22_MyFunc()” and in script Bar
              “<SID>MyFunc()” is e.g. “<SNR>47_MyFunc()”. In the script itself, the
              script’s author can use <SID> without bothering to define a unique
              prefix; the automatic replacement then ensures that functions with the
              same names don’t clash outside the script.

              > it's weird that echo wincol() starting from 7, instead of 1, when I move
              > my cursor to the leftmost column.

              That’s because wincol() really starts counting at the window’s left
              side, before line numbers.

              Best,
              Paul

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