I am having issue with my .vimrc file. I have completed an autocommand for all python and sh files. I have included both below. All works as expected when using a direct path ie:
gvim test.py
If I use a path relative to the cwd, however, such as:
gvim ../test.py
I receive the following error:
Error detected while processing BufNewFile Auto commands for "*.{py,sh}"
E488: Trailing characters
Any ideas on how to fix this problem?
autocmd bufnewfile *.{py,sh}
\ let path = expand("~/bin/Templates/")|
\ let extension = expand("%:e")|
\ let template = path . extension|
\ let name = "John Doe" |
\ if filereadable(template)|
\ execute "silent! 0r" . template|
\ execute "1," . 10 . "g/# File Name:.*/s//# File Name: " .expand("%")|
\ execute "1," . 10 . "g/# Creation Date:.*/s//# Creation Date: " .strftime("%b-%d-%Y")|
\ execute "1," . 10 . "g/Created By:.*/s//Created By: " . name|
\ execute "normal Gdd/CURSOR\<CR>dw"|
\ endif|
\ startinsert!
autocmd bufwritepre,filewritepre *.{py,sh}
\ execute "normal ma"|
\ execute "1," . 10 . "g/# Last Modified:.*/s/# Last Modified:.*/# Last Modified: "
\ .strftime("%b-%d-%Y")
autocmd bufwritepost,filewritepost *.{py,sh}
\ execute "normal 'a"
The template for python files is as follows:
#!/usr/bin/python
# File Name: <filename>
# Creation Date: <date>
# Last Modified: <N/A>
# Created By: <Name>
# Description: CURSOR
First of all, let's have a look at :help 10.2:
The general form of the `:substitute` command is as follows:
:[range]substitute/from/to/[flags]
Please keep /[flags] in mind. Now when you enter gvim test.py in the command line, the following command is executed in Vim:
:s//# File Name: test.py
But when you enter gvim ../test.py Vim executes:
:s//# File Name: ../test.py
so Vim uses test.py as :substitute's flags and that's not the desired behavior.
What you need is to replace expand("%") with expand("%:t") to get only the file name. See :help expand() for details.
Related
Fzf seems to automatically add spaces in front of the matched content, And then transfer it to sink.
let g:vimspector_json_path=$HOME . "/.config/vimspector_template/"
command! -bang -nargs=* LoadVimSpectorJson call fzf#run({
\ 'source': 'ls ' . vimspector_json_path,
\ 'sink': 'e .vimspector.json | 0r' . vimspector_json_path,
\ 'down': '25%',
\ 'options': '--preview-window=hidden'
\ })
Vim(read):E484: Can't open file /home/lee/.config/vimspector_template/ python.json
Error because of the space before the filename python.json .
Is there any way to remove this space?
You can create an additional user-command to load a template by name and do the directory concatenation in that command.
For example:
command! -bar -nargs=1 LoadVimSpectorTemplate
\ execute "0r ".g:vimspector_json_path.<q-args>
So :LoadVimSpectorTemplate python.json will load that template file from the vimspector template directory.
In your fzf#run() call, you can then use:
'sink': 'e .vimspector.json | LoadVimSpectorTemplate'
I am trying to create installation script for https://github.com/junegunn/vim-plug/wiki/tips
if empty(glob('~/.vim/autoload/plug.vim'))
let s:downloadurl = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
let s:destinedirectory = $HOME . "/.vim/autoload/"
let s:destinefile = s:destinedirectory . "plug.vim"
if !isdirectory(s:destinedirectory)
call mkdir(s:destinedirectory, "p")
echo "Created directory: " . s:destinedirectory
endif
if executable("curl")
silent !curl --location --fail --output s:destinefile --create-dirs s:downloadurl
else
silent !wget -o s:destinefile --force-directories s:downloadurl
endif
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
But vim is not evaluating my variables, i.e., instead of running the command
wget -o /home/user/.vim/plug.vim --force-directories https://raw.githubusercontent...
It is running:
wget -o s:destinefile --force-directories s:downloadurl
You could use execute to evaluate the variables in commands. For your case:
silent execute '!wget -o '.s:destinefile.' --force-directories '.s:downloadurl
Here the dot is the string concatenation operator documented in :help expr-..
I have a function in my .vimrc that automatically updates the file I'm currently editing with the timestamp (Modified) of the last 'save' (:w).
I would like to also update the Filename and Filepath. I have an autocmd that updates the filename (through expand("%"). As for the Filepath, from what I read in the documentation, using expand("%:p:h") should permit me to insert the path (excluding the filename), but it does not work.
Anybody can tell me how insert the Filepath in my header ?
Example of file header that I wish to update:
Modified: November 13 2016
Filename: myfile
Filepath: /home/me/path/tomyfile/
Code I have at the moment :
autocmd BufWritePre * call UpdHeader()
function! UpdHeader()
" update path <<<<<< DOES NOT WORK >>>>>>>
silent! execute "1," . 10 . "g/Filepath:.*/s//Filepath: " .expand("%:p:h")
" update filename <<WORKS>>
silent! execute "1," . 10 . "g/Filename:.*/s//Filename: " . expand("%")
" update last mod date <<WORKS>>
silent! execute "1," . 10 . "g/Modified:.*/s//Modified: " . strftime("%d %B %Y%t%t%T (%z)%tBy : ") . $USER
...
endf
thx!
M
You need to perform proper escaping on the filepath, as you use / both as a separator in :substitute, and the (Unix-style) replacement path also has / separators in it. :substitute would have alerted your via E488: Trailing characters, but you've :silent! it.
A quick fix would be switching of :substitute separators, hoping that # will never appear in a file path:
silent! execute "1," . 10 . "g/Filepath:.*/s##Filepath: " .expand("%:p:h")
Better do proper escaping:
silent! execute "1," . 10 . "g/Filepath:.*/s//Filepath: " .escape(expand("%:p:h"), '/\'. (&magic ? '&~' : ''))
Alternatively, you can replace with an expression:
silent! execute "1," . 10 . "g/Filepath:.*/s//\\='Filepath: ' .expand('%:p:h')"
Your filename expansion would benefit from that as well.
In my vimrc I call Uncrustify by this command:
%!uncrustify -l CPP -c D:\uncrustify\default.cfg
After that on some code I get a Windows Fatal error:
But when I call uncrustify on the same code in the console using the -f option, there is no error.
How can I change my vimrc to avoid such errors in the future? What can invoke this error?
In order to integrate Uncrustify with Vim properly, add the following to your .vimrc:
" Restore cursor position, window position, and last search after running a
" command.
function! Preserve(command)
" Save the last search.
let search = #/
" Save the current cursor position.
let cursor_position = getpos('.')
" Save the current window position.
normal! H
let window_position = getpos('.')
call setpos('.', cursor_position)
" Execute the command.
execute a:command
" Restore the last search.
let #/ = search
" Restore the previous window position.
call setpos('.', window_position)
normal! zt
" Restore the previous cursor position.
call setpos('.', cursor_position)
endfunction
" Specify path to your Uncrustify configuration file.
let g:uncrustify_cfg_file_path =
\ shellescape(fnamemodify('~/.uncrustify.cfg', ':p'))
" Don't forget to add Uncrustify executable to $PATH (on Unix) or
" %PATH% (on Windows) for this command to work.
function! Uncrustify(language)
call Preserve(':silent %!uncrustify'
\ . ' -q '
\ . ' -l ' . a:language
\ . ' -c ' . g:uncrustify_cfg_file_path)
endfunction
Now you can either map this function (Uncrustify) to a combination of keys or you could do the convenient trick that I use. Create a file ~/.vim/after/ftplugin/cpp.vim where you can override any Vim settings particularly for C++ and add the following line there:
autocmd BufWritePre <buffer> :call Uncrustify('cpp')
This basically adds a pre-save hook. Now when you save the file with C++ code it will be automatically formatted by Uncrustify utilizing the configuration file you supplied earlier.
For example, the same could be done for Java: in ~/.vim/after/ftplugin/java.vim add:
autocmd BufWritePre <buffer> :call Uncrustify('java')
You got the point.
NOTE: Everything presented here is well-tested and used every day by me.
I have found the placing the following code into your .vimrc to be sufficient:
let g:uncrustifyCfgFile = '~/.uncrustify.cfg'
function! UncrustifyFunc(options) range
exec a:firstline.','.a:lastline.'!uncrustify '.a:options
\.' -c '.g:uncrustifyCfgFile.' -q -l '.&filetype
endfunction
command! -range=% UncrustifyRange <line1>,<line2>call UncrustifyFunc('--frag')
command! Uncrustify let s:save_cursor = getcurpos()
\| %call UncrustifyFunc('')
\| call setpos('.', s:save_cursor)
Note this does assume that you have "uncrustify" binary in your $PATH.
It also assumes your configure file is ~/.uncrustify.cfg however you can change that by modifiying the g:uncrustifyCfgFile variable.
To call run
:Uncrustify
It also works on ranges (which was what promoted me to make this function). Visual selection example:
:'<,'>UncrustifyRange
I have only tired it with C, CPP and JAVA (I assume others will work as well)
In addition to #Alexander Shukaev's answer, adding the following will perform a check for uncrustify config correctness and not auto format if error is detected:
let output = system('uncrustify -q -c ' . a:cfgfile)
if v:shell_error != 0
echo output
endif
return v:shell_error
endfunction
" Don't forget to add Uncrustify executable to $PATH (on Unix) or
" %PATH% (on Windows) for this command to work.
function! Uncrustify(language)
if CheckUncrustifyCfg(g:uncrustify_cfg_file_path)
echo "Config file" g:uncrustify_cfg_file_path "has errors"
echo "No formatting will be performed"
return
endif
call Preserve(':silent %!uncrustify'
\ . ' -q '
\ . ' -l ' . a:language
\ . ' -c ' . g:uncrustify_cfg_file_path)
endfunction
I am trying to create an autocommand that will create boiler plate comments and code for new Java source files. As a simple start, I have added the following two lines (only a new line after the first line below in the actual file) to my .vim/ftplugin/java.vim:
autocmd BufNewFile *.java
\ exe "normal O/*\r" . expand('%:t') . "\t" . strftime("%B %d %Y") .
"\r/\r\rpublic class " . expand('%:t:r') . " {\r\t\<Esc>i"
With the last part, \t\<Esc>i, I am trying to insert a tab and shift to insert mode automatically. I can't make the switch to insert mode work and have tried different permutations of two or more of \<Esc>, \<Insert>, "insert" , i and \t. What am I missing ?
I am using VIM 7.2 on Linux.
You could use the :startinsert command. Just execute it after the :normal command:
autocmd! BufNewFile *.java
\ exe "normal O/*\r" . expand('%:t') . "\t" . strftime("%B %d %Y") .
\ "\r/\r\rpublic class " . expand('%:t:r') . " {\r\t" |
\ startinsert!
Here's some more information on that: http://vimdoc.sourceforge.net/htmldoc/insert.html#:startinsert.