VIM : Trouble mapping <c-/> and re-selecting visual selection? - comments

I am using a vim plugin called tComment
It allows me to comment a line by pressing gc or <c-_><c-_>
Also, it works on the shortcut <c-/><c-/> but the visual selection is lost.
So, I tried:
To make it work on single <c-/>
To retain the visual selection.
My attempts :
inoremap <c-/> gc
vnoremap <c-/> gc gv
nnoremap <c-/> gc
=========
imap <c-/> gc
vmap <c-/> gc gv
nmap <c-/> gc
=========
imap <c-/> gc$
vmap <c-/> gc$ gv
nmap <c-/> gc$
=========
inoremap <c-/> <c-_><c-_>
vnoremap <c-/> <c-_><c-_> gv
nnoremap <c-/> <c-_><c-_>
=========
imap <c-/> <c-_><c-_>
vmap <c-/> <c-_><c-_> gv
nmap <c-/> <c-_><c-_>
( Non of the above seems to work )
Note:
I have not done any other customizations from my side.
My attempts are listed above
Installing tComment on native vim (Ubuntu) lands you to my setup.

If you want to map keys to another mapping, you need to use :map, not :noremap.
For most plugins, this shouldn't be necessary; they usually provide either configuration variables or <Plug>PluginName... for that. Read :help g:tcommentMaps for instructions for this particular plugin, then place your overrides into your ~/.vimrc.

If I understand you correctly, you want to have one map (in i, n, & v-mode) that either comments the current line or the visual selection. This is what tcomment's <c-_><c-_> map does now (with the exception that you want to maintain the visual selection). In order to use <c-/> you have to set g:tcommentMapLeader1 = '' (or some other map, since <c-/> seems to be the same as <c-_> as echristopherson pointed out) in vimrc and then define your maps for <c-/>.
This should work (add these lines to .vimrc):
let g:tcommentMapLeader1 = ''
noremap <silent> <c-/> :TComment<cr>
vnoremap <silent> <c-/> :TCommentMaybeInline<cr>gv
inoremap <silent> <c-/> <c-o>:TComment<cr>
You might have to replace <c-/> with <c-_> to make this work. Since you reported that tcomment already worked when typing <c-/><c-/>, the <c-_> map should work.
Anyway, I'd also recommend to use the operator maps since those fit better the way vim works. I don't think using a single key is still a good idea though.

Related

VIM run command when opening .sql files

I am having a hard time figuring this out.
I am trying to run the below command when i open a sql file in VIM.
:%!sqlformat --reindent --keywords upper --identifiers upper -
I know this is probably easy and i am over thinking it but have been attempting various variations of the below in my _vimrc file and no luck
autocmd FileType sql call SqlFormatter()
augroup end
function SqlFormatter()
set noai
set mappings map ,pt :%!sqlformat --reindent --keywords upper --identifiers upper -<CR>
endfunction
EDIT:
when i run this inside VIM nothing happens
:call SqlFormatter()
when i run i can see the SqlFormatter() function in the list
:function
Currently the function in my _vimrc file looks like and i am still having no luck
autocmd FileType sql call SqlFormatter()
augroup end
function SqlFormatter()
set noai
" set mappings...
map ,pt :%!sqlformat --reindent --keywords upper --identifiers lower -
endfunction
Let's break this down into components. First the mapping:
map ,pt :%!sqlformat --reindent --keywords upper --identifiers upper -<cr>
The general rules with mappings is to supply a mode and use noremap if you are able. So this becomes:
nnoremap ,pt :%!sqlformat --reindent --keywords upper --identifiers upper -<cr>
Next we need to understand buffer-local mappings. Your mapping is global which means once you open a buffer with a 'filetype' of sql then this mapping will work in any buffer. This is not likely not what you want. By using the <buffer> option we can set this mapping for just this buffer.
You are using an FileType autocmd event to trigger this mapping for sql filetypes. Here is that cleaned up:
augroup SqlStuff
autocmd!
autocmd FileType sql call SqlFormatter()
augroup end
function SqlFormatter()
set noautoindent
nnoremap <buffer> ,pt :%!sqlformat --reindent --keywords upper --identifiers upper -<cr>
endfunction
Additionally, you may want to avoid the autocmd & function all together and just add both the setting and the mapping into ~/.vim/after/ftplugin/sql.vim
set noautoindent
nnoremap <buffer> ,pt :%!sqlformat --reindent --keywords upper --identifiers upper -<cr>
Note: I have not tested this mapping so if there is an issue with sqlformat then that will also need to be fixed
For more help see:
:h :map-commands
:h :map-local
:h :autocmd
:h :augroup
:h FileType
:h after-directory
More help from Learning Vimscript the Hard Way:
Basic Mapping
Modal Mapping
Strict Mapping
Buffer-Local Options and Mappings
Autocommands
Autocommand Groups

Vim Command Mapping "Copy to Clipboard" Not Working

I recently began using Vim as my primary editor instead of programs like Atom/VSCode. I added a number of leader mappings to simplify tasks I do quite often but I'm having trouble with a few of them.
In Visual mode, I would like to be able to press <Space>y to copy the current selection to the clipboard (+ register). I've verified that I can do this manually by entering visual mode, selecting the text I want, and pressing "+y. However, my mapping doesn't seem to work:
vmap <Leader>y "+y
I set my leader the following way:
map <Space> <Leader>
I do it this way so that when showcmd is set, I get a visual indicator in operator-pending mode. By looking at that indicator, I can tell that when I press <Space>, I do enter operator pending mode on the \ key as expected. Then, when I press y, I am no longer in operator pending mode, but I am still in visual mode and haven't yanked the selection to the register.
To make sure there wasn't a plugin colliding with my mapping, I backed up my .vimrc and replaced it with one that only has the following contents:
set showcmd
map <Space> <Leader>
vmap <Leader>y "+y
Does one of these keys need to be escaped? Or am I doing something else wrong?
(I'm currently running Ubuntu Bash on Windows. Vim is version 7.4)
For reference, I got the idea from this article (And use the exact same command):
https://sheerun.net/2014/03/21/how-to-boost-your-vim-productivity/
Thankfully, the fix is pretty simple.
map <Space> <Leader>
is incorrect. The right way is
let mapleader=" "
From :help mapleader
*<Leader>* *mapleader*
To define a mapping which uses the "mapleader" variable, the special string
"<Leader>" can be used. It is replaced with the string value of "mapleader".
If "mapleader" is not set or empty, a backslash is used instead. Example: >
:map <Leader>A oanother line<Esc>
Works like: >
:map \A oanother line<Esc>
But after: >
:let mapleader = ","
It works like: >
:map ,A oanother line<Esc>
Note that the value of "mapleader" is used at the moment the mapping is
defined. Changing "mapleader" after that has no effect for already defined
mappings.
How to define the "leader" key is explained under :help mapleader. If you want to use <Space> as "leader" you are supposed to do:
let mapleader = "\<Space>"
Note that the "leader" key is not a special key at all. With <Space> as "leader", the two mappings below are strictly equivalent:
vmap <leader>y "+y
vmap <Space>y "+y

How to set line numbers by default in vim?

I know you can add line numbers in vim by using,
:set number
How do I set this to default behavior?
add this line to ~/.vimrc (if not exist, create a new file)
:set nu
and save the file
the settings in $HOME/.vimrc file would be loaded automatically.
Except for set number to show linenumber, I have this to toggle normal line number and relative line number: (by pressing <leader>nu)
"---------------------------------------------------------
"toggle relativeline number
"---------------------------------------------------------
function! ToggleRelativeNumber()
let &relativenumber = &relativenumber?0:1
"let &number = &relativenumber? 0:1
endfunction
nnoremap <silent> <Leader>nu :call ToggleRelativeNumber()<cr>
https://github.com/sk1418/myConf/blob/master/common/.vimrc#L704
Open the file /etc/vim/vimrc (in sudo mode) and add the following line: set number
By the way, you will also find other (highly recommended) interesting commands you can enable:
" The following are commented out as they cause vim to behave a lot
" differently from regular Vi. They are highly recommended though.
"set showcmd " Show (partial) command in status line.
"set showmatch " Show matching brackets.
"set ignorecase " Do case insensitive matching
"set smartcase " Do smart case matching
"set incsearch " Incremental search
"set autowrite " Automatically save before commands like :next and :make
"set hidden " Hide buffers when they are abandoned
"set mouse=a " Enable mouse usage (all modes)

vim keyboard mapping problems on mac OSX

1.Env
vim7.3+zsh+iTerm2 on mavericks
2. Mapping Problem
Here are my problem list:
My vim could not get some shortcuts: <C-q>,<C-s>,<A-Left|Right|..>,<D-char>.
I could not map some special keys such as <A-char> , <A-S-char> , <C-A-char>in mac.
<C-q> and <C-s>
In iTerm2, <C-q> will delete whole line, (and <C-s> will launch Fwd-i-search).
It doesn't behave like start/stop character , so that I thought this problem is nothing to do with stty start and stty stop.
But after I add this into ~/.zshrc, I surprised to see that the map for <C-q> and <C-s> works well in Vim. At the same time it doesn't change the behavior of <C-q> and <C-s> in iTerm2(I don't know why).
stty start undef
stty stop undef
<A-char> problem in mac
In mac, mappings for <A-char> won't directly work in mac.
:inoremap <A-u> type some string A-u
:inoremap <A-p> type some string A-p
:inoremap
i õ * type some string A-u
i ð * type some string A-p
As far as I know about <A-char> in mac, hit <A-u> will print nothing but with a sound alert. hit <A-p> will print π. I found that map for π works well.
:inoremap π type some string A-p
Is it possible to map <A-u> in vim?
Another complex question, is it possible for <A-S-char>, <C-A-char>
:map <A-S-p> not work
:map ∏ works well(A-S-p will print `∏`)
:map <C-A-p> not work
:map <C-π> still not work
:map <C-S-p> do work
Another complex question related above, is it possible mapping <C-A-char>?
<A-Left|Right|UP|Down
In iTerm2 , hitting <A-Left|... will result in(iTerm2 doesn't bind any shortcut for them.):
<A-Up> print 'A' with a sound alert.
<A-Down> print 'B' with a sound alert.
<A-Left> print 'D' with a sound alert.
<A-Down> print 'C' with a sound alert.
In vim, <A-Left|... is same as <Left><Right><Up><Down> in insert mode , normal mode, visual mdoe and Ex Mode, etc.
<D-char>
Some keys about <D-char> are iTerms's own hotkeys, such as :
1. <D-q> will quit iTerm2
1. <D-w> will close current tab in iTerm2
On the other hand, the other keys such as <D-s> are not hotkey, and do not print any char in vim and terminal. Is it possible to map them in vim?
Map <C-1>
Vim doesn't provide keycode <C-1>, but you can use other unused vim keycodes instead
Potentially unused Vim keycodes that can be used include:
<F13> to <F37>
<S-F13> to <S-F37>
<xF1> to <xF4>
<S-xF1> to <S-xF4>
Type :set termcap to see which vim keycodes are unused.
If you want to use hotkey Ctrl+1, map it to Esc Sequence (such as ^[C-1) in terminal preference first, then bind this terminal keycode with an unused vim keycode such as <F13>, <xF1>, <t_bc>, etc.
"bind vim keycode `<F13>` to terminal keycode `^[C-1`
:set <F13>=^[C-1
:imap <F13> Input some characters
For more details, refer to fastcodes in vim
Map <A-char>
By default, <A-char> will print special character in mac. In generally, you can map this special character. Or you can remap <Alt> as Meta in your terminal.
Map <C-A-char> and <D-char>
Same with <C-1>, if you use termainal vim you could use fastcodes instead of.
Bind <C-A-char> with terminal any keycodes, for example : ^[C-A-a
Set vim fastkeycodes and do mapping:
Mapping:
:set <C-A-a>=^[C-A-a
:map <C-A-a> Input some characters

How does one navigate Ruby methods in VIM?

I'm learning VIM for Rails development and would like to easily navigate methods in a file. So far I see several options:
Find 'def' by using
/def<space>
Create a macro that corresponds to a key using q and record
use VIM marks? (not even sure what they do, they just sound promising
Anyone have any better ideas?
:help ]m
I think it requires vim-ruby for ruby support.
you'll want a feature called ctags
see exuberant ctags, it works for many languages included Ruby and is v simple to use.
from VIM :help ctags
ctags will create an index of all identifiers in a source tree. You can then use the tag commands to navigate around your source tree. see :help tag-commands. The easiest is to place the cursor over a keyword and press CTRL-]. To get back to where you came from press CTRL-T
Beyond this you might want to look at this page which documents how to use VIM as a more full featured Ruby IDE: Using Vim as a Complete Ruby On Rails IDE
Best solution for Vim: use ctags. Read Vim documentation about how to navigate in TAGS files, also install plugin like CtrlP which allows you to visually browse tags.
Warning: Exuberant ctags does not work well with Ruby, the parser is not in good condition and it has not been changed 4 years now.
ctags doesn't deal with: module A::B
ctags doesn't tag (at least some of) the operator methods like ==
ctags doesn't support qualified tags, -type=+
ctags doesn't output tags for constants or attributes.
Unfortunately all the others (I found 2) Ruby ctags generators are either outdated (no Ruby 1.9+ support) or very slow.
There is one solution tho. Ripper-ctags: https://github.com/tmm1/ripper-tags It is fast and it works as expected. It is based on Ruby 1.9+ feature called "Ripper" which allows us to build on top of (fast) Ruby original parser. It is the most accurate ctags generator today.
Ripper CLI options are almost identical to ctags, so if you already know ctags, you will find ripper-tags easy to learn. It's as easy as:
ripper-tags -R .
This creates TAGS file which vim automatically reads by default (must be the directory where you open your vim instance in, or manually change path setting in vim if you start it in a different directory - more in the Vim manual).
If you like this, you can go step further and install my project which automatically creates TAGS for all the gems you install: https://github.com/lzap/gem-ripper-tags
Usage is very simple (note again, only Ruby 1.9+):
gem install gem-ripper-tags
Then generate tags for all already installed gems:
gem ripper_tags
Anytime you install a gem now, tags will be automatically created.
gem instal some_gem ...
I go one additional step further - I have a git template which is regenerating my project TAGS after every git pull or merge automatically (using ripper-tags):
https://github.com/lzap/bin-public/blob/master/git-hooks-reinstall
Note you will need directory files/git_template as well from the very same git repository.
I hope this is good starting point for navigating in Ruby codebases :-)
A couple of ideas:
Firstly, make a mapping to use the C function searching keys in ~/.vim/after/ftplugin/ruby.vim:
:nmap [[ ?def <CR>
:nmap ]] /def <CR>
Then you can use [[ and ]] to go forward and back a function, just like in C/Perl/Java code etc.
Another way that might help:
In .vimrc, add the line:
:let ruby_fold = 1
Then use zj, zk, z[ and z] to navigate by folds. You could also install this plugin so that you can easily delete folds using daz.
For finding specific functions (rather than just navigating around them) you'll want to use ctags (as mentioned by chillitom). The taglist plugin makes it much easier to navigate to a specific function, but (as chillitom said) Ctrl-] and Ctrl-T are useful for following keywords under the cursor.
For more information, see:
:help [[
:help ft-ruby-syntax
:help z[
:help after-directory
I recently found that Ruby.vim (per one of the answers above) comes with pretty useful key-bindings:
nnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','n')<CR>
nnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','n')<CR>
nnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','n')<CR>
nnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','n')<CR>
xnoremap <silent> <buffer> [m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','b','v')<CR>
xnoremap <silent> <buffer> ]m :<C-U>call <SID>searchsyn('\<def\>','rubyDefine','','v')<CR>
xnoremap <silent> <buffer> [M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','b','v')<CR>
xnoremap <silent> <buffer> ]M :<C-U>call <SID>searchsyn('\<end\>','rubyDefine','','v')<CR>
nnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','n')<CR>
nnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','n')<CR>
nnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','n')<CR>
nnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','n')<CR>
xnoremap <silent> <buffer> [[ :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','b','v')<CR>
xnoremap <silent> <buffer> ]] :<C-U>call <SID>searchsyn('\<\%(class\<Bar>module\)\>','rubyModule\<Bar>rubyClass','','v')<CR>
xnoremap <silent> <buffer> [] :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','b','v')<CR>
xnoremap <silent> <buffer> ][ :<C-U>call <SID>searchsyn('\<end\>','rubyModule\<Bar>rubyClass','','v')<CR>
One trick is to just search using '/f methodName'.
You should also look at turning on code folding by adding this line to your .vimrc:
:let ruby_fold
See :help ft-ruby-syntax for more details.
Usually I just type the name of the method on the incremental search.
I wrote a small shell script using ag (The Silver Searcher). Define the following functions in your .vimrc
This method will expand the word under the cursor.
function! SearchForDeclarationCursor()
let searchTerm = expand("<cword>")
call SearchForDeclaration(searchTerm)
endfunction
Then declare the SearchForDeclaration method
function! SearchForDeclaration(term)
let definition = 'def ' . a:term
cexpr system('ag -w ' . shellescape(definition))
endfunction
Note that we are explicitly searching for def keyword. (You can use your language method signature syntax)
We then map the above function to a Leader command.
map <Leader>cd :call SearchForDeclarationCursor()<CR>
Now if you place your cursor anywhere on a method that is defined "in your project", and press <Leader>cd, it will navigate you to where the method is defined.
Note that a method can be defined in multiple classes. You can cycle using <Leader>n for next or <Leader>p for prev.
If you want a more detailed explanation for the above, I've written a blog post here: http://pradyumna.io/2017/12/17/search-ruby-method-declarations-in-vim.html
Hope this helps!

Resources