mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
Some files don't need nesting and can be root level again to reduce conflicts with other PRs. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
766 lines
22 KiB
Nix
766 lines
22 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
inherit (lib)
|
|
concatStrings
|
|
concatStringsSep
|
|
mkIf
|
|
mkOption
|
|
mkEnableOption
|
|
optional
|
|
optionalString
|
|
types
|
|
;
|
|
|
|
cfg = config.programs.kakoune;
|
|
|
|
hook = types.submodule {
|
|
options = {
|
|
name = mkOption {
|
|
type = types.enum [
|
|
"NormalIdle"
|
|
"NormalKey"
|
|
"InsertIdle"
|
|
"InsertKey"
|
|
"InsertChar"
|
|
"InsertDelete"
|
|
"InsertMove"
|
|
"WinCreate"
|
|
"WinClose"
|
|
"WinResize"
|
|
"WinDisplay"
|
|
"WinSetOption"
|
|
"BufSetOption"
|
|
"BufNewFile"
|
|
"BufOpenFile"
|
|
"BufCreate"
|
|
"BufWritePre"
|
|
"BufWritePost"
|
|
"BufReload"
|
|
"BufClose"
|
|
"BufOpenFifo"
|
|
"BufReadFifo"
|
|
"BufCloseFifo"
|
|
"RuntimeError"
|
|
"ModeChange"
|
|
"PromptIdle"
|
|
"GlobalSetOption"
|
|
"KakBegin"
|
|
"KakEnd"
|
|
"FocusIn"
|
|
"FocusOut"
|
|
"RawKey"
|
|
"InsertCompletionShow"
|
|
"InsertCompletionHide"
|
|
"ModuleLoaded"
|
|
"ClientCreate"
|
|
"ClientClose"
|
|
"RegisterModified"
|
|
"User"
|
|
];
|
|
example = "SetOption";
|
|
description = ''
|
|
The name of the hook. For a description, see
|
|
<https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc#default-hooks>.
|
|
'';
|
|
};
|
|
|
|
once = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Remove the hook after running it once.
|
|
'';
|
|
};
|
|
|
|
group = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
Add the hook to the named group.
|
|
'';
|
|
};
|
|
|
|
option = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
example = "filetype=latex";
|
|
description = ''
|
|
Additional option to pass to the hook.
|
|
'';
|
|
};
|
|
|
|
commands = mkOption {
|
|
type = types.lines;
|
|
default = "";
|
|
example = "set-option window indentwidth 2";
|
|
description = ''
|
|
Commands to run when the hook is activated.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
keyMapping = types.submodule {
|
|
options = {
|
|
mode = mkOption {
|
|
type = types.str;
|
|
example = "user";
|
|
description = ''
|
|
The mode in which the mapping takes effect.
|
|
'';
|
|
};
|
|
|
|
docstring = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
Optional documentation text to display in info boxes.
|
|
'';
|
|
};
|
|
|
|
key = mkOption {
|
|
type = types.str;
|
|
example = "<a-x>";
|
|
description = ''
|
|
The key to be mapped. See
|
|
<https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc#mappable-keys>
|
|
for possible values.
|
|
'';
|
|
};
|
|
|
|
effect = mkOption {
|
|
type = types.str;
|
|
example = ":wq<ret>";
|
|
description = ''
|
|
The sequence of keys to be mapped.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
configModule = types.submodule {
|
|
options = {
|
|
colorScheme = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
Set the color scheme. To see available schemes, enter
|
|
{command}`colorscheme` at the kakoune prompt.
|
|
'';
|
|
};
|
|
|
|
tabStop = mkOption {
|
|
type = types.nullOr types.ints.unsigned;
|
|
default = null;
|
|
description = ''
|
|
The width of a tab in spaces. The kakoune default is
|
|
`6`.
|
|
'';
|
|
};
|
|
|
|
indentWidth = mkOption {
|
|
type = types.nullOr types.ints.unsigned;
|
|
default = null;
|
|
description = ''
|
|
The width of an indentation in spaces.
|
|
The kakoune default is `4`.
|
|
If `0`, a tab will be used instead.
|
|
'';
|
|
};
|
|
|
|
incrementalSearch = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = ''
|
|
Execute a search as it is being typed.
|
|
'';
|
|
};
|
|
|
|
alignWithTabs = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Use tabs for the align command.
|
|
'';
|
|
};
|
|
|
|
autoInfo = mkOption {
|
|
type = types.nullOr (
|
|
types.listOf (
|
|
types.enum [
|
|
"command"
|
|
"onkey"
|
|
"normal"
|
|
]
|
|
)
|
|
);
|
|
default = null;
|
|
example = [
|
|
"command"
|
|
"normal"
|
|
];
|
|
description = ''
|
|
Contexts in which to display automatic information box.
|
|
The kakoune default is `[ "command" "onkey" ]`.
|
|
'';
|
|
};
|
|
|
|
autoComplete = mkOption {
|
|
type = types.nullOr (
|
|
types.listOf (
|
|
types.enum [
|
|
"insert"
|
|
"prompt"
|
|
]
|
|
)
|
|
);
|
|
default = null;
|
|
description = ''
|
|
Modes in which to display possible completions.
|
|
The kakoune default is `[ "insert" "prompt" ]`.
|
|
'';
|
|
};
|
|
|
|
autoReload = mkOption {
|
|
type = types.nullOr (
|
|
types.enum [
|
|
"yes"
|
|
"no"
|
|
"ask"
|
|
]
|
|
);
|
|
default = null;
|
|
description = ''
|
|
Reload buffers when an external modification is detected.
|
|
The kakoune default is `"ask"`.
|
|
'';
|
|
};
|
|
|
|
scrollOff = mkOption {
|
|
type = types.nullOr (
|
|
types.submodule {
|
|
options = {
|
|
lines = mkOption {
|
|
type = types.ints.unsigned;
|
|
default = 0;
|
|
description = ''
|
|
The number of lines to keep visible around the cursor.
|
|
'';
|
|
};
|
|
|
|
columns = mkOption {
|
|
type = types.ints.unsigned;
|
|
default = 0;
|
|
description = ''
|
|
The number of columns to keep visible around the cursor.
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = null;
|
|
description = ''
|
|
How many lines and columns to keep visible around the cursor.
|
|
'';
|
|
};
|
|
|
|
ui = mkOption {
|
|
type = types.nullOr (
|
|
types.submodule {
|
|
options = {
|
|
setTitle = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Change the title of the terminal emulator.
|
|
'';
|
|
};
|
|
|
|
statusLine = mkOption {
|
|
type = types.enum [
|
|
"top"
|
|
"bottom"
|
|
];
|
|
default = "bottom";
|
|
description = ''
|
|
Where to display the status line.
|
|
'';
|
|
};
|
|
|
|
assistant = mkOption {
|
|
type = types.enum [
|
|
"clippy"
|
|
"cat"
|
|
"dilbert"
|
|
"none"
|
|
];
|
|
default = "clippy";
|
|
description = ''
|
|
The assistant displayed in info boxes.
|
|
'';
|
|
};
|
|
|
|
enableMouse = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to enable mouse support.
|
|
'';
|
|
};
|
|
|
|
changeColors = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = ''
|
|
Change color palette.
|
|
'';
|
|
};
|
|
|
|
wheelDownButton = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
Button to send for wheel down events.
|
|
'';
|
|
};
|
|
|
|
wheelUpButton = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
Button to send for wheel up events.
|
|
'';
|
|
};
|
|
|
|
shiftFunctionKeys = mkOption {
|
|
type = types.nullOr types.ints.unsigned;
|
|
default = null;
|
|
description = ''
|
|
Amount by which shifted function keys are offset. That
|
|
is, if the terminal sends F13 for Shift-F1, this
|
|
should be `12`.
|
|
'';
|
|
};
|
|
|
|
useBuiltinKeyParser = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Bypass ncurses key parser and use an internal one.
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = null;
|
|
description = ''
|
|
Settings for the ncurses interface.
|
|
'';
|
|
};
|
|
|
|
showMatching = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Highlight the matching char of the character under the
|
|
selections' cursor using the `MatchingChar`
|
|
face.
|
|
'';
|
|
};
|
|
|
|
wrapLines = mkOption {
|
|
type = types.nullOr (
|
|
types.submodule {
|
|
options = {
|
|
enable = mkEnableOption "the wrap lines highlighter";
|
|
|
|
word = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Wrap at word boundaries instead of codepoint boundaries.
|
|
'';
|
|
};
|
|
|
|
indent = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Preserve line indentation when wrapping.
|
|
'';
|
|
};
|
|
|
|
maxWidth = mkOption {
|
|
type = types.nullOr types.ints.unsigned;
|
|
default = null;
|
|
description = ''
|
|
Wrap text at maxWidth, even if the window is wider.
|
|
'';
|
|
};
|
|
|
|
marker = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
example = "⏎";
|
|
description = ''
|
|
Prefix wrapped lines with marker text.
|
|
If not `null`,
|
|
the marker text will be displayed in the indentation if possible.
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = null;
|
|
description = ''
|
|
Settings for the wrap lines highlighter.
|
|
'';
|
|
};
|
|
|
|
numberLines = mkOption {
|
|
type = types.nullOr (
|
|
types.submodule {
|
|
options = {
|
|
enable = mkEnableOption "the number lines highlighter";
|
|
|
|
relative = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Show line numbers relative to the main cursor line.
|
|
'';
|
|
};
|
|
|
|
highlightCursor = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Highlight the cursor line with a separate face.
|
|
'';
|
|
};
|
|
|
|
separator = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
String that separates the line number column from the
|
|
buffer contents. The kakoune default is
|
|
`"|"`.
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = null;
|
|
description = ''
|
|
Settings for the number lines highlighter.
|
|
'';
|
|
};
|
|
|
|
showWhitespace = mkOption {
|
|
type = types.nullOr (
|
|
types.submodule {
|
|
options = {
|
|
enable = mkEnableOption "the show whitespace highlighter";
|
|
|
|
lineFeed = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
The character to display for line feeds.
|
|
The kakoune default is `"¬"`.
|
|
'';
|
|
};
|
|
|
|
space = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
The character to display for spaces.
|
|
The kakoune default is `"·"`.
|
|
'';
|
|
};
|
|
|
|
nonBreakingSpace = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
The character to display for non-breaking spaces.
|
|
The kakoune default is `"⍽"`.
|
|
'';
|
|
};
|
|
|
|
tab = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
The character to display for tabs.
|
|
The kakoune default is `"→"`.
|
|
'';
|
|
};
|
|
|
|
tabStop = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = ''
|
|
The character to append to tabs to reach the width of a tabstop.
|
|
The kakoune default is `" "`.
|
|
'';
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = null;
|
|
description = ''
|
|
Settings for the show whitespaces highlighter.
|
|
'';
|
|
};
|
|
|
|
keyMappings = mkOption {
|
|
type = types.listOf keyMapping;
|
|
default = [ ];
|
|
description = ''
|
|
User-defined key mappings. For documentation, see
|
|
<https://github.com/mawww/kakoune/blob/master/doc/pages/mapping.asciidoc>.
|
|
'';
|
|
};
|
|
|
|
hooks = mkOption {
|
|
type = types.listOf hook;
|
|
default = [ ];
|
|
description = ''
|
|
Global hooks. For documentation, see
|
|
<https://github.com/mawww/kakoune/blob/master/doc/pages/hooks.asciidoc>.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
kakouneWithPlugins = pkgs.wrapKakoune cfg.package {
|
|
configure = {
|
|
plugins = cfg.plugins;
|
|
};
|
|
};
|
|
|
|
configFile =
|
|
let
|
|
wrapOptions =
|
|
with cfg.config.wrapLines;
|
|
concatStrings [
|
|
"${optionalString word " -word"}"
|
|
"${optionalString indent " -indent"}"
|
|
"${optionalString (marker != null) " -marker ${marker}"}"
|
|
"${optionalString (maxWidth != null) " -width ${toString maxWidth}"}"
|
|
];
|
|
|
|
numberLinesOptions =
|
|
with cfg.config.numberLines;
|
|
concatStrings [
|
|
"${optionalString relative " -relative "}"
|
|
"${optionalString highlightCursor " -hlcursor"}"
|
|
"${optionalString (separator != null) " -separator ${separator}"}"
|
|
];
|
|
|
|
showWhitespaceOptions =
|
|
with cfg.config.showWhitespace;
|
|
let
|
|
quoteSep =
|
|
sep:
|
|
if sep == "'" then
|
|
''"'"''
|
|
else if lib.strings.stringLength sep == 1 then
|
|
"'${sep}'"
|
|
else
|
|
sep; # backwards compat, in case sep == "' '", etc.
|
|
|
|
in
|
|
concatStrings [
|
|
(optionalString (tab != null) " -tab ${quoteSep tab}")
|
|
(optionalString (tabStop != null) " -tabpad ${quoteSep tabStop}")
|
|
(optionalString (space != null) " -spc ${quoteSep space}")
|
|
(optionalString (nonBreakingSpace != null) " -nbsp ${quoteSep nonBreakingSpace}")
|
|
(optionalString (lineFeed != null) " -lf ${quoteSep lineFeed}")
|
|
];
|
|
|
|
uiOptions =
|
|
with cfg.config.ui;
|
|
concatStringsSep " " [
|
|
"terminal_set_title=${if setTitle then "true" else "false"}"
|
|
"terminal_status_on_top=${if (statusLine == "top") then "true" else "false"}"
|
|
"terminal_assistant=${assistant}"
|
|
"terminal_enable_mouse=${if enableMouse then "true" else "false"}"
|
|
"terminal_change_colors=${if changeColors then "true" else "false"}"
|
|
"${optionalString (wheelDownButton != null) "terminal_wheel_down_button=${wheelDownButton}"}"
|
|
"${optionalString (wheelUpButton != null) "terminal_wheel_up_button=${wheelUpButton}"}"
|
|
"${optionalString (
|
|
shiftFunctionKeys != null
|
|
) "terminal_shift_function_key=${toString shiftFunctionKeys}"}"
|
|
"terminal_builtin_key_parser=${if useBuiltinKeyParser then "true" else "false"}"
|
|
];
|
|
|
|
userModeString =
|
|
mode:
|
|
optionalString (
|
|
!builtins.elem mode [
|
|
"insert"
|
|
"normal"
|
|
"prompt"
|
|
"menu"
|
|
"user"
|
|
"goto"
|
|
"view"
|
|
"object"
|
|
]
|
|
) "try %{declare-user-mode ${mode}}";
|
|
|
|
userModeStrings = map userModeString (lib.lists.unique (map (km: km.mode) cfg.config.keyMappings));
|
|
|
|
keyMappingString =
|
|
km:
|
|
concatStringsSep " " [
|
|
"map global"
|
|
"${km.mode} ${km.key} '${km.effect}'"
|
|
"${optionalString (km.docstring != null) "-docstring '${km.docstring}'"}"
|
|
];
|
|
|
|
hookString =
|
|
h:
|
|
concatStringsSep " " [
|
|
"hook"
|
|
"${optionalString (h.group != null) "-group ${h.group}"}"
|
|
"${optionalString (h.once) "-once"}"
|
|
"global"
|
|
"${h.name}"
|
|
"${optionalString (h.option != null) h.option}"
|
|
"%{ ${h.commands} }"
|
|
];
|
|
|
|
cfgStr =
|
|
with cfg.config;
|
|
concatStringsSep "\n" (
|
|
[ "# Generated by home-manager" ]
|
|
++ optional (colorScheme != null) "colorscheme ${colorScheme}"
|
|
++ optional (tabStop != null) "set-option global tabstop ${toString tabStop}"
|
|
++ optional (indentWidth != null) "set-option global indentwidth ${toString indentWidth}"
|
|
++ optional (!incrementalSearch) "set-option global incsearch false"
|
|
++ optional alignWithTabs "set-option global aligntab true"
|
|
++ optional (autoInfo != null) "set-option global autoinfo ${concatStringsSep "|" autoInfo}"
|
|
++ optional (
|
|
autoComplete != null
|
|
) "set-option global autocomplete ${concatStringsSep "|" autoComplete}"
|
|
++ optional (autoReload != null) "set-option global autoreload ${autoReload}"
|
|
++ optional (wrapLines != null && wrapLines.enable) "add-highlighter global/ wrap${wrapOptions}"
|
|
++ optional (
|
|
numberLines != null && numberLines.enable
|
|
) "add-highlighter global/ number-lines${numberLinesOptions}"
|
|
++ optional showMatching "add-highlighter global/ show-matching"
|
|
++ optional (
|
|
showWhitespace != null && showWhitespace.enable
|
|
) "add-highlighter global/ show-whitespaces${showWhitespaceOptions}"
|
|
++ optional (
|
|
scrollOff != null
|
|
) "set-option global scrolloff ${toString scrollOff.lines},${toString scrollOff.columns}"
|
|
|
|
++ [ "# UI options" ]
|
|
++ optional (ui != null) "set-option global ui_options ${uiOptions}"
|
|
|
|
++ [ "# User modes" ]
|
|
++ userModeStrings
|
|
++ [ "# Key mappings" ]
|
|
++ map keyMappingString keyMappings
|
|
|
|
++ [ "# Hooks" ]
|
|
++ map hookString hooks
|
|
);
|
|
in
|
|
pkgs.writeText "kakrc" (optionalString (cfg.config != null) cfgStr + "\n" + cfg.extraConfig);
|
|
|
|
in
|
|
{
|
|
options = {
|
|
programs.kakoune = {
|
|
enable = mkEnableOption "the kakoune text editor";
|
|
|
|
package = lib.mkPackageOption pkgs "kakoune-unwrapped" { nullable = true; };
|
|
|
|
finalPackage = mkOption {
|
|
type = types.nullOr types.package;
|
|
readOnly = true;
|
|
description = "Resulting customized kakoune package.";
|
|
};
|
|
|
|
config = mkOption {
|
|
type = types.nullOr configModule;
|
|
default = { };
|
|
description = "kakoune configuration options.";
|
|
};
|
|
|
|
defaultEditor = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to configure {command}`kak` as the default
|
|
editor using the {env}`EDITOR` environment variable.
|
|
'';
|
|
};
|
|
|
|
extraConfig = mkOption {
|
|
type = types.lines;
|
|
default = "";
|
|
description = ''
|
|
Extra configuration lines to add to
|
|
{file}`$XDG_CONFIG_HOME/kak/kakrc`.
|
|
'';
|
|
};
|
|
|
|
plugins = mkOption {
|
|
type = with types; listOf package;
|
|
default = [ ];
|
|
example = lib.literalExpression "[ pkgs.kakounePlugins.kak-fzf ]";
|
|
description = ''
|
|
List of kakoune plugins to install. To get a list of
|
|
supported plugins run:
|
|
{command}`nix-env -f '<nixpkgs>' -qaP -A kakounePlugins`.
|
|
|
|
Requires `package` to not be set to have effect.
|
|
'';
|
|
};
|
|
|
|
colorSchemePackage = mkOption {
|
|
type = with types; nullOr package;
|
|
default = null;
|
|
example = lib.literalExpression "pkgs.kakounePlugins.kakoune-catppuccin";
|
|
description = ''
|
|
A kakoune color schemes to add to your colors folder. This works
|
|
because kakoune recursively checks
|
|
{file}`$XDG_CONFIG_HOME/kak/colors/`. To apply the color scheme use
|
|
`programs.kakoune.config.colorScheme = "theme"`.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
warnings = lib.optional (cfg.package == null && cfg.plugins != [ ]) ''
|
|
You have configured `plugins` for `kakoune` but have not set `package`.
|
|
|
|
The listed plugins will not be installed.
|
|
'';
|
|
|
|
programs.kakoune.finalPackage = lib.mkIf (cfg.package != null) kakouneWithPlugins;
|
|
|
|
home.packages = lib.mkIf (cfg.finalPackage != null) [ cfg.finalPackage ];
|
|
home.sessionVariables = mkIf cfg.defaultEditor { EDITOR = "kak"; };
|
|
xdg.configFile = lib.mkMerge [
|
|
{ "kak/kakrc".source = configFile; }
|
|
(mkIf (cfg.colorSchemePackage != null) {
|
|
"kak/colors/${cfg.colorSchemePackage.name}".source = cfg.colorSchemePackage;
|
|
})
|
|
];
|
|
};
|
|
}
|