Skip to content

Instantly share code, notes, and snippets.

@raikhan
Created January 8, 2026 12:28
Show Gist options
  • Select an option

  • Save raikhan/30018ddf6ac5480de247e5e8cfbf2928 to your computer and use it in GitHub Desktop.

Select an option

Save raikhan/30018ddf6ac5480de247e5e8cfbf2928 to your computer and use it in GitHub Desktop.
Doom Emacs-like helix config with lots of external tools
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