New answers tagged

1

As @statox suggested in comments I should have used tnoremap to implement it. The following works fine: execute "tnoremap ".g:toggle_term ." <C-w>:call ToggleTerminal()<CR>" The mistake I initially made was the space right after the N execute "tnoremap ".g:toggle_term ." <C-w>N :call ToggleTerminal()<CR>" and since I rebound ...


2

When sourcing a script again, a function that was previously defined in that script will be silently replaced. That's a fairly recent (Vim 8.1) change. Previously, you had to use :function! to redefine an existing function. As plugin writers very frequently reload their scripts during development (as its much faster than restarting Vim and restoring all ...


1

Yes, I also wondered at seeing this topic first time. I suspect that the whole story is due to VimScript version changes, however, personally I still see these points: As it turns out, for a script-local function there's absolutely no difference between function and function!. Therefore, it becomes rather a matter of taste: some people may prefer "shorter" ...


1

This code works: augroup reload_vimrc autocmd! autocmd BufWritePost *.vim,vimrc,$MYVIMRC ++once source $MYVIMRC | e augroup END It does the augroup group/autocmd! dance to set up a group and clear any commands already in it establishes a one-time (++once) autocmd that sources the vimrc uses :edit to re-edit the current file (effectively sourcing ...


0

Not an answer to your question. But thought I'd mention that this exists: https://github.com/terryma/vim-smooth-scroll


0

I have now just checked manually whether the cursor is at the border of scrolloff, i.e. if it would be scrolled by <C-y> for example or not, and if not, then I move it manually at each iteration with j or k: function SmoothScroll(up) let cursormov="" if a:up let scrollaction= "normal \<C-y>" " now also check how far the cursor is ...


1

You might go with setline function or simple: let text = "Lorem ipsum sit dolor amet ..." exe "normal! a" . text . "\<Esc>" exe (:execute) is to execute vimscript normal! a executes a command as you type in vim (append after cursor) . text then you concatenate your text with normal a. As you would type this text in vim after a. and '\<Esc> to ...


3

You can do a literal insert of register contents through :help i_CTRL-R_CTRL-R, combined with the expression register (:help quote=) to reference the variable: execute "normal! i\<C-r>\<C-r>=text\<CR>\<Esc>" If you know that the variable contents are just plain text (without any special control characters), you could also just ...


4

The only problems I see with :substitute are: it messes a few registers we may have to be wary of the separator character used that'll need to be escaped its behaviour depends on 'magic' option (as well as substitute()'s one) If you really want to operate on the whole buffer without :s, you could also use the following oneliner (that'll be more efficient ...


0

One way could be using regular for loop: let idx = 1 for line in getbufline(bufnr('%'), 1, "$") call setline(idx, substitute(line, 'A', 'B', 'g')) let idx += 1 endfor or for line in range(0, line('$')) call setline(line, substitute(getline(line), 'A', 'B', 'g')) endfor which is pretty obvious. Another one could be: let buflines = getbufline(...


2

since this is documented best-practice in scripts Documented where? In vimscript (in which plugins are written), every "statement" is an Ex command, you can do function MyFunc() abort %substitute/pattern/repl/g endfunction or whatever it is you're trying to do. This is in fact the simplest mechanism. You can add modifiers (keepjumps, etc.) to the ...


1

You've identified most of the issues - I think the best one can do is using the unnamed register, saving its contents and type, and temporarily resetting 'clipboard' and :help cpo-y for yanks. I don't think it's possible to avoid the aliasing of register 0, but as these numbered registers are ephemeral and therefore rarely used, it's not so bad. Here's the ...


5

I though it wasn't possible, but I was wrong. See :h :func-closure You need to patch two things: add closure at the end of the inner of the function declaration respect the usual naming conventions For instance function! s:my_function(dict_arg) let darg = copy(a:dict_arg) func! s:my_inner_func(cond) closure return darg[a:cond] endfunc ...


2

feedkeys() is the correct approach, but to respect the special keys, I must use double quotes (as mentioned in the vimhelp): execute 'normal! 27Go' startinsert call feedkeys("\<c-x>\<c-o>")


0

I had the same need, because I run make from a split terminal below the code - so I often put the cursor on an error in the compiler's output and want to jump there with the split above. The following functions and mappings will make gf do a find of the file, then go to the line and column (if present), in the split above. If you want it to use the same ...


3

What you are seeing here, is essentially the same problem, as why many people struggle with using variables on the command line with the ex commands. See e.g. this question, there are a lot similar ones. Basically, Vims ex commandline commands expect their arguments to be literal, they cannot contain expressions (like variables or strings). Those commands ...


2

:help TextChanged has this: Not triggered when there is typeahead or when an operator is pending. Typeahead means the input buffer has keys about to be executed. A mapping (e.g. :nmap <F12> aTEXT<Esc>) fills it (and therefore, no TextChangedI events are fired for the TEXT here, neither), and macro playback is treated the same way as ...


2

You can use this: :echo len(split(getline('.'), ',')) That will get the content of the current line, split it on the , (comma) to a list and count the number of items of the list. Note: that the count() function just relatively recently learned about counting items in strings, while this solution is also compatible with Vim 7.


2

VimScript does not have a special character type. In fact, you always count() for substrings (or items in list): :echo count(getline("."), ",")


1

Here is a (modified) piece from one of my scripts. This now also returns a empty string if <Esc> is hit. let s:ESC = char2nr("\e") " Gets a single char from user, returns empty string if Ctrl-C or ESC was hit. " Ignores special keys (F-Keys, mouse clicks etc). function! GetChar(message) let msg = a:message . " (Ctrl-C to cancel) > " try ...


1

Redirect the output of the command to a new window, then use :BLines. This is mainly useful for editing the output. function! Exec(cmd) redir @a exec printf('silent %s',a:cmd) redir END tabnew norm "ap endfunction This function executes the command and printes the output onto a new tab. I use it from time to time. For example try : call Exec('nmap')


1

If you're only interested in working with fzf plugin you probably should do as @dedowsdi suggests. I'm going to talk about the general case, as stands in the question title. First of all, let's not forget that Vim has a builtin function for filtering command output which can come in handy on many occasions. Its usage (:h :filter) is quite straightforward: :...


1

com -nargs=+ FF call fzf#run({'source' : split(execute(<q-args>), "\n"), 'sink':'"'}) Examples: FF map [ FF set termcap FF buffers FF oldfiles :h :quote is used as sink, it's ignored. update Filter blank lines, add -bang to support reverse order, add sink to copy into default register. command! -nargs=+ -bang -complete=command FF call fzf#run({ ...


2

This is certainly possible, but it requires a bit of VimScript. The following function does the basic thing: func SwapHiGroup(group) let id = synIDtrans(hlID(a:group)) for mode in ['cterm', 'gui'] for g in ['fg', 'bg'] exe 'let '. mode.g. "= synIDattr(id, '". \ g."#', '". mode. "')" exe "let "....


0

Not sure if it's a good idea at all, but it's certainly possible: function! HiliteSwap(group) let l:hi = execute('hi ' . a:group) let l:ctermfg = matchstr(l:hi, 'ctermfg=\zs\S*') let l:ctermbg = matchstr(l:hi, 'ctermbg=\zs\S*') let l:guifg = matchstr(l:hi, 'guifg=\zs\S*') let l:guibg = matchstr(l:hi, 'guibg=\zs\S*') call execute(...


7

The simple way is if get(g:, 'myplugin_enable_feature', defaultvalue) do whatever you want endif Now when I need to check a setting in more than one place, I usually prefer to have a dedicated getter in my plugin to be sure I have the same default value everywhere function! s:enable_feature() abort return get(g:, 'myplugin_enable_feature', ...


4

Usually it suffices to use get() function. Like that if get(g:, 'myplugin_enable_feature') " do something endif If the feature should be enabled by default you can change it to get(g:, 'myplugin_enable_feature', 1).


0

expandcmd() expands wildcards, environment variables and such. It is not intended for VimScript execution. In general, you can use execute() function to run VimScript interpreter and get the ouput as a string. But in this case it's enough to use &-notation (see :h expr-option): i<C-R>=&shm


1

An alternative implementation which does not stop at the first error in a script: command! -range=% Exec call execute(getline(<line1>, <line2>), '') Now in visual mode type :'<,'>Exec to process the selected lines ('<,'> is added automatically as usual). Also, :Exec in normal mode executes the whole buffer, just as :source %, except ...


Top 50 recent answers are included