I have the following command run as a vim plugin under ~/.vim/plugin/autohighlight.vim
:autocmd CursorMoved * exe printf('match IncSearch /\<%s\>/', expand('<cword>'))
The thing is, it throws a bunch of errors anywhere except when I'm editing a file. (file Explorer, other windows)
Is there a way to tell the script to only take effect when a file is edited and not anywhere else in VIM?
You can try this one:
autocmd CursorMoved * :if filewritable(#%)==1 |
\ call matchadd('IncSearch', '\V\<'.escape(expand('<cword>').'\>', '\'), 10, 1) |
\endif
It will do highlighting only if current buffer name is a writable file (not directory). It will fail if you are editing something which uses BufWriteCmd to perform saving (for example, if you are editing file inside a zip archive).
By the way, can you provide these errors? I was able to get an error when I used :e ., but it was not related to the fact that you are observing a directory, it appeared just because you forgot to do escaping. If you have written escape(expand('<cword>'), '\/') instead of expand('<cword>') then such error would not appear.
Related
I'm trying a simple way to compile pdfs in LaTeX and open them with zathura from a single autocmd inside vim, so far I tried:
command Latex !pdflatex %:t
command Za !zathura #%.pdf
autocmd FileType tex map <leader>pdf :w<CR>:Latex<CR>:Za <CR>
Obviously, #%.pdf is wrong, but I've had no luck in finding how to append an extension to the file name. I'm newbie in vim scripting so please point out any other errors.
Since no one bother to answer, I came up with a shell solution for it, a script called zatex:
tex=".tex"
pdf=".pdf"
cd $1;
texfile="$2$tex";
pdflatex $texfile;
pdffile="$2$pdf";
setsid zathura $pdffile;
And inside my .vimrc:
command Zatex !zatex %:p:h %:p:h:t
autocmd FileType tex map <leader>pdf :w<CR>:Zatex<CR>
Of course, after the first compiling it might be handy to have another mapping just to compile the pdf, since zathura is already open:
command Latex !pdflatex %:t
autocmd FileType tex map <leader>tex :w<CR>:Latex<CR>
I believe %:r is what you are looking for, without the # character. It will return the file name, without extension.
Also, have a look at this question.
EDIT: I just tested here (not with !zathura, but with !echo) and the following line should work for you (just append the correct extension after the file name expand):
command Za !zathura %:r.pdf
I am recently moving from sublime 3 go to mvim (vim on the mac os) and am trying to get my Golang development environment to be as similar on vim to my sublime implementation as possible.
Within my sublime setup, it runs go build anytime I save the a Go file. This provides me instant feedback on if I have unused vars or other info go build provides.
I'm attempting to move to vim, and am wondering if I can have this functionality implemented there as well. I am using vim-go but have not found a setting to implement this.
In short I want to run :GoBuild upon the saving of a Go file while using vim / vim-go. Is this Possible and how do I do so?
yes, use vim autocommand to run :GoBuild:
You can specify commands to be executed automatically when reading or
writing a file, when entering or leaving a buffer or window, and when
exiting Vim. The usual place to put autocommands is in your .vimrc or
.exrc file.
Run the following command:
:autocmd BufWritePre *.go :GoBuild
Now each time you save your Go file with :w it will run :GoBuild too.
The event type is BufWritePre, which means the event will be checked just before you write *.go file.
BufWritePre starting to write the whole buffer to a file
BufWritePost after writing the whole buffer to a file
and:
When your .vimrc file is sourced twice, the autocommands will appear
twice. To avoid this, put this command in your .vimrc file, before
defining autocommands:
:autocmd! " Remove ALL autocommands for the current group.
If you don't want to remove all autocommands, you can instead use a
variable to ensure that Vim includes the autocommands only once:
:if !exists("autocommands_loaded")
: let autocommands_loaded = 1
: au ...
:endif
like this (put this at the end of your vim startup file):
:if !exists("autocommands_loaded")
: let autocommands_loaded = 1
: autocmd BufWritePost *.go :GoBuild
:endif
ref:
http://vimdoc.sourceforge.net/htmldoc/autocmd.html
http://learnvimscriptthehardway.stevelosh.com/chapters/12.html
Create ~/.vim/after/ftplugin/go.vim with:
autocmd BufWritePre *.go :GoBuild
The current gf command will open *.pdf files as ascii text. I want the pdf file opened with external tools (like okular, foxitreader, etc.). I tried to use autocmd to achieve it like this:
au BufReadCmd *.pdf silent !FoxitReader % & "open file under cursor with FoxitReader
au BufEnter *.pdf <Ctrl-O> "since we do not really open the file, go back to the previous buffer
However, the second autocmd failed to work as expected. I could not figure out a way to execute <Ctrl-o> command in a autocmd way.
Could anyone give me a hint on how to <Ctrl-O> in autocmd, or just directly suggest a better way to open pdf files with gf?
Thanks.
That's because what follows an autocmd is an ex command (the ones beginning
with a colon). To simulate the execution of a normal mode command, use the
:normal command. The problem is that you can't pass a <C-O> (and not
<Ctrl-O>) directly to :normal, it will be taken as literal characters (<,
then C, then r) which is not a very meaningful normal command. You have two
options:
1.Insert a literal ^O Character
Use controlvcontrolo to get one:
au BufEnter *.pdf normal! ^O
2.Use :execute to Build Your Command
This way you can get a more readable result with the escaped sequence:
au BufEnter *.pdf exe "normal! \<c-o>"
Anyway, this is not the most appropriate command. <C-O> just jumps to the
previous location in the jump list, so your buffer remains opened. I would do
something like:
au BufEnter *.pdf bdelete
Instead. Still I have another solution for you.
Create another command with a map, say gO. Then use your PDF reader
directly, or a utility like open if you're in MacOS X or Darwin (not sure if
other Unix systems have it, and how it's called). It's just like double clicking
the icon of the file passed as argument, so it will open your default PDF reader
or any other application configured to open any file by default, like images or
so.
:nnoremap gO :!open <cfile><CR>
This <cfile> will be expanded to the file under the cursor. So if you want to
open the file in Vim, use gf. If you want to open it with the default
application, use gO.
If you don't have this command or prefer a PDF-only solution, create a map to
your preferred command:
:nnoremap gO :!FoxitReader <cfile> &<CR>
If the default app is acceptable, then simply using :!open % in command mode works. You can always map this to a suitable leader combination in your vim config file etc.
If you want something that works with normal mode, then you could try something like the following (i use this too for opening HTML files), and modify to your own needs:
if has('win32') || has ('win64')
autocmd FileType html nmap <Leader>g :silent ! start firefox "%"<cr>
elseif has('mac')
autocmd FileType html nmap <Leader>g :!open "%"<cr><cr>
endif
I'd like to set up my .vimrc so that NERDTree is open whenever vim (or MacVim) is called from the command line with a directory argument, but closed when vim is called with a file argument. I looked through the list of vim's built-in variables but couldn't find anything that looked promising.
Looked up arglist per Alligator's advice. Ended up with the following:
if argc() > 0 && isdirectory(argv(0))
autocmd VimEnter * silent NERDTree
endif
I have an auto command triggered off BufEnter in my .vimrc to cd into the current buffer directory (very useful)
au BufEnter * execute ":lcd " . expand("%:p:h")
The problem is this fails on FTP files (as you might expect). The real problem is the error message telling me it has failed. Is there any way to suppress the error message, or alternatively "cd" into the current directory for FTP files as well (to make opening other files in the directory easier).
Just making the error message go away would be very helpful though! I've tried various experiments with the :silent command, but either it's not working for this command, or I didn't put it in the correct place.
Did you try:
au BufEnter * execute ":silent! lcd " . expand("%:p:h")
:silent! is supposed to skip errors as well as messages.
As a side note, also have a look at :h 'autochdir' which does something similar to your autocommand. (However see :h netrw-incompatible for caveats.)