···11-{pkgs, ...}:
22-# nu
33-''
44- # Wrapper for git branch
55- def "from git branches" []: list<string> -> list<string> {
66- lines
77- | each {
88- str trim
99- | str replace --regex '^\* ' ""
1010- }
1111- }
1212-1313- # Wrapper for fzf
1414- def "into fzf" []: list<string> -> string {
1515- to text
1616- | ^${pkgs.fzf}
1717- }
1818-1919- # Wrapper for fzf with multiple selections
2020- def "into fzf multi" []: list<string> -> list<string> {
2121- to text
2222- | ^${pkgs.fzf} --multi
2323- | lines
2424- }
2525-2626- # Cast to list, for e.g. ranges
2727- def "into list" []: any -> list<any> {
2828- each {}
2929- }
3030-''
+26
nix/home/modules/cli/nushell/commands.nu
···11+# Wrapper for git branch
22+def "from git branches" []: list<string> -> list<string> {
33+ lines
44+ | each {
55+ str trim
66+ | str replace --regex '^\* ' ""
77+ }
88+}
99+1010+# Wrapper for fzf
1111+def "into fzf" []: list<string> -> string {
1212+ to text
1313+ | ^fzf
1414+}
1515+1616+# Wrapper for fzf with multiple selections
1717+def "into fzf multi" []: list<string> -> list<string> {
1818+ to text
1919+ | ^fzf --multi
2020+ | lines
2121+}
2222+2323+# Cast to list, for e.g. ranges
2424+def "into list" []: any -> list<any> {
2525+ each {}
2626+}
-121
nix/home/modules/cli/nushell/config.nix
···11-# nu
22-''
33- $env.config = {
44- show_banner: false # true or false to enable or disable the welcome banner at startup
55-66- ls: {
77- use_ls_colors: true # use the LS_COLORS environment variable to colorize output
88- clickable_links: true # enable or disable clickable links. Your terminal has to support links.
99- }
1010-1111- rm: {
1212- always_trash: false # always act as if -t was given. Can be overridden with -p
1313- }
1414-1515- table: {
1616- mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
1717- index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column
1818- show_empty: true # show 'empty list' and 'empty record' placeholders for command output
1919- padding: { left: 1, right: 1 } # a left right padding of each column in a table
2020- trim: {
2121- methodology: wrapping # wrapping or truncating
2222- wrapping_try_keep_words: true # A strategy used by the 'wrapping' methodology
2323- truncating_suffix: "..." # A suffix used by the 'truncating' methodology
2424- }
2525- header_on_separator: false # show header text on separator/border line
2626- # abbreviated_row_count: 10 # limit data rows from top and bottom after reaching a set point
2727- }
2828-2929- error_style: "fancy" # "fancy" or "plain" for screen reader-friendly error messages
3030-3131- # datetime_format determines what a datetime rendered in the shell would look like.
3232- # Behavior without this configuration point will be to "humanize" the datetime display,
3333- # showing something like "a day ago."
3434- datetime_format: {
3535- # normal: '%a, %d %b %Y %H:%M:%S %z' # shows up in displays of variables or other datetime's outside of tables
3636- # table: '%m/%d/%y %I:%M:%S%p' # generally shows up in tabular outputs such as ls. commenting this out will change it to the default human readable datetime format
3737- }
3838-3939- history: {
4040- max_size: 100_000 # Session has to be reloaded for this to take effect
4141- sync_on_enter: true # Enable to share history between multiple sessions, else you have to close the session to write history to file
4242- file_format: "plaintext" # "sqlite" or "plaintext"
4343- isolation: false # only available with sqlite file_format. true enables history isolation, false disables it. true will allow the history to be isolated to the current session using up/down arrows. false will allow the history to be shared across all sessions.
4444- }
4545-4646- completions: {
4747- case_sensitive: false # set to true to enable case-sensitive completions
4848- quick: true # set this to false to prevent auto-selecting completions when only one remains
4949- partial: true # set this to false to prevent partial filling of the prompt
5050- algorithm: "fuzzy" # prefix or fuzzy
5151- external: {
5252- enable: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up may be very slow
5353- max_results: 100 # setting it lower can improve completion performance at the cost of omitting some options
5454- # completer: null # check 'carapace_completer' above as an example
5555- }
5656- }
5757-5858- filesize: {
5959- metric: true # true => KB, MB, GB (ISO standard), false => KiB, MiB, GiB (Windows standard)
6060- format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, auto
6161- }
6262-6363- cursor_shape: {
6464- emacs: line # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (line is the default)
6565- vi_insert: line # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (block is the default)
6666- vi_normal: block # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (underscore is the default)
6767- }
6868-6969- edit_mode: vi # emacs, vi
7070- shell_integration: {
7171- # osc2 abbreviates the path if in the home_dir, sets the tab/window title, shows the running command in the tab/window title
7272- osc2: true
7373- # osc7 is a way to communicate the path to the terminal, this is helpful for spawning new tabs in the same directory
7474- osc7: true
7575- # osc8 is also implemented as the deprecated setting ls.show_clickable_links, it shows clickable links in ls output if your terminal supports it. show_clickable_links is deprecated in favor of osc8
7676- osc8: true
7777- # osc9_9 is from ConEmu and is starting to get wider support. It's similar to osc7 in that it communicates the path to the terminal
7878- osc9_9: false
7979- # osc133 is several escapes invented by Final Term which include the supported ones below.
8080- # 133;A - Mark prompt start
8181- # 133;B - Mark prompt end
8282- # 133;C - Mark pre-execution
8383- # 133;D;exit - Mark execution finished with exit code
8484- # This is used to enable terminals to know where the prompt is, the command is, where the command finishes, and where the output of the command is
8585- osc133: true
8686- # osc633 is closely related to osc133 but only exists in visual studio code (vscode) and supports their shell integration features
8787- # 633;A - Mark prompt start
8888- # 633;B - Mark prompt end
8989- # 633;C - Mark pre-execution
9090- # 633;D;exit - Mark execution finished with exit code
9191- # 633;E - NOT IMPLEMENTED - Explicitly set the command line with an optional nonce
9292- # 633;P;Cwd=<path> - Mark the current working directory and communicate it to the terminal
9393- # and also helps with the run recent menu in vscode
9494- osc633: true
9595- # reset_application_mode is escape \x1b[?1l and was added to help ssh work better
9696- reset_application_mode: true
9797- }
9898- render_right_prompt_on_last_line: false # true or false to enable or disable right prompt to be rendered on last line of the prompt.
9999- use_kitty_protocol: true # enables keyboard enhancement protocol implemented by kitty console, only if your terminal support this
100100-101101- hooks: {
102102- pre_prompt: [{ null }] # run before the prompt is shown
103103- pre_execution: [{ null }] # run before the repl input is run
104104- env_change: {
105105- PWD: [{|before, after| null }] # run if the PWD environment is different since the last repl input
106106- }
107107- display_output: "if (term size).columns >= 100 { table -e } else { table }" # run to display the output of a pipeline
108108- command_not_found: { null } # return an error message when a command is not found
109109- }
110110-111111- keybindings: [
112112- {
113113- name: open_command_editor
114114- modifier: alt
115115- keycode: char_e
116116- mode: [emacs, vi_normal, vi_insert]
117117- event: { send: openeditor }
118118- }
119119- ]
120120- }
121121-''
+46
nix/home/modules/cli/nushell/config.nu
···11+$env.config = {
22+ show_banner: false # true or false to enable or disable the welcome banner at startup
33+ edit_mode: vi # emacs, vi
44+ use_kitty_protocol: true # enables keyboard enhancement protocol implemented by kitty console, only if your terminal support this
55+66+ table: {
77+ mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
88+ index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column
99+ show_empty: true # show 'empty list' and 'empty record' placeholders for command output
1010+ }
1111+1212+ history: {
1313+ max_size: 100_000 # Session has to be reloaded for this to take effect
1414+ sync_on_enter: true # Enable to share history between multiple sessions, else you have to close the session to write history to file
1515+ file_format: "plaintext" # "sqlite" or "plaintext"
1616+ isolation: false # only available with sqlite file_format. true enables history isolation, false disables it. true will allow the history to be isolated to the current session using up/down arrows. false will allow the history to be shared across all sessions.
1717+ }
1818+1919+ completions: {
2020+ case_sensitive: false # set to true to enable case-sensitive completions
2121+ quick: true # set this to false to prevent auto-selecting completions when only one remains
2222+ partial: true # set this to false to prevent partial filling of the prompt
2323+ algorithm: "fuzzy" # prefix or fuzzy
2424+ external: {
2525+ enable: true # set to false to prevent nushell looking into $env.PATH to find more suggestions, `false` recommended for WSL users as this look up may be very slow
2626+ max_results: 100 # setting it lower can improve completion performance at the cost of omitting some options
2727+ # completer: null # check 'carapace_completer' above as an example
2828+ }
2929+ }
3030+3131+ cursor_shape: {
3232+ emacs: line # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (line is the default)
3333+ vi_insert: line # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (block is the default)
3434+ vi_normal: block # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (underscore is the default)
3535+ }
3636+3737+ keybindings: [
3838+ {
3939+ name: open_command_editor
4040+ modifier: alt
4141+ keycode: char_e
4242+ mode: [emacs, vi_normal, vi_insert]
4343+ event: { send: openeditor }
4444+ }
4545+ ]
4646+}
···11+# Provides new nu script writers with a few QoL enhancements
22+# - Support from reading from stdin
33+# - Extra newline prepended to content so script help contents display properly
44+{inputs, ...}: let
55+ inherit (inputs.nixpkgs) lib;
66+in (final: prev: let
77+ inherit (prev.writers) makeScriptWriter;
88+ interpreter = "${lib.getExe prev.nushell} --no-config-file --stdin";
99+ patch = writer:
1010+ writer.overrideAttrs (prev: {
1111+ content = "\n${prev.content}";
1212+ });
1313+in rec {
1414+ # Based on the original implementation, see https://noogle.dev/f/pkgs/writers/writeNu
1515+ writeNuScriptStdin = name: argsOrScript:
1616+ if lib.isAttrs argsOrScript && !lib.isDerivation argsOrScript
1717+ then patch (makeScriptWriter (argsOrScript // {inherit interpreter;}) name)
1818+ else patch (makeScriptWriter {inherit interpreter;} name argsOrScript);
1919+ writeNuScriptStdinBin = name: writeNuScriptStdin "/bin/${name}";
2020+})
···11+args: let
22+ inherit ((import ../lib args).loaders) loadNonDefault;
33+in {
44+ perSystem = {
55+ self',
66+ pkgs,
77+ ...
88+ } @ systemArgs: {
99+ legacyPackages = let
1010+ scripts = loadNonDefault ./. systemArgs;
1111+ in
1212+ scripts # Provide them at the top level as well so they're more convenient to run
1313+ // {inherit scripts;};
1414+ };
1515+}
+18
nix/scripts/lastdl.nix
···11+{pkgs, ...}:
22+pkgs.writeNuScriptStdinBin "lastdl"
33+# nu
44+''
55+ # Print the last downloaded file
66+ def main [
77+ --short # Print the filename instead of full path
88+ --quote # Print the raw path with added quotes
99+ ]: nothing -> string {
1010+ ls (${pkgs.xdg-user-dirs}/bin/xdg-user-dir DOWNLOAD)
1111+ | where type == file
1212+ | sort-by modified
1313+ | last
1414+ | get name
1515+ | if $short { path basename } else { $in }
1616+ | if $quote { $'"($in)"' } else { $in }
1717+ }
1818+''
+21
nix/scripts/leastspaces.nix
···11+{pkgs, ...}:
22+pkgs.writeNuScriptStdinBin "leastspaces"
33+# nu
44+''
55+ # Computes the least prepending spaces present in any line of the supplied text
66+ def main []: string -> any {
77+ let lines = $in
88+ | split row "\n";
99+ let least = $lines
1010+ | each {
1111+ parse --regex '^(\s*)'
1212+ | values
1313+ | first
1414+ | str length
1515+ }
1616+ | math min
1717+ $lines
1818+ | each { str substring ($least | first).. }
1919+ | str join "\n"
2020+ }
2121+''
+23
nix/scripts/nu-generate-carapace-spec.nix
···11+{pkgs, ...}:
22+pkgs.writeNuScriptStdinBin "nu-generate-carapace-spec"
33+# nu
44+''
55+ # Generates carapace completion spec based on structured command metadata
66+ def main []: string -> string {
77+ $in
88+ | from nuon
99+ | insert flags ($in.params
1010+ | each { [
1111+ ($in.name
1212+ | parse --regex '^(?<full>--\w*)(?:\s*\((?<abbr>-\w*)\))?'
1313+ | first
1414+ | select abbr full | values
1515+ | where { is-not-empty }
1616+ | str join ', ')
1717+ $in.description
1818+ ] }
1919+ | into record)
2020+ | select name description flags
2121+ | to yaml
2222+ }
2323+''
+33
nix/scripts/nu-generate-manpage.nix
···11+{
22+ self',
33+ lib,
44+ pkgs,
55+ ...
66+}: let
77+ inherit (self'.legacyPackages.scripts) nu-parse-help;
88+in
99+ pkgs.writeNuScriptStdinBin "nu-generate-manpage"
1010+ # nu
1111+ ''
1212+ # Converts the output of nu --help to a crude manpage
1313+ def main []: string -> any {
1414+ let sections = $in
1515+ | ${lib.getExe nu-parse-help}
1616+ | from json
1717+ let name = [$sections.name $sections.description]
1818+ | filter { $in != "" }
1919+ | str join " - "
2020+ let flags = $sections.flags
2121+ | each { $"\t($in.switches)\n\t\t($in.description)" }
2222+ | str join "\n";
2323+2424+ $"($sections.name | str upcase)\(1)
2525+2626+ NAME
2727+ \t($name)
2828+2929+ OPTIONS
3030+ ($flags)
3131+ "
3232+ }
3333+ ''
+26
nix/scripts/nu-inspect.nix
···11+{
22+ lib,
33+ pkgs,
44+ ...
55+}:
66+pkgs.writeNuScriptStdinBin "nu-inspect"
77+# nu
88+''
99+ # Outputs structured command data based on nushell script contents
1010+ def main [
1111+ --name: string = "main"
1212+ ]: string -> string {
1313+ $in | save ./tmp.nu
1414+ ${lib.getExe pkgs.nushell} --commands $"
1515+ source './tmp.nu'
1616+1717+ help commands
1818+ | where name == 'main'
1919+ | to nuon
2020+ "
2121+ | from nuon
2222+ | update name $name
2323+ | first
2424+ | to nuon
2525+ }
2626+''
+66
nix/scripts/nu-parse-help.nix
···11+{
22+ self',
33+ lib,
44+ pkgs,
55+ ...
66+}: let
77+ inherit (self'.legacyPackages.scripts) leastspaces;
88+in
99+ pkgs.writeNuScriptStdinBin "nu-parse-help"
1010+ # nu
1111+ ''
1212+ # Creates a record representation of a command's --help output
1313+ def main []: string -> any {
1414+ let sections = $in
1515+ | split row --regex "\n\n"
1616+ | where { str trim | $in != "" }
1717+ | each {
1818+ parse --regex '^(?<header>[^:]+:)?\n?(?<contents>.*(?:\n.*)*)?'
1919+ | update header { default "" | str replace --regex ':$' "" | str downcase }
2020+ | update contents { ${lib.getExe leastspaces} }
2121+ }
2222+ | where { $in.header != "" or $in.content != "" }
2323+ | flatten
2424+ let description = $sections
2525+ | where header == ""
2626+ | first
2727+ | safeget contents ""
2828+ let usage = $sections
2929+ | where header =~ usage
3030+ | first
3131+ | safeget contents ""
3232+ | str substring 2..
3333+ let name = $usage
3434+ | parse --regex '(?<name>\w*) .*'
3535+ | first
3636+ | safeget name ""
3737+ let flags = $sections
3838+ | where header =~ flags
3939+ | first
4040+ | safeget contents ""
4141+ | split row "\n"
4242+ | each {
4343+ split row ": "
4444+ | {
4545+ switches: $in.0
4646+ description: $in.1
4747+ }}
4848+4949+ {
5050+ name: $name
5151+ description: $description
5252+ usage: $usage
5353+ flags: $flags
5454+ }
5555+ | to json
5656+ }
5757+5858+ def safeget [
5959+ field: string
6060+ default: string
6161+ ]: record -> string {
6262+ $in
6363+ | get --ignore-errors $field
6464+ | default $default
6565+ }
6666+ ''