Vim Error E20 'Mark not set' when running BuffWrite Command - vim

I set up an auto run script in my vimrc to condense any block of 3 or more empty newlines down to 3 newlines. I set a mark so after the script executes, I retain my cursor position but I'm getting an E20 Mark not set error when the cursor is within an area that is being removed.
How can I fix this issue/silence the error when this happens?
" .vimrc file:
autocmd BufWrite * mark ' | silent! %s/\n\{3,}/\r\r\r/e | norm''

You could replace your marks with winsaveview() and winrestview().
autocmd BufWrite * let w:winview = winsaveview() | ... | if exists('w:winview') | call winrestview(w:winview) | endif

Also silence the normal command:
autocmd BufWrite * mark ' | silent! %s/\n\{3,}/\r\r\r/e | silent! exe "norm! ''"

Related

Restoring cursor position after typing :make

I am using the following in my .vimrc to restore the cursor position after reopening the file:
" Copied from defaults.vim
" Put these in an autocmd group, so that you can revert them with:
" ":augroup vimStartup | au! | augroup END"
augroup vimStartup
au!
" When editing a file, always jump to the last known cursor position.
" Don't do it when the position is invalid, when inside an event handler
" (happens when dropping a file on gvim) and for a commit message (it's
" likely a different one than last time).
autocmd BufReadPost *
\ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
\ | exe "normal! g`\""
\ | endif
augroup END
The problem is that when I type :make, the cursor position is not restored; the cursor merely appears at the beginning of the line on which it was before typing :make.
Do you have any advise on how to fix this? Thank you for help.
The command :make doesn't seem to throw BufReadPost, so the autocommand will not execute.
You can do :make | norm! ``
:help ''

Vim: Add two lines after auto shebang

I have set my .vimrc to automatically add a shebang line, as below:
autocmd BufNewFile * execute 'silent! 1s/.*/#!\/usr\/bin\/env ' . (empty(&filetype) ? '' : ' '.&filetype)
However, I would like it to also add two lines below it and go into insert mode. When I simply add $i to the end of the command, as below, I get an error. Ideas?
autocmd BufNewFile * execute 'silent! 1s/.*/#!\/usr\/bin\/env ' . (empty(&filetype) ? '' : ' '.&filetype) $<CR><CR>i
You can use this:
autocmd BufNewFile * if !empty(&filetype) | execute 'silent! 1s/.*/#!\/usr\/bin\/' . &filetype . '\r\r'| :startinsert | endif
Btw, neat thinking, I'm adding this to my vimrc :)

Cause vim to exit on final bd

I would like to exit on :bd if i'm on the last buffer. I am not very familiar with vimscript, but I assume something must be bound to the autocmd BufDelete.
From this answer:
:au BufDelete * if len(filter(range(1, bufnr('$')), 'buflisted(v:val)')) == 1 | quit | endif
Add the above snippet to your ~/.vimrc.

VIM autocmd corrupts default register

I'm trying to update some text lines containing filenames in specific file in Vim. To do that I've added this in my .vimrc:
let logs_pat = "/ARCHIVE/logs/db_agent.log*"
au! BufEnter *_search.txt execute "/\\[DBA_LOGS\\]/,$d | $put = '[DBA_LOGS]' | $r!ls -t " . logs_pat . " | head "
It works fine except some artifacts. And question is about how to eliminate those artifacts.
Every time when I get into a buffer with file *_search.txt,
1) the contents of the register "" is replaced by the text been added by autocmd to file *_search.txt 2) a message appears on the vim status line: "10 more lines" or "search hit BOTTOM, continuing at TOP"
Thanks
The /\\[DBA_LOGS\\]/,$d command deletes the range of lines into the default register. To avoid that, append the black hole register (_). To suppress the message, prepend :silent.
au! BufEnter *_search.txt execute "silent /\\[DBA_LOGS\\]/,$delete _ | $put = '[DBA_LOGS]' | silent $r!ls -t " . logs_pat . " | head "
To maintain the original cursor position, you can wrap this with either:
:mark z
...
:normal! g`z
or
:let pos = getpos('.')
...
:call setpos('.', pos)

vim : insert mode problem : remaps (imap) and abbreviations (ab) in .vimrc don't work

I have a problem in vim:
If I modify the .vimrc file and add this lines:
map ;bb A78
it just works in normal mode.
If I got it, it should work in insert mode too, shouldn't it?
While editing, I've verified that everything was read properly (command ":map"):
i ;bb A78
If I do the same thing with "imap", I got the same problem: command ":imap" shows it's configured, but if I go in insert mode, and type ";bb" or ";bb" or ";bb" nothing is changed, I don't get the A78
What am I missing?
(And the marvellous codeSnippet plugin works only in normal mode too, which is a big problem to me)
If forgot to precise: I have only the plugin Tabularize, it's vim version 7.3 under cygwin, but I get the same problem in SSH / Linux Debian / vim version 7.0
If I try to do exactly what written here (to give another try, if it may help), that doesn't work either: "To use the abbreviation, switch to Insert mode and type th, followed by any whitespace above (space, tab, or carriage return)." doesn't work at all. This drives me nuts.
Here follows my .vimrc file, maybe there's something wrong here I didn't see:
set nocompatible
filetype plugin on
syntax enable
set ignorecase
set paste
set ruler
set modeline
set showcmd
set expandtab
set tabstop=2
set autoindent
set smartindent
set number
colorscheme desert
set vb t_vb=
set backup
set backupdir=~/.vim/backup
set directory=~/.vim/tmp
set fileencodings=utf-8,ucs-bom,default,latin1
set scrolloff=5
set undolevels=1000
nmap ;bw :. w! ~/.vimxfer<CR>
nmap ;br :r ~/.vimxfer<CR>
nmap ;ba :. w! >>~/.vimxfer<CR>
" Tell vim to remember certain things when we exit
" '10 : marks will be remembered for up to 10 previously edited files
" "100 : will save up to 100 lines for each register
" :20 : up to 20 lines of command-line history will be remembered
" % : saves and restores the buffer list
" n... : where to save the viminfo files
set viminfo='10,\"100,:20,%,n~/.viminfo
" when we reload, tell vim to restore the cursor to the saved position
augroup JumpCursorOnEdit
au!
autocmd BufReadPost *
\ if expand("<afile>:p:h") !=? $TEMP |
\ if line("'\"") > 1 && line("'\"") <= line("$") |
\ let JumpCursorOnEdit_foo = line("'\"") |
\ let b:doopenfold = 1 |
\ if (foldlevel(JumpCursorOnEdit_foo) > foldlevel(JumpCursorOnEdit_foo - 1)) |
\ let JumpCursorOnEdit_foo = JumpCursorOnEdit_foo - 1 |
\ let b:doopenfold = 2 |
\ endif |
\ exe JumpCursorOnEdit_foo |
\ endif |
\ endif
" Need to postpone using "zv" until after reading the modelines.
autocmd BufWinEnter *
\ if exists("b:doopenfold") |
\ exe "normal zv" |
\ if(b:doopenfold > 1) |
\ exe "+".1 |
\ endif |
\ unlet b:doopenfold |
\ endif
augroup END
set backspace=2
inoremap <silent> <Bar> <Bar><Esc>:call <SID>align()<CR>a
function! s:align()
let p = '^\s*|\s.*\s|\s*$'
if exists(':Tabularize') && getline('.') =~# '^\s*|' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p)
let column = strlen(substitute(getline('.')[0:col('.')],'[^|]','','g'))
let position = strlen(matchstr(getline('.')[0:col('.')],'.*|\s*\zs.*'))
Tabularize/|/l1
normal! 0
call search(repeat('[^|]*|',column).'\s\{-\}'.repeat('.',position),'ce',line('.'))
endif
endfunction
:autocmd BufNewFile * silent! 0r ~/.vim/templates/%:e.tpl
:autocmd BufNewFile *.php call search('w', '', line("w$"))
Thanks a lot!
You need to make sure that vim is not in "paste" mode.
Try
:set nopaste
map doesn't make the mapping work in insert mode: for ALL modes, you want map!. See :help :map! for more information on this.
However, imap should work, so you're probably having issues either with timeouts or the 'paste' setting. The way a mapping works in insert mode is that it gives you a certain amount of time to enter the mapping (I think the default is 1 second) and if you type it slower than that it assumes you mean the individual characters. So if you do:
:map! ;bb A78
And then type:
;<pause>bb
(where <pause> is just a pause, not something you type)
You'll get ;bb, but if you type:
;bb
really quickly, you'll get A78.
To find out more about timeouts, have a look at these help pages:
:help 'timeout'
:help 'ttimeout'
:help 'timeoutlen'
:help 'ttimeoutlen'
The 'paste' option also has an effect: it disables mappings in insert mode and abbreviations. Try :set paste? to find out if you have this set and :set nopaste to disable it.
See:
:help 'paste'

Resources