1

To grab a full word from anywhere in the word I can do:

  • viw

And to grab an entire line from start to finish I can do:

  • V

However, is there a section that grabs all text from the first char to the last? For example, like this:

enter image description here

I find myself selecting the line of text (from anywhere in the line) quite frequently and it seems like this is a pretty common thing to do.

0

3 Answers 3

2

The fastest I can come up with is really ^vg_ to be precise about start and end of line.

But, by way of challenge, perhaps you really need dd, yy, cc, or similar? Even guu and g~~ work.


If you can do it with an ex command, . is the shortest "this line" range; note that many commands take it by default.

2
  • Thanks for this. Could you please explain a bit guu and g~~ ?
    – David542
    Apr 25, 2020 at 2:07
  • Sure; according to :help gu, it's an operator that lowercases the following motion. gU uppercases, and g~ toggles case. As with most builtin operators, doubling the sequence operates on the current line (and, since these are length 2, gugu and guu have been made to work). You might also like g? @David542, it's a ROT13
    – D. Ben Knoble
    Apr 25, 2020 at 2:21
3

Here's an il operator that behaves like iw but selects a line, from first to last non-blank character in the line:

function! SelectLine(count) abort
  normal! gv
  if visualmode() !=# 'v'
    normal! v
  endif
  let startpos = getpos("'<")
  let endpos = getpos("'>")
  if startpos == endpos
    execute "normal! ^o".a:count."g_"
    return
  endif
  let curpos = getpos('.')
  if curpos == endpos
    normal! g_
    let curpos = getpos('.')
    if curpos == endpos
      execute "normal!" (a:count+1)."g_"
    elseif a:count > 1
      execute "normal!" a:count."g_"
    endif
  else
    normal! ^
    let curpos = getpos('.')
    if curpos == startpos
      execute "normal!" a:count."-"
    elseif a:count > 1
      execute "normal!" (a:count-1)."-"
    endif
  endif
endfunction
xnoremap <silent> il :<C-U>call SelectLine(v:count1)<CR>
onoremap <silent> il :<C-U>execute "normal! ^v".v:count1."g_"<CR>

Supports usage in visual mode (e.g.vil) or in operator mode (yil to yank the line in characterwise mode.)

Supports usage with a count (v3il or y3il.)

In visual mode, it supports adding to the visual selection with further ils adding more lines of text. Works both forward (when the cursor is at the end of the visual selection) or backward (when the cursor is at the start.)

I don't know that this operator is really that useful, considering in many cases you could just as well use a linewise operator or linewise visual mode instead... But I found myself wanting to yank a line in characterwise mode before, and this does it, so here it is if you find it useful.

1
  • 1
    Comments are not for extended discussion; this conversation has been moved to chat.
    – D. Ben Knoble
    May 1, 2020 at 16:09
1

You can use plug-in vim-textobj-user to define custom text objects using patterns or higher level functions.

In fact, vim-textobj-user uses il as an example of how to use the plug-in:

Complex text objects defined by functions

Define al to select the current line, and define il to select the current line without indentation:

call textobj#user#plugin('line', {
\   '-': {
\     'select-a-function': 'CurrentLineA',
\     'select-a': 'al',
\     'select-i-function': 'CurrentLineI',
\     'select-i': 'il',
\   },
\ })

function! CurrentLineA()
  normal! 0
  let head_pos = getpos('.')
  normal! $
  let tail_pos = getpos('.')
  return ['v', head_pos, tail_pos]
endfunction

function! CurrentLineI()
  normal! ^
  let head_pos = getpos('.')
  normal! g_
  let tail_pos = getpos('.')
  let non_blank_char_exists_p = getline('.')[head_pos[2] - 1] !~# '\s'
  return
  \ non_blank_char_exists_p
  \ ? ['v', head_pos, tail_pos]
  \ : 0
endfunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.