67

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!

8 Answers 8

76

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
82

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
  • 8
    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
14

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
0

See Vi Reference Card under Motion:

next word, blank delimited word w, W

beginning of word, of blank delimited word b, B

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .