I’ve installed the winmanager, NERDTree and BufExplorer plugins. Now, I have <F8> set to toggle the winmanager display, using the following code in my .vimrc:
" mapping for triggering winmanager plugin
nnoremap <silent> <F8> :if IsWinManagerVisible() <BAR>WMToggle<CR><BAR> else<BAR> WMToggle<CR>:q<CR> endif <CR><CR>
This works fine.
What I want to do is to have winmanager show up automatically if the filetype is .c or .cpp. I added this to my .vimrc:
autocmd FileType c,cpp nested "\<F8>"
but it does not work.
Any help? Thanks in advance!
<F8> is a normal-mode mapping, but :autocmd expects an Ex command on its right-hand side. You need to use :normal (without a ! here, to allow mappings to take effect), and :execute to interpret the special key code:
:autocmd FileType c,cpp nested execute "normal \<F8>"
But I think it is cleaner to avoid the additional redirection and duplicate the mapping's commands instead:
:autocmd FileType c,cpp nested if IsWinManagerVisible() |exe 'WMToggle'| else| exe 'WMToggle' | quit | endif
Related
I have the following on my .vimrc
au FileType ruby nnoremap <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')
This executes rspec on the line specified, and gives me option to edit the line before pressing enter. But I have to be on the test file so it get the file name and line number correctly.
While developing I run nnoremap <leader>t :!rspec some/spec/file.rb:123 manually to run the test I want from anywhere in the code. So I can code and fire the test without need to visit the test file.
The problem is that if I visit another ruby file the mapping in .vimrc runs again and I loose the nnoremap command I used before. Is there a command to only map (in normal mode) if there isn't already a map for that sequence?
Regards,
This should be a buffer-local mapping. Use <buffer>:
au FileType ruby nnoremap <buffer> <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')
We can do better!
Use an augroup and make is self clearing to make it safe to re-:source.
augroup ruby_testing
autocmd!
autocmd FileType ruby nnoremap <buffer> <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')
augroup END
Even better forgo the autocmd and put this mapping in the after directory. Add the following line to ~/.vim/after/ftplugin/ruby.vim:
nnoremap <buffer> <expr> <leader>t ':!rspec ' . expand('%') . ':' . line('.')
For more help see:
:h :map-local
:h :augroup
:h after-directory
Vim has the :help :map-<unique> modifier which makes the mapping fail if such mapping already exists.
au FileType ruby nnoremap <unique> <expr> <leader>t ...
You can suppress the error message with :silent!:
au FileType ruby silent! nnoremap <unique> <expr> <leader>t ...
Alternatively (and this is slightly better because it doesn't suppress any other errors in the mapping definition, like syntax errors), you could explicitly check for the mapping's existence via maparg():
au FileType ruby if empty(maparg('<leader>t', 'n')) | nnoremap <expr> <leader>t ... | endif
Note that this literally implements that (I understand) you're asking for; i.e. the first Ruby file will define the mapping, and any subsequent Ruby files are ignored; the mapping will always use the first file's name and line number. If you instead want to have different right-hand sides for the same mapping, depending on the currently edited file, the solution is a buffer-local mapping as per #PeterRincker's answer. But with that, you have to be inside the original Ruby buffer to trigger the correct mapping.
A remedy for that might be to recall the executed command-line from the command-line history (should happen automatically for your incomplete mapping, else via histadd()), so that you can easily recall the command from another file.
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 am using SimpleFold for folding vim. I mapped it to a key setting:
map <unique> <silent> <Leader>f <Plug>SimpleFold_Foldsearch
However, I would like to set it up as an auto command. I tried adding this line to my .vimrc file:
autocmd FileType ruby <Plug>SimpleFold_Foldsearch
But, I just get an error now when I open a ruby file. Can anybody help me setup the autocmd so that it works?
:autocmd is executing Ex mode commands, so your code is wrong. You should be using :normal or feedkeys():
autocmd FileType ruby :execute "normal \<Plug>SimpleFold_Foldsearch"
In my .vimrc file, I have a key binding for commenting out that inserts double slashes (//) at the start of a line:
" the mappings below are for commenting blocks of text
:map <C-G> :s/^/\/\//<Esc><Esc>
:map <C-T> :s/\/\/// <Esc><Esc>
However, when I’m editing Python scripts, I want to change that to a # sign for comments
I have a Python.vim file in my .vim/ftdetect folder that also has settings for tab widths, etc.
What is the code to override the keybindings if possible, so that I have Python use:
" the mappings below are for commenting blocks of text
:map <C-G> :s/^/#/<Esc><Esc>
:map <C-T> :s/#/ <Esc><Esc>
You can use :map <buffer> ... to make a local mapping just for the active buffer. This requires that your Vim was compiled with +localmap.
So you can do something like
autocmd FileType python map <buffer> <C-G> ...
The ftdetect folder is for scripts of filetype detection. Filetype plugins must be inside the ftplugin folder. The filetype must be included in the file name in one of the following three forms:
.../ftplugin/<filetype>.vim
.../ftplugin/<filetype>_foo.vim
.../ftplugin/<filetype>/foo.vim
For instance, you can map comments for the cpp filetype putting the following inside the .../ftplugin/cpp_mine.vim:
:map <buffer> <C-G> :s/^/\/\//<Esc><Esc>
:map <buffer> <C-T> :s/\/\/// <Esc><Esc>
I prefer to have my configuration in a single file so I use the autocmd approach.
augroup pscbindings
autocmd! pscbindings
autocmd Filetype purescript nmap <buffer> <silent> K :Ptype<CR>
autocmd Filetype purescript nmap <buffer> <silent> <leader>pr :Prebuild!<CR>
augroup end
Vim doesn't clear set autocmds when you source your vimrc, so starting vim, changing something in your vimrc and running :so ~/.vimrc would define autocmds twice. That's why the bindings are grouped and cleared with autocmd! group_name. You can read more here.
Since mappings are applied to every buffer by default, and you want to change them for buffers matching the filetype only, the <buffer> modifier is in there, limiting the mappings to the local buffer.
Btw... if your primary problem is about commenting... you should check out 'nerdcommenter' plugin, its the fastest way to comment/uncomment your code in java/c/c++/python/dos_batch_file/etc etc.
This is only a partial answer for people coming here having difficulties getting any ftplugin scripts working, but remember that your .vimrc (or a file that it sources) should contain
filetype plugin on
or
:filetype plugin on
for filetype-plugins to be executed when a file of a given type is loaded.
I recommend the .../ftplugin/<filetype>.vim approach that freitass suggests, but in your specific case Vim Commentary will solve all of this for you.
I'm trying to define mappings for "cpp" filetype:
autocmd! FileType cpp map <leader>c echo "test c"
autocmd! FileType cpp map <leader>r echo "test r"
autocmd! FileType cpp map <leader>t echo "test t"
My leader key is redefined:
let mapleader = ","
When I open *.cpp file only one of the mappings works as expected: the ",t" sequence makes the "echo" happen, but the other two behaves as if there were no any mappings defined: ",r" makes Vim to switch to replace mode and ",c" brings Vim to insert mode.
What am I doing wrong?
I don't know how your example (including ,c one) could work: you forgot to prepend echo with a colon. But there is another mistake: according to the help:
:au[tocmd]! [group] {event} {pat} [nested] {cmd}
Remove all autocommands associated with {event} and {pat}, and add the command {cmd}.
So, the last one (,t) should replace all previous ones.
There are also another things you should to consider:
Don't use map, use noremap instead: it may once save you from doing a debug job after you add some mapping.
If you define filetype mapping you should normally add <buffer> as an argument to :noremap in a position before {lhs}: it will make this mapping local to the current buffer.
In case you want to re-source vimrc you should put all command into augroup:
augroup VimrcCpp
autocmd!
autocmd FileType cpp nnoremap <buffer> <leader>c :echo "c"<CR>
autocmd FileType cpp nnoremap <buffer> <leader>r :echo "r"<CR>
autocmd FileType cpp nnoremap <buffer> <leader>t :echo "t"<CR>
augroup END
I would have removed it from vimrc and added to ~/.vim/ftplugin/cpp.vim (after directory is to be used only to override options that you don't like if they are unconditionally defined by a plugin. If there are no mapping conflicts, don't use after).
I suggest you put those mapping in a file called cpp.vim placed in your ~/.vim/after/ftplugin/ (or any equivalent based on OS) directory.
Vim automatically loads it as long as you have
filetype plugin on
in your .vimrc.
This saves you writing autocommands and keeps your configuration well organized.