开发者

Pressing "Home" in Vim on an Indented Line

开发者 https://www.devze.com 2022-12-16 02:34 出处:网络
I have a bad habit of using the \'home开发者_运维百科\' key to go back to the beginning of a line. As I recently started using vim I noticed that when I press the home key on a lined that is indented,

I have a bad habit of using the 'home开发者_运维百科' key to go back to the beginning of a line. As I recently started using vim I noticed that when I press the home key on a lined that is indented, it returns me to the very beginning of the line. In Notepad++ (the editor I used to use) it would return me to the beginning of the code on that line, right after the indent.

Is there some way to replicate this behavior in vim? Usually, when I'm pressing home it's in the Insert mode for me to (usually) stick a variable there.

I have set smartindent in my vimrc, with set noautoindent as a "tips" page told me to make sure to disable autoindent (although it didn't seem to be enabled in the first place - perhaps that option is extraneous.)


There are two usual ways to go to the "beginning" of a line in Vim:

  • 0 (zero) go to the first column of text
  • ^ go to the first non-whitespace on the line

I find that using 0w is usually the most convenient way for me to go to the first nonblank character on a line, it's the same number of keys as ^ and is easier to reach. (Of course, if there are no leading spaces on the line, don't press w.)


You could remap Home to be the same as ^ (the docs say Home's default function is equivalent to the movement command 1|):

:map <Home> ^  
:imap <Home> <Esc>^i  

Which should make the insert mode mapping be equivalent to escaping out of insert mode, pressing ^ and then returning to insert mode. I don't know about the best method of mapping a motion command for use inside insert mode, so this may break something, but it seems to work.

As to your indentation settings, they shouldn't have an effect on movement controls, but I also think you probably would prefer to have them set differently. autoindent just keeps your current indentation for new lines (so if you place 4 spaces at the beginning of a line, after you press return your new line will also have 4 spaces placed in front of it). I don't know why you wouldn't want that, since it's pretty useful in pretty much any programming language, or even just freeform text. smartindent on the other hand implements a couple of hard-coded lightly C-ish indentation rules, like indenting after an opening {, and deindenting after a closing }, but doesn't automatically carry over indentation from previous lines. The docs recommend keeping autoindent on if you use smartindent.

However, smartindent is useless for languages that don't meet its hard-coded rules, or even actively harmful (like when it automatically removes indentation from any line starting with a '#', which it thinks is a preprocessor directive but is wrong for python programmers trying to write an indented comment).

So vim also includes a more advanced indentation mode, filetype indentation, which allows flexible indentation rules on a per-language/filetype basis and is the preferred indentation mode for most people (even for C-like languages). If you do use filetype indentation, it's best to turn off smartindent (otherwise it can interfere with the filetype indentation, like moving all comment lines to column 0 in python files).

Personally, I always have autoindent on, use filetype when available, and never use smartindent. My .vimrc includes:

set autoindent " doesn't interfere with filetype indents, and is useful for text  
if has("autocmd")  
  " Enable file type detection and indentation  
  filetype plugin indent on  
  set nosmartindent  
endif  

I imagine there's something you could do to have smartindent turned on only when filetype indenting doesn't exist for a filetype, if you're editing that many different C-like languages with no filetype indentation available.


Here’s what I have in my .vimrc. This maps Home to move to the beginning of the text if you are anywhere in the line, and column 0 if you are at the beginning of the text.

function ExtendedHome()
    let column = col('.')
    normal! ^
    if column == col('.')
        normal! 0
    endif
endfunction
noremap <silent> <Home> :call ExtendedHome()<CR>
inoremap <silent> <Home> <C-O>:call ExtendedHome()<CR>

Note: I am using a keyboard layout that maps Home to Alt Gr+A, that why I’m using this. If you have to leave the letter field of your keyboard to reach Home, you should probably go to normal mode instead.


You could also use _ in Normal mode to go to the first non-whitespace character of the current line. You can also use a count with this motion.

_  <underscore>     [count] - 1 lines downward,
                    on the first non-blank character linewise.


Try pressing 0 (also see :help 0)

also, this might help:

:imap <C-Home> <esc>0a
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号