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.
Related
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.
I've tried:
:map <F2> :.y" :g/<C-R>"/d<CR>
No luck :(
What this does, yank the current line into register "
Then, globally, delete lines that match exactly the line in the register.
It works dandy when I do it manually.
:vmap <F2> ["]yy<ESC><ESC> :g/<C-R>"/d<CR>
Similar to above - I select a few words, whatever - I make a selection, then yank it to register ". I then globally, delete the lines that match whats in the register.
It works dandy when I do it manually.
What am I doing wrong?
You might try this for the first one:
:nnorempa <F2> :silent exe "g/".getline(".")."/d"<CR>
For the second, something like this if you want to delete only the words:
:vmap <F7> y:silent exe "%s/".#"."//g"<CR>
And this if you want to delete the matching lines:
:vmap <F7> y:silent exe "g/".#"."/d"<CR>
You have remapped F2 to :.y" :etc. You need <cr> not a simple space. If you type :.y" in vim and don't hit ENTER but space, nothing will happen.
So:
:nnoremap <f2> :.y"<CR>:g/<C-R>"/d<CR>
could do it.
Still, warning, if your line contains any of /\*[~$^. this could fail. You could use the expression register in order to escape in-place:
:nnoremap <f2> :.y"<CR>:g/<c-r>=escape(#", '/\*[~$^.')<cr>/d<cr>
Still better, without overwriting your default (") register is:
:nnoremap <f2> :g/^<c-r><c-o>=escape(getline('.'), '/\*[~$^.')<CR>$/d<cr>
which will delete all identical lines. Still note that 'ignorecase' or 'smartcase' matter.
First of all - make sure you're using vim :)
vim --version
Here's the mapping I was going for. As I go through lots of data in log files, this will be incredibly useful. Select the area you want to eliminate, then and all instances of highlight area is done for.
NOTE: This does NOT go through the highlighted text and escape any regex characters. So a /, *, ^ will foul it up.
:map <F2> y:g/<C-R>"/d<CR>
:)
When the cursor is placed at the end of a line containing nothing but withspace characters, vim will, when i press enter, remove that whitespace. I find this irritating, as it breaks my script for selecting code that are indented to the same level. How can I prevent vim from doing this?
In my .vimrc (http://bjuhn.com/randomstuff/vimrc) I have the following:
filetype plugin on
set copyindent
that is, I am not using any syntax-aware auto-indention, as I have yet to find one that does everything to my liking.
The Vim wiki suggests this:
inoremap <CR> <CR>x<BS>
because the indenting is not removed if some text has been entered on the line, even if it has been deleted.
[EDIT - milimetric]
Just a couple of pieces missing from a full solution. You also need remaps for o and O and whatever else you use to add lines:
inoremap <CR> <CR>x<BS>
nnoremap o ox<BS>
nnoremap O Ox<BS>
Same idea but people newer to vim might not figure it out quickly.
For me this code works:
inoremap <silent> <Esc> <C-O>:stopinsert<CR>
Right now in Vim when I go to a new line (or press 'p' or 'o' in normal mode) I get a lovely automatic indent, that also disappears if I exit insert mode without adding anything to it.
Is there a way to bind something to before I exit insert mode, such as inserting a phantom character then removing it?
Argh, I just read about this exact thing like two days ago but I can't remember where.
Anyway, the trick is to input a character right after <CR> and delete it immediately. There are a bunch of ways to do it:
<CR>a<Esc>x
<CR>a<C-w>
<CR>a<BS>
--EDIT--
Vim being Vim there are probably many other ways.
To automate these, you need to add a mapping to your .vimrc:
inoremap <CR> <CR>a<BS> " insert mode mapping for <CR>
nnoremap o oa<BS> " normal mode mapping for o
But I'm not sure you should overwrite defaults like that.
--EDIT--
However, what is annoying with Vim's default behaviour is that you may need to do some <Tab><Tab><Tab><Tab> before actually inputing some text on non-indented line or do == when you are done or rely on the automatic indentation rules for your language at the next <CR>.
All that can be skipped by using <S-S> which puts you in INSERT mode right at the correct indentation level.
Try either cc or S in normal mode to change a line with respect to indention. No need for phantom characters.
:h cc
:h S
A mapping like the following should do the trick:
imap <esc> <esc>:s/\s\+$//<CR>
This one deletes trailing characters when you press esc in insert mode.
I like to insert blank lines without entering insert mode and I used this keymapping:
nomap go o <esc>
This does create the blank line but introduces some weird behaviour. I have smart indent and autoindent set. The new line follows the indents but doesn't remove them even though doing so manually automatically removes the redundant whitespace. It also adds a single whitespace where the cursor is each time.
Anyone have any insights as to explain this behaviour?
Vim is very literal with how you write your mapping commands - it's actually processing the space in your mapping before it does the <ESC>. In other words, your mapping does this:
nnoremap go o<SPACE><ESC>
You should change it to:
nnoremap go o<ESC>
And make sure you don't have any extra spaces in the mapping!
I agree with "too much php".
This is the relevant section from my .vimrc
nnoremap <A-o> o<ESC>k
nnoremap <A-O> O<ESC>j
I think it's faster since you get the cursor back at the original line (Although not on the original character).
As usual, the vim wiki has a useful tip: Quickly adding and deleting empty lines. The trick is to set paste before adding the new line and afterwards set nopaste. Additionally, this will set a mark to remember the cursor position and jump back to where you were.
nnoremap go :set paste<CR>m`o<Esc>``:set nopaste<CR>
nnoremap gO :set paste<CR>m`O<Esc>``:set nopaste<CR>