Hot answers tagged

6

I have a file (myWords.txt) which contains one word on each line Then simply let mylist = readfile('myWords.txt')


5

It's possible to use index({list}, {expr} ..) for this: let mydict = {'foo': {'a': 1, 'b': 2}, 'bar': {'c': 3, 'd': 4}} let myfilter = ['foo', 'asdf'] call filter(mydict, 'index(myfilter, v:key) == -1') index() returns -1 when {expr} is not found in {list} and otherwise the lowest index in {list}. :echo index(['foo'], 'foo') == -1 0 filter() removes the ...


5

It is a little bit faster to use a string expression than a lambda (and arguably easier to understand in this case), call filter(a, 'index(b, v:val)<0') This naive implementation is O(N^2) but is still fairly fast in practice as index() is implemented in C. If you have a very large number of elements in the RHS, it may be faster to use a pre-computed ...


4

Use :h call(): func! Bar(...) abort return a:000 endfunc func! Foo(...) abort echo call('Bar', a:000) endfunc call Foo('asdf', 'qwer') " --> ['asdf', 'qwer']


3

To keep it simple, I assume all elements are different (i.e. it's "set difference"): :call filter(list1, {_, v -> index(list2, v) < 0})


3

Simply use :let to set each entry of the dictionary at a time. let text = {} let text['code1'] =<< trim END if ok echo 'done' endif END let text['code2'] =<< trim END if something echo something else endif END echo text This produces the following output: {'code1': ['if ok', ' echo ''done''', 'endif'], 'code2': ['if ...


3

Matt's answer is the best way to do this, but here's an alternative. After you load your file into the buffer, you can call getline() which returns the lines you ask for as a List: let myList = getline(1, '$') As a side note, I'd also like to point out that none of your uses of exe are necessary. You can write all of these Ex commands directly into your ...


3

No, there is no datatype Set. So you have to implement it yourself or maybe find some implementation on the net. If you implement it yourself, you might consider "Dictionary functions" (see :help Dictionary-function) or "numbered functions" (see :help numbered-function). Here is a quick hack. Maybe you can start from this. Note: This "Set" can only handle ...


3

You can do something like this: :let a=[] :%s/\w\+/\=add(a, submatch(0))/gn :new :put =uniq(sort(a)) This will first declare a list a to work with. Then we run a :%s command, to capture all word-characters (\w\+) and act on all matches (g flag of the :s command), but won't actually replace (n flag). We use a sub-replace-expression(\=) in the replacement ...


3

You can use :set cscopetag to get that effect. When this setting is enabled, it uses :cstag whenever :tag, <C-]>, or vim -t is used. :cstag will use a cscope database if present, but if not it falls back to :tjump. As far as why you see it on one system and not another, I'm pretty sure CentOS (and possibly RedHat) enable 'cscopetag' by default in ...


2

You can map the Ctrl-] command so that it uses the :tselect command instead of :tag: :noremap <C-]> :execute ":tselect " . expand("<cword>")<CR>


2

If you really want to follow the destructive remove() path, you could also execute the following convoluted expression: echo map(copy(myfilter), 'has_key(mydict, v:val) ? remove(mydict, v:val) : mydict')[0] It may be faster with big dictionaries and small list of keys, but honestly, @timss' solution based on filter() + index() is the way to go. Both ...


2

There is nothing built in. But you might check lh-vim-lib. It has the following functions working on sorted lists: lh#list#equal_range() lh#list#lower_bound() lh#list#upper_bound()


2

At least for single characters, here's what I would do. First, let's build a little function for an expression map. It takes a dictionary corresponding to the cycle, examines the character under the cursor, and returns the sequence of commands to do. This is either a r command or nothing. function CyclePair(which_pairs) abort let char_under_cursor = ...


2

You are looking for :h 'list' and :h 'listchars' which is a built-in feature in vim/neovim. For example: set list set listchars=tab:>-,eol:¶ Will show the tab characters as >- and add a ¶ at the end of each line.


2

Maybe this: :%s/\W/\r\0\r/g :sort u :g/^\s*$/d The first puts a line break before and after each non-word character. The second command sorts the entire file with the option "unique", so all duplicate lines are removed. The third command deletes all lines that are empty or only contain whitespaces.


1

Style You spell out functions/commands/&c., which I think is wonderful. But you didn't spell out &cb. Prefer &clipboard. It appears you mixed spaces and tabs. Prefer one or the other (I use 2 spaces for vimscript). You're missing abort on your functions. function! is not strictly necessary according to :help E127, but this changed—I believe its ...


1

You can use grep with the --only-matching/-o flag to accomplish this: :%!grep -o '\w\+\|\W' | sort -u


1

Well maybe it is not exactly what you want, but why not use such subst command after insert finished: '[+1,']s/^/> / Where '[+1 is second inserted line number '] is last inserted line number s - subst command ^ - start of line (position after "enter") > - replacement text You can map this to key for example: nnoremap <F4> :'[+1,']s/^/> /&...


1

In that case, you could simply use the good old exists() :let foo = exists('$FOO') ? $FOO : 'default' There is also empty(), IMO it only makes sense if you want to undefine environment variables from within Vim. Indeed, as :unlet $FOO isn't possible, yet, we have to use :let $FOO='' To obtain all environment variables, you could use getcompletion() on ...


1

$VIM_DATA_DIR already gives you the environment variable, so you can do let $VIM_DATA_DIR = !empty($VIM_DATA_DIR) ? $VIM_DATA_DIR : "default" If you really need all environment variables take a look at this answer on stackoverflow: function! Env() redir => s sil! exe "norm!:ec$\<c-a>'\<c-b>\<right>\<right>\<del>'\&...


Only top voted, non community-wiki answers of a minimum length are eligible