Files
NixOsConfig/modules/user/helix.nix
T

193 lines
5.5 KiB
Nix

{ inputs, pkgs, lib, config, ... }: let
# glibc >= 2.44 defines bsearch() as a C23 const-generic macro, which clashes
# with the copy vendored by some tree-sitter grammars (tree-sitter-perl).
# Drop the vendored implementation, same as nixpkgs does for upstream helix.
patchedStdenv = pkgs.stdenv // {
mkDerivation = args: pkgs.stdenv.mkDerivation (args // {
postPatch = (args.postPatch or "") + ''
if [ -e src/bsearch.c ]; then
rm src/bsearch.c
substituteInPlace src/tsp_unicode.h \
--replace-fail '#include "bsearch.c"' ""
fi
'';
});
};
helixGrammars = pkgs.callPackage "${inputs.helix-steel}/grammars.nix" {
stdenv = patchedStdenv;
};
helixSteel =
(
pkgs.callPackage "${inputs.helix-steel}/default.nix" {
gitRev = inputs.helix-steel.rev;
# The upstream flake builds the grammars with its own callPackage,
# swap in the patched ones.
callPackage = path: args:
if toString path == toString "${inputs.helix-steel}/grammars.nix" then helixGrammars
else pkgs.callPackage path args;
}
)
.overrideAttrs (old: {
cargoBuildFlags = (old.cargoBuildFlags or []) ++ [
"--features"
"steel,git"
];
});
comment-headers = pkgs.fetchurl {
url = "https://github.com/codingvivi/comment-dividers.hx/raw/refs/heads/main/comment_headers.scm";
name = "comment_headers.scm";
hash = "sha256-ohgn6DFJl0rdRJuri6Frs/uUlUsPxMvPHDuw4FS3qEE=";
};
patched-comment-headers = pkgs.runCommand "comment_headers.scm" { } ''
install -m 0644 ${comment-headers} "$out"
${pkgs.python3}/bin/python3 - <<'PY'
from pathlib import Path
import os
import sys
p = Path(os.environ["out"])
s = p.read_text()
start_marker = "(define (get-block-delims)"
end_marker = "(define (delete_till_first_nonwhitespace!)"
try:
start = s.index(start_marker)
end = s.index(end_marker, start)
except ValueError as e:
sys.exit(f"failed to find function markers: {e}")
new_get_block_delims = """(define (get-block-delims)
(helix.static.open_above)
(helix.static.insert_string "test_string")
(helix.static.normal_mode)
(helix.static.extend_to_line_bounds)
(helix.static.trim_selections)
(helix.static.toggle_comments)
(let* ([commented-test-string (helix.static.current-highlighted-text!)]
[strings-without-whitespace (split-whitespace commented-test-string)])
(delete-line-noyank!)
(cond
[(and (> (length strings-without-whitespace) 1)
(equal? (last strings-without-whitespace) "test_string"))
(list (first strings-without-whitespace) "")]
[(> (length strings-without-whitespace) 2)
(list (first strings-without-whitespace) (last strings-without-whitespace))]
[else
(list "" "")])))
"""
s = s[:start] + new_get_block_delims + s[end:]
old = "(make-line line-length fill-pattern #f padding-pattern)"
new = "(make-line line-length \"\" fill-pattern padding-pattern)"
if old not in s:
sys.exit("failed to find insert-divider make-line call")
s = s.replace(old, new)
p.write_text(s)
PY
'';
in {
home.packages = with pkgs; [
steel
wakatime-cli
];
# Wakapi is WakaTime-compatible, so the same plugin/client works.
sops.templates.".wakatime.cfg" = {
path = "${config.home.homeDirectory}/.wakatime.cfg";
mode = "0600";
content = ''
[settings]
api_url = https://coding.srcoder.moe/api
api_key = ${config.sops.placeholder."tokens/apis/wakapi"}
'';
};
home.activation.installWakatimeHx = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
export PATH="${pkgs.steel}/bin:$PATH"
export STEEL_HOME="${config.xdg.dataHome}/steel"
if [ ! -f "$STEEL_HOME/cogs/wakatime/wakatime.scm" ]; then
forge pkg install --git https://github.com/Xerxes-2/wakatime.hx.git
fi
'';
programs.helix = {
enable = true;
package = helixSteel;
defaultEditor = true;
settings = {
# theme = "catppuccin-mocha";
editor = {
insert-final-newline = false;
indent-guides.render = true;
whitespace.render = {
space = "all";
tab = "all";
nbsp = "none";
nnbsp = "none";
newline = "none";
};
cursor-shape = {
normal = "block";
insert = "bar";
select = "underline";
};
};
keys.normal = {
space = {
C-c = {
h = ":comment-h1";
j = ":comment-h2";
k = ":comment-h3";
d = ":comment-divider";
};
};
S-down = ["extend_to_line_bounds" "delete_selection" "paste_after"];
S-up = ["extend_to_line_bounds" "delete_selection" "move_line_up" "paste_before"];
};
};
};
xdg.configFile = {
"helix/cogs/comment_headers.scm".source = patched-comment-headers;
"helix/helix.scm".text = ''
(require (prefix-in div. "cogs/comment_headers.scm"))
(provide comment-h1 comment-h2 comment-h3 comment-divider)
(define (comment-h1)
(div.insert-h1!))
(define (comment-h2)
(div.insert-h2!))
(define (comment-h3)
(div.insert-h3!))
(define (comment-divider)
(div.insert-divider! 80 "~"))
'';
"helix/init.scm".text = ''
;; Steel init file
(require "wakatime/wakatime.scm")
'';
};
}