Skip to content

Instantly share code, notes, and snippets.

@g0xA52A2A
Last active May 19, 2021 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save g0xA52A2A/2d3d04b91117447703522b026765a117 to your computer and use it in GitHub Desktop.
Save g0xA52A2A/2d3d04b91117447703522b026765a117 to your computer and use it in GitHub Desktop.

Helpers

Some functions that I think should exist or re-implementations of existing functions with modified behaviour.

Contains

Check if a list contains an item or not, returns a boolean.

Typically the index() function is used to do this. However as it returns an index a value of 0 indicates the value is present, though 0 is considered false when used as a boolean. So when using index() for the successful path there are three conditions we could check.

  • The returned value must not be -1
  • The returned value must be greater than or equal to 0
  • The returned value plus 1 must be greater than 0

Clumsy.

function! Contains(list, item) abort
  return index(a:list, a:item) == -1 ? 0 : 1
endfunction

Equal

Compare equality of items without fear of type coercion.

Whilst Vim's documentation says the following for uniq().

The default compare function uses the string representation of each item.

It does not appear to be true.

echo uniq([0, '0'])
[0, '0']

So this suffices.

function! Equal(...) abort
  return len(uniq(copy(a:000))) == 1 ? 1 : 0
endfunction

A more thorough version would be to pair each item with its type.

function! Equal(...) abort
  return len(uniq(map(copy(a:000), "[type(v:val), v:val]"))) == 1 ? 1 : 0
endfunction

FeedKeys

Enqueue characters for processing without recursing into mappings.

Passing the n to the mode argument of feedkeys() is required to ensure this behaviour, which should really be the default.

Should the below be passed m in the mode argument it will take effect despite n always being present. This is because n is prepended and when given both n and m whichever is last takes precedence.

function! FeedKeys(keys, ...)" abort
  call feedkeys(a:keys, 'n' . join(a:000))
endfunction

GetCommands

Get a list of user commands that are either global or local to a buffer (indicated by boolean argument).

User commands can be displayed with the Ex command :command however this is pretty printed, to get an actual list structure we could do something like getcompletion('[A-Z]', 'command') but then we lose information about the commands such as if they are local to a buffer.

function! GetCommands(local) abort
  let      commands = split(execute('command'), '\n')[1:]
  call map(commands, "split(v:val)")
  call map(commands, "v:val[0] =~# '^[A-Z]' ? [''] + v:val : v:val")

  let expr  = a:local ? '' : '!'
  let expr .= "helper#Contains(split(v:val[0], '\\zs'), 'b')"
  return map(filter(commands, expr), "v:val[1]")
endfunction

GetCompletion

Get completion(s) case sensitively, returns a list.

function! GetCompletion(pattern, type, ...) abort
  let completions = getcompletion(a:pattern, a:type, a:0 ? a:1 : 0)
  return filter(completions, "v:val =~# a:pattern")
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment