diff --git a/modules/common/default-packages.nix b/modules/common/default-packages.nix new file mode 100644 index 0000000..e03f027 --- /dev/null +++ b/modules/common/default-packages.nix @@ -0,0 +1,3 @@ +{ + environment.defaultPackages = []; +} diff --git a/modules/common/editor/default.nix b/modules/common/editor/default.nix new file mode 100644 index 0000000..8e549c1 --- /dev/null +++ b/modules/common/editor/default.nix @@ -0,0 +1,177 @@ +{ config, lib, pkgs, ... }: let + inherit (lib) attrValues enabled mkIf mkValue mapAttrs optionalAttrs elem; +in { + options.editor.defaultAlias = mkValue "nano"; + + options.editor.languageConfigsHelix = mkValue (let + formattedLanguages = { + astro = "astro"; + css = "css"; + html = "html"; + javascript = "js"; + json = "json"; + jsonc = "jsonc"; + jsx = "jsx"; + markdown = "md"; + scss = "scss"; + svelte = "svelte"; + tsx = "tsx"; + typescript = "ts"; + vue = "vue"; + yaml = "yaml"; + } + |> mapAttrs (name: extension: { + inherit name; + + auto-format = true; + formatter.command = "deno"; + formatter.args = [ "fmt" "--unstable-component" "--ext" extension "-" ]; + } // optionalAttrs (elem name [ "javascript" "jsx" "typescript" "tsx" ]) { + language-servers = [ "deno" ]; + }) + |> attrValues; + in formattedLanguages ++ [ + { + name = "nix"; + auto-format = false; + formatter.command = "nixfmt"; + } + + { + name = "python"; + auto-format = true; + language-servers = [ "basedpyright" ]; + } + + { + name = "toml"; + auto-format = true; + } + + { + name = "rust"; + + debugger.name = "lldb-dap"; + debugger.transport = "stdio"; + debugger.command = "lldb-dap"; + + debugger.templates = [{ + name = "binary"; + request = "launch"; + + completion = [{ + name = "binary"; + completion = "filename"; + }]; + + args.program = "{0}"; + args.initCommands = let + primer = pkgs.runCommand "primer" {} (/* py */ '' + mkdir $out + echo ' + + import subprocess + import pathlib + import lldb + + # Not hardcoding a nix store path here on purpose. + rustlib_etc = pathlib.Path(subprocess.getoutput("rustc --print sysroot")) / "lib" / "rustlib" / "etc" + if not rustlib_etc.exists(): + raise RuntimeError("Unable to determine rustc sysroot") + + # Load lldb_lookup.py and execute lldb_commands with the correct path + lldb.debugger.HandleCommand(f"""command script import "{rustlib_etc / 'lldb_lookup.py'}" """) + lldb.debugger.HandleCommand(f"""command source -s 0 "{rustlib_etc / 'lldb_commands'}" """) + + ' > $out/primer.py + ''); + in [ "command script import ${primer}/primer.py" ]; + }]; + } + ]); + + options.editor.lspConfigsHelix = mkValue { + deno = { + command = "deno"; + args = [ "lsp" ]; + + environment.NO_COLOR = "1"; + + config.javascript = enabled { + lint = true; + unstable = true; + + suggest.imports.hosts."https://deno.land" = true; + + inlayHints.enumMemberValues.enabled = true; + inlayHints.functionLikeReturnTypes.enabled = true; + inlayHints.parameterNames.enabled = "all"; + inlayHints.parameterTypes.enabled = true; + inlayHints.propertyDeclarationTypes.enabled = true; + inlayHints.variableTypes.enabled = true; + }; + }; + + rust-analyzer = { + config = { + cargo.features = "all"; + check.command = "clippy"; + completion.callable.snippets = "add_parentheses"; + completion.excludeTraits = [ "yansi::Paint" ]; + diagnostics.disabled = [ "inactive-code" "unlinked-file" ]; + }; + }; + }; + + config.environment = { + shellAliases.x = "echo 'use `e`, retard'"; + + shellAliases.e = config.editor.defaultAlias; + variables.EDITOR = config.editor.defaultAlias; + + systemPackages = mkIf config.isDesktop <| attrValues { + inherit (pkgs) + # CMAKE + cmake-language-server + + # GO + gopls + + # HTML + vscode-langservers-extracted + + # KOTLIN + kotlin-language-server + + # LATEX + texlab + + # LUA + lua-language-server + + # MARKDOWN + markdown-oxide + + # NIX + nixfmt-rfc-style + nil + + # PYTHON + basedpyright + + # RUST + rust-analyzer-nightly + lldb + + # TYPESCRIPT & OTHERS + deno + + # YAML + yaml-language-server + + # ZIG + zls + ; + }; + }; +} diff --git a/modules/common/editor/helix.nix b/modules/common/editor/helix.nix new file mode 100644 index 0000000..8044eed --- /dev/null +++ b/modules/common/editor/helix.nix @@ -0,0 +1,97 @@ +{ config, lib, pkgs, ... }: let + inherit (lib) const enabled genAttrs mkAfter mkIf; + + # CullOS Helix with Cab support: + _package_cab = pkgs.helix.overrideAttrs (old: { + src = pkgs.fetchzip { + url = "https://github.com/cull-os/helix/releases/download/ci-release-25.01.1/helix-ci-release-25.01.1-source.tar.xz"; + hash = "sha256-bvlzXRAdPvz8P49KENSw9gupQNaUm/+3eZZ1q7+fTsw="; + stripRoot = false; + }; + + cargoDeps = pkgs.rustPlatform.fetchCargoVendor { + inherit (pkgs.helix) src; + hash = "sha256-soOnSRvWO7OzxYENFUBGmgSAk1Oy9Av+wDDLKkcuIbs="; + }; + }); + + package = pkgs.helix.overrideAttrs (finalAttrs: _previousAttrs: { + version = "25.07.2"; + src = pkgs.fetchzip { + url = "https://github.com/bloxx12/helix/releases/download/${finalAttrs.version}/helix-${finalAttrs.version}-source.tar.xz"; + hash = "sha256-ZNsQwFfPXe6oewajx1tl68W60kVo7q2SuvTgy/o1HKk="; + stripRoot = false; + }; + + doInstallCheck = false; + + cargoDeps = pkgs.rustPlatform.fetchCargoVendor { + inherit (pkgs.helix) src; + hash = "sha256-3poZSvIrkx8lguxxDeNfngW6+4hH8TV/LHcZx5W5aXg="; + }; + }); +in { + editor.defaultAlias = "hx"; + + home-manager.sharedModules = [{ + programs.nushell.configFile.text = mkIf /*(*/config.isDesktop/* && config.isLinux)*/ <| mkAfter /* nu */ '' + def --wrapped hx [...arguments] { + if $env.TERM == "xterm-kitty" { + kitty @ set-spacing padding=0 + } + + RUST_BACKTRACE=full ^hx ...($arguments | each { glob $in } | flatten) + + if $env.TERM == "xterm-kitty" { + kitty @ set-spacing padding=${toString config.theme.padding} + } + } + ''; + + programs.helix = enabled { + inherit package; + + languages.language = config.editor.languageConfigsHelix; + languages.language-server = config.editor.lspConfigsHelix; + + settings.theme = "gruvbox_dark_hard"; + + settings.editor = { + auto-completion = false; + bufferline = "multiple"; + color-modes = true; + cursorline = true; + file-picker.hidden = false; + idle-timeout = 0; + shell = [ "nu" "--commands" ]; + text-width = 100; + }; + + settings.editor.cursor-shape = { + insert = "bar"; + normal = "block"; + select = "underline"; + }; + + settings.editor.statusline.mode = { + insert = "INSERT"; + normal = "NORMAL"; + select = "SELECT"; + }; + + settings.editor.indent-guides = { + character = "▏"; + render = true; + }; + + settings.editor.whitespace = { + characters.tab = "→"; + render.tab = "all"; + }; + + settings.keys = genAttrs [ "normal" "select" ] <| const { + D = "extend_to_line_end"; + }; + }; + }]; +} diff --git a/modules/common/editor/nano.nix b/modules/common/editor/nano.nix new file mode 100644 index 0000000..8de3ffe --- /dev/null +++ b/modules/common/editor/nano.nix @@ -0,0 +1,7 @@ +{ config, lib, ... }: let + inherit (lib) disabled optionalAttrs; +in { + programs = optionalAttrs config.isLinux { + nano = disabled; # Garbage. + }; +} diff --git a/modules/common/git.nix b/modules/common/git.nix index 32cb99f..dbca01f 100644 --- a/modules/common/git.nix +++ b/modules/common/git.nix @@ -77,7 +77,7 @@ in { home-manager.sharedModules = [ (homeArgs: let - homeConfig = homeArgs.config; + config' = homeArgs.config; gitUrl = self.best.services.forgejo.settings.server.ROOT_URL; gitDomain = head <| match "https://(.*)/" gitUrl; @@ -96,8 +96,8 @@ in { ''; programs.git = enabled { - userName = homeConfig.programs.jujutsu.settings.user.name; - userEmail = homeConfig.programs.jujutsu.settings.user.email; + userName = config'.programs.jujutsu.settings.user.name; + userEmail = config'.programs.jujutsu.settings.user.email; lfs = enabled; diff --git a/modules/common/helix.nix b/modules/common/helix.nix deleted file mode 100644 index d896322..0000000 --- a/modules/common/helix.nix +++ /dev/null @@ -1,256 +0,0 @@ -{ config, lib, pkgs, ... }: let - inherit (lib) attrValues const elem enabled genAttrs mapAttrs mkAfter mkIf optionalAttrs; -in { - environment = { - variables.EDITOR = "hx"; - shellAliases.x = "hx"; - }; - - nixpkgs.overlays = [(self: super: { - # CullOS Helix with Cab support: - # helix = super.helix.overrideAttrs (old: { - # src = self.fetchzip { - # url = "https://github.com/cull-os/helix/releases/download/ci-release-25.01.1/helix-ci-release-25.01.1-source.tar.xz"; - # hash = "sha256-bvlzXRAdPvz8P49KENSw9gupQNaUm/+3eZZ1q7+fTsw="; - # stripRoot = false; - # }; - - # cargoDeps = self.rustPlatform.fetchCargoVendor { - # inherit (self.helix) src; - # hash = "sha256-soOnSRvWO7OzxYENFUBGmgSAk1Oy9Av+wDDLKkcuIbs="; - # }; - # }); - - helix = super.helix.overrideAttrs (finalAttrs: _previousAttrs: { - version = "25.07.2"; - src = self.fetchzip { - url = "https://github.com/bloxx12/helix/releases/download/${finalAttrs.version}/helix-${finalAttrs.version}-source.tar.xz"; - hash = "sha256-ZNsQwFfPXe6oewajx1tl68W60kVo7q2SuvTgy/o1HKk="; - stripRoot = false; - }; - - doInstallCheck = false; - - cargoDeps = self.rustPlatform.fetchCargoVendor { - inherit (self.helix) src; - hash = "sha256-3poZSvIrkx8lguxxDeNfngW6+4hH8TV/LHcZx5W5aXg="; - }; - }); - })]; - - home-manager.sharedModules = [{ - programs.nushell.configFile.text = mkIf /*(*/config.isDesktop/* && config.isLinux)*/ <| mkAfter /* nu */ '' - def --wrapped hx [...arguments] { - if $env.TERM == "xterm-kitty" { - kitty @ set-spacing padding=0 - } - - RUST_BACKTRACE=full ^hx ...($arguments | each { glob $in } | flatten) - - if $env.TERM == "xterm-kitty" { - kitty @ set-spacing padding=${toString config.theme.padding} - } - } - ''; - - programs.helix = enabled { - languages.language = let - formattedLanguages = { - astro = "astro"; - css = "css"; - html = "html"; - javascript = "js"; - json = "json"; - jsonc = "jsonc"; - jsx = "jsx"; - markdown = "md"; - scss = "scss"; - svelte = "svelte"; - tsx = "tsx"; - typescript = "ts"; - vue = "vue"; - yaml = "yaml"; - } |> mapAttrs (name: extension: { - inherit name; - - auto-format = true; - formatter.command = "deno"; - formatter.args = [ "fmt" "--unstable-component" "--ext" extension "-" ]; - } // optionalAttrs (elem name [ "javascript" "jsx" "typescript" "tsx" ]) { - language-servers = [ "deno" ]; - }) - |> attrValues; - in formattedLanguages ++ [ - { - name = "nix"; - auto-format = false; - formatter.command = "nixfmt"; - } - - { - name = "python"; - auto-format = true; - language-servers = [ "basedpyright" ]; - } - - { - name = "rust"; - - debugger.name = "lldb-dap"; - debugger.transport = "stdio"; - debugger.command = "lldb-dap"; - - debugger.templates = [{ - name = "binary"; - request = "launch"; - - completion = [{ - name = "binary"; - completion = "filename"; - }]; - - args.program = "{0}"; - args.initCommands = let - primer = pkgs.runCommand "primer" {} (/* py */ '' - mkdir $out - echo ' - - import subprocess - import pathlib - import lldb - - # Not hardcoding a nix store path here on purpose. - rustlib_etc = pathlib.Path(subprocess.getoutput("rustc --print sysroot")) / "lib" / "rustlib" / "etc" - if not rustlib_etc.exists(): - raise RuntimeError("Unable to determine rustc sysroot") - - # Load lldb_lookup.py and execute lldb_commands with the correct path - lldb.debugger.HandleCommand(f"""command script import "{rustlib_etc / 'lldb_lookup.py'}" """) - lldb.debugger.HandleCommand(f"""command source -s 0 "{rustlib_etc / 'lldb_commands'}" """) - - ' > $out/primer.py - ''); - in [ "command script import ${primer}/primer.py" ]; - }]; - } - ]; - - languages.language-server.deno = { - command = "deno"; - args = [ "lsp" ]; - - environment.NO_COLOR = "1"; - - config.javascript = enabled { - lint = true; - unstable = true; - - suggest.imports.hosts."https://deno.land" = true; - - inlayHints = { - enumMemberValues.enabled = true; - functionLikeReturnTypes.enabled = true; - parameterNames.enabled = "all"; - parameterTypes.enabled = true; - propertyDeclarationTypes.enabled = true; - variableTypes.enabled = true; - }; - }; - }; - - languages.language-server.rust-analyzer = { - config = { - cargo.features = "all"; - check.command = "clippy"; - completion.callable.snippets = "add_parentheses"; - completion.excludeTraits = [ "yansi::Paint" ]; - diagnostics.disabled = [ "inactive-code" "unlinked-file" ]; - }; - }; - - settings.theme = "gruvbox_dark_hard"; - - settings.editor = { - auto-completion = false; - bufferline = "multiple"; - color-modes = true; - cursorline = true; - file-picker.hidden = false; - idle-timeout = 0; - shell = [ "nu" "--commands" ]; - text-width = 100; - }; - - settings.editor.cursor-shape = { - insert = "bar"; - normal = "block"; - select = "underline"; - }; - - settings.editor.statusline.mode = { - insert = "INSERT"; - normal = "NORMAL"; - select = "SELECT"; - }; - - settings.editor.indent-guides = { - character = "▏"; - render = true; - }; - - settings.editor.whitespace = { - characters.tab = "→"; - render.tab = "all"; - }; - - settings.keys = genAttrs [ "normal" "select" ] <| const { - D = "extend_to_line_end"; - }; - }; - }]; - - environment.systemPackages = mkIf config.isDesktop <| attrValues { - inherit (pkgs) - # CMAKE - cmake-language-server - - # GO - gopls - - # HTML - vscode-langservers-extracted - - # KOTLIN - kotlin-language-server - - # LATEX - texlab - - # LUA - lua-language-server - - # MARKDOWN - markdown-oxide - - # NIX - nixfmt-rfc-style - nil - - # PYTHON - basedpyright - - # RUST - rust-analyzer-nightly - lldb - - # TYPESCRIPT & OTHERS - deno - - # YAML - yaml-language-server - - # ZIG - zls - ; - }; -} diff --git a/modules/common/nushell/default.nix b/modules/common/nushell/default.nix deleted file mode 100644 index 06cc79d..0000000 --- a/modules/common/nushell/default.nix +++ /dev/null @@ -1,89 +0,0 @@ -{ config, lib, pkgs, ... }: let - inherit (lib) attrValues const enabled getExe mapAttrs mkIf optionalAttrs readFile removeAttrs replaceString; -in { - environment = optionalAttrs config.isLinux { - sessionVariables.SHELLS = getExe pkgs.nushell; - } // { - shells = mkIf config.isDarwin [ pkgs.nushell ]; - - shellAliases = { - la = "ls --all"; - ll = "ls --long"; - lla = "ls --long --all"; - sl = "ls"; - - cp = "cp --recursive --verbose --progress"; - mk = "mkdir"; - mv = "mv --verbose"; - rm = "rm --recursive --verbose"; - - pstree = "pstree -g 3"; - tree = "eza --tree --git-ignore --group-directories-first"; - }; - - systemPackages = attrValues { - inherit (pkgs) - carapace # For completions. - fish # For completions. - zsh # For completions. - inshellisense # For completions. - - zoxide # For better cd. - ; - }; - }; - - home-manager.sharedModules = [(homeArgs: let - homeConfig = homeArgs.config; - in { - xdg.configFile = { - "nushell/carapace.nu".source = pkgs.runCommand "carapace.nu" {} '' - ${getExe pkgs.carapace} _carapace nushell > $out - ''; - - "nushell/zoxide.nu".source = pkgs.runCommand "zoxide.nu" {} '' - ${getExe pkgs.zoxide} init nushell --cmd cd > $out - ''; - - "nushell/ls_colors.txt".source = pkgs.runCommand "ls_colors.txt" {} '' - ${getExe pkgs.vivid} generate gruvbox-dark-hard > $out - ''; - }; - - programs.direnv = enabled { - nix-direnv = enabled; - - enableNushellIntegration = true; - }; - - programs.nushell = enabled { - configFile.text = readFile ./config.nu; - envFile.text = readFile ./environment.nu; - - environmentVariables = let - environmentVariables = config.environment.variables; - - homeVariables = homeConfig.home.sessionVariables; - # homeVariablesExtra = pkgs.runCommand "home-variables-extra.env" {} '' - # alias export=echo - # # echo foo > $out - # # FIXME - # eval $(cat ${homeConfig.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh) > $out - # '' - # # |> (aaa: (_: break _) aaa) - # |> readFile - # |> splitString "\n" - # |> filter (s: s != "") - # |> map (match "([^=]+)=(.*)") - # |> map (keyAndValue: nameValuePair (first keyAndValue) (last keyAndValue)) - # |> foldl' (x: y: x // y) {}; - homeVariablesExtra = {}; - in environmentVariables // homeVariables // homeVariablesExtra - |> mapAttrs (const <| replaceString "$HOME" homeConfig.home.homeDirectory); - - shellAliases = removeAttrs config.environment.shellAliases [ "ls" "l" ] // { - cdtmp = "cd (mktemp --directory)"; - }; - }; - })]; -} diff --git a/modules/common/nushell/environment.nu b/modules/common/nushell/environment.nu deleted file mode 100644 index bf1124b..0000000 --- a/modules/common/nushell/environment.nu +++ /dev/null @@ -1 +0,0 @@ -# Crickets... diff --git a/modules/common/shell/0_nushell.nix b/modules/common/shell/0_nushell.nix new file mode 100644 index 0000000..0226b61 --- /dev/null +++ b/modules/common/shell/0_nushell.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: let + inherit (lib) attrNames attrValues concatStringsSep const enabled filter filterAttrs flatten foldl' head last listToAttrs mapAttrs mapAttrsToList match nameValuePair readFile replaceStrings splitString; + + package = pkgs.nushell; +in { + shells."0" = package; + + home-manager.sharedModules = [(homeArgs: let + config' = homeArgs.config; + + environmentVariables = let + variablesMap = { + HOME = config'.home.homeDirectory; + USER = config'.home.username; + + XDG_CACHE_HOME = config'.xdg.cacheHome; + XDG_CONFIG_HOME = config'.xdg.configHome; + XDG_DATA_HOME = config'.xdg.dataHome; + XDG_STATE_HOME = config'.xdg.stateHome; + } + |> mapAttrsToList (name: value: [ + { name = "\$${name}"; inherit value; } + { name = "\${${name}}"; inherit value; } + ]) + |> flatten + |> listToAttrs; + + environmentVariables = config.environment.variables; + + homeVariables = config'.home.sessionVariables; + + homeVariablesExtra = pkgs.runCommand "home-variables-extra.env" {} '' + bash -ic ' + ${variablesMap + |> mapAttrsToList (name: value: "export ${name}='${value}'") + |> concatStringsSep "\n"} + + alias export=echo + source ${config'.home.sessionVariablesPackage}/etc/profile.d/hm-session-vars.sh + ' > $out + '' + |> readFile + |> splitString "\n" + |> filter (s: s != "") + |> map (match "([^=]+)=(.*)") + |> map (keyAndValue: nameValuePair (head keyAndValue) (last keyAndValue)) + |> foldl' (x: y: x // y) {}; + + homeSearchVariables = config'.home.sessionSearchVariables + |> mapAttrs (const <| concatStringsSep ":"); + in environmentVariables + // homeVariables + // homeVariablesExtra + // homeSearchVariables + |> mapAttrs (const <| replaceStrings (attrNames variablesMap) (attrValues variablesMap)) + |> filterAttrs (name: const <| name != "TERM"); + in { + programs.nushell = enabled { + inherit package; + + inherit (config.environment) shellAliases; + inherit environmentVariables; + + configFile.text = readFile ./0_nushell.nu; + }; + })]; +} diff --git a/modules/common/nushell/config.nu b/modules/common/shell/0_nushell.nu similarity index 98% rename from modules/common/nushell/config.nu rename to modules/common/shell/0_nushell.nu index e80e59e..6595198 100644 --- a/modules/common/nushell/config.nu +++ b/modules/common/shell/0_nushell.nu @@ -1,121 +1,6 @@ use std-rfc/clip use std null_device -source ~/.config/nushell/zoxide.nu - -$env.CARAPACE_BRIDGES = "inshellisense,carapace,zsh,fish,bash" -source ~/.config/nushell/carapace.nu - -# Retrieve the output of the last command. -def _ []: nothing -> any { - $env.last? -} - -# Create a directory and cd into it. -def --env mc [path: path]: nothing -> nothing { - mkdir $path - cd $path -} - -# Create a directory, cd into it and initialize version control. -def --env mcg [path: path]: nothing -> nothing { - mkdir $path - cd $path - jj git init --colocate -} - -def --env "nu-complete jc" [commandline: string] { - let stor = stor open - - if $stor.jc_completions? == null { - stor create --table-name jc_completions --columns { value: str, description: str, is_flag: bool } - } - - if $stor.jc_completions_ran? == null { - stor create --table-name jc_completions_ran --columns { _: bool } - } - - if $stor.jc_completions_ran == [] { try { - let about = ^jc --about - | from json - - let magic = $about - | get parsers - | each { { value: $in.magic_commands?, description: $in.description } } - | where value != null - | flatten - - let options = $about - | get parsers - | select argument description - | rename value description - - let inherent = ^jc --help - | lines - | split list "" # Group with empty lines as boundary. - | where { $in.0? == "Options:" } | get 0 # Get the first section that starts with "Options:" - | skip 1 # Remove header - | each { str trim } - | parse "{short}, {long} {description}" - | update description { str trim } - | each {|record| - [[value, description]; - [$record.short, $record.description], - [$record.long, $record.description], - ] - } - | flatten - - for entry in $magic { - stor insert --table-name jc_completions --data-record ($entry | insert is_flag false) - } - - for entry in ($options ++ $inherent) { - stor insert --table-name jc_completions --data-record ($entry | insert is_flag true) - } - - stor insert --table-name jc_completions_ran --data-record { _: true } - } } - - if ($commandline | str contains "-") { - $stor.jc_completions - } else { - $stor.jc_completions - | where is_flag == 0 - } | select value description -} - -# Run `jc` (JSON Converter). -def --wrapped jc [...arguments: string@"nu-complete jc"]: [any -> table, any -> record, any -> string] { - let run = ^jc ...$arguments | complete - - if $run.exit_code != 0 { - error make { - msg: "jc exection failed" - label: { - text: ($run.stderr | str replace "jc:" "" | str replace "Error -" "" | str trim) - span: (metadata $arguments).span - } - } - } - - if "--help" in $arguments or "-h" in $arguments { - $run.stdout - } else { - $run.stdout | from json - } -} - -# `nu-highlight` with default colors -# -# Custom themes can produce a lot more ansi color codes and make the output -# exceed discord's character limits -def nu-highlight-default [] { - let input = $in - $env.config.color_config = {} - $input | nu-highlight -} - $env.config.history.file_format = "sqlite" $env.config.history.isolation = false $env.config.history.max_size = 10_000_000 @@ -133,6 +18,8 @@ $env.config.cursor_shape.emacs = "line" $env.config.cursor_shape.vi_insert = "line" $env.config.cursor_shape.vi_normal = "block" +$env.CARAPACE_BRIDGES = "inshellisense,carapace,zsh,fish,bash" + $env.config.completions.algorithm = "substring" $env.config.completions.sort = "smart" $env.config.completions.case_sensitive = false @@ -187,7 +74,6 @@ $env.config.render_right_prompt_on_last_line = false $env.config.float_precision = 2 -$env.LS_COLORS = (open ~/.config/nushell/ls_colors.txt) $env.config.ls.use_ls_colors = true $env.config.hooks.pre_prompt = [] @@ -210,10 +96,20 @@ $env.config.hooks.display_output = {|| $env.config.hooks.command_not_found = [] +# `nu-highlight` with default colors +# +# Custom themes can produce a lot more ansi color codes and make the output +# exceed discord's character limits +def nu-highlight-default [] { + let input = $in + $env.config.color_config = {} + $input | nu-highlight +} + # Copy the current commandline, add syntax highlighting, wrap it in a # markdown code block, copy that to the system clipboard. # -# Perfect for sharing code snippets on discord +# Perfect for sharing code snippets on Discord. def "nu-keybind commandline-copy" []: nothing -> nothing { commandline | nu-highlight-default @@ -300,7 +196,7 @@ do --env { } else { $pwd } - + $"($hostname)(ansi cyan)($pwd)(ansi reset)" } @@ -541,3 +437,103 @@ module dump { } use dump + +# Retrieve the output of the last command. +def _ []: nothing -> any { + $env.last? +} + +# Create a directory and cd into it. +def --env mc [path: path]: nothing -> nothing { + mkdir $path + cd $path +} + +# Create a directory, cd into it and initialize version control. +def --env mcg [path: path]: nothing -> nothing { + mkdir $path + cd $path + jj git init --colocate +} + +def --env "nu-complete jc" [commandline: string] { + let stor = stor open + + if $stor.jc_completions? == null { + stor create --table-name jc_completions --columns { value: str, description: str, is_flag: bool } + } + + if $stor.jc_completions_ran? == null { + stor create --table-name jc_completions_ran --columns { _: bool } + } + + if $stor.jc_completions_ran == [] { try { + let about = ^jc --about + | from json + + let magic = $about + | get parsers + | each { { value: $in.magic_commands?, description: $in.description } } + | where value != null + | flatten + + let options = $about + | get parsers + | select argument description + | rename value description + + let inherent = ^jc --help + | lines + | split list "" # Group with empty lines as boundary. + | where { $in.0? == "Options:" } | get 0 # Get the first section that starts with "Options:" + | skip 1 # Remove header + | each { str trim } + | parse "{short}, {long} {description}" + | update description { str trim } + | each {|record| + [[value, description]; + [$record.short, $record.description], + [$record.long, $record.description], + ] + } + | flatten + + for entry in $magic { + stor insert --table-name jc_completions --data-record ($entry | insert is_flag false) + } + + for entry in ($options ++ $inherent) { + stor insert --table-name jc_completions --data-record ($entry | insert is_flag true) + } + + stor insert --table-name jc_completions_ran --data-record { _: true } + } } + + if ($commandline | str contains "-") { + $stor.jc_completions + } else { + $stor.jc_completions + | where is_flag == 0 + } | select value description +} + +# Run `jc` (JSON Converter). +def --wrapped jc [...arguments: string@"nu-complete jc"]: [any -> table, any -> record, any -> string] { + let run = ^jc ...$arguments | complete + + if $run.exit_code != 0 { + error make { + msg: "jc exection failed" + label: { + text: ($run.stderr | str replace "jc:" "" | str replace "Error -" "" | str trim) + span: (metadata $arguments).span + } + } + } + + if "--help" in $arguments or "-h" in $arguments { + $run.stdout + } else { + $run.stdout | from json + } +} diff --git a/modules/common/shell/aliases.nix b/modules/common/shell/aliases.nix new file mode 100644 index 0000000..906ec9d --- /dev/null +++ b/modules/common/shell/aliases.nix @@ -0,0 +1,16 @@ +{ + environment.shellAliases = { + la = "ls --all"; + ll = "ls --long"; + lla = "ls --long --all"; + sl = "ls"; + + cp = "cp --recursive --verbose --progress"; + mk = "mkdir"; + mv = "mv --verbose"; + rm = "rm --recursive --verbose"; + + pstree = "pstree -g 3"; + tree = "eza --tree --git-ignore --group-directories-first"; + }; +} diff --git a/modules/common/shell/carapace.nix b/modules/common/shell/carapace.nix new file mode 100644 index 0000000..426539a --- /dev/null +++ b/modules/common/shell/carapace.nix @@ -0,0 +1,16 @@ +{ lib, pkgs, ... }: let + inherit (lib) attrValues enabled; +in { + environment.systemPackages = attrValues { + inherit (pkgs) + carapace + fish + zsh + inshellisense + ; + }; + + home-manager.sharedModules = [{ + programs.carapace = enabled; + }]; +} diff --git a/modules/common/shell/default.nix b/modules/common/shell/default.nix new file mode 100644 index 0000000..a22401e --- /dev/null +++ b/modules/common/shell/default.nix @@ -0,0 +1,21 @@ +{ config, lib, ... }: let + inherit (lib) attrsToList catAttrs mkConst mkIf mkValue sortOn toInt; +in { + options.shells = mkValue {}; + + options.shellsByPriority = mkConst (config.shells + |> attrsToList + |> sortOn ({ name, ... }: toInt name) + |> catAttrs "value"); + + config = mkIf config.isDarwin { + environment.shells = config.shellsByPriority; + }; + + # More at modules/linux/shell/default.nix. + # + # Can't put that here with an optionalAttributes + # becuase of an infinite recursion error, and can't + # do that with a mkIf because the nix-darwin module + # system doesn't have those attributes. +} diff --git a/modules/common/shell/direnv.nix b/modules/common/shell/direnv.nix new file mode 100644 index 0000000..9808c2d --- /dev/null +++ b/modules/common/shell/direnv.nix @@ -0,0 +1,9 @@ +{ lib, ... }: let + inherit (lib) enabled; +in { + home-manager.sharedModules = [{ + programs.direnv = enabled { + nix-direnv = enabled; + }; + }]; +} diff --git a/modules/common/shell/vivid.nix b/modules/common/shell/vivid.nix new file mode 100644 index 0000000..0c4520c --- /dev/null +++ b/modules/common/shell/vivid.nix @@ -0,0 +1,9 @@ +{ lib, pkgs, ... }: let + inherit (lib) getExe readFile; +in { + # Yes, IFD. Deal with it. + environment.variables.LS_COLORS = readFile <| + pkgs.runCommand "ls_colors.txt" {} '' + ${getExe pkgs.vivid} generate gruvbox-dark-hard > $out + ''; +} diff --git a/modules/common/shell/zoxide.nix b/modules/common/shell/zoxide.nix new file mode 100644 index 0000000..235183e --- /dev/null +++ b/modules/common/shell/zoxide.nix @@ -0,0 +1,9 @@ +{ lib, ... }: let + inherit (lib) enabled; +in { + home-manager.sharedModules = [{ + programs.zoxide = enabled { + options = [ "--cmd cd" ]; + }; + }]; +} diff --git a/modules/linux/crash.nix b/modules/linux/crash.nix deleted file mode 100644 index adef320..0000000 --- a/modules/linux/crash.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ pkgs, ... }: { - users.defaultUserShell = pkgs.crash; -} diff --git a/modules/linux/nano.nix b/modules/linux/nano.nix deleted file mode 100644 index 4f3d1d5..0000000 --- a/modules/linux/nano.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ lib, ... }: let - inherit (lib) disabled; -in { - environment.defaultPackages = []; - - programs.nano = disabled; # Garbage. -} diff --git a/modules/linux/restic/default.nix b/modules/linux/restic/default.nix index 7596bfa..60a7007 100644 --- a/modules/linux/restic/default.nix +++ b/modules/linux/restic/default.nix @@ -1,6 +1,6 @@ { config, lib, ... }: let inherit (lib) genAttrs mkConst mkIf remove; -in{ +in { options.services.restic.hosts = mkConst <| remove config.networking.hostName [ "nine" "best" ]; config.secrets.resticPassword.file = mkIf config.isServer ./password.age; diff --git a/modules/linux/shell/default.nix b/modules/linux/shell/default.nix new file mode 100644 index 0000000..dff21fa --- /dev/null +++ b/modules/linux/shell/default.nix @@ -0,0 +1,9 @@ +{ config, lib, pkgs, ... }: let + inherit (lib) concatStringsSep; +in { + users.defaultUserShell = pkgs.crash; + + environment.sessionVariables.SHELLS = config.shellsByPriority + |> map (drv: "${drv}${drv.shellPath}") + |> concatStringsSep ":"; +}