nix/common/editor.nix
2026-04-08 11:51:33 +10:00

271 lines
5.8 KiB
Nix

{
pkgs,
lib,
config,
...
}:
let
toml = (pkgs.formats.toml { }).generate;
pal = config.rice.palette.hex;
ui = config.rice.roles pal;
helixConfig = toml "config.toml" {
theme = "nix-rice";
editor = {
bufferline = "multiple";
cursorline = true;
true-color = true;
cursor-shape = {
insert = "block";
normal = "block";
select = "block";
};
statusline.left = [
"mode"
"spinner"
"version-control"
"file-name"
"file-modification-indicator"
];
lsp.display-messages = true;
};
};
helixLanguages = toml "languages.toml" {
language = [
{
name = "rust";
language-servers = [ "rust-analyzer" ];
}
{
name = "nix";
language-servers = [ "nil" ];
file-types = [ "nix" ];
auto-format = true;
formatter = {
command = "nixfmt";
};
}
];
language-server = {
qmlls = {
command = "qmlls";
args = [ "-E" ];
};
nil = {
command = "nil";
};
rust-analyzer = {
config = {
cargo.buildScripts.enable = true;
procMacro.enable = true;
check.command = "clippy";
};
};
};
};
helixTheme = toml "nix-rice.toml" {
# === Syntax (palette) ===
"attribute" = pal.bright.cyan;
"keyword" = {
fg = pal.normal.red;
};
"keyword.directive" = pal.normal.red;
"namespace" = pal.bright.cyan;
"punctuation" = pal.bright.yellow;
"punctuation.delimiter" = pal.bright.yellow;
"operator" = pal.bright.magenta;
"special" = pal.normal.magenta;
"variable.other.member" = pal.bright.blue;
"variable" = pal.util.fg;
"variable.builtin" = pal.bright.yellow;
"variable.parameter" = pal.bright.white;
"type" = pal.normal.yellow;
"type.builtin" = pal.normal.yellow;
"constructor" = {
fg = pal.bright.magenta;
modifiers = [ "bold" ];
};
"function" = {
fg = pal.normal.green;
modifiers = [ "bold" ];
};
"function.macro" = pal.bright.cyan;
"function.builtin" = pal.normal.yellow;
"tag" = pal.normal.red;
"comment" = {
fg = pal.normal.magenta;
modifiers = [ "italic" ];
};
"constant" = {
fg = pal.bright.magenta;
};
"constant.builtin" = {
fg = pal.bright.magenta;
modifiers = [ "bold" ];
};
"string" = pal.normal.green;
"constant.numeric" = pal.bright.magenta;
"constant.character.escape" = {
fg = pal.bright.white;
modifiers = [ "bold" ];
};
"label" = pal.bright.cyan;
"module" = pal.bright.cyan;
# === Markup (palette) ===
"markup.heading" = pal.bright.cyan;
"markup.bold" = {
modifiers = [ "bold" ];
};
"markup.italic" = {
modifiers = [ "italic" ];
};
"markup.strikethrough" = {
modifiers = [ "crossed_out" ];
};
"markup.link.url" = {
fg = pal.bright.green;
modifiers = [ "underlined" ];
};
"markup.link.text" = pal.bright.red;
"markup.raw" = pal.bright.red;
# === Diff / diagnostics (roles) ===
"diff.plus" = ui.added;
"diff.delta" = ui.changed;
"diff.minus" = ui.removed;
"warning" = ui.warning;
"error" = ui.error;
"info" = ui.info;
"hint" = ui.hint;
"diagnostic.warning" = {
underline = {
color = ui.warning;
style = "curl";
};
};
"diagnostic.error" = {
underline = {
color = ui.error;
style = "curl";
};
};
"diagnostic.info" = {
underline = {
color = ui.info;
style = "curl";
};
};
"diagnostic.hint" = {
underline = {
color = ui.hint;
style = "curl";
};
};
# === UI (roles) ===
"ui.background" = {
bg = ui.bg;
};
"ui.text" = {
fg = ui.fg;
};
"ui.text.focus" = {
fg = ui.fg;
};
"ui.linenr" = {
fg = pal.normal.cyan;
};
"ui.linenr.selected" = {
fg = pal.normal.yellow;
modifiers = [ "bold" ];
};
"ui.cursorline" = {
bg = ui.surface;
};
"ui.statusline" = {
fg = ui.fg;
bg = ui.overlay;
};
"ui.statusline.normal" = {
fg = ui.fg;
bg = ui.overlay;
};
"ui.statusline.insert" = {
fg = ui.fg;
bg = ui.primary;
};
"ui.statusline.select" = {
fg = ui.fg;
bg = ui.highlight;
};
"ui.statusline.inactive" = {
fg = ui.muted;
bg = ui.surface;
};
"ui.popup" = {
bg = ui.surface;
};
"ui.window" = {
bg = ui.surface;
};
"ui.help" = {
bg = ui.surface;
fg = ui.fg;
};
"ui.selection" = {
bg = ui.highlight;
};
"ui.selection.primary" = {
modifiers = [ "reversed" ];
};
"ui.cursor.primary" = {
bg = ui.muted;
fg = ui.surface;
};
"ui.cursor.match" = {
bg = ui.accent;
};
"ui.menu" = {
fg = ui.fg;
bg = ui.overlay;
};
"ui.menu.selected" = {
fg = ui.overlay;
bg = ui.secondary;
modifiers = [ "bold" ];
};
"ui.virtual.whitespace" = ui.overlay;
"ui.virtual.ruler" = {
bg = ui.surface;
};
"ui.virtual.inlay-hint" = {
fg = pal.normal.magenta;
};
};
helixConfigDir = pkgs.runCommand "helix-xdg" { } ''
mkdir -p $out/helix/themes
cp ${helixConfig} $out/helix/config.toml
cp ${helixLanguages} $out/helix/languages.toml
cp ${helixTheme} $out/helix/themes/nix-rice.toml
'';
helixWrapped = pkgs.symlinkJoin {
name = "helix";
paths = [ pkgs.helix ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/hx \
--set XDG_CONFIG_HOME "${helixConfigDir}"
'';
meta.mainProgram = "hx";
};
in
scope "apps.editor" <| helixWrapped