VIM: execute autocommand on enew - vim

I want to automatically set the paste mode on when I open a new file (an empty file that doesn't exist).
autocmd BufNewFile * :set paste
in the vimrc does the trick with vim newfile or :e newfile, but not with :enew.
How can I run an autocommand on :enew?

set paste will have many side effects, e.g. disable indention. I would imagine the requested behavior would become annoying quickly.
Alternatives:
Use 'pastetoggle' setting to setup a key to toggle 'paste',
unimpaired.vim's yo mappings which put Vim in insert mode with 'paste' set and disables 'paste' upon leaving insert mode
vim-bracketed-paste enables transparent pasting into Vim for certain terminals.
For more help see:
:h 'paste'
:h 'pastetoggle'

To answer the question, the following will run an autocommand on :enew:
autocmd BufCreate * if '' == expand("<afile>") | set paste | endif
You can replace BufCreate with BufAdd or BufNew, it will work all the same. The important part is the if '' == expand("<afile>") that will only execute the command if it the new buffer has no name.
NB:
For the specific use-case of pasting text in new buffer, auto-switching to paste mode is not a great solution though, I wouldn't recommend using this.
As the paste is maintained even when you switch buffer. You'd need additional autocommands to unset the paste mode when you switch buffer/window (autocmd WinEnter * set nopaste will work for windows, but for some reason autocmd BufEnter * set nopaste doesn't help when switching buffer).
To ease pasting stuff in new buffers (or otherwise), I'd recommend either:
typing "*p or "+p in normal mode, as to use vim's native mechanism to paste from the clipboard registers, as suggested by #dartNNN (assuming you're on your local machine)
using one of the plugins recommended in #peter-rincker's answer

Related

Vim, when exiting without editing, creates unsaved buffer

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.

Vim -- detecting ex mode in vimrc

I have previously asked this in comp.editors, but without getting any replies.
This ought to be simple: I want to configure vim to set number whenever the editor is in ex mode (to get visible line numbers), but never have that option set in visual mode. How?
If the solution involves having to start ex instead of vim, that's fine, but the solution should ideally also cover the case of entering ex mode from visual mode (using Q in vim visual mode, for example).
A solution that also works in nvi would be nice, but not necessary.
You can try something like this:
let &number = mode(1) ==# 'ce'
nnoremap <silent> Q :set number<CR>Q
This will set number when you run vim -e and when you enter ex mode with Q, but it won't clear it when you go back to visual mode. As far as I can tell there is no way to detect the actual event of switching modes. shrug
Vim's Autocmd seemed like your best bet, since it has event listeners. An example would be
:autocmd InsertLeave * :set nonumber
:autocmd InsertEnter * :set number
which shows/hides line numbers
However, I couldn't find any events for Ex mode when I looked.

.vimrc set paste not taking effect consistently

It seems like my 'set paste' option in .vimrc isn't being picked up. When I start vim and go to to insert mode, I get insert (paste) as expected. However when I paste from my clipboard with apple-V, the text is progressively indented at each line as if I didn't have paste mode on. Then I manually enter :set paste and try again, and the text is formatted properly.
Also it seems like the autoindent is spotty even though it's explicitly set as well.
This is vim 7.3 on OSX Lion. Thanks!
set paste
set autoindent
syntax on
colorscheme elflord
set tabstop=2
set softtabstop=2
set shiftwidth=2
set paste has no business being in your ~/.vimrc as it conflicts with a number of useful options.
The only use for :set paste is to reset a bunch of indentation-related options to allow your text to be pasted "correctly" when you use the mouse or your system's "paste" facilities. It's probably a good idea to read :h pastetoggle.
In such a situation, you are supposed to do :set paste before you paste and :set nopaste afterwards.
If your Vim has clipboard support built-in (:echo has('clipboard') should return 1) and you work locally, I highly recommend you use "+y and "+p instead.
The options paste and autoindent don't get along with each other. I suggest to leave autoindent on and map to a function key <F10> the toggle of the paste option, like:
:map <F10> :set invpaste<CR>

How to autosave in Vim 7 when focus is lost from the window?

I've tried the following in my .vimrc:
:au FocusLost * silent! wa
autocmd BufLeave,FocusLost silent! wall
And also tried:
How can I make Vim autosave files when it loses focus?
but can't get it to work, when I do a Ctrl+Z or switch to another tab in Terminal (mac) it still doesn't auto save.
BufLeave is triggered when you go to another buffer. Neither <C-z> nor switching to another Terminal.app tab will trigger this because you are using CLI Vim which doesn't care at all about the terminal emulator's GUI or environment and… you are not leaving your buffer.
The same is true for FocusLost (more or less, the doc says that it's GUI only but can work in some terminals without telling which one).
So, these setting will probably work in MacVim but definetly not in CLI Vim.
Actually, since Vim is not aware of your terminal emulator's tabs or about it being put in the background, I doubt you can achieve your goal in CLI Vim.
I happen to have autocmd FocusLost * :wa in my ~/.vimrc but I've put it in an if has("gui_running") conditional and also inoremap <Esc> <Esc>:w<CR> to save on ESC. Hope it helps.
On OS X and Vim CLI, I use this plugin http://www.vim.org/scripts/script.php?script_id=4521
AutoSave - automatically save changes to disk without having to use :w
(or any binding to it) every time a buffer has been modified.
AutoSave is disabled by default, run :AutoSaveToggle to enable/disable
AutoSave. If you want plugin to be always enabled it can be done with
g:auto_save option (place 'let g:auto_save = 1' in your .vimrc).

How do I make imap work in paste mode in Vim?

I recently started use :imap jj and am trying to unlearn Ctrl+[.
However, imap doesn't work when paste mode is on. How do I make it work in paste mode?
You simply can not have mappings work when 'paste' is enabled, since that is the whole point of Vim's paste mode.
Vim's paste mode is meant to allow you to paste stuff even in an instance of console Vim in a terminal—where Vim may not be aware you're using the mouse to paste—and you want to insert literal text form your paste buffer without triggering mappings, or auto/smart/expression indenting, etc.
I suggest you take a look at:
:help 'paste'
:help 'pastetoggle'
Add following snippet to your .vimrc to trigger paste mode automatically when pasting via the terminal:
let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"
inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()
function! XTermPasteBegin()
set pastetoggle=<Esc>[201~
set paste
return ""
endfunction
From:
https://coderwall.com/p/if9mda

Resources