From 2682af3b05fe67fb31a711fd62cf1ae6ef42054b Mon Sep 17 00:00:00 2001 From: Daniel Lundin Date: Sun, 31 Mar 2024 20:12:05 +0200 Subject: [PATCH] give helix a proper whirl as a daily driver --- .config/helix/config.toml | 25 ++++ .config/helix/languages.toml | 30 +++++ .config/helix/themes/sumi-e.toml | 194 +++++++++++++++++++++++++++++++ .tmux.conf | 2 +- bin/tmux-edit-helper | 45 +------ bin/tmux-hx-helper | 21 ++++ bin/tmux-nvim-helper | 44 +++++++ 7 files changed, 316 insertions(+), 45 deletions(-) create mode 100644 .config/helix/config.toml create mode 100644 .config/helix/languages.toml create mode 100644 .config/helix/themes/sumi-e.toml mode change 100755 => 120000 bin/tmux-edit-helper create mode 100755 bin/tmux-hx-helper create mode 100755 bin/tmux-nvim-helper diff --git a/.config/helix/config.toml b/.config/helix/config.toml new file mode 100644 index 0000000..8af7ba4 --- /dev/null +++ b/.config/helix/config.toml @@ -0,0 +1,25 @@ +theme = "sumi-e" + +[editor] +true-color = true +undercurl = true +cursorline = true +color-modes = true +auto-pairs = false + +[editor.cursor-shape] +insert = "bar" +normal = "block" +select = "underline" + +[editor.indent-guides] +character = "│" # "╎" +render = true + +[editor.lsp] +display-inlay-hints = true + +[keys.normal] +H = ":toggle lsp.display-inlay-hints" +Z = { Z = ":write-quit-all" } +"esc" = ["keep_primary_selection", "collapse_selection"] diff --git a/.config/helix/languages.toml b/.config/helix/languages.toml new file mode 100644 index 0000000..bcbd0e7 --- /dev/null +++ b/.config/helix/languages.toml @@ -0,0 +1,30 @@ +[[language]] +name = "rust" +auto-format = true +roots = [ + "Cargo.toml", + "Cargo.lock" +] + +[language.auto-pairs] +'(' = ')' +'{' = '}' +'[' = ']' +'"' = '"' +'`' = '`' + +[language-server.rust-analyzer] +command = "rust-analyzer" + +[language-server.rust-analyzer.config.inlayHints] +bindingModeHints.enable = false +chainingHints.enable = false +# closingBraceHints.enable = false +closingBraceHints.minLines = 10 +closureReturnTypeHints.enable = "with_block" +# discriminantHints.enable = "fieldless" +discriminantHints.enable = "always" +lifetimeElisionHints.enable = "skip_trivial" +parameterHints.enable = true +typeHints.enable = true +typeHints.hideClosureInitialization = false diff --git a/.config/helix/themes/sumi-e.toml b/.config/helix/themes/sumi-e.toml new file mode 100644 index 0000000..b643f8b --- /dev/null +++ b/.config/helix/themes/sumi-e.toml @@ -0,0 +1,194 @@ +# Template document for helix color schemes +# See also: https://docs.helix-editor.com/themes.html +# +# NOTE: Keys default to the most specific parent value. +# e.g ui.cursor.primary > ui.cursor > ui + +# GENERAL ============================== + +warning = { fg = "#ff7700" } # Editor warnings. +error = { fg = "#ff0038" } # Editor errors, like mis-typing a command. +info = { fg = "#00d992" } # Contextual info in diagnostic messages (LSP). +hint = { } # Code diagnostics hints (LSP). +diagnostic = { fg = "#c49848"} # Code diagnostics in editing area (LSP). +"diagnostic.hint" = { underline = { color = "silver", style = "curl" } } +"diagnostic.info" = { underline = { color = "delta", style = "curl" } } +"diagnostic.warning" = { underline = { color = "lightning", style = "curl" } } +"diagnostic.error" = { underline = { color = "apricot", style = "curl" } } +"diagnostic.unnecessary" = { modifiers = ["dim"] } +"diagnostic.deprecated" = { modifiers = ["crossed_out"] } + + +# UI ============================== +# For styling helix itself. + +'ui.background' = { bg="background" } # Default background color. +'ui.background.separator' = { fg="#00a171" } +'ui.window' = { bg="#224466" } # Window border between splits. +'ui.gutter' = { } # Left gutter for diagnostics and breakpoints. + +'ui.text' = { fg = "#e3e0cd" } # Default text color. +'ui.text.focus' = { bg = "#294467" } # Selection highlight in buffer-picker or file-picker. +'ui.text.info' = { } # Info popup contents (space mode menu). + +'ui.cursor' = { bg = "#00a171", fg = "#000000" } # Fallback cursor colour, non-primary cursors when there are multiple (shift-c). +'ui.cursor.primary' = { bg ="#23fdb6", fg = "#000000" } # The primary cursor when there are multiple (shift-c). +'ui.cursor.insert' = { fg = "#ff0000" } # The cursor in insert mode (i). +'ui.cursor.select' = { } # The cursor in select mode (v). +'ui.cursor.match' = { } # The matching parentheses of that under the cursor. +'ui.cursorline.primary' = { bg = "#141b23" } + +'ui.selection' = { bg = "#294467" } # All currently selected text. +'ui.selection.primary' = { bg = "#294467" } # The primary selection when there are multiple. + +'ui.linenr' = { fg = "#374351" } # Line numbers. +'ui.linenr.selected' = { fg = "#617d9d", bg = "#14202e" } # Current line number. + +'ui.virtual' = { } # Namespace for additions to the editing area. +"ui.virtual.indent-guide" = { fg = "#273341" } +"ui.virtual.inlay-hint" = { fg = "#51a0cf", modifiers = ["italic"] } +'ui.virtual.ruler' = { } # Vertical rulers (colored columns in editing area). +'ui.virtual.whitespace' = { } # Whitespace markers in editing area. + +'ui.statusline' = { bg = "#151920", fg = "#4d5a6c" } # Status line. +'ui.statusline.inactive' = { } # Status line in unfocused windows. +"ui.statusline.normal" = { } # Statusline mode during normal mode (only if editor.color-modes is enabled) +"ui.statusline.insert" = { fg = "#b99912" } # Statusline mode during insert mode (only if editor.color-modes is enabled) +"ui.statusline.select" = { } # Statusline mode during select mode (only if editor.color-modes is enabled) + +'ui.help' = { } # `:command` descriptions above the command line. + +'ui.highlight' = { } # selected contents of symbol pickers (spc-s, spc-S) and current line in buffer picker (spc-b). +"ui.highlight.frameline" = { } + +'ui.menu' = { bg = "#242d38", fg="#bfd5e2" } # Autocomplete menu. +'ui.menu.selected' = { bg = "#135d7e" } # Selected autocomplete item. + +'ui.popup' = { bg = "#253d6b", fg="#b2c6e9" } # Documentation popups (space-k). +'ui.popup.info' = { } # Info popups box (space mode menu). + + +# SYNTAX HIGHLIGHTING ============================== +# All the keys here are Treesitter scopes. + +'property' = { } # Regex group names. +'special' = { fg="#ffecd3" } # Special symbols e.g `?` in Rust, `...` in Hare. +'attribute' = { } # Class attributes, html tag attributes. + +'type' = { } # Variable type, like integer or string, including program defined classes, structs etc.. +'type.builtin' = { } # Primitive types of the language (string, int, float). +'type.enum.variant' = { } # A variant of an enum. + +'constructor' = { } # Constructor method for a class or struct. + +'constant' = { } # Constant value +'constant.builtin' = { } # Special constants like `true`, `false`, `none`, etc. +'constant.builtin.boolean' = { } # True or False. +'constant.character' = { } # Constant of character type. +'constant.character.escape' = { } # escape codes like \n. +'constant.numeric' = { } # constant integer or float value. +'constant.numeric.integer' = { } # constant integer value. +'constant.numeric.float' = { } # constant float value. + +'string' = { fg="#88ab8a", modifiers=["italic"] } # String literal. +'string.regexp' = { } # Regular expression literal. +'string.special' = { } # Strings containing a path, URL, etc. +'string.special.path' = { } # String containing a file path. +'string.special.url' = { } # String containing a web URL. +'string.special.symbol' = { } # Erlang/Elixir atoms, Ruby symbols, Clojure keywords. + +'comment' = { fg = "#e57373", modifiers = ["bold", "italic"] } # This is a comment. +'comment.line' = { } # Line comments, like this. +'comment.block' = { } # Block comments, like /* this */ in some languages. +'comment.block.documentation' = { } # Doc comments, e.g '///' in rust. + +'variable' = { fg="#eceff1" } # Variable names. +'variable.builtin' = { } # Language reserved variables: `this`, `self`, `super`, etc. +'variable.parameter' = { } # Function parameters. +'variable.other.member' = { } # Fields of composite data types (e.g. structs, unions). + +'label' = { } # Loop labels, among other things. + +'punctuation' = { } # Any punctuation symbol. +'punctuation.delimiter' = { fg = "#999999" } # Commas, colons or other delimiter depending on the language. +'punctuation.bracket' = { } # Parentheses, angle brackets, etc. + +'keyword' = { } # Language reserved keywords. +'keyword.control' = { } # Control keywords. +'keyword.control.conditional' = { } # `if`, `else`, `elif`. +'keyword.control.repeat' = { } # `for`, `while`, `loop`. +'keyword.control.import' = { } # `import`, `export` `use`. +'keyword.control.return' = { } # `return` in most languages. +'keyword.control.exception' = { } # `try`, `catch`, `raise`/`throw` and related. +'keyword.operator' = { } # `or`, `and`, `in`. +'keyword.directive' = { } # Preprocessor directives (#if in C...). +'keyword.function' = { } # The keyword to define a function: 'def', 'fun', 'fn'. + +'operator' = { } # Logical, mathematical, and other operators. + +'function' = { fg = "#f7f7f7" } #, modifiers = [ "bold" ] } +'function.builtin' = { } +'function.method' = { } # Cla"ss / Struct methods. +'function.macro' = { } +'function.special' = { } # Preprocessor function in C. + +'tag' = { } # As in for html, css tags. +'tag.error' = { } # Erroneous closing html tags. + +'namespace' = { } # Namespace or module identifier. + + +# Markup ============================== +# Colors for markup languages, like Markdown or XML. + +'markup.heading.1' = { } # Markdown heading 1 color. +'markup.heading.2' = { } # Markdown heading 2 color. +'markup.heading.3' = { } # Markdown heading 3 color. +'markup.heading.4' = { } # Markdown heading 4 color. +'markup.heading.5' = { } # Markdown heading 5 color. +'markup.heading.6' = { } # Markdown heading 6 color. +'markup.heading.marker' = { } # Hashtag color on Markdown headings. + +'markup.list' = { } +'markup.list.numbered' = { } # Numbered list. +'markup.list.unnumbered' = { } # Bullet point list. + +'markup.bold' = { } # Bold text. +'markup.italic' = { } # Italicised text. + +'markup.link' = { } +'markup.link.url' = { } # Urls pointed to by links. +'markup.link.label' = { } # Non-URL link references. +'markup.link.text' = { } # URL and image descriptions in links. + +'markup.quote' = { } # `> Quotes` in Markdown. + + +# Markup - Interface ============================== +# "These scopes are used for theming the editor interface." + +'markup.normal' = { } +'markup.normal.completion' = { } # For completion doc popup ui. +'markup.normal.raw' = { } # For hover popup ui. + +'markup.heading.completion' = { } # Headings for completion doc popup ui. +'markup.heading.raw' = { } # Headings for hover popup ui. + +'markup.raw' = { } # Code block in Markdown. +'markup.raw.block' = { } # Multiline (```) codeblock in Markdown. +'markup.raw.inline' = { } # `Inline code block` in Markdown. +'markup.raw.inline.completion' = { } # ? +'markup.raw.inline.hover' = { } # ? + +# Diff ============================== +# Version control changes. + +'diff.plus' = { fg = "#469e58" } # Additions. +'diff.minus' = { fg = "#ff0038" } # Deletions. +'diff.delta' = { fg = "#3caba4" } # Modifications. +'diff.delta.moved' = { } # Renamed or moved files. + + +[palette] # Define your custom colors here. +white = '#ffffff' + diff --git a/.tmux.conf b/.tmux.conf index d2d0757..61cb9e5 100644 --- a/.tmux.conf +++ b/.tmux.conf @@ -39,7 +39,7 @@ bind -n M-k copy-mode \; send-keys -X previous-prompt -o \; send-keys -X cursor- bind -n M-j copy-mode \; send-keys -X previous-prompt -o \; send-keys -X cursor-up bind -n M-Up select-pane -U bind -n M-Down select-pane -D -bind -n M-1 select-window -t nvim +bind -n M-1 select-window -t 42 bind -n M-2 select-window -t 2 bind -n M-3 select-window -t 3 bind -n M-4 select-window -t 4 diff --git a/bin/tmux-edit-helper b/bin/tmux-edit-helper deleted file mode 100755 index c912ee7..0000000 --- a/bin/tmux-edit-helper +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -set -fe -o pipefail - -eval "$(direnv export bash 2>/dev/null)" - -PATH="$HOME/bin:$PATH" - -if [ -n "$1" ]; then - _file=$(readlink -f "$@") -else - FZF=${FZF:-"fzf-tmux -p 90%,50% -y 0"} - _root=$(git rev-parse --show-toplevel 2>/dev/null || jj workspace root 2>/dev/null || pwd) - _store=$(echo "$_root" | sha1sum | cut -d ' ' -f 1) - _file=$( ( (fre --store_name "$_store" --sorted | xargs -n 100 ls -d 2>/dev/null || true) && fd --type f --hidden --follow --exclude .git --exclude .jj --ignore-file "${_root}/.gitignore" . "$_root") | cat -n | sort -k2 -k1n | uniq -f1 | sort -nk1,1 | cut -f2- | sed -e "s#^${_root}/##" | $FZF --no-sort) - _file="${_root}/${_file}" - fre --store_name "$_store" --add "$_file" -fi - -_nvim_socket="$XDG_RUNTIME_DIR/nvim-persistent.sock" - -(tmux select-window -t nvim 2>/dev/null && tmux select-pane -t 0) && exec nvim --server "$_nvim_socket" --remote "$_file" - -# nvim is not running/listening on remote socket, so start it. -tmux new-window -S -n nvim \ - -e "AR=$AR" \ - -e "AS=$AS" \ - -e "BUILD_COMMAND=$BUILD_COMMAND" \ - -e "CC=$CC" \ - -e "CXX=$CXX" \ - -e "GOFLAGS=$GOFLAGS" \ - -e "GOPACKAGESDRIVER=$GOPACKAGESDRIVER" \ - -e "LC_ALL=$LC_ALL" \ - -e "LD=$LD" \ - -e "NM=$NM" \ - -e "NM=$NM" \ - -e "OBJCOPY=$OBJCOPY" \ - -e "OBJDUMP=$OBJDUMP" \ - -e "PATH=$PATH" \ - -e "RANLIB=$RANLIB" \ - -e "READELF=$READELF" \ - -e "RUST_SRC_PATH=$RUST_SRC_PATH" \ - -e "SIZE=$SIZE" \ - -e "STRIP=$STRIP" \ - nvim --listen "$_nvim_socket" "$_file" diff --git a/bin/tmux-edit-helper b/bin/tmux-edit-helper new file mode 120000 index 0000000..90b21a9 --- /dev/null +++ b/bin/tmux-edit-helper @@ -0,0 +1 @@ +tmux-hx-helper \ No newline at end of file diff --git a/bin/tmux-hx-helper b/bin/tmux-hx-helper new file mode 100755 index 0000000..a292eb3 --- /dev/null +++ b/bin/tmux-hx-helper @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -exo pipefail + +eval "$(direnv export bash 2>/dev/null)" + +PATH="$HOME/bin:$PATH" + +if [ -n "$1" ]; then + _file=$(readlink -f "$@") +else + FZF=${FZF:-"fzf-tmux -p 90%,50% -y 0"} + _root=$(git rev-parse --show-toplevel 2>/dev/null || pwd) + _store=$(echo "$_root" | sha1sum | cut -d ' ' -f 1) + _file=$( ( (fre --store_name "$_store" --sorted | xargs -n 100 ls -d 2>/dev/null || true) && fd --type f --hidden --follow --exclude .git --ignore-file "${_root}/.gitignore" . "$_root") | cat -n | sort -k2 -k1n | uniq -f1 | sort -nk1,1 | cut -f2- | sed -e "s#^${_root}/##" | $FZF --no-sort) + _file="${_root}/${_file}" + fre --store_name "$_store" --add "$_file" +fi + +(tmux select-window -t helix && +tmux send-keys -t helix Escape && +tmux send-keys -t helix ":open ${_file}" Enter) || tmux new-window -t 42 -n helix helix "${_file}" diff --git a/bin/tmux-nvim-helper b/bin/tmux-nvim-helper new file mode 100755 index 0000000..3c89522 --- /dev/null +++ b/bin/tmux-nvim-helper @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +set -fe -o pipefail + +eval "$(direnv export bash 2>/dev/null)" + +PATH="$HOME/bin:$PATH" + +if [ -n "$1" ]; then + _file=$(readlink -f "$@") +else + FZF=${FZF:-"fzf-tmux -p 90%,50% -y 0"} + _root=$(git rev-parse --show-toplevel 2>/dev/null || jj workspace root 2>/dev/null || pwd) + _store=$(echo "$_root" | sha1sum | cut -d ' ' -f 1) + _file=$( ( (fre --store_name "$_store" --sorted | xargs -n 100 ls -d 2>/dev/null || true) && fd --type f --hidden --follow --exclude .git --exclude .jj --ignore-file "${_root}/.gitignore" . "$_root") | cat -n | sort -k2 -k1n | uniq -f1 | sort -nk1,1 | cut -f2- | sed -e "s#^${_root}/##" | $FZF --no-sort) + _file="${_root}/${_file}" + fre --store_name "$_store" --add "$_file" +fi + +_nvim_socket="$XDG_RUNTIME_DIR/nvim-persistent.sock" + +(tmux select-window -t nvim 2>/dev/null && tmux select-pane -t 0) && exec nvim --server "$_nvim_socket" --remote "$_file" + +# nvim is not running/listening on remote socket, so start it. +tmux new-window -S -t 1001-n nvim \ + -e "AR=$AR" \ + -e "AS=$AS" \ + -e "BUILD_COMMAND=$BUILD_COMMAND" \ + -e "CC=$CC" \ + -e "CXX=$CXX" \ + -e "GOFLAGS=$GOFLAGS" \ + -e "GOPACKAGESDRIVER=$GOPACKAGESDRIVER" \ + -e "LC_ALL=$LC_ALL" \ + -e "LD=$LD" \ + -e "NM=$NM" \ + -e "NM=$NM" \ + -e "OBJCOPY=$OBJCOPY" \ + -e "OBJDUMP=$OBJDUMP" \ + -e "PATH=$PATH" \ + -e "RANLIB=$RANLIB" \ + -e "READELF=$READELF" \ + -e "RUST_SRC_PATH=$RUST_SRC_PATH" \ + -e "SIZE=$SIZE" \ + -e "STRIP=$STRIP" \ + nvim --listen "$_nvim_socket" "$_file"