vimtricks.wiki Concise Vim tricks, one at a time.

How do I use glob() in Vimscript to get a list of files matching a wildcard pattern?

Answer

glob()

Explanation

The glob() built-in function expands a wildcard pattern into a list of matching filesystem paths, entirely within Vimscript. This is the idiomatic way to discover files in plugins and config scripts without shelling out to find or ls.

How it works

glob({pattern} [, {nosuf} [, {list} [, {alllinks}]]])
  • pattern: A shell-style glob (supports *, ?, ** for recursive)
  • nosuf (0/1): If 1, ignores 'suffixes' and 'wildignore' settings
  • list (0/1): If 1, returns a List of strings instead of a newline-separated string — almost always what you want
  • alllinks (0/1): If 1, includes broken symlinks in results

Always pass list=1 (third argument) to get a proper Vim List:

let l:files = glob('~/.vim/plugin/**/*.vim', 0, 1)

Example

Source all files in a config directory:

for l:file in glob('~/.config/vim/plugin/*.vim', 0, 1)
  execute 'source ' . fnameescape(l:file)
endfor

List available colorschemes:

let l:colors = glob($VIMRUNTIME . '/colors/*.vim', 0, 1)
let l:names = map(l:colors, 'fnamemodify(v:val, ":t:r")')
echo join(l:names, ', ')

Count Lua config files:

echo len(glob('~/.config/nvim/**/*.lua', 0, 1)) . ' Lua files'

Tips

  • Always use list=1 — the default newline-separated string form is awkward to work with
  • Wrap results in fnameescape() before using paths in Ex commands to handle spaces and special characters
  • **/*.vim expands recursively across subdirectories (Vim's built-in wildcard)
  • For searching across 'runtimepath' directories, use globpath(&runtimepath, 'after/ftplugin/*.vim', 0, 1) instead
  • Compare to readdir() (Vim 8.1.1511+) which lists a directory's entries without glob expansion

Next

How do I encode and decode JSON data in Vimscript for configuration and plugin development?