Created
January 8, 2026 12:28
-
-
Save raikhan/30018ddf6ac5480de247e5e8cfbf2928 to your computer and use it in GitHub Desktop.
Doom Emacs-like helix config with lots of external tools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| theme = "modus_vivendi_tinted" | |
| [editor] | |
| line-number = "relative" | |
| soft-wrap.enable = false | |
| true-color = true | |
| jump-label-alphabet = "jfkdls;aurieowpqnvmcxz" # changes the goto-word letters to focus on the main row | |
| shell = ["nu", "--stdin","--env-config", "~/.config/nushell/config.nu", "-c"] | |
| clipboard-provider = "pasteboard" | |
| end-of-line-diagnostics = "hint" | |
| [editor.file-picker] | |
| hidden = false | |
| [editor.statusline] | |
| separator = "│" | |
| mode.normal = "NORMAL" | |
| mode.insert = "INSERT" | |
| mode.select = "SELECT" | |
| center = ["version-control"] | |
| [editor.cursor-shape] | |
| normal = "block" | |
| insert= "bar" | |
| select = "underline" | |
| [editor.inline-diagnostics] | |
| cursor-line = "warning" | |
| [keys.normal] | |
| esc = ["collapse_selection", "keep_primary_selection"] | |
| X = "select_line_above" | |
| ret = "goto_word" | |
| "C-l" = ":reload-all" | |
| "C-j" = "insert_newline" | |
| "{" = "goto_prev_paragraph" | |
| "}" = "goto_next_paragraph" | |
| "C-n" = "extend_search_next" | |
| "C-A-n" = "extend_search_prev" | |
| # Standard vim commands, to practive muscle memory | |
| "G" = "goto_file_end" | |
| 0 = "goto_line_start" | |
| "$" = "goto_line_end" | |
| "^" = "goto_first_nonwhitespace" | |
| # Move selection up and down like in Emacs | |
| "C-A-j" = ["delete_selection", "move_visual_line_down", "paste_before"] | |
| "C-A-k" = ["delete_selection", "move_visual_line_up", "paste_before"] | |
| # Write to kill ring JSONL file on yank/delete | |
| "y" = ["yank", ":pipe-to python ~/.config/save_to_kill_ring.py"] | |
| "d" = [":pipe-to python ~/.config/save_to_kill_ring.py", "delete_selection"] | |
| "c" = [":pipe-to python ~/.config/save_to_kill_ring.py", "change_selection"] | |
| # Insert from kill ring with fzf | |
| "Y" = ':insert-output try {open $"($env.HOME)/.config/helix_kill_ring.jsonl" | from json -o | where tmux_session == $"(tmux_session)" | get text | reduce {|it, acc| $acc + (char nul) + $it} | fzf --tac --gap --highlight-line --read0 --tmux 80%%} catch {null}' | |
| # This is Ctrl-/ actually - see: https://github.com/helix-editor/helix/issues/3210 | |
| # Trigger my helix swiper | |
| "C-7" = ':pipe-to ~/.config/swiper/swiper -file %{buffer_name} -line %{cursor_line} -selection-stdin' | |
| "A-/" = "@/(?-i)" # case sensitive search | |
| # Send selected text to different process tmux panes | |
| [keys.normal.C-p] | |
| n = ":sh send_text_to_process nu '%{selection}'" | |
| p = ":sh send_text_to_process ipython '%{selection}'" | |
| c = ":sh send_text_to_process -s claude '%{selection}'" | |
| x = ":sh send_text_to_process opencode '%{selection}'" | |
| r = ":sh send_text_to_process crush '%{selection}'" | |
| # Send the selection to OpenAI with different system prompts | |
| [keys.normal.C-e] | |
| "g" = [":pipe-to send_selection_to_ask_openai learn_go"] | |
| # Snippets of text to speed up use of Aider | |
| [keys.normal.C-y] | |
| "i" = ["goto_line_end", "move_char_right",":insert-output ~/.config/helix/snippets.sh pyright_ignore"] | |
| "e" = [":insert-output cat ~/.config/helix/emojis.txt | fzf --header 'Select emoji' | cut -d ' ' -f2", ":redraw"] | |
| ## Send the selection to new buffer with Claude task template | |
| "t" = ["yank", | |
| ":new", | |
| ":insert-output cat ~/.config/claude/helix_template.md", | |
| "paste_after", | |
| "collapse_selection", | |
| "insert_newline", | |
| "goto_file_start" | |
| ] | |
| [keys.insert.C-y] | |
| "i" = ["goto_line_end", "move_char_right",":insert-output ~/.config/helix/snippets.sh pyright_ignore"] | |
| "e" = [":insert-output cat ~/.config/helix/emojis.txt | fzf --header 'Select emoji' | cut -d ' ' -f2", ":redraw"] | |
| # Making the some keybindings closer to Doom Emacs | |
| [keys.normal.space.g] | |
| # lazygit | |
| g = [":write-all", ":insert-output lazygit", ":redraw", ":reload-all"] | |
| # lazydocker | |
| o = [":write-all", ":insert-output lazydocker", ":redraw", ":reload-all"] | |
| # fend calculator in a bottom tmux popup | |
| c = [":sh tmux split-window -p 30 fend"] | |
| # Open a terminal in a bottom tmux popup | |
| t = [":sh tmux split-window -p 30 nu"] | |
| [keys.normal.space] | |
| "." = "file_picker" | |
| "," = "buffer_picker" | |
| [keys.normal.space.f] | |
| b = "file_picker_in_current_buffer_directory" # Open file picker relative to current file | |
| f = "file_picker" | |
| g = "changed_file_picker" | |
| s = ":write" | |
| S = ":write!" | |
| a = ":write-all" | |
| d = [":sh tmux split-window -p 100 'source ~/.config/yazi/sidebar/yazi_cmd.nu'"] | |
| l = [":sh tmux split-window -p 100 'BROOT_CONFIG_DIR=~/.config/broot/broot_in_helix broot'"] | |
| c = [":sh tmux split-window -p 100 '~/.config/helix/change_working_dir.sh'"] # change working dir using fzf/zoxide | |
| w = [":cd %sh{dirname %{buffer_name}}"] # change the working dir to the location of current buffer | |
| r = ":sh tmux split-window -p 100 'scooter'" # Open scooter for find-and-replace | |
| [keys.normal.space.b] | |
| b = "buffer_picker" | |
| n = ":new" | |
| k = ":buffer-close" | |
| x = ":buffer-close!" | |
| o = ":buffer-close-others" | |
| a = ":buffer-close-all" | |
| [keys.normal.space.q] | |
| q = ":quit-all" | |
| a = ":write-quit-all" | |
| x = ":quit-all!" | |
| # Backspace command groups | |
| [keys.normal.backspace] | |
| g = ":reset-diff-change" # deletes git change below cursor | |
| t = ":sh pytest -q" # Run 'pytest' to get all test results | |
| w = ["trim_selections", ":pipe str replace -ra ' +' ' '"] # Replace multiple spaces with single space in selection | |
| m = ":sh git mergetool --no-prompt --tool=p4merge" # start the git mergetool | |
| d = [":sh rm %{buffer_name}",":buffer-close"] # Delete currently opened file and close its buffer | |
| # Helix config access | |
| [keys.normal.backspace.c] | |
| c = ":config-open" # open the config file | |
| r = ":config-reload" # reload the config | |
| # LSP commands | |
| [keys.normal.backspace.l] | |
| c = ":lsp-workspace-command" # Show LSP commands | |
| r = ":lsp-restart" # restart server | |
| s = ":lsp-stop" # stop server | |
| # commands for my custom kill ring | |
| [keys.normal.backspace.k] | |
| o = ":open ~/.config/helix_kill_ring.jsonl" # Open kill ring file | |
| d = ":sh try {let fname = $'($env.HOME)/.config/helix_kill_ring.jsonl'; open $fname | lines | uniq | save -f $fname} catch { echo 'No kill ring file'}" # Remove duplicates from kill ring | |
| k = ":sh try {rm ~/.config/helix_kill_ring.jsonl} catch {echo 'No kill ring file'}" # Clear kill ring | |
| a = ':insert-output try {open $"($env.HOME)/.config/helix_kill_ring.jsonl" | from json -o | get text | reduce {|it, acc| $acc + (char nul) + $it} | fzf --tac --gap --highlight-line --read0 --tmux 80%%} catch {null}' # Show all items in the kill ring regardless of the TMUX session | |
| # Set Helix options | |
| [keys.normal.backspace.o] | |
| w = ":set-option soft-wrap.enable true" # enable soft wrap | |
| W = ":set-option soft-wrap.enable false" # disable soft wrap | |
| # Keybinds to set the language | |
| [keys.normal.backspace.o.l] | |
| g = ":set-language go" | |
| m = ":set-language markdown" | |
| p = ":set-language python" | |
| j = ":set-language json" | |
| t = ":set-language toml" | |
| [keys.select] | |
| "{" = "goto_prev_paragraph" | |
| "}" = "goto_next_paragraph" | |
| # Go to swiper from select mode, but drop to normal first so the selection doesn't extend | |
| "C-7" = ['normal_mode',':pipe-to ~/.config/swiper/swiper -file %{buffer_name} -line %{cursor_line} -selection-stdin'] | |
| [keys.insert] | |
| # Added some Emacs movement to the INSERT mode (instead of cursors, makes sense) | |
| "C-p" = "move_line_up" | |
| "C-n" = "move_line_down" | |
| "C-f" = "move_char_right" | |
| "C-g" = "move_char_left" | |
| "C-a" = "goto_line_start" | |
| "C-e" = "goto_line_end_newline" | |
| "A-f" = "move_next_word_start" | |
| "A-b" = "move_prev_word_start" | |
| # TESTING: exit insert mode by pressing j twice | |
| j = { j = "normal_mode" } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment