Set up Vim to use Fasd for quickly jumping to directories

Rate this post

Fasd is a command-line tool that enhances productivity by providing quick access to files and directories. It is inspired by autojump, z and v.

By using the code provided below, you can configure Vim to leverage Fasd for swiftly jumping to directories:

" Language: Vim script
" Description: Vim Fasd integration
" Usage: Execute the command: 
"        :Fasd <QUERY>
" License: MIT
" Author: James Cherti
" URL:

function! Fasd(query)
  " -d: Match directories only.
  " -l: List paths without scores.
  let l:cmd = 'fasd -d -l ' . shellescape(a:query)
  let l:result = systemlist(l:cmd)
  if v:shell_error !=# 0
    echoerr 'Fasd error: ' . join(l:result, "\n")

  if len(l:result) ==# 0 || !isdirectory(l:result[0])
    echo 'Fasd has not found anything for: ' . a:query

  let l:path = l:result[0]
  exec 'edit ' . fnameescape(l:path)
  exec 'lcd ' . fnameescape(l:path)
  echo l:path

command! -bar -nargs=1 Fasd call Fasd(<f-args>)
Code language: Vim Script (vim)

Vim: Quickly replace the word that is under the cursor

" Language: Vim script
" Description: Quickly replace the word that is under the cursor.
" Usage: Press the keys '<Leader>rr', type the new word, and 
"        then leave insert mode (<Esc>).
" License: MIT
" Author: James Cherti
" URL:

function! s:replace_word_under_cursor(...) abort
  let l:action = 'main'
  if len(a:000) > 0
    let l:action = a:000[0]
  " Main action
  if l:action ==# 'main'
    let b:replace_word_data = {}
    let b:replace_word_data['changenr'] = changenr()

    let l:regex_prefix = ''
    let l:regex_suffix = ''
    if mode() ==# 'n'
      normal! diw
      let l:regex_prefix = '\<'
      let l:regex_suffix = '\>'
      echoerr 'Unsupported mode: ' . mode()

    let b:replace_word_data['string'] = substitute(@@, '\v\n+$', '', 'g')
    let b:replace_word_data['escaped_string'] =
        \ '\V' . l:regex_prefix . 
        \ escape(b:replace_word_data['string'], '/\') . 
        \ l:regex_suffix

    augroup ReplaceString
      autocmd InsertLeave * call s:replace_word_under_cursor('insert_leave')
    augroup END


  " Insert Leave
  if l:action ==# 'insert_leave'
    autocmd! ReplaceString InsertLeave
    let l:new_string = expand('<cword>')
    if empty(l:new_string) 
      execute 'undo ' . b:replace_word_data['changenr']
    let l:cursor_pos = getpos('.')
    execute 'keeppatterns silent! %substitute/' . 
        \ b:replace_word_data['escaped_string'] . '/' . 
        \ escape(l:new_string, '/\') . '/g'
    call setpos('.', l:cursor_pos)
    echo 'Replace: ' . b:replace_word_data['string'] . ' -> ' . l:new_string
    unlet b:replace_word_data

nnoremap <Leader>rr :call <SID>replace_word_under_cursor()<CR>Code language: Vim Script (vim)

How to make Vim edit/diff files from outside of Vim? (e.g. from a shell like Bash, Zsh, Fish..)


The Vim editor offers the ability to connect to a Vim server and make it perform various tasks from outside of Vim. The command-line tools vim-client-edit, vim-client-diff and the vim_client Python module, written by James Cherti, can be used to easily find and connect to a Vim server and make it perform the following tasks:

  • Edit files or directories in new tabs (The command-line tool vim-client-edit),
  • Diff/Compare up to eight files (The command-line tool vim-client-diff),
  • Evaluate expressions and return their result (The Python module vim_client),
  • Send commands and expressions to Vim (The Python module vim_client).

The command-line tools vim-client-edit and vim-client-diff are especially useful when a quick edit or comparison needs to be performed on a file from outside of Vim (e.g. from a shell like Bash, Zsh, Fish, etc.).

Additionally, the vim_client Python module allows running expressions on a Vim server and retrieving their output, which can be useful for automating tasks or scripting. For example, you can use vim-client to run a search and replace operation on a file or directory, or to perform a complex diff operation between two files.

Overall, vim-client is a powerful tool for interacting with Vim from the vim-client-edit and vim-client-diff command-line tools. The vim_client Python module can also be used to run and retrieve the output of Vim expressions, which can help automate various tasks.

Please star vim-client on GitHub to support the project!


To use vim-client, you will need to have Vim and Python installed on your system.


The vim-client package can be installed with pip:

$ sudo pip install vim-clientCode language: Bash (bash)

Execute Vim server

The Vim editor must be started with the option “–servername”, which enables the Vim server feature that allows clients to connect and send commands to Vim:

$ vim --servername SERVERNAMECode language: plaintext (plaintext)

Make Vim server edit multiple files in tabs

Editing a list of files in new tabs:

$ vim-client-edit file1 file2 file3 

Make Vim server diff files (like vimdiff)

Comparing/diff up to eight files:

$ vim-client-diff file1 file2

Useful ~/.bashrc aliases:

Adding the following aliases to ~/.bashrc is recommended as it makes it easy to execute the command-line tools vim-client-edit and vim-client-diff:

alias gvim=vim-client-edit
alias vim=vim-client-edit
alias vi=vim-client-edit
alias vimdiff=vim-client-diff

Links related to vim-client

Vim: Edit all the files in the current directory of a Git repository in new tabs (git ls-files)

Rate this post
" Language: Vim script
" Description: edit all the Git files in the current
"              directory in new tabs (git ls-files
" License: MIT
" Author: James Cherti
" URL:

function! GitEditFiles() abort
  if &modified
    echoerr 'fatal: No write since last change.'

  let l:list_lines = systemlist('git ls-files')
  if v:shell_error !=# 0
    echomsg 'fatal: Git: ' . join(l:list_lines, "\n")

  let l:list_files = []
  for l:filename in l:list_lines
    if filereadable(l:filename)
      call add(l:list_files, l:filename)

  if len(l:list_files) ==# 0
    echo 'No Git files were found in the directory ' . getcwd()

  if len(l:list_files) > 7
    for l:filename in l:list_lines
      echo l:filename

    echo "\n"
    echo 'Git directory: ' . getcwd()
    echo 'Number of Git files: ' . len(l:list_files)
    echo "\n"
    let l:answer = input('Edit? [y,n]')
    if l:answer !=# 'y'

  let l:first = 1
  for l:file in l:list_files
    if l:first
      let l:first = 0
      execute 'tabnew'

    execute 'edit ' . fnameescape(l:file)

command! -nargs=0 GitEditFiles call GitEditFiles()Code language: Vim Script (vim)

Vim theme: tomorrow-night-deepblue, a refreshing color scheme with a deep blue background


The Vim color scheme jamescherti/vim-tomorrow-night-deepblue is a beautiful deep blue variant of the “Tomorrow Night” colorscheme, which is renowned for its elegant color palette. It is pleasing to the eyes and is easy to read (The colorscheme was previously called tomorrow-night-seablue).

The “Tomorrow Night Deepblue” color scheme features a deep blue background color that creates a calming atmosphere. The contrasting colors make it easy to distinguish between different elements of your code. The tomorrow-night-deepblue colorscheme is also a great choice for programmer who miss the blue themes that were trendy a few years ago.

The Vim theme: Tomorrow Night Deepblue

The theme was inspired by classic DOS text editors such as QuickBASIC, RHIDE, and Turbo Pascal, which featured blue backgrounds by default. There’s something special about the early days of programming and the tools we used that brings back fond memories.

Install the tomorrow-night-deepblue colorscheme with Vim’s built-in package manager (Vim 8 and above)

mkdir -p ~/.vim/pack/jamescherti/start
cd ~/.vim/pack/jamescherti/start
git clone --depth 1
vim -u NONE -c "helptags vim-tomorrow-night-deepblue/doc" -c qCode language: Bash (bash)

Activate the color scheme

:color tomorrow-night-deepblueCode language: Vim Script (vim)


Vim: Open documentation in a new tab for the word under the cursor (Vim help, Python, man pages, Markdown, Ansible…)


The following Vim script (VimL) function can be used to make Vim open the documentation of the word under the cursor in a new tab for various languages and tools such as Vim help (:help), Python (Pydoc), Markdown (sdcv dictionary), man pages (Vim’s built-in ‘:Man’), and Ansible (ansible-doc).

The VimL function is also extensible, meaning that you can adapt it to work with any other documentation tool. By default, the key mapping upper-case “K” can be used to open the documentation for the word under the cursor in a new tab.

" Language: Vim script
" Author: James Cherti
" License: MIT
" Description: Vim: open help/documentation in a new tab 
"              (Vim script, Python, Markdown, man pages, Ansible...).
"              Press upper-case K to open help for the word under the cursor.
" URL:

function! TabHelp(word) abort
  let l:cmd = ''

  let l:tabhelpprg = get(b:, 'tabhelpprg', '')
  if l:tabhelpprg ==# ''
    normal! K

  if l:tabhelpprg[0] ==# ':'
    if stridx(l:tabhelpprg, '%s') ==# -1
      execute l:tabhelpprg
      execute printf(l:tabhelpprg, fnameescape(a:word))
    let l:cmd = 'silent read! '
    if stridx(l:tabhelpprg, '%s') ==# -1
      let l:cmd .= l:tabhelpprg
      let l:cmd .= printf(l:tabhelpprg, shellescape(a:word))

  execute 'silent tabnew help:' . fnameescape(a:word)

  setlocal modifiable
  silent normal! ggdG
  silent normal! 1Gdd
  if l:cmd !=# ''
    execute l:cmd
  silent normal! gg0
  setlocal nomodifiable
  setlocal noswapfile
  setlocal nowrap
  setlocal nonumber
  setlocal nomodified
  setlocal buftype=nofile
  setlocal bufhidden=delete
  if exists('&relativenumber')
    setlocal norelativenumber
  if exists('&signcolumn')
    setlocal signcolumn=no
  setlocal nofoldenable
  setlocal foldcolumn=0

augroup TabHelp
  autocmd FileType vim let b:tabhelpprg = ':tab help %s'
  autocmd FileType sh,zsh,csh if ! exists(':Man') | runtime ftplugin/man.vim | endif | let b:tabhelpprg = ':tab Man %s'
  autocmd FileType yaml.ansible if executable('ansible-doc') | let b:tabhelpprg = 'ansible-doc %s' | endif
  autocmd FileType markdown if executable('sdcv') | let b:tabhelpprg = 'sdcv %s' | endif
  autocmd FileType vim,sh,zsh,csh,yaml.ansible,markdown nnoremap <silent> <buffer> K :call TabHelp(expand('<cword>'))<CR>
augroup ENDCode language: Vim Script (vim)

Vim: Tango color scheme for Vim’s built-in Terminal


The following code snippet will allow you to apply the Tango Dark color scheme to the Vim’s built-in terminal and ensure that the terminal’s color scheme remains consistent, even if you change the Vim color scheme with the ‘:colorscheme’ command.

The snippet uses autocmd to ensures that the Vim terminal’s color scheme remains Tango Dark.

For more information about Vim’s built-in terminal:

  • :help terminal
" Language: Vim script
" Author: James Cherti
" License: MIT
" Description: Improve the color scheme of Vim Terminal (Tango dark theme),
"              and prevent :colorscheme from changing the terminal color scheme.
" URL:

" Gnome-Terminal Tango Dark
let g:terminal_ansi_colors_black = '#2E3436'
let g:terminal_ansi_colors_darkred = '#CC0000'
let g:terminal_ansi_colors_darkgreen = '#4E9A06'
let g:terminal_ansi_colors_brown = '#C4A000'
let g:terminal_ansi_colors_darkblue = '#3465A4'
let g:terminal_ansi_colors_darkmagenta = '#75507B'  " dark purple
let g:terminal_ansi_colors_darkcyan = '#06989A'  " dark turquoise
let g:terminal_ansi_colors_lightgrey = '#D3D7CF'
let g:terminal_ansi_colors_darkgrey = '#555753'
let g:terminal_ansi_colors_red = '#EF2929'
let g:terminal_ansi_colors_green = '#8AE234'
let g:terminal_ansi_colors_yellow = '#FCE94F'
let g:terminal_ansi_colors_blue = '#729FCF'
let g:terminal_ansi_colors_magenta = '#AD7FA8'  " purple
let g:terminal_ansi_colors_cyan = '#34E2E2' " turquoise
let g:terminal_ansi_colors_white = '#EEEEEC'

" Text and background: Gnome dark
let g:terminal_ctermbg = 'black'
let g:terminal_ctermfg = 'white'
let g:terminal_statuslineterm_ctermbg = 'black'
let g:terminal_statuslineterm_ctermfg = 'white'
let g:terminal_statuslinetermnc_ctermbg = 'black'
let g:terminal_statuslinetermnc_ctermfg = 'white'
let g:terminal_guibg = '#000000'
let g:terminal_guifg = '#D0CFCC'
let g:terminal_statuslineterm_guibg = g:terminal_guibg
let g:terminal_statuslineterm_guifg = g:terminal_guifg
let g:terminal_statuslinetermnc_guibg = g:terminal_guibg
let g:terminal_statuslinetermnc_guifg = g:terminal_guifg

function! SetTerminalColorScheme() abort
  if !has('terminal')

  let g:terminal_ansi_colors = [
        \ g:terminal_ansi_colors_black,
        \ g:terminal_ansi_colors_darkred,
        \ g:terminal_ansi_colors_darkgreen,
        \ g:terminal_ansi_colors_brown,
        \ g:terminal_ansi_colors_darkblue,
        \ g:terminal_ansi_colors_darkmagenta,
        \ g:terminal_ansi_colors_darkcyan,
        \ g:terminal_ansi_colors_lightgrey,
        \ g:terminal_ansi_colors_darkgrey,
        \ g:terminal_ansi_colors_red,
        \ g:terminal_ansi_colors_green,
        \ g:terminal_ansi_colors_yellow,
        \ g:terminal_ansi_colors_blue,
        \ g:terminal_ansi_colors_magenta,
        \ g:terminal_ansi_colors_cyan,
        \ g:terminal_ansi_colors_white
        \ ]

  execute printf(
        \ 'highlight Terminal ctermbg=%s ctermfg=%s guibg=%s guifg=%s',
        \ g:terminal_ctermbg, g:terminal_ctermfg, g:terminal_guibg,
        \ g:terminal_guifg
        \ )
  execute printf(
        \ 'highlight StatusLineTerm ctermbg=%s ctermfg=%s guibg=%s guifg=%s',
        \ g:terminal_statuslineterm_ctermbg, g:terminal_statuslineterm_ctermfg,
        \ g:terminal_statuslineterm_guibg, g:terminal_statuslineterm_guifg
        \ )
  execute printf(
        \ 'highlight StatusLineTermNC ctermbg=%s ctermfg=%s guibg=%s guifg=%s',
        \ g:terminal_statuslinetermnc_ctermbg, g:terminal_statuslinetermnc_ctermfg,
        \ g:terminal_statuslinetermnc_guibg, g:terminal_statuslinetermnc_guifg
        \ )

if has('terminal')
  augroup TerminalColorScheme
    autocmd ColorScheme * call SetTerminalColorScheme()
    autocmd VimEnter * call SetTerminalColorScheme()
  augroup END

  call SetTerminalColorScheme()
endifCode language: Vim Script (vim)

Vim: Enhance Vim tabs (file name only, file status, and the ability to rename tabs)

" Language: Vim script
" Author: James Cherti
" License: MIT
" Description: Enhance the tab line. The tabs will show the base name of 
"              the file and its status. Tabs can be renamed with 'TabRename'. 
" URL:

function! MyTabLabel(tabnr) abort
  let l:bufnr = tabpagebuflist(a:tabnr)[tabpagewinnr(a:tabnr) - 1]

  let l:modified = 0
  if getbufvar(l:bufnr, '&modified')
    let l:modified = 1

  let l:tablabel = ''
  let l:custom_tablabel = gettabvar(a:tabnr, 'tablabel', '')
  if empty(l:custom_tablabel)
    let l:bufname = bufname(l:bufnr)
    if empty(l:bufname)
      let l:tablabel = empty(&buftype) ? 'No Name' : '<' . &buftype . '>'
      let l:tablabel = fnamemodify(l:bufname, ':t')
    let l:tablabel .= l:custom_tablabel

  if l:modified
    let l:tablabel .= '*'

  return l:tablabel

function! MyTabLine() abort
  let l:tabline = ''

  for l:num in range(1, tabpagenr('$'))
    let l:tabline .= (l:num != tabpagenr()) ? '%#TabLine#' : '%#TabLineSel#'
    let l:tabline .= '%' . l:num . 'T %{MyTabLabel(' . l:num . ')} '

  let l:tabline .= '%#TabLineFill#%T%='
  let l:tabline .= repeat('%#TabLine#%999X[X]', l:num > 1)

  return l:tabline

function! MyGuiTabLine() abort
  return MyTabLabel(tabpagenr())

function! TabRename(tablabel) abort
  let t:tablabel = a:tablabel
  execute 'redrawtabline'

if exists('+showtabline')
  command! -nargs=1 TabRename call TabRename(<q-args>)
  set tabline=%!MyTabLine()
  set guitablabel=%{MyGuiTabLine()}
endifCode language: Vim Script (vim)

Vim script: Replace the home directory with a tilde ~


The following Vim script (VimL) code snippet can be used to replace the full path of a home directory in a string with a tilde (“~”). This can be useful as a way to shorten the path to a file or directory, making it more readable.

" Language: Vim script
" Author: James Cherti
" License: MIT
" Description: A function that replaces the home directory 
"              with a tilde (e.g. '/home/user/file.txt' will 
"              be replaced with '~/file.txt').
" URL:

function! ReplaceHomeWithTilde(path) abort
  let l:path = fnamemodify(a:path, ':p')
  let l:path_sep = (!exists('+shellslash') || &shellslash) ? '/' : '\'
  let l:home = fnamemodify('~', ':p')

  if l:path[0:len(l:home)-1] ==# l:home
    return '~' . l:path_sep . l:path[len(l:home):]
  elseif l:path == l:home
    return '~' . l:path_sep

  return l:path
endfunctionCode language: Vim Script (vim)

A Vim function that returns all monospaced fonts (UNIX / Linux only)

" Language: Vim script
" Author: James Cherti
" License: MIT
" Description: A function that returns all available monospaced fonts 
"              (Linux and UNIX only).
" URL:

function! FontList() abort
  let l:result = []

  if has('win32') || !has('gui_running') || !executable('fc-list')
    return l:result

  " Search for monospaced fonts (spacing=100)
  let l:fclist_output = systemlist('fc-list :spacing=100')
  let l:style_var = 'style='

  for l:fclist_line in l:fclist_output
    let l:fclist_line_items = split(l:fclist_line, ':')
    let l:font_file = l:fclist_line_items[0]

    let l:list_font_names = split(l:fclist_line_items[1], ',')
    let l:font_name = trim(l:list_font_names[0])

    if len(l:fclist_line_items) <= 2
      if index(l:result, l:font_name) ==# -1
        call add(l:result, l:font_name)

    let l:font_style = l:fclist_line_items[2]
    if l:font_style[0:len(l:style_var)-1] ==# l:style_var
      for l:font_style in split(l:font_style[len(l:style_var):], ',')
        let l:font_name = l:font_name . ' ' . trim(l:font_style)
        if index(l:result, l:font_name) ==# -1
          call add(l:result, l:font_name)

  return l:result
endfunctionCode language: Vim Script (vim)

A Vim plugin for persisting and restoring Vim editing sessions easily and effortlessly


The Vim plugin vim-easysession, written by James Cherti, offers a convenient and effortless way to persist and restore Vim editing sessions. It can significantly increase productivity and save a lot of time for users who frequently switch between different projects and those who frequently open and close the Vim editor.

In addition to its automatic session management capabilities, the Vim plugin Easysession also offers a variety of useful Vim commands that allow users to save, switch, list and delete sessions manually.

Easysession features

  • Save and restore the session “main”, which includes various settings such as the font, background, and color scheme (The &guifont, &background, and the color scheme are also part of the session file that is generated by Easysession)
  • Auto-complete the Vim commands :EasySessionLoad and :EasySessionRemove
  • Specify the directory where the session files are located:
    let g:easysession_dir = expand('~/.my_vim_sessions')
  • Save the session:
  • Switch to a different session:
    :EasySessionLoad SESSION_NAME
  • List the available sessions:
  • Delete a session with:
    :EasySessionRemove SESSION_NAME

Please star vim-easysession on GitHub to support the project!


The Vim plugin Easysession can be installed with Vim’s built-in package manager (Vim 8 and higher):

mkdir -p ~/.vim/pack/jamescherti/start
cd ~/.vim/pack/jamescherti/start
git clone --depth 1
vim -u NONE -c "helptags vim-easysession/doc" -c qCode language: JavaScript (javascript)

The plugin can also be installed with any third-party plugin manager such as Pathogen or Vundle.


The Vim plugin Easysession provides an easy and effortless way to persist and restore Vim editing sessions. Its automatic session management capabilities, manual commands, auto-complete feature, and its ability to specify the directory for saves session are all valuable features that make it easy to manage Vim editing sessions.

If you are looking for a way to manage and organize your Vim session more efficiently, the Easysession Vim plugin is an excellent option to consider.

Master the HJKL navigation with the Vim plugin Hjklmode, which can help breaking the habit of moving the right hand away from the home row


Vim’s popularity is largely due to its ability to increase productivity through efficient navigation and editing techniques. One such technique is HJKL navigation, which allows using the H, J, K, and L keys to move the cursor left, down, up, and right. This method of navigation may seem strange at first, but it is actually a very efficient way to navigate through text and can greatly increase productivity when using Vim.

In addition to that, the HJKL navigation can help reduce wrist strain, as it allows moving the cursor without having to reach for the arrow keys, which are located in a position that can cause wrist to bend and flex in an unnatural position.

However, HJKL navigation can be hard to learn at first, because it requires using unfamiliar key combinations to move the cursor. One way of making it easier to learn HJKL navigation is by using the Vim plugin Hjklmode, written by James Cherti. You can use the Vim plugin to force yourself to rely on HJKL navigation to move around the text.

If you are interested in trying the Hjklmode Vim plugin, you can download it from its Git repository:

Hjklmode Vim plugin features

One of the key features of the Vim plugin Hjklmode is its ability to disable certain keys that require moving the hand away from the Touch Typing position, which can disrupt typing flow. These keys include: Backspace, Insert, Delete, Home, End, Page Up and Page Down, Arrows.

In addition to disabling certain keys, the Vim plugin Hjklmode also adds key mappings for Alt+h, Alt+j, Alt+k, Alt+l to Insert Mode, Command Mode, and Terminal Mode, which allow moving the cursor even in those modes.

Overall, the Hjklmode Vim plugin is a great tool for those looking to learn the HJKL navigation to increase their efficiency and productivity. Whether you are a beginner or an experienced Vim user, the Hjklmode Vim plugin can help you break the habit of moving your hand away from the home row/Touch Typing position.

Do you like the Vim plugin Hjklmode? Please add a star to vim-hjklmode on GitHub.

Install the Vim plugin Hjklmode with Vim’s Built-in package manager (Vim 8 and above)

mkdir -p ~/.vim/pack/jamescherti/start
cd ~/.vim/pack/jamescherti/start
git clone --depth 1
vim -u NONE -c "helptags vim-hjklmode/doc" -c qCode language: JavaScript (javascript)

(The plugin can also be installed with any third-party plugin manager such as Pathogen or Vundle)

What are the alternatives to pressing the Escape, Backspace, and Arrow keys?

Built-in Vim Key MappingEquivalent to
Ctrl-fPage down
Ctrl-bPage up
0 (zero)Home

For more information:

  • :help motion.txt
  • :help search-commands