65

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!

7 Answers 7

74

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)

1
  • 4
    +1 on the 0 comment Sep 1, 2017 at 17:01
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.)

2
  • 7
    Can also use <CR> as an alternative to +, which is nice because it doesn't require holding shift. May 7, 2020 at 16:07
  • 2
    For a discussion about the difference between the ^ and _ motions, see here. Apr 2, 2021 at 14:55
12

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

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
1
  • 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, 2016 at 19:13
1

I just remap the 0 key to ^

Edit your ~/.vimrc

set visualbell t_vb=
map 0 ^
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

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.