A while ago, I had to put
filetype plugin on
in my .vimrc for a plugin I use.
But this caused a change in autoindent: Whenever I write a comment "//", and then press enter, vim autoindentation automatically enters another "//" in the next line.
// This is a comment. <ENTER>
// <-- vim automatically puts '// ' there
What can I do to avoid this?
I use the autoindent setting in my vim file.
I already tried
filetype plugin indent off
but it does not work.
I am answering your title rather than the body of your question, since your title brings people to this page who are looking to stop Vim from indenting comments.
The variable that controls whether Vim auto-indents a new character is indentkeys. I've noticed incorrect indentation only in Python and Yaml, so I've turned off auto-indentation only for the "#" character at the beginning of the line: :set indentkeys-=0#
Since loading the filetype indentation plugin will override any .vimrc settings you've made, you can set up an autocmd to change the indentkeys after a file is created or loaded. Here are mine:
autocmd BufNewFile,BufReadPost * if &filetype == "python" | set indentkeys-=0# | endif
autocmd BufNewFile,BufReadPost * if &filetype == "yaml" | set expandtab shiftwidth=2 indentkeys-=0# | endif
See :h indentkeys
Note that because of (possibly) a bug, if you use Neovim you must also specify filetype plugin indent on, or the filetype won't be set.
Take a look at :h formatoptions and :h fo-table. The options you need to turn off are r and o. Turning them off prevents vim from automatically inserting the comment leader (in this case "//") when you press enter in insert mode or when you press o or O in normal mode.
See :help 'formatoptions' - I know how annoying this is!
Try this:
:set fo-=or
Related
I would like to set up VIM for Cobol development and wanted to have the lines form column 7 to 11 marked so as to indicate the code areas. However, when I added this line of code in my vimrc file it colorized the NERDTree too.
set colorcolumn=7,11,73,80
autocmd VimEnter * NERDTree
autocmd VimEnter * wincmd p
How can I make the NERDTree columns not colorized and keep colorization only on the working file?
With the following line in your vimrc:
set colorcolumn=7,11,73,80
you define a global value for a window-local option which is reused for every new window. It is set for the 1st window, which passes it on to the 2nd window, etc.
Since that specific value for that specific option only is to be applied to Cobol buffers, you are supposed to use Vim's built-in filetype plugin support:
Make sure you have either of those lines in your vimrc:
filetype plugin on
filetype plugin indent on
filetype indent plugin on
See :help :filetype.
Create after/ftplugin/cobol.vim under your Vim runtime. On a typical Unix system, it should look like this:
$HOME/.vim/after/ftplugin/cobol.vim
And add the line below:
setlocal colorcolumn=7,11,73,80
We use :help :setlocal to make sure that the option won't be passed on to other windows.
I am having some weird behavior when it comes to VIM.
The behavior that I'm expecting:
When editing a file, if one is in insert mode and doesn't make any file modifications when you exit insert mode the buffer should be considered "saved".
The behavior that I'm actually getting:
When editing a file and when I exit insert mode while making NO MODIFICATIONS, the buffer says that the file has been edited. Even though
I tested if this behavior was normal in vim by opening a clean version of vim, and it seems that the behavior I'm expecting is the default.
This a snippet of my config, my full configuration is here: (https://github.com/TheBabu/Config/blob/master/.vimrc)
I'm assuming whatever is causing this behavior is here otherwise it might be a plugin
"Setup
set shell=bash
set nowrap
set number
set nocompatible
set noshowmode
set directory^=$HOME/.vim/.swapfiles
set undofile
set mouse=a
syntax on
colorscheme neodark
hi Normal ctermbg=none
sign define transparent_sign
augroup SignColFixAu
au!
au BufReadPost *.c,*.cc,*.h,*.cpp,*.hh,*.hpp,*.py,*.js,*.php,*.rs exe "sign place 1111 name=transparent_sign line=1 file=".#%
augroup end
inoremap <cr> <space><bs><cr>
inoremap <esc> ~<bs><esc>
inoremap <expr> <up> pumvisible() ? "\<c-p>" : "~\<bs>\<up>"
inoremap <expr> <down> pumvisible() ? "\<c-p>" : "~\<bs>\<down>"
inoremap <Esc>x <Esc>x
"Tabs
set listchars=tab:➡\
set list
set autoindent
set noexpandtab
set tabstop=4
set shiftwidth=4
..SNIP...
"Plugins
Plugin 'VundleVim/Vundle.vim'
Plugin 'scrooloose/nerdtree'
Plugin 'Valloric/YouCompleteMe'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'easymotion/vim-easymotion'
Plugin 'w0rp/ale'
Plugin 'godlygeek/tabular'
Plugin 'LukeLike/auto-pairs'
Plugin 'ananagame/vimsence'
Plugin 'preservim/nerdcommenter'
call vundle#end()
filetype plugin indent on
...SNIP...
Thank you for any help!
The problem is caused by your <Esc> mapping:
inoremap <esc> ~<bs><esc>
This mapping is inserting a ~ character then backspacing over it, which in practice doesn't change the contents, but still marks the buffer as modified. (Vim doesn't really track the exact contents of the buffer, but tracks whether any change was introduced, and both inserting ~ and backspacing over a character count as such.)
You mentioned in the comments you use this mapping (together with the <CR> mapping) to change how Vim behaves with indentation. The usual behavior of Vim is to remove auto-indentation when you move to a new line (with <CR> on an otherwise blank line) or leave Insert mode (with <Esc>.)
There doesn't seem to be a way to change this behavior in Vim. But the default Vim behavior is actually very useful, as it prevents ending up with lines with trailing spaces all over the place. (Many use Vim autocmd's to trim trailing whitespace on save and others use git hooks or code review bots to block source code files that have trailing whitespace.)
I imagine your motivation to keep the trailing whitespace is so that you can leave Insert mode and then later enter Insert mode again on that same line, while preserving indentation. But it turns out you don't really need to do that, since Vim has many ways to start Insert mode again with the proper indentation.
For example, if you insert a line above (with O) or below the current one (with o), Vim will insert the appropriate indentation on the new line. If you're on a blank line and want to start inserting there, then instead of using i to start Insert mode, use S to replace the contents of the current line. Since the line is empty, there won't be anything to replace, but the S command will start the replacement with the current indentation, so that should solve that too.
If you're already in Insert mode (and not necessarily at the beginning of a line), you can also use Ctrl+F to have Vim apply the proper indentation to the current line, so that's an option too. With some languages (notably Python), Vim can't always figure out the proper indentation (since you indent to end a block), so Vim might not be able to guess right. In those cases, you also have Ctrl+T to increase indentation and Ctrl+D to decrease it. Both are Insert mode commands and can be executed anywhere in the line.
Hopefully with the use of these commands you'll be able to let go of the trailing spaces that you're using to track indentation and also drop those mappings.
A good starting point to debug this might be comparing both original and modified versions after vim says its been edited.
To see the changes, use git diff if the file is VCS controlled, or vim -d original_copy edited_copy if it's not.
The diff-ed characters should give you an idea of the side-effect of the code that might be causing this. Paste the diff here if you can't figure that out.
I have the following text:
");
When I hit return in insert mode, Vim creates a new line (as expected), but also indents the line on which return was hit:
");
Vim only does this with some lines, presumably when it thinks the indentation is incorrect.
How do I configure Vim to not indent the current line when hitting return? I want Vim to not touch the line at all. My current settings are as follows:
set tabstop=4
set shiftwidth=4
set expandtab
set softtabstop=4
Filetype plugins may set 'cinkeys' or 'indentkeys' so
that automatic indenting is triggered when certain keys are
pressed. To turn this off, while leaving 'indentexpr' intact
so that you can still indent with ==, you can add the
following autocommand to your vimrc:
" Allow filetype detection, plugins and indent files ...
filetype plugin indent on
" ... but keep certain preferred defaults.
augroup overrideftplugins
au!
au FileType * set cinkeys= indentkeys=
augroup END
Note that the autocommand needs to come after the line that turns on filetype detection etc. This is because they are triggered in the order that they were
registered, and we want the autocommands for the overrides to fire after the autocommands that are set up for the ftplugins and indent scripts.
I was able to reproduce your issue with an XML document where one tag was not aligned with the others. I tried disabling autoindent, cindent and smartindent, but what finally fixed it for me was clearing the indentexpr.
:setlocal indentexpr=
Alternatively, you can remove return from the list of indentkeys, or clear them altogether.
:setlocal indentkeys=
I have created a function which can satisfy your need.
function! Enter()
let pos=getpos('.')
let substr = strpart(getline(pos[1], pos[2])
if strlen(substr)==0
exe("normal! o")
exe("normal x")
startinsert
return 1
else
exe("normal! li\<Enter>")
startinsert
return 0
endif
endfunction
When the current cursor is at the end, and you press enter, it will create a new line and move to first column. (As usual, any lines below will be moved down)
When the cursor is at the middle of the line, and you press Enter, it will split the line.
To use the function, you can map like
:imap <Enter> :call Enter()<CR>
This works well for C comments, subroutines/functions.
Whenever I want to open a new line in Vim with o, it automatically indents (instead of starting at the beginning of the line). Why is that? How can I fix this?
(I don't want to switch off auto-indent, which is great for other file types.)
UPDATE:
It seems to have something to do with the actual text: auto-indenting (=) the following two lines indents the second line (why? -- I would like both lines to start in column 1!)
*in golf: failing to make par is a loss, missing a birdie putt is a foregone gain, not a loss
*negotiations, especially renegotiations: concessions you make cause you much more pain
UPDATE 2 (my .vimrc):
:set cpoptions+=$
:set virtualedit=all
:filetype plugin indent on
:set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1
:set fdm=expr
:set gfn=Ubuntu\ Mono\ 11
setlocal autoindent
setlocal cindent
setlocal cinwords=if,else,elseif,do,while,foreach,for,case,default,function,class,interface,abstract,private,public,protected,final
setlocal cinkeys=0{,0},0),!^F,o,O,e
setlocal nosmartindent " don't use smart indent option
You can set options to take effect only for specific files. For example, I have the following in my vimrc:
if has("autocmd")
augroup LISP
au!
au BufReadPost *.cl :set autoindent
augroup END
augroup C
au!
autocmd BufNewFile,BufRead *.cpp set formatprg=c:\\AStyle\\bin\\AStyle.exe\ -A4Sm0pHUk3s4
augroup END
endif
Using this, I can turn on autoindent, or file formatting, or whatever for the files where it makes sense, but not have it on generally, when it might annoy me in other cases. In this case, I turn on autoindent for .cl files, but not necessarily for others.
You could also, in theory, use the same thing to turn off autoindent for .txt files.
I have a simple goal: Map Ctrl-C, a command I don't think I've ever used to kill vim, to automatically insert at the beginning of a line the correct character(s) to comment out that line according to the file's filetype.
I figured I could use an autocommand the recognize the file type and set a vim variable to the correct comment character when the file is open. So I tried something like:
" Control C, which is NEVER used. Now comments out lines!
autocmd BufNewFile,BufRead *.c let CommentChar = "//"
autocmd BufNewFile,BufRead *.py let CommentChar = "#"
map <C-C> mwI:echo &CommentChar<Esc>`wll
That map marks my current location, goes to the beginning of the line in insert mode, echoes the Comment Character(s) at that point, enters command mode, goes back to the set mark, and goes two characters right to make up for the inserted comment characters (assuming C style comment).
The italicized portion is the part I'm having trouble with; it is only there as a place holder to represent what I want to do. Can you help me figure out how to achieve this? Bonus points if you use strlen(CommentChar) to step the correct number of spaces to the right! Extra bonus points for the vim-master that includes how to do block-style comments if you are in visual mode!!
I'm still fairly new at vim scripting; my .vimrc is a measly 98 lines long, so if you could please help me by explaining any answers you provide! Thanks.
You can use <C-r> here:
noremap <C-c> mwI<C-r>=g:CommentChar<CR><Esc>`wll
see :h i_CTRL-R.
Also look at NERDCommenter plugin, with it mapping will look like this:
" By default, NERDCommenter uses /* ... */ comments for c code.
" Make it use // instead
let NERD_c_alt_style=1
noremap <C-c> :call NERDComment(0, "norm")<CR>
And you will not have to define comment characters by yourself.
I pulled this off the vim tips wiki at some point and use it myself. The only downside is it adds a space to the end of the line(s) for some reason, probably something small I overlooked.
" Set comment characters for common languages
autocmd FileType python,sh,bash,zsh,ruby,perl,muttrc let StartComment="#" | let EndComment=""
autocmd FileType html let StartComment="<!--" | let EndComment="-->"
autocmd FileType php,cpp,javascript let StartComment="//" | let EndComment=""
autocmd FileType c,css let StartComment="/*" | let EndComment="*/"
autocmd FileType vim let StartComment="\"" | let EndComment=""
autocmd FileType ini let StartComment=";" | let EndComment=""
" Toggle comments on a visual block
function! CommentLines()
try
execute ":s#^".g:StartComment." #\#g"
execute ":s# ".g:EndComment."$##g"
catch
execute ":s#^#".g:StartComment." #g"
execute ":s#$# ".g:EndComment."#g"
endtry
endfunction
" Comment conveniently
vmap <Leader>c :call CommentLines()<CR>