Applying augroup to more than one extension - vim

I have the following augroup for binary files in my `.vimrc':
augroup Binary
au!
au BufReadPre *.bin let &bin=1
au BufReadPost *.bin if &bin | %!xxd
au BufReadPost *.bin set ft=xxd | endif
au BufWritePre *.bin if &bin | %!xxd -r
au BufWritePre *.bin endif
au BufWritePost *.bin if &bin | %!xxd
au BufWritePost *.bin set nomod | endif
augroup END
How can I make it work with file extensions other than .bin (without repeating all the lines quoted above)?

Auto commands take comma separated lists for the autocommand pattern
So if you wanted to add the file extension *.xxx to the list the autocommands in your group it would look like
augroup Binary
au!
au BufReadPre *.bin,*.xxx let &bin=1
au BufReadPost *.bin,*.xxx if &bin | %!xxd
au BufReadPost *.bin,*.xxx set ft=xxd | endif
au BufWritePre *.bin,*.xxx if &bin | %!xxd -r
au BufWritePre *.bin,*.xxx endif
au BufWritePost *.bin,*.xxx if &bin | %!xxd
au BufWritePost *.bin,*.xxx set nomod | endif
augroup END
Take a look at :h autocommand-pattern

Related

vimscript autocmd passing a argument to a function

I'm trying to run tags upon file save. But I can't get the current buffers name inside the function, I need this after the write, since I want ctags to process the new amendments. Ideally I want to pass the . argument into the function from the autocmd
23 function! UpdateTagsIfHasTags()
24 echom "adsfsdf"
25 return
26 let tagsPath = printf('%s/tags', expand("%:h"))
27 if !empty(glob(tagsPath))
28 system(printf('/usr/local/bin/phpctags %s', filepath))
29 endif
30 endfunction
31 augroup tags
32 autocmd!
33 autocmd BufEnter *.tex silent! !start /min ctags *.tex
34 autocmd BufEnter *.php :call UpdateTagsIfHasTags()
35 augroup END
How can I pass the current file path to the function?
You can get autocmd file name with special variables <afile> or <amatch>. See :h expand, :h <afile>, :h <amatch> for details.
function! Update()
echom expand('<afile>')
echom expand('<amatch>')
endfunction
autocmd BufEnter *.vim :call Update()

How to enable/disable "function" (if ... els)

I have the following keymaps:
nnoremap <silent> <leader>vn :call Number()<CR>
function! Number()
set number relativenumber
augroup numbertoggle
autocmd!
autocmd BufEnter,FocusGained,InsertLeave * set relativenumber
autocmd BufLeave,FocusLost,InsertEnter * set norelativenumber
augroup END
endfunction
nnoremap <silent> <leader>vN :call NoNumber()<CR>
function! NoNumber()
set number! norelativenumber
augroup numbertoggle
autocmd!
autocmd BufEnter,FocusGained,InsertLeave * set norelativenumber
autocmd BufLeave,FocusLost,InsertEnter * set norelativenumber
augroup END
endfunction
But I would like to use only one <leader>vn shortcut for this; i.e. to call NoNumber if Number has already been called. What is the correct way to do this?
It seems like I can use if ... else in Number function, but I'm not sure how to implement it correctly. Or is there some other way?
Just check if the option number is set:
if &number
set nonumber
else
set number
endif
See the docs on using &option.
You can combine if with the mapping:
:nnoremap <silent> <leader>vn :if &number | call NoNumber() | else | call Number() | endif<CR>

How to retain cursor position when using :%!filtercmd in vim?

When I issue a vim command that starts with :%!, such as :%!sort to sort all lines in the buffer, the cursor moves to the first line. How do I preserve the cursor position?
Ultimately, I want to use this command in an autocmd, such as:
augroup filetype_xxx
autocmd!
autocmd BufWrite *.xxx :%!sort
augroup END
Will the same method work in both places?
You can use a mark to remember the current line number (but note that the line contents could change):
augroup filetype_xxx
autocmd!
autocmd BufWrite *.xxx :kk
autocmd BufWrite *.xxx :%!sort
autocmd BufWrite *.xxx :'k
augroup END
I would rather use the Preserve function. Beyond solving your problem in this particular task you can use it for much more.
" preserve function
if !exists('*Preserve')
function! Preserve(command)
try
let l:win_view = winsaveview()
"silent! keepjumps keeppatterns execute a:command
silent! execute 'keeppatterns keepjumps ' . a:command
finally
call winrestview(l:win_view)
endtry
endfunction
endif
augroup filetype_xxx
autocmd!
autocmd BufWrite *.xxx :call Preserve("%!sort")
augroup END
You can also use the "Preserve Function" to perform other useful tasks like:
command! -nargs=0 Reindent :call Preserve('exec "normal! gg=G"')
DelBlankLines')
fun! DelBlankLines() range
if !&binary && &filetype != 'diff'
call Preserve(':%s/\s\+$//e')
call Preserve(':%s/^\n\{2,}/\r/ge')
endif
endfun
endif
command! -nargs=0 DelBlank :call DelBlankLines()
nnoremap <Leader>d :call DelBlankLines()<cr>
" remove trailing spaces
if !exists('*StripTrailingWhitespace')
function! StripTrailingWhitespace()
if !&binary && &filetype != 'diff'
call Preserve(":%s,\\s\\+$,,e")
endif
endfunction
endif
command! Cls call StripTrailingWhitespace()
cnoreabbrev cls Cls
cnoreabbrev StripTrailingSpace Cls

How to enable mapping only if there is no quickfix window opened in Vim?

I would like do disable following mapping when I open quickfix window.
map <F5> :ZoomWin<cr>
Did you mean quickfix? If so, there are three ways:
Use <expr> mappings:
nnoremap <expr> <F5> (&buftype is# "quickfix" ? "" : ":\<C-u>ZoomWin\n")
Use BufEnter event to set/restore mapping:
augroup F5Map
autocmd! BufEnter * :if &buftype is# 'quickfix' | nunmap <F5> | else | nnoremap <F5> :<C-u>ZoomWin<CR> | endif
augroup END
Create mapping locally only for buffers where it is needed:
augroup F5Map
autocmd! BufEnter * :if &buftype isnot# 'quickfix' && empty(maparg('<F5>')) | nnoremap <buffer> <F5> :<C-u>ZoomWin<CR> | endif
augroup END
Update: to disable mapping when any of the opened windows contains quickfix buffer use the following:
nnoremap <expr> <F5> (&buftype is# "quickfix" || empty(filter(tabpagebuflist(), 'getbufvar(v:val, "&buftype") is# "quickfix"')) ? ":\<C-u>ZoomWin\n" : "")

Vim start with cursor where last went off

How do i make Vim always start at the line I was at when i exited that given file last time?
Put this in your .vimrc:
" When editing a file, always jump to the last cursor position
au BufReadPost *
\ if ! exists("g:leave_my_cursor_position_alone") |
\ if line("'\"") > 0 && line ("'\"") <= line("$") |
\ exe "normal g'\"" |
\ endif |
\ endif
then you can use :let g:leave_my_cursor_position_alone=1 at runtime to deactivate the feature.
put this into your .vimrc
set viewoptions=cursor,folds
au BufWinLeave * mkview
au BufWinEnter * silent loadview

Resources