Tech notes for vimscript



  1. Vimscript: Search for a line
  2. Vimscript: filter and map lists (arrays)
  3. Vimscript: Lambdas
  4. Vimscript: Simple popup menu
  5. Vimscript: Dictionaries
  6. Vimscript: Closures
  7. Vimscript: String concatenation, substring and character regex matches
  8. Vimscript: getline(): a file's lines into an array
  9. Vimscript: Regex equal operator
  10. Vimscript: Filter a list (array) with an inline function
  11. Vimscript: Function parameter (scoping)
  12. Vimscript: Lists (arrays) and loops
  13. Vimscript: Global variable
  14. Vimscript: Function with user input and a variable
  15. Vimscript: Simple function

Vimscript: Search for a line

search() does that. It returns the line number of that match.

The first parameter is the string you want to search for.

The optional second parameter is a options string. "b" is backwards search. "nb" is a backwards search that doesn't move the cursor. There are a number of options.

Imagine this file with your cursor at the top of the file.

var grass = "green"
function things() {
function bings() {

And you have the function:

function Hi()
  let line1 = search("function")
  let line2 = search("function")
  let lines = getline(line1, line2)
  echo lines

Then :call Hi() will return

['function things() {', '  console.log("are")', '  console.log("solid")', '}', 'function bings() {']

Therefore missing out the first line and stopping at the start of the next function.

Your cursor will also be moved. If the cursor didn't move, the second search wouldn't pick up the start of the second function.


Vimscript: filter and map lists (arrays)

You can filter and map an array with one line lambdas.

function Hi()
  let things = ['grain', 'butter', 'salt', 'logical permissiveness']
  let things = things->map({i, thing -> thing . "!"})
  let things = things->filter({i, thing -> thing =~ "l"})
  echo things

:call Hi() will output ['salt!', 'logical permissiveness!'].


Vimscript: Lambdas

You define them with curly brackets.

A -> separates the comma-separated arguments and the one line body (which must return a value).

You don't need to prefix the arguments with a: as in normal functions.

function Hi()
  let s:fn = { arg1, arg2 -> arg1 . arg2 }
  echo s:fn('super','great')

:call Hi() returns in supergreat.


Vimscript: Simple popup menu

Since Vim 8.2 there are popup menus.

Pass popup_menu() a list of strings and a dictionary. The dictionary will contain a callback to a function.

function Hi()
  let things = ['bread','milk','beer']
  call popup_menu(things, #{ callback: 'Clicked', title: 'Something!' })

function Clicked(id, result) 
  echo result

And the callaback function will give you the selected menu number, starting from 1, as result. It's -1 if you pressed escaped the menu.

The options list is huge, borders and various things. See :help popup_up or do a stackoverflow search.

Notes: I have no idea what id is but apparently it's the id of the popup menu. And I don't know how to make the callback an inner function, although you can put functions inside functions but they're still global.


Vimscript: Dictionaries

Dictionaries use the curly bracket syntax: {'name':'dave', 'profession':'cook'}

If you use a hash, the dictionary names don't need to be strings: #{name: 'dave', profession: 'cook'}

You access them through square brackets or dot notation: and dict['name']

You remove an entry with unlet: unlet


Page 1 of 3
Click me