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

Re: "hungry" delete in vim?

Expand Messages
  • Mark Khemma
    Try this out: imap bi :s/ +// i basically what it does is go into normal mode, then move back to the beginning of
    Message 1 of 5 , Sep 2, 2002
      Try this out:
      imap <your mapkey of choice> <ESC>bi<CR><ESC>:s/ \+//<CR>i<BS>

      basically what it does is go into normal mode,
      then move back to the beginning of the previous word
      go into insert mode
      carriage return to move it to next line
      the regex continuous whitespace (one instance)
      back into insert mode
      the move the word back.

      you have to move that last word to the next line because if you do the
      regex without it, it would remove the first instance of continuous
      whitespaces at the beginning of that line, if that makes any sense.

      I dont' know if this is exactly what you want but, it was a
      fun puzzle for me to try :)

      -mark.k

      On Mon, 2 Sep 2002, Peter Wright wrote:

      >
      > Hi all,
      >
      > I've been trying to work out how to implement a "hungry" whitespace
      > delete mapping in Vim 6.1. By this I mean: in insert mode, if you hit
      > the backspace key (though I've used control-backspace in my attempts
      > below, so I don't inadvertantly stuff up my "normal" backspace), it
      > will delete backwards over consecutive whitespace characters until
      > reaching a non-whitespace character (including blank lines).
      >
      > For those who know Emacs, yes, much like the hungry-delete feature in
      > Emacs' C-mode.
      >
      > I played around with this for a bit, trying to work out some way to
      > implement it, but have not completely succeeded, and I was hoping
      > someone could either (a) tell me a way to get my attempt (shown below)
      > working properly, or (b) could suggest a completely different way of
      > solving the problem.
      >
      >
      > I tried a mapping like so:
      >
      > " Attempt at hungry-delete...
      > " NB. using control-backspace for now.
      > set virtualedit=block
      > imap <C-BS> <Esc>vgE<Space>xi
      >
      >
      > Unfortunately, this (a) doesn't handle the case of multiple blank
      > lines between starting point and "corrent" end point as empty lines
      > are considered "words" (see :help gE):
      >
      > > A WORD consists of a sequence of non-blank characters, separated
      > > with white space. An empty line is also considered to be a word and
      > > a WORD.
      >
      > ...and (b) doesn't handle the case where the starting cursor point is
      > at the _beginning_ of a line.
      >
      > Also, I really don't like the idea of 'x'-ing stuff into a register,
      > when the user normally wouldn't expect backspacing to "copy" the
      > deleted text.
      >
      > I'd prefer some way to map <C-BS> to some kind of function that will
      > keep backspacing while (character-immediately-before-cursor is
      > whitespace or end-of-line). But I'm not actually sure if that's
      > possible *wry grin*... my Vim scripting experience is fairly minimal.
      >
      > I'd appreciate any suggestions on implementing this... a complete
      > solution would be fantastic, but even a hint on implementing just the
      > "while" condition described in the previous paragraph would be nice.
      > Hell, I'd like to know how to do that even if someone can offer a
      > completely different way to handle the mapping... ;-)
      >
      >
      > Thanks,
      >
      > Pete.
      > --
      > http://akira.apana.org.au/~pete/
      > "Beware of bugs in the above code; I have only proved
      > it correct, not tried it." -- Donald Knuth
      >
    • Preben 'Peppe' Guldberg
      ... While not excactly what you describe, I quite like setting softtabstop equal to shiftwidth when I set expandtab . Doing so, a backspace in insert mode
      Message 2 of 5 , Sep 2, 2002
        Thus wrote Peter Wright (pete@...) on [020902]:

        > I've been trying to work out how to implement a "hungry" whitespace
        > delete mapping in Vim 6.1. By this I mean: in insert mode, if you hit
        > the backspace key (though I've used control-backspace in my attempts
        > below, so I don't inadvertantly stuff up my "normal" backspace), it
        > will delete backwards over consecutive whitespace characters until
        > reaching a non-whitespace character (including blank lines).

        While not excactly what you describe, I quite like setting 'softtabstop'
        equal to 'shiftwidth' when I set 'expandtab'. Doing so, a backspace in
        insert mode will delete a soft tabstops worth of spaces.

        For an initial test, try

        $ vim -u NONE -N -c 'se et sts=8'

        Also see ":help 'softtabstop'".

        Peppe
        --
        Preben 'Peppe' Guldberg __/-\__ "Before you criticize someone, walk
        peppe@... (o o) a mile in his shoes. That way, if
        -----------------------oOOo (_) oOOo-- he gets angry, he'll be a mile away
        http://www.xs4all.nl/~peppe/ - and barefoot." --Sarah Jackson
      • David Brown
        Try this out: imap v? S?e+1 di This mapping does not work if only white space exists to the beginning of the file. If you have wrapscan turned
        Message 3 of 5 , Sep 5, 2002
          Try this out:

          imap <C-BS> <ESC>v?\\S?e+1<CR>di

          This mapping does not work if only white space exists to the beginning of
          the file. If you have wrapscan turned on it will delete everything from the
          cursor to the last nonwhite stuff in the file. If you have wrapscan turned
          off it gives an error message (no nonwhite space to find) and deletes
          nothing. Other then that, it seemed to work very well.

          -----Original Message-----
          From: Peter Wright [mailto:pete@...]On Behalf Of Peter
          Wright
          Sent: Monday, September 02, 2002 1:37 AM
          To: vim@...
          Subject: "hungry" delete in vim?



          Hi all,

          I've been trying to work out how to implement a "hungry" whitespace
          delete mapping in Vim 6.1. By this I mean: in insert mode, if you hit
          the backspace key (though I've used control-backspace in my attempts
          below, so I don't inadvertantly stuff up my "normal" backspace), it
          will delete backwards over consecutive whitespace characters until
          reaching a non-whitespace character (including blank lines).

          For those who know Emacs, yes, much like the hungry-delete feature in
          Emacs' C-mode.

          I played around with this for a bit, trying to work out some way to
          implement it, but have not completely succeeded, and I was hoping
          someone could either (a) tell me a way to get my attempt (shown below)
          working properly, or (b) could suggest a completely different way of
          solving the problem.


          I tried a mapping like so:

          " Attempt at hungry-delete...
          " NB. using control-backspace for now.
          set virtualedit=block
          imap <C-BS> <Esc>vgE<Space>xi


          Unfortunately, this (a) doesn't handle the case of multiple blank
          lines between starting point and "corrent" end point as empty lines
          are considered "words" (see :help gE):

          > A WORD consists of a sequence of non-blank characters, separated
          > with white space. An empty line is also considered to be a word and
          > a WORD.

          ...and (b) doesn't handle the case where the starting cursor point is
          at the _beginning_ of a line.

          Also, I really don't like the idea of 'x'-ing stuff into a register,
          when the user normally wouldn't expect backspacing to "copy" the
          deleted text.

          I'd prefer some way to map <C-BS> to some kind of function that will
          keep backspacing while (character-immediately-before-cursor is
          whitespace or end-of-line). But I'm not actually sure if that's
          possible *wry grin*... my Vim scripting experience is fairly minimal.

          I'd appreciate any suggestions on implementing this... a complete
          solution would be fantastic, but even a hint on implementing just the
          "while" condition described in the previous paragraph would be nice.
          Hell, I'd like to know how to do that even if someone can offer a
          completely different way to handle the mapping... ;-)


          Thanks,

          Pete.
          --
          http://akira.apana.org.au/~pete/
          "Beware of bugs in the above code; I have only proved
          it correct, not tried it." -- Donald Knuth
        • Thomas S. Urban
          ... This behaves strangely for me, leaving the cursor at the wrong place and deleting multiple characters when used on non-whitespace. I think your best bet
          Message 4 of 5 , Sep 6, 2002
            On Fri, Sep 06, 2002 at 00:42:12 -0400, David Brown sent 2.8K bytes:
            > From: Peter Wright [mailto:pete@...]On Behalf Of Peter
            > > I've been trying to work out how to implement a "hungry" whitespace
            > > delete mapping in Vim 6.1. By this I mean: in insert mode, if you hit
            > > the backspace key (though I've used control-backspace in my attempts
            > > below, so I don't inadvertantly stuff up my "normal" backspace), it
            > > will delete backwards over consecutive whitespace characters until
            > > reaching a non-whitespace character (including blank lines).
            >
            > Try this out:
            >
            > imap <C-BS> <ESC>v?\\S?e+1<CR>di

            This behaves strangely for me, leaving the cursor at the wrong place and
            deleting multiple characters when used on non-whitespace. I think your
            best bet is to write a function and call it from your mapping, the below
            is a quick trial that seems to handle beginning of file, newline, and
            normal characters. The logic could probably use some clean up:

            function! GreedyBackspace()
            let c = getline(line("."))[col(".") - 1]
            if c == ' ' || c == "\t" || col("$") == 1
            while c == ' ' || c == "\t" || col("$") == 1
            if col("$") == 1
            if line (".") == 1
            break
            endif
            normal k$gJ
            else
            normal x
            endif
            let c = getline(line("."))[col(".") - 1]
            endwhile
            else
            normal x
            endif
            endfunction
            imap <C-BS> <Esc>:call GreedyBackspace()<CR>a

            <snip>

            Scott

            --
            ... The prejudices people feel about each other disappear when then get
            to know each other.
            -- Kirk, "Elaan of Troyius", stardate 4372.5
          Your message has been successfully submitted and would be delivered to recipients shortly.