Inrtroduce a new standard text-object for whitespace? (Example for application -- trim whitespace)

1 view
Skip to first unread message

pepegnu

unread,
Nov 22, 2009, 6:59:37 PM11/22/09
to vim_dev
Hi everybody,

This is my first post to this group to propose an enhancement to Vim
which (I'm just a Vim user and not a developer, so that all the
statements below should be considered beginning with "IMHO")

1) provides some often needed functionality
2) is not available (at least in <= three keystrokes) in Vim
(while existent, in two keystrokes, in Emacs -> `M-\’ (‘delete-
horizontal-space’))
3) is highly consistent with the spirit of Vim
4) is not affecting/orthogonal/independent of/to existing normal-
mode commands
4) should be quite easy to implement

Suppose we had a predefined text-object for whitespace ([[:blank:]],
consecutive spaces+TABs+(newlines?) in Vim following the same logic as
w|Word, sentence, paragraph, block, tag, etc (used every so often by
daw (the delete-a-word command), cit (change-in-tag), vit (mark-in-
tag), etc.).

Consider the following situation, you edit the text (underscore
represents whitespace):

blah-blah-blah_____________________<cursor
here>___________________blah-blah-blah again

Now, it seems that '_' (underscore) is a free token in the context of
a text-object. If defined as a new text-object for whitespace, one
will be able to trim whitespace around the cursor in the example above
by issuing da_ (mnemonics: delete-a-blank), or ci_ (change-in-blank)
in normal mode to get

blah-blah-blah blah-blah-blah again

This will be consistent with the behaviour all the other text objects
under the operations c(hange)|d(elete)|v(mark) etc., so I suppose that
it will be a welcome extension, which is

* easy to memorize
* acting consistentley under the same operators as
the rest of the text objects
* hopefully benevolently embraced by the Vim-users
community.

Best regards,
//Peppe

Kana Natsuno

unread,
Nov 22, 2009, 8:38:07 PM11/22/09
to vim...@googlegroups.com
On Mon, 23 Nov 2009 08:59:37 +0900, pepegnu <pep...@gmail.com> wrote:
> Consider the following situation, you edit the text (underscore
> represents whitespace):
>
> blah-blah-blah_____________________<cursor
> here>___________________blah-blah-blah again
>
> Now, it seems that '_' (underscore) is a free token in the context of
> a text-object. If defined as a new text-object for whitespace, one
> will be able to trim whitespace around the cursor in the example above
> by issuing da_ (mnemonics: delete-a-blank), or ci_ (change-in-blank)
> in normal mode to get
>
> blah-blah-blah blah-blah-blah again

It seems to be somewhat useful, but:

- What is the differences between a_ and i_?

- Currently iw on spaces serves as your a_/i_.
Isn't it enough? If not so, why?


--
To Vim, or not to Vim.
http://whileimautomaton.net/

Andy Spencer

unread,
Nov 22, 2009, 8:30:01 PM11/22/09
to vim...@googlegroups.com
On 2009-11-22 15:59, pepegnu wrote:
> Consider the following situation, you edit the text (underscore
> represents whitespace):
>
> blah-blah-blah_____________________<cursor
> here>___________________blah-blah-blah again
>
> Now, it seems that '_' (underscore) is a free token in the context of
> a text-object. If defined as a new text-object for whitespace, one
> will be able to trim whitespace around the cursor in the example above
> by issuing da_ (mnemonics: delete-a-blank), or ci_ (change-in-blank)
> in normal mode to get
>
> blah-blah-blah blah-blah-blah again

Does iw (diw, ciw, etc) do what you want? iw it has odd behavior when
using newlines which might not be what you want, but it might work for
tabs and spaces.

pepegnu

unread,
Nov 23, 2009, 4:21:51 AM11/23/09
to vim_dev
You're quite right, though diw does the job

* only for spaces and tabs, but does not trim, i.e. it leaves
the words glued together, e.g.,

textbefore_____<cursor>______textafter -->
textbeforetextafter

which requires typing an aditional space

* Does not trim vertical whitespace (newlines)

What i had in mind was approximately that

* di_ is the same as diw + additional space, e.g.

textbefore_____<cursor>______textafter --> textbefore
textafter

*while da_ trims also vertical whitespace (if present), e.g.,

_______textbefore______
____\n
______ \n
<cursor>
___\n
___\n
_______textafter --> textbefore textafter

If there is not vertical whitespace, da_ should double the
functionality of di_.




On Nov 23, 2:38 am, "Kana Natsuno" <k...@whileimautomaton.net> wrote:

Peppe Gnu

unread,
Nov 23, 2009, 7:13:52 AM11/23/09
to vim...@googlegroups.com
I wansted to add a couple of words more:
While diw and dip achieve almost (apart from inserting a space) the
desired effect for trimming whitespace,

* This behaviour is not consistent with the definition of W|word and
paragraph (it seems that when the cursor resides in whitespace the
definition of word and paragraph, bounded from both sides by
corresponding whitespace and not vice versa, are negated)
* This behaviour does not seem to be documented, and is thus not
quite anticipated by the user
* Finally, as objects are not part of the classical vi,

it seems to be easier to introduce whitespace as a new object and free
the def of W|word and paragraph of context dependence.

One gains consistence while not braking backward compatibility.

Andy Wokula

unread,
Nov 23, 2009, 8:42:36 AM11/23/09
to vim...@googlegroups.com
pepegnu schrieb:

> You're quite right, though diw does the job
>
> * only for spaces and tabs, but does not trim, i.e. it leaves
> the words glued together, e.g.,
>
> textbefore_____<cursor>______textafter -->
> textbeforetextafter
>
> which requires typing an aditional space

You can use dviw instead. This will leave the last character of the
whitespace sequence (can be a Tab - type "r " to turn it into a Space).
:h o_v

> * Does not trim vertical whitespace (newlines)

You can use dvip instead. If this leaves a blank line (instead of an
empty line), you can type 0D to make it empty.

> What i had in mind was approximately that
>
> * di_ is the same as diw + additional space, e.g.
>
> textbefore_____<cursor>______textafter --> textbefore
> textafter

See dviw above.

> * while da_ trims also vertical whitespace (if present), e.g.,


>
> _______textbefore______
> ____\n
> ______ \n
> <cursor>
> ___\n
> ___\n
> _______textafter --> textbefore textafter

This is not how text objects work. You can select text, but not edit
text. If the selection between "textbefore" and "textafter" doesn't
contain a Space, there is no way to make "da_" leave a Space afterwards.

> If there is not vertical whitespace, da_ should double the
> functionality of di_.

---------------------------------------------------------------------

The following mapping trims whitespace around the cursor, leaving one
Space or one empty line.
This has been for a long time in my vimrc (note the many bug fixes) ...


nn <silent> drw :<C-U>call DeleteRubbishWhitespace()<CR>

func! DeleteRubbishWhitespace()
" Former "delete reduced word" (a word but one character); but, only
" useful to reduce many SPACES or BLANK LINES to one, as it works
" now. This is a safe command, it does not delete real text!
" BF: now works if some of the blank lines are within a folded area
" BF: now keeps the buffer unmodified if there is no actual change
" BF: does no longer unwanted scrolling
" NF: repeatable with "." (Vimscript #2136)
" BF: didn't work with 've=all'
" BF: '] is bad when no change was made
let savopt = [&ve]
set virtualedit=
let line = getline(".")
if line =~ '^\s*$'
let sav_pos = winsaveview()
let sav_fen = &fen
setlocal nofoldenable
normal! dvip0D
let sav_pos.lnum = line(".")
let &l:fen = sav_fen
call winrestview(sav_pos)
elseif line[col(".")-1] =~ '\s'
normal! zvyiw
if @@ != " "
normal! dviwr m[
" m[ is just to avoid a trailing space
endif
endif
let [&ve] = savopt
silent! call repeat#set("drw")
endfunc

--
Andy

Reply all
Reply to author
Forward
0 new messages