How to view all variables associated with a plugin in vim - vim

Is there a way to do something like this in vim?
:echom g:tagbar*
Basically, I'd like to get a listing of all the tagbar variables and what they are set to (without having to enter each of them individually)

for v in split(execute(":let"), '\n')
if v =~? '^tagbar_.*'
echo v
endif
endfor
Displays variables starting with tagbar_ and their values

g: is a predefined Dictionary of all global variables. You can do with it whatever you want.
:put =string(filter(copy(g:), {k, _ -> k =~? '^tagbar'}))

Related

How to toggle (all) line numbers on or off

Let's say I have some combination of:
" one if not both is usually on
set number " could be on or off
set relativenumber " could be on or off
Is there a way to toggle these on/off without losing information (not knowing what is set -- i.e., I would like to make a simple keyboard shortcut to toggle the visibility of the current line-number selection)? For example if I have only rnu set and I do:
:set number!
It really doesn't help me at all, since I'll still have rnu set and there will still be a line-number column on the left. If so, how could this be done?
give this a try:
currently, I am mapping it to <F7> you can change the mapping if you like
I am using the global variable, you can change the scope if it is required
This function will disable all line-number displays and restore to the old line number settings.
function! MagicNumberToggle() abort
if &nu + &rnu == 0
let &nu = g:old_nu
let &rnu = g:old_rnu
else
let g:old_nu = &nu
let g:old_rnu = &rnu
let &nu = 0
let &rnu =0
endif
endfunction
nnoremap <F7> :call MagicNumberToggle()<cr>
The one liner solution
:nnoremap <silent> <C-n> :let [&nu, &rnu] = [!&rnu, &nu+&rnu==1]<cr>
To understand what happens try:
:echo [&nu, !&rnu]
&nu ............. gets the value of number
!&rnu ........... the oposite value of relative number
For more :h nu

jedi-vim how to jump to the definition of a function in other file

I am new to jedi-vim, and I do not know how to jump the definition of a function in other file.
The jedi-vim's doc is:
The following are parts of them:
NOTE: subject to change!
let g:jedi#goto_command = "<leader>d"
let g:jedi#goto_assignments_command = "<leader>g"
let g:jedi#goto_definitions_command = ""
let g:jedi#documentation_command = "K"
let g:jedi#usages_command = "<leader>n"
let g:jedi#completions_command = "<C-Space>"
let g:jedi#rename_command = "<leader>r"
And I wonder what are <leader> and <C-Space> mean and how to use these commands on VIM
<leader> is a placeholder: when vim registers a mapping containing that string it replaces it with the current value of the mapleader variable.
If you didn't set that variable explicitly, <leader> is replaced with \ by default and those mapping are supposed to be read as \d, \g, etc. That is, press \ followed by d in rapid succession.
:help mapleader tells you how to set <leader> to something else if you don't like \.
<C-Space> means Ctrl+Space.
See :help key-notation, :help mapleader.
The correct way to jump to the file of function definition is this command:
<leader>d
It is the first command listed in your list of mappings.

VIM: Replace [aeiou]' with the respective accented letter

I know that VIM support digraph, and it would be perfect if it's possible to use with :s command, but I can't find a way to use it!
I think something like:
:%s/\([aeiouAEIOU]\)'/\=digraph(submatch(1)."!")/g
Would be perfect, but I didn't find a digraph function.
Thanks in advance.
EDIT
Ok, after a bit of diggin in the built-in VIM's functions, I've found tr and a first solution to the problem:
:%s/\([aeiouAEIOU]\)'/\=tr(submatch(1), 'aeiouAEIOU', 'àèìòùÀÈÌÒÙ')/g
However, I still want to know if there's a way to use digraph in expressions :)
function! Digraph(letter, type)
silent exec "normal! :let l:s = '\<c-k>".a:letter.a:type."'\<cr>"
return l:s
endfunction
This function will allow you to generate any digraph you want.
It simulates typing <c-k><char><char> by running it with the normal command and assigning it to the local variable s. And then it returns s.
After this function is defined and you can use it like this.
:%s/\([aeiouAEIOU]\)'/\=Digraph(submatch(1), "!")/g
Note: This was based off of the source code for EasyDigraph
Here's another approach using a hand-coded vim function (add to your vimrc):
" get a matching digraph for a given ASCII character
function! GetDigraph(var1)
"incomplete dictionary of digraphs, add your own....
let DigDict = {'a': 'à', 'e': 'è', 'i': 'ì'}
"get the matching digraph. If no match, just return the given character
let DictEntry = get(DigDict, a:var1, a:var1)
return DictEntry
endfunction
Call it like this :%s/\([aeiouAEIOU]\)'/\=GetDigraph(submatch(1))/g

Case insensitive f key in vim?

Does anyone know of any way to get the 'f' key in vim normal command mode to operate case insensitive
Example
function! OpenCurrentFileInMarked()
In the above line, if I am at the start of the line I want to be able to type 'fi'and get the first 'i' and then ';' to toggle to the capital 'I' in the middle of the function name. I would prefer that the 'f' key is always bound to case insensitivity. Would work much better for me as a default.
The easy answer here is: use a plugin. Others have had the idea before.
Fanf,ingTastic;: Find a char across lines
The main purpose of this plugin is to make f and t cross the line boundary.
To make them ignore case you need to let g:fanfingtastic_ignorecase = 1 in your vimrc.
ft_improved: improved f/t command
Same here.
To make it ignore case you again need to set a variable in your vimrc, this time let g:ft_improved_ignorecase = 1.
The first part of this (case insensitive f) is actually in the reference manual as an example of how to use the getchar() function:
This example redefines "f" to ignore case:
:nmap f :call FindChar()<CR>
:function FindChar()
: let c = nr2char(getchar())
: while col('.') < col('$') - 1
: normal l
: if getline('.')[col('.') - 1] ==? c
: break
: endif
: endwhile
:endfunction
See :help getchar().
You'll need to save the character returned and write a similar map for ; if you want that to work too.
You can't do this with regular vim commands. However, you can write your own function and bind the f key to it.

vim - set auto indent to fill the leading space with space or tabstop

It seems if we enable 'ai', vim will fill the the leading space with tabstop.
I can make it fill with just space with 'et'. I don't like a C file mixed with space and tabstop.
My vimrc:
set ts=4 et
set ai
set hlsearch
syntax on
filetype plugin indent on
autocmd FileType make setlocal noexpandtab
However, in some condition I do need to input tabstop when I hit the 'TAB' on keyboard, for example, in makefile and some others.
The 'autocmd FileType' command is not good: I can't add every file type in vimrc.
What I want is simple:
autoindent to fill leading area with
space;
when hit 'TAB' on keyboard, tabstop
input, not space (so no 'et')
How to do it?
inoremap <expr> <tab> ((getline('.')[:col('.')-2]=~'\S')?("\<C-v>\t"):(repeat(' ', &ts-((virtcol('.')-1)%&ts))))
It does the same as #Lynch answer if I read it correctly.
You can also use <C-v><Tab>: this will insert <Tab> without invoking any mappings and ignores expandtab unless you remapped <C-v> or <C-v><Tab> for some reason.
If you want to just insert tab do
inoremap <Tab> <C-v><Tab>
It will ignore expandtab setting.
I did it using a function. I tested it, but maybe in some particular case you will have to fix some bugs. Try adding this to your vimrc:
set et
function! Inserttab()
let insert = ""
let line = getline('.')
let pos = getpos('.')[2]
let before = ""
let after = line
if pos != 1
let before = line[ 0: pos - 1]
let after = line[pos : strlen(line) ]
endif
if pos != 1 && substitute(before, "[ \t]", "", "g") != ""
let insert = "\t"
else
let insert = " "
endif
let line = before . insert . after
call setline('.', line)
call cursor(line('.'), strlen(before . insert))
endfunction
inoremap <tab> <esc>:call Inserttab()<CR>a
Basicaly it does remap your key in visual mode to the function Inserttab(). Also note that if you change ts for something other than 4 it will still output 4 spaces instead of two because the value is hard coded.
Also im not very familiar with vim scripts, but I think all the variables used will be global which is a bad thing.
I forgot to mention that to "see" white spaces you can use set list. You disable this with set nolist. Also in normal mode you can use ga to see information about the character your cursor is on.
Edit
I realise that you may want to insert tab at the beginin of the line. My script insert space at the begining and tab anywhere else.
If you really want a tab every time you hit tab key you could simply use this:
set et
function! Inserttab()
let insert = ""
let line = getline('.')
let pos = getpos('.')[2]
let before = ""
let after = line
if pos != 1
let before = line[ 0: pos - 1]
let after = line[pos : strlen(line) ]
endif
let insert = "\t"
let line = before . insert . after
call setline('.', line)
call cursor(line('.'), strlen(before . insert))
endfunction
inoremap <tab> <esc>:call Inserttab()<CR>a
But I dont see the point, with this version you will never be able to indent manually from insert mode.
One way to do it is
:set sw=4 (or whatever you want)
:set ts=46 (or some large number)
Then autoindent will not insert tabs unless you reach 46 spaces, in which case you can put in a higher number.
Only drag about this is if someone else is using tabs, then you have to reset ts to agree with the file you are editing. On the other hand, it will make the tabs immediately obvious, which can be desirable as well.

Resources