#12986·fish-shell

Allow customizing directory shortcut letters in cdh (e.g. fish_cdh_alphabet)

Author: XadeckCreated Sep 8, 2026Updated Sep 16, 2026

Description

Currently, cdh provides a menu of recently visited directories and assigns shortcut letters sequentially from a hardcoded list:

fish
set -l letters a b c d e f g h i j k l m n o p q r s t u v w x y z

This maps the most recent directory (item 1) to a, the second newest to b, the third to c, and so on.

It would be very convenient to allow users to customize this shortcut sequence via a configuration variable (for example, $fish_cdh_alphabet or $fish_cdh_letters).

Motivation & Use Cases

  1. Ergonomics & Home Row / Vi Keybindings: For users who rely heavily on home-row navigation (such as those using fish_vi_key_bindings or modal editors like Vim/Neovim), reaching for a, b, c, etc. requires moving across different rows for the most frequently selected items. Prioritizing home-row keys (such as h j k l, j k l ;, or a s d f j k l ;) makes jumping to the most recent directories faster and more natural.

  2. Precedent in Modern Terminal and CLI Tooling: This pattern is widely used in terminal tools. For instance, Kitty's hints kitten supports a custom --alphabet flag:

    conf
    map kitty_mod+p kitten hints --type path --alphabet asdfjkl;qweruiopzxcvbnm --program -

    Similar home-row hint mechanics exist in browser extensions (Vimium, Tridactyl), tmux plugins (tmux-thumbs), and modal jump plugins (Leap, Flash). Bringing customizable shortcut keys to cdh provides a consistent and ergonomic experience.

  3. Alternative Keyboard Layouts: Users of Dvorak, Colemak, or ergonomic split keyboards can tailor the shortcut keys to their physical layout for optimal comfort.

Proposed Behavior

  • Introduce an optional variable, e.g., $fish_cdh_alphabet.
  • If unset, it defaults to the existing a b c d e f g h i j k l m n o p q r s t u v w x y z (100% backward-compatible).
  • If set (either as a list set -g fish_cdh_alphabet h j k l a s d f ... or as a string 'hjklasdf...'), cdh uses those characters in order.
  • If the configured alphabet has fewer characters than the current directory history, cdh can cap the displayed entries to (count $letters) rather than erroring out, gracefully showing the top N most recent directories.

Potential Implementation

In share/functions/cdh.fish:

diff
@@ -23,12 +23,20 @@ function cdh --description "Menu based cd command"
     end

     set -l letters a b c d e f g h i j k l m n o p q r s t u v w x y z
+    if set -q fish_cdh_alphabet[1]
+        if test (count $fish_cdh_alphabet) -eq 1 -a (string length -- $fish_cdh_alphabet) -gt 1
+            set letters (string split '' -- $fish_cdh_alphabet)
+        else
+            set letters $fish_cdh_alphabet
+        end
+    end
+
     set -l dirc (count $uniq_dirs)
     if test $dirc -gt (count $letters)
-        set -l msg (_ 'This should not happen. Have you changed the cd function?')
-        printf "$msg\n" >&2
-        set -l msg (_ 'There are %s unique dirs in your history but I can only handle %s')
-        printf "$msg\n" $dirc (count $letters) >&2
-        return 1
+        set dirc (count $letters)
     end

     # Print the recent directories, oldest to newest. Since we previously
@@ -58,9 +66,8 @@ function cdh --description "Menu based cd command"
     read -l -p "echo '$msg'" choice
     if test -z "$choice"
         return 0
-    else if string match -q -r '^[a-z]$' $choice
-        # Convert the letter to an index number.
-        set choice (contains -i $choice $letters)
+    else if set -l idx (contains -i -- $choice $letters)
+        set choice $idx
     end

     set -l msg (_ 'Error: expected a number between 1 and %d or letter in that range, got "%s"')