Skip to content

Instantly share code, notes, and snippets.

@mattn
Last active March 3, 2026 02:27
Show Gist options
  • Select an option

  • Save mattn/f6b47de9c1f1b7074b036b8fce07167b to your computer and use it in GitHub Desktop.

Select an option

Save mattn/f6b47de9c1f1b7074b036b8fce07167b to your computer and use it in GitHub Desktop.
let s:hashes = {}
function! dirhash#add(name, path) abort
let path = fnamemodify(a:path, ':p')
let path = substitute(path, '[/\\]$', '', '')
let s:hashes[a:name] = path
endfunction
function! dirhash#remove(name) abort
if has_key(s:hashes, a:name)
unlet s:hashes[a:name]
else
echohl ErrorMsg
echomsg 'dirhash "' .. a:name .. '" not found'
echohl None
endif
endfunction
function! dirhash#list() abort
if empty(s:hashes)
echo 'No dirhashes defined'
return
endif
for [name, path] in sort(items(s:hashes))
echo printf(' %-14s %s', name, fnamemodify(path, ':~'))
endfor
endfunction
function! dirhash#expand(str) abort
return substitute(a:str,
\ '\(^\|[[:space:]=,:"'']\)\zs\~\([a-zA-Z0-9_]\+\)',
\ '\=s:expand_one(submatch(2))', 'g')
endfunction
function! s:expand_one(name) abort
return get(s:hashes, a:name, '~' .. a:name)
endfunction
function! dirhash#expand_cmdline() abort
return dirhash#expand(getcmdline())
endfunction
function! dirhash#expand_cr() abort
if getcmdtype() !=# ':'
return "\<CR>"
endif
let cmd = getcmdline()
let expanded = dirhash#expand(cmd)
if cmd !=# expanded
return "\<C-\>edirhash#expand_cmdline()\<CR>\<CR>"
endif
return "\<CR>"
endfunction
function! dirhash#expand_tab() abort
if getcmdtype() !=# ':'
return "\<Tab>"
endif
let cmd = getcmdline()
let expanded = dirhash#expand(cmd)
if cmd !=# expanded
return "\<C-\>edirhash#expand_cmdline()\<CR>\<Tab>"
endif
return "\<Tab>"
endfunction
function! dirhash#command(args) abort
let args = a:args
if args ==# ''
call dirhash#list()
return
endif
let m = matchlist(args, '^\s*\(\S\+\)\s\+\(.\+\S\)\s*$')
if empty(m)
echohl ErrorMsg
echo 'Usage: :Dirhash [name path]'
echohl None
return
endif
call dirhash#add(m[1], m[2])
endfunction
function! dirhash#complete_undirhash(ArgLead, CmdLine, CursorPos) abort
return filter(sort(keys(s:hashes)), 'v:val =~# "^" .. a:ArgLead')
endfunction
function! dirhash#get(name) abort
return get(s:hashes, a:name, '')
endfunction
function! dirhash#names() abort
return keys(s:hashes)
endfunction
*dirhash.txt* Directory shortcuts for Vim
Author: mattn
License: MIT
==============================================================================
INTRODUCTION *dirhash*
Create directory shortcuts similar to zsh's `hash -d`.
==============================================================================
COMMANDS *dirhash-commands*
*:Dirhash*
:Dirhash List all directory hashes.
:Dirhash {name} {path} Create a directory hash. After this, `~{name}` is
expanded to {path} on the command line.
*:Undirhash*
:Undirhash {name} Remove a directory hash.
==============================================================================
USAGE *dirhash-usage*
Create a hash: >
:Dirhash v ~/src/vim
<
Now `~v` expands on the command line: >
:e ~v/src/map.c
<
Also works with |expand()| on the command line: >
:echo expand('~v/foo')
<
Tab completion expands the hash first, then completes files: >
:e ~v/<Tab>
<
List all hashes: >
:Dirhash
<
Remove a hash: >
:Undirhash v
<
==============================================================================
FUNCTIONS *dirhash-functions*
*dirhash#expand()*
dirhash#expand({str}) Expand `~name` patterns in {str}. >
:echo dirhash#expand('~v/foo')
<
*dirhash#get()*
dirhash#get({name}) Return the path for {name}, or empty string.
*dirhash#names()*
dirhash#names() Return a list of all hash names.
==============================================================================
OPTIONS *dirhash-options*
*g:dirhash_no_map*
g:dirhash_no_map Set to 1 before loading the plugin to disable the
command-line mappings for <CR> and <Tab>.
==============================================================================
vim:tw=78:ts=8:ft=help:norl:
if exists('g:loaded_dirhash')
finish
endif
let g:loaded_dirhash = 1
command! -nargs=* -complete=file Dirhash call dirhash#command(<q-args>)
command! -nargs=1 -complete=customlist,dirhash#complete_undirhash Undirhash call dirhash#remove(<q-args>)
if !get(g:, 'dirhash_no_map', 0)
cnoremap <expr> <CR> dirhash#expand_cr()
cnoremap <expr> <Tab> dirhash#expand_tab()
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment