Consider a the following minimal vimrc:
set nocompatible
filetype plugin indent on
let g:tex_flavor = 'latex'
function! CompileLatex()
let save_pwd = getcwd()
lcd %:p:h
let compiler = 'pdflatex '
let mainfile = expand('%:p:r')
let &l:makeprg = compiler . mainfile . '.tex'
echon "compiling latex file..."
silent make!
execute 'lcd ' . save_pwd
endfunction
function! EchoLatexMessage()
redraw
echo 'This message is not shown'
endfunction
augroup echo_message
au!
au QuickFixCmdPost make call EchoLatexMessage()
augroup END
And in a foo.tex file like:
\documentclass{article}
\begin{document}
Foo
\end{document}
run :call CompileLatex(). As seen in the GIF the message This message is not shown from function EchoLatexMessage() is not shown (on the other hand the message compiling latex file... is always on screen). Why is this happening? I expect the new message to be echoed once :make finishes.
This is because of the silent make! in your function. The :silent apparently not only applies to the :make itself, but also to the autocmds invoked by it (which sort of makes sense). If you want to silence the compilation output itself, but not the messages from the autocmd, you can prepend :unsilent to :echo in the EchoLatexMessage() function.
Related
I am trying to use a template for Ruby files, by adding this to my .vimrc:
function! RubyTemplate()
" Add pragma comment
call setline(1, '# frozen_string_literal: true')
" Add two empty lines
call append(1, repeat([''], 2))
" Place cursor on line number 3
call cursor(3, 0)
endfunction
autocmd BufNewFile *.rb :call RubyTemplate()
However, this doesn't work and when I open a new Ruby file, it's empty.
Everything works as expected if I issue an :e! afterwards. However, this doesn't work if I add e! to the function, so I have to manually fire it every time.
What am I doing wrong?
You can use a static template file instead of invoking a function.
For instance, you can create a template file for your ruby scripts in your vim directory as ~/.vim/skeletons/ruby.skel, with the desired contents.
1 # frozen_string_literal: true
2
3
Then in your vimrc you should add the following code:
" Skeleton for .rb files
augroup ruby
" Remove all existing autocommands in the group
au!
au BufNewFile *.rb 0r ~/.vim/skeletons/ruby.skel
augroup end
Noah Frederick has an elegant solution that allows us to insert snippets manually or automatically.
It uses ultisnips plugin and two files
" after/plugin/ultisnips_custom.vim
if !exists('g:did_UltiSnips_plugin')
finish
endif
augroup ultisnips_custom
autocmd!
autocmd BufNewFile * silent! call snippet#InsertSkeleton()
augroup END
and
" autoload/snippet.vim
function! s:try_insert(skel)
execute "normal! i_" . a:skel . "\<C-r>=UltiSnips#ExpandSnippet()\<CR>"
if g:ulti_expand_res == 0
silent! undo
endif
return g:ulti_expand_res
endfunction
function! snippet#InsertSkeleton() abort
let filename = expand('%')
" Abort on non-empty buffer or extant file
if !(line('$') == 1 && getline('$') == '') || filereadable(filename)
return
endif
call s:try_insert('skel')
endfunction
In my case, I have done some changes but now if I create an empty python file, for example, I end up with:
An important note: In my case, if vim or neovim is not detecting the filetype correctly, and it can be done with auto commands, your automatic snippet insertion will not work.
I have this function to compile my tex files:
function! CompileTex()
silent write!
call setqflist([])
echon "compiling with arara ..."
exec 'lcd %:h'
if expand("%:p") =~# '\(figuras\|figures\)'
let mainfile = fnameescape(expand("%:p"))
else
let mainfile = fnameescape(Tex_GetMainFileName())
endif
let &l:makeprg = 'arara -v ' . mainfile
silent make!
if !empty(getqflist())
copen
wincmd J
else
cclose
redraw
echon "successfully compiled"
endif
endfunction
The first conditional is there because when creating figures I want to compile the current buffer even if there is a main file. However when I call the function in a path that contains "figures" I get
Error detected while processing function CompileTex:
line 4:
E499: Empty file name for '%' or '#', only works with ":p:h": lcd %:h
and the mainfile variable is set to the main tex file and not to the current buffer as I want.
Try as the error message suggests, and change "lcd %:h" to "lcd %:p:h".
Also, you don't need the :exec. Just write it directly, it's an ex command:
function! CompileTex()
silent write!
call setqflist([])
echon "compiling with arara ..."
lcd %:p:h
...
etc.
Over on askubuntu.com I was told how to run python on Vim. I am testing the set up which works with the code 1st or 2nd code python code at using python to solve a non linear equation.
The only thing I have done different was added print(a) as the last line. I ran this yesterday from the shell and it worked perfectly. Could someone let me know what is going wrong?
Ok so I corrected the vimrc with the appropriate question marks,
chmod +x ~/path/to/file/hw6problem2.py
Then from vim I ran
:Shell ./#
but I received the same syntax error again. (Does the file have to be saved as .sh because I can't get any .py files to run?)
dustin#dustin:~$ vim /home/dustin/Documents/School/UVM/Engineering/OrbitalMechanics/hw6problem2.py
File "hw6problem2.py", line 14
a0 = max(s/2, (s - c)/2)
^
SyntaxError: invalid syntax
shell returned 1
Press ENTER or type command to continue
vimrc
syntax on
au BufWinLeave * mkview "records settings
au BufWinEnter * silent loadview "reloads settings
set nu "puts line numbers on
set ic "case insensitive
set foldmethod=syntax "for the latex-suite
set autoread "autoload when files in the buffer have been modified
set autochdir "autochange directory
"set wrap
set wrap
" set lines=50 columns=80
" resizes window
:map g1 :set lines=20<CR>:set columns=80<CR>
:map g2 :set lines=50<CR>:set columns=80<CR>
:map g3 :set lines=50<CR>:set columns=170<CR>
:map <F6> :! firefox % &<CR>
:map E Ea
"set autoindent
set tabstop=4
set shiftwidth=2
set expandtab
set smartindent
"
" Stuff for latex-suite
" REQUIRED. This makes vim invoke Latex-Suite when you open a tex file.
" It also allows you to set different actions for different filetypes
" in ~/.vim/after/ftplugin/*.vim
filetype plugin on
set shellslash
" IMPORTANT: grep will sometimes skip displaying the file name if you
" search in a singe file. This will confuse Latex-Suite. Set your grep
" program to always generate a file-name.
set grepprg=grep\ -nH\ $*
" OPTIONAL: This enables automatic indentation as you type.
filetype indent on
" OPTIONAL: Starting with Vim 7, the filetype of empty .tex files defaults to
" 'plaintex' instead of 'tex', which results in vim-latex not being loaded.
" The following changes the default filetype back to 'tex':
let g:tex_flavor='latex'
let g:Tex_ViewRule_pdf = 'okular'
"""""""""""""""""""""""""""""""""""""""
" => Shell command
"""""""""""""""""""""""""""""""""""""""
command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
function! s:RunShellCommand(cmdline)
let isfirst = 1
let words = []
for word in split(a:cmdline)
if isfirst
let isfirst = 0 " don't change first word (shell command)
else
if word[0] =~ '\v[%#<]'
let word = expand(word)
endif
let word = shellescape(word, 1)
endif
call add(words, word)
endfor
let expanded_cmdline = join(words)
rightbelow new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded to: ' . expanded_cmdline)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
silent execute '$read !'. expanded_cmdline
1
endfunction
This is likely to be a python issue.
On a side not, there's a great shell function for executing scripts and redirecting output to vim buffer (split window).
Syntax to execute current script (you should have chmod +x and shebang line):
:Shell ./#
In order to add the function, add this to .vimrc:
command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
function! s:RunShellCommand(cmdline)
let isfirst = 1
let words = []
for word in split(a:cmdline)
if isfirst
let isfirst = 0 " don't change first word (shell command)
else
if word[0] =~ '\v[%#<]'
let word = expand(word)
endif
let word = shellescape(word, 1)
endif
call add(words, word)
endfor
let expanded_cmdline = join(words)
rightbelow new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded to: ' . expanded_cmdline)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
silent execute '$read !'. expanded_cmdline
1
endfunction
https://github.com/ruslanosipov/dotfiles/blob/master/.vimrc#L137
I have a pre-buffer write hook set up in vim that makes a few small adjustments before the contents of the buffer is saved out to a file.
if !exists("autocommands_loaded")
let autocommands_loaded = 1
autocmd BufWritePre *.php call TidyUpFormatting()
endif
func! TidyUpFormatting()
let save_cursor = getpos('.')
%s/\s\+$//ge
%s/\($\n\s*\)\+\%$//ge
%s/var_dump /var_dump/ge
%s/){/) {/ge
%s/( /(/ge
%s/if(/if (/ge
%s/while(/while (/ge
call setpos('.', save_cursor)
endfunction
This is in my ftplugin/php.vim file.
I've noticed though that these substitutions in TidyUpFormatting show up in the history of all substitutions - for example if I scroll up through the list of substitutions that I've done manually, there they are.
Is there a flag I can use, or indeed some better way, to do this so that these substitutions don't "leak out"?
Search patterns from :substitution inside a function indeed do pollute the search history (once for an entire function, not for every :s). You can remedy this by adding this at the end of the function:
:call histdel('search', -1)
I needed to prefix the substitution commands with the "silent" command, changing the TidyUpFormatting function to:
func! TidyUpFormatting()
let save_cursor = getpos('.')
silent! %s/\s\+$//ge
silent! %s/\($\n\s*\)\+\%$//ge
silent! %s/var_dump /var_dump/ge
silent! %s/){/) {/ge
silent! %s/( /(/ge
silent! %s/if(/if (/ge
silent! %s/while(/while (/ge
call setpos('.', save_cursor)
endfunction
Can anybody help me to get solution for my requirement?
Requirement is when a user exits from vim, cppcheck should happen and if any warning or error occurs then it should be prompted to a user.
Thanks in advance.
I assume you don't care if the command is executed asynchronously, since you're quitting the buffer anyway. You can use the :! command to run shell commands and :read to capture the output to a new window:
function! s:RunShellCommand(cmdline)
let first = 1
let words = []
" Expand and escape cmd arguments.
" shellescape() should work with '\'
for part in split(a:cmdline)
if first
" skip the cmd. ugly, i know.
let first = 0
else
if part[0] =~ '\v[%#<]'
let part = expand(part)
endif
let part = shellescape(part, 1)
endif
call add(words, part)
endfor
let expanded_cmdline = join(words)
" Create the new window
botright new
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call setline(1, 'Showing output from cmd: ' . expanded_cmdline)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
" This is where actual work is getting done :-)
silent execute '$read !'. expanded_cmdline
" Uncomment the line below if you want the buffer to be
" non-modifiable
" setlocal nomodifiable
1
endfunction
Then you can define an autocommand for when a buffer is unloading:
au BufUnload *.cpp s:RunShellCommand('cppcheck %')
or a somewhat more generic command which you can call at any time:
command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
Now, to prevent closing your buffer, you have to remap :wq or :q to a function that will perform the aforementioned (plus perhaps some confirmation?), since once :quit is invoked, it cannot be aborted.