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 **/*.vimexpands recursively across subdirectories (Vim's built-in wildcard)- For searching across
'runtimepath'directories, useglobpath(&runtimepath, 'after/ftplugin/*.vim', 0, 1)instead - Compare to
readdir()(Vim 8.1.1511+) which lists a directory's entries without glob expansion