I have tried the autocmd way, not work for me.
One line comment with i, indent wrong.
Press i at begin of the line, then press #, the # and cursor auto indent.
One line comment with I, indent right.
Press I at begin of the line, the cursor auto indent; then press #.
Block comment with Ctrl+v, followed with Shift + i, followed with Esc, indent wrong.
---------------------Edit------------------------
Block comment with cursor on the -
The first block and the second block bahaves different.
This drove me nuts too! Thankfully the solution is pretty simple:
autocmd FileType yaml,yaml.ansible setlocal indentkeys-=0#
You need to use "yaml.ansible" if you use the ansible-vim plugin. Using "setlocal" instead of "set" is optional but after decades with Vim I've learned that it is a good idea to specify local when you know you only want it local to avoid nasty surprises.
Related
While inserting a new line below a comment in vim, the result tends to insert a " at the start of the new line. It's probably a simple solution or reason why this is happening, but I am unable to find an exact solution.
If you’re editing a file of the vim filetype, Vim might by default insert the comment character (in Vimscript, this would be ") at the beginning of each new line you enter after a comment. As already mentioned, this is a result of Vim’s formatoptions setting.
To turn this behavior off in the current file, run
:set formatoptions-=ro
To turn it off by default, add this to your ~/.vimrc:
set formatoptions-=ro
To turn it off for Vimscript files, add this to your ~/.vimrc:
augroup filetype_vim
autocmd!
autocmd FileType vim setlocal formatoptions-=ro
augroup END
r and o are options which can be given to formatoptions. For the full list of possible options, run :help fo-table.
This behaviour is governed by the formatoptions variable.
Use :h formatoptions to find out more.
The following article might also be helpful: Disable automatic comment insertion.
I think this should work, regardless of your formatoptions settings.
inoremap <CR> <CR><C-U>
what command are you using to insert below?
If you use the standard "o" keystroke while in Navigation mode, it should insert a new line immediately below whatever the cursor is on, and automatically place you into Insert mode, without inserting an extra "
Similarly an uppercase "O" will insert a new line above whatever line the cursor is on, and place you in insert mode.
When I am editing a python file, after I insert a new line then press <ESC>, the cursor moves all the way to the beginning of the line (ie. column 0). How do I stop this behavior? It's really annoying when I want to paste something on the new line.
Here are my relevant .vimrc settings:
set softtabstop=2
set expandtab
set shiftwidth=2
set smartindent
If your goal is to paste something on the new line after just starting it using o or O, you do not have to enter normal mode for it.
Just type Control-R " to paste from the default register directly from insert mode.
More generally, you can type Control-R <RegisterName> to paste from that register from insert mode.
If you edit the line (e.g. by pressing SpaceBackspace) before pressing Esc then Vim will leave the indentation intact.
From normal mode, a quick == will indent the line to whatever position it should be at using your indentation settings. At least, that's how it's working for me. My relevant indent section in my vimrc:
if has("autocmd")
filetype plugin indent on
endif
You can add mapping so when the auto indentation is triggered a single character is inserted and then deleted:
:nnoremap o ox^H
:nnoremap O Ox^H
:inoremap <enter> <enter>x^H
^H must be introduced by pressing ctrl+vctrl+h.
So do not copypaste.
If you already pressed Esc or are coming back to the line later, it is very easy to get the indent back for editing or pasting.
Just use cc to edit the line, re-applying the automatic indent and landing you in insert mode. Then you can start typing or use CTRL+R+ for example to paste from the system clipboard from the current cursor position.
Note Vim will remove the indent again if you stop editing the line without entering any text. This is intentional as it prevents wasteful trailing whitespace littering the file.
I have set autoindent
I go to a line, press A and <CR> which gets me to the next line and inserts an indent. However if I press Esc the cursor jumps to the beginning of the line and the indent is gone.
I have to go about and press tabs to get to the right place again.
I know the help says:
If you do not type anything on the new line except <BS> or CTRL-D and then type
<Esc>, CTRL-O or <CR>, the indent is deleted again.
Is there a way to disable this, or at least a workaround?
I had this exact problem until two days ago.
There is no way to disable this, but luckily, you don't need to, because instead:
Enter insert mode with S or cc. Entering insert mode again with S will enter insert mode with the proper level of indentation, making the fact that Vim deleted the indents unimportant.
Note: I found that this trick worked for me most places. But for some reason, it did not work with Python files. I'm guessing it's something to do with the Python filetype messing with its own indentation functions, or something along those lines.
Edit:
Another trick, you can define cpoptions in a way that, if you're on a line with an indent and move the cursor, it will preserve the indent. This won't solve your problem of hitting Esc right away, but it's a related issue that might also be bothering you.
A simple way is to press '.' (or any char), escape, then press x to remove the char. The indent should be preserved.
Alright, I figured this out.
Based on Edan Maor's answer, S or cc should enter insert mode with the proper level of indentation.
...except when it doesn't :)
This works under two circumstances.
when cindent is set, it will insert indent based on C formatting rules
This may prove annoying when editing non C-like files.
when indentexpr is set.
I found that the best solution is to have this is my .vimrc
set autoindent
set indentexpr=GetIndent()
function GetIndent()
let lnum = prevnonblank(v:lnum - 1)
let ind = indent(lnum)
return ind
endfunction
Now when I press S or cc, it will insert the same indent as on the previous non-blank line.
consider I use 'o' to start a newline. I add below config in _vimrc(notice I have ':set autoindent')
" ugly hack to start newline and keep indent
nnoremap o ox<BS>
nnoremap O Ox<BS>
type your text then press == in normal mode in that line
It may be worth noting that with proper plugins S and cc seem to work properly again. It is most likely python-mode that is fixing this.
https://github.com/klen/python-mode
I had want to achieve the same effect, but because I want the plugin showing indent to work properly. This is my workaround: I've found that <enter> in normal mode is almost useless. It only moves the cursor one line down, which could be achieved by j.
So I added this in my .vimrc:
nmap <cr> o.<c-h><esc>
Whenever I need a blank line for its indentation, I'd use <enter> instead.
Is there a way to just have Vim copy the indent from the line above, whether it be spaces or tabs, oblivious of the file types?
:set ai
See :help autoindent
I assume you are going to paste something and adjust the indent.
Try ]p
If you are at the beginning of the line and want to copy all the indenting characters above the line that you are currenly on now you can use Ctrl+y. It copies the character from the line above one at a time. Ctrl+e does the same thing but it copies from the line below.
It seems what I've wanted isn't actually possible as Vim automatically removes whitespaces, and uses configuration settings for its indention.
I've avoided this put slapping these in to my vimrc:
:inoremap <CR> x<BS><CR>x<BS>
:inoremap <up> x<BS><up>
:inoremap <down> x<BS><down>
:nnoremap o ox<BS>
:nnoremap O Ox<BS>
It simply puts a character in place and then removes it before I exit the editing mode, so Vim doesn't remove the empty line. If this is the case then it may be simply Vim checking if any editing was done to the line, auto indenting not counted. Maybe someday I'll check out the source and poke around.
I also wanted to use the previous line's indent (so I'd get different indents for different files and not have to tamper with settings each time), but I've managed to compromise and use the lovely Vim plugin.
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