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.

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.

| improve this answer | |
  • Thanks for this. Could you please explain a bit guu and g~~ ? – David542 Apr 25 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 at 2:21
2

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.

| improve this answer | |
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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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