I generally use GVim, but most of my configuration is done via .vimrc (like keymappings) because I want them in vim and gvim. So when I edit my vimrc and then source it from gvim, I have to source my .gvimrc after that in order to get my colorscheme back (since it's gvim only). I tried to write a function to do this, and ran into the problems described in the comments below:
function ReloadConfigs()
:source ~/.vimrc
if has("gui_running")
:source ~/.gvimrc
endif
endfunction
command! Recfg call ReloadConfigs()
" error: function already exists, add ! to replace it
function! ReloadConfigs()
:source ~/.vimrc
if has("gui_running")
:source ~/.gvimrc
endif
endfunction
command! Recfg call ReloadConfigs()
" error: cannot replace function, it is in use
Is it possible to do something like this? Or, since my .gvimrc only has a few lines, should I just put its contents into an if has("gui_running") block?
You've put your function somewhere in your .vimrc. This means that, while it's being executed, the :source .vimrc is trying to redefine it, which is a problem. You could try doing this:
if !exists("*ReloadConfigs")
function ReloadConfigs()
:source ~/.vimrc
if has("gui_running")
:source ~/.gvimrc
endif
endfunction
command! Recfg call ReloadConfigs()
endif
If the function is already defined, this should skip redefining it, avoiding the issue.
I would say that whatever you have in your .vimrc that's messing up gvim settings should be surrounded by an if !has("gui_running") block.
An autocmd seems to be the easiest way of handling what you're trying to do:
autocmd BufWritePre .gvimrc,.vimrc source <amatch>
This way you get your configuration file automatically reloaded when you save it without having to mess around with functions. Alternatively, you could use a mapping to trigger :source $MYVIMRC or :source $MYGVIMRC.
Related
I have an autocommand for source files that runs an autoformatter on save. If the autoformatter modifies the file, all my marks are lost. Is there a way to preserve the marks in this case? My relevant .vimrc configuration is this:
function! s:FormatCode()
if (s:formatOnSave == 1)
Autoformat
endif
endfunction
Then in an augroup:
if (executable("clang-format"))
autocmd FileType c,cpp,objc,objcpp autocmd BufWritePre <buffer> silent! call s:FormatCode()
endif
Assuming that the autoformatter is using the filter command, this can be done by prepending :help :keepmarks to the command:
keepmarks Autoformat
Read the caveats in the help. If that doesn't work, you'd have to manually save and restore the marks, e.g. using getpos() and setpos().
I like using code cleanup scripts; perldidy; uglifierjs, etc. I previously ran them all like this in my vimrc...
map <leader>pt :!perltidy<CR>
map <leader>jt :!uglifyjs -b<CR>
map <leader>pjt :!python -mjson.tool<CR>
map <leader>ct :!column -t<CR>
How this functionally works; it runs currently selected text throguh the CLI program, and replaces the selection with the output. Works wonderfully; but as you can see I now have to stop and think what beautifier I want to run and remember the nemonic I have for it. This led me to think there has to be a better way. So I tried did this...
map <leader>jt :call RunTidy()<cr>
function! RunTidy()
if (&ft == "javascript")
echo 'is js..'
:'<,'>!ulifyjs -b
endif
if (&ft == "json")
echo 'is json'
:'<,'>!python -mjson.tool
endif
endfunction
The problem being this just doesn't work; executing once for each line and not replacing contents.. Anyone aware of a better way to do this? I feel like this should be a solved problem...
augroup filters
autocmd!
autocmd FileType perl map <buffer> <leader>t :!perltidy<CR>
autocmd FileType javascript map <buffer> <leader>t :!uglifyjs -b<CR>
autocmd FileType json map <buffer> <leader>t :!python -mjson.tool<CR>
augroup END
or put those mappings, all with the same lhs, in different ~/.vim/after/ftplugin/{filetype}.vim.
Use ftplugins. You need to have filetype plugin indent on in your vimrc.
Create files in ~/.vim/ftplugin/<filetype>.vim. These files will be sourced when the file type is set.
For example using javascript put the following in ~/.vim/ftplugin/javascript.vim
noremap <buffer> <leader>jt :!uglifyjs -b<CR>
to map <leader>jt to :!uglifyjs -b<CR> in all javascript buffers. This will not show up in other filetypes.
You would do the same for all other filetypes.
You can do the same for file type specific settings by using setlocal.
Take a look at :h ftplugin
I have this in my .vimrc:
autocmd Filetype mkd call SetWritingOptions()
function SetWritingOptions()
setlocal guioptions-=T
colorscheme pencil
setlocal background=light
endfunction
I have a plugin which I activate by doing :VimroomToggle
Now, I would like to add that to the SetWritingOptions() function, so :VimroomToggle gets called each time I open a mkd file. How to do that?
Using this line in the function:
VimroomToggle
Commands you call in functions are the same as functions you enter using the : leader.
I have a symlink which points my .vimrc to the one from my repo.
Vim loads that just fine, but I can't get it to auto-source upon it being changed.
I have the typical:
if has("autocmd")
autocmd! BufWritePost .vimrc source $MYVIMRC
endif
Which works if the vimrc is not symlinked.
I have a similar setup where ~/.vimrc is just a symlink to a git repository. The following autocommand works for me:
autocmd! bufwritepost .vimrc source %
I don't like symlinks in general and Vim doesn't really like them either.
The layout I use is probably similar to yours:
~/.vimrc
~/.vim/vimrc
with a big difference: ~/.vimrc is a real file, not a symlink, and it contains only one line:
runtime vimrc
that executes my real ~/.vim/vimrc. Because it is a Vim command and it doesn't use a file path, that line can be the same on every system.
Because $MYVIMRC points to a real file, :so $MYVIMRC always works.
I solved that problem that way that all my configuration I am keeping in dotfiles folder
https://github.com/lis2/dotfiles
Then I have small and simple ruby script which I running when I am changing something in configuration
#!/usr/bin/env ruby
require "fileutils"
config_hash = { "tmux.conf" => ".tmux.conf", "vimrc" => ".vimrc", "vim" => ".vim", "gitconfig" => ".gitconfig", "gitignore" => ".gitignore"}
config_hash.each do |k,v|
FileUtils.rm_rf(File.dirname(__FILE__) + "/../#{v}")
FileUtils.ln_s(File.dirname(__FILE__) + "/#{k}", File.dirname(__FILE__) + "/../#{v}")
end
I recommend you to built same configuration. On all computers (private/work) I just clone my repo, run symlink.rb and my simple environment is ready for work.
cheers!
I have both .vimrc and .gvimrc symlinked to a git repo like you are describing. I'm running MacVim macOS.
I found a great answer to the question progressively-slower-reloading-time-of-vimrc.
I modified it a bit to reload both vimrc and gvimrc when any of them changes. I have been using it for months now without issues.
Here it is. You need just this and just in .vimrc. You don't have to add anything to .gvimrc.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Autoreload vimrc
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
augroup configsGroup
autocmd!
" Make changes effective after saving .vimrc. Beware that autocommands are
" duplicated if .vimrc gets sourced again, unless they are wrapped in an
" augroup and the autocommands are cleared first using 'autocmd!'
autocmd! bufwritepost *\<vimrc\> call OnSavingConfigs()
autocmd! bufwritepost *\<gvimrc\> call OnSavingConfigs()
augroup END
" Avoid infinite loops
if !exists("*OnSavingConfigs")
function! OnSavingConfigs()
" Clear previous mappings, they don't go away automatically when
" sourcing vimrc.
mapclear
source $MYGVIMRC
source $MYVIMRC
redraw
echo "Reloaded " . $MYVIMRC . " and " . $MYGVIMRC . "."
endfunction
endif
Is there any way to autosave the buffer before issuing :make? I use MacVim and make is bound to Command-B, which is very helpful but I cannot seem to figure out how to write the buffer before a make. I looked at all the autocmd events and nothing seemed to fit.
There's a QuickFixCmdPre which should be called before a make but can't seem to get it to work:
~/.vimrc
function! AutoSaveOnMake ()
if &modified
write
endif
endfunction
autocmd QuickFixCmdPre *.c :call AutoSaveOnMake()
Vim has a built-in setting for that:
:set autowrite
Write the contents of the file, if it has been modified, on each
:next, :rewind, :last, :first, :previous, :stop, :suspend, :tag, :!,
:make, CTRL-] and CTRL-^ command; and when a :buffer, CTRL-O, CTRL-I,
'{A-Z0-9}, or `{A-Z0-9} command takes one to another file.
Instead of creating an autocmd command, why not just update the Command-B mapping?
nnoremap <d-b> :update<bar>make<cr>