66

In Vim, is there a way to move the cursor to the beginning of non-whitespace characters in a line? For instance, how can I move the cursor to the "S" in the second line below?

First line
    Second line

If it matters, I primarily use MacVim, but I'd also like to be able to do this from the console.

Thanks!

Joe Mornin
  • 1,607
  • 4
  • 18
  • 23

7 Answers7

79

Instead of pressing ^ you can press _(underscore) to jump to the first non-whitespace character on the same line the cursor is on.

+ and - jump to the first non-whitespace character on the next / previous line.

(These commands only work in normal mode, not in insert mode.)

Ben
  • 891
  • 6
  • 3
75

If I understand correctly - from :h ^:

^ To the first non-blank character of the line.
  |exclusive| motion.

(in contrast to 0, which gets you to the beginning, regardless of whitespace or not)

slhck
  • 223,558
  • 70
  • 607
  • 592
13

Also possibly useful: + and - will move the cursor up or down, respectively, to the first non-blank character.

shmup
  • 290
  • 2
  • 8
7

below is a snippet from by .vimrc
^[[1~ is created by pressing ctrl+v and Home

"jump to first non-whitespace on line, jump to begining of line if already at first non-whitespace
map <Home> :call LineHome()<CR>:echo<CR>
imap <Home> <C-R>=LineHome()<CR>
map ^[[1~ :call LineHome()<CR>:echo<CR>
imap ^[[1~ <C-R>=LineHome()<CR>
function! LineHome()
  let x = col('.')
  execute "normal ^"
  if x == col('.')
    execute "normal 0"
  endif
  return ""
endfunction
Andrew Sohn
  • 171
  • 1
  • 2
  • Thanks, this is what I was searching for. This behaviour is common on editors nowadays (Atom/VSCode/Sublime to name a few) and I've gotten used to it... – yyny Nov 30 '16 at 19:13
1

I just remap the 0 key to ^

Edit your ~/.vimrc

set visualbell t_vb=
map 0 ^
Sunding Wei
  • 119
  • 2
0

Expanding on Andrew Sohn's answer, if you'd like to use 0 for this behavior, just wrap it like so:

function! LineHome()
  let x = col('.')
  execute "normal ^"
  if x == col('.')
    unmap 0
    execute "normal 0"
    map 0 :call LineHome()<CR>:echo<CR>
  endif
  return ""
endfunction 
0

And just for completeness, here is the dual of Andrew Sohn's Answer:

" jump to the last non-whitespace char on line, or eol if already there
map <End> :call LineEnd()<CR>:echo<CR>
imap <End> <C-R>=LineEnd()<CR>
function! LineEnd()
  let x = col('.')
    execute "normal g_"
  if x == col('.')
    execute "normal $"
  endif
 return ""
endfunction
MERM
  • 166
  • 4