diff options
Diffstat (limited to 'mut')
| -rw-r--r-- | mut/nushell/config.nu | 914 | ||||
| -rw-r--r-- | mut/nushell/env.nu | 117 | ||||
| -rw-r--r-- | mut/nushell/login.nu | 14 | ||||
| -rw-r--r-- | mut/nushell/scripts/task.nu | 434 |
4 files changed, 1479 insertions, 0 deletions
diff --git a/mut/nushell/config.nu b/mut/nushell/config.nu new file mode 100644 index 0000000..d62e610 --- /dev/null +++ b/mut/nushell/config.nu @@ -0,0 +1,914 @@ +if ($env | default "" DOCKER_NAME | get DOCKER_NAME | is-empty) { + pnsh-nvim +} +# Nushell Config File +# +# version = "0.99.1" + +# For more information on defining custom themes, see +# https://www.nushell.sh/book/coloring_and_theming.html +# And here is the theme collection +# https://github.com/nushell/nu_scripts/tree/main/themes +let dark_theme = { + # color for nushell primitives + separator: white + leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off + header: green_bold + empty: blue + # Closures can be used to choose colors for specific values. + # The value (in this case, a bool) is piped into the closure. + # eg) {|| if $in { 'light_cyan' } else { 'light_gray' } } + bool: light_cyan + int: white + filesize: cyan + duration: white + date: purple + range: white + float: white + string: white + nothing: white + binary: white + cell-path: white + row_index: green_bold + record: white + list: white + block: white + hints: dark_gray + search_result: { bg: red fg: white } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_yellow_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + # shapes are used to change the cli syntax highlighting + shape_garbage: { fg: white bg: red attr: b } + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple +} + +let light_theme = { + # color for nushell primitives + separator: dark_gray + leading_trailing_space_bg: { attr: n } # no fg, no bg, attr none effectively turns this off + header: green_bold + empty: blue + # Closures can be used to choose colors for specific values. + # The value (in this case, a bool) is piped into the closure. + # eg) {|| if $in { 'dark_cyan' } else { 'dark_gray' } } + bool: dark_cyan + int: dark_gray + filesize: cyan_bold + duration: dark_gray + date: purple + range: dark_gray + float: dark_gray + string: dark_gray + nothing: dark_gray + binary: dark_gray + cell-path: dark_gray + row_index: green_bold + record: dark_gray + list: dark_gray + block: dark_gray + hints: dark_gray + search_result: { fg: white bg: red } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_purple_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + # shapes are used to change the cli syntax highlighting + shape_garbage: { fg: white bg: red attr: b } + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple +} + +# The default config record. This is where much of your global configuration is setup. +$env.config = { + show_banner: true # true or false to enable or disable the welcome banner at startup + + ls: { + use_ls_colors: true # use the LS_COLORS environment variable to colorize output + clickable_links: true # enable or disable clickable links. Your terminal has to support links. + } + + rm: { + always_trash: false # always act as if -t was given. Can be overridden with -p + } + + table: { + mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other + index_mode: always # "always" show indexes, "never" show indexes, "auto" = show indexes when a table has "index" column + show_empty: true # show 'empty list' and 'empty record' placeholders for command output + padding: { left: 1, right: 1 } # a left right padding of each column in a table + trim: { + methodology: wrapping # wrapping or truncating + wrapping_try_keep_words: true # A strategy used by the 'wrapping' methodology + truncating_suffix: "..." # A suffix used by the 'truncating' methodology + } + header_on_separator: false # show header text on separator/border line + # abbreviated_row_count: 10 # limit data rows from top and bottom after reaching a set point + } + + error_style: "fancy" # "fancy" or "plain" for screen reader-friendly error messages + + # Whether an error message should be printed if an error of a certain kind is triggered. + display_errors: { + exit_code: false # assume the external command prints an error message + # Core dump errors are always printed, and SIGPIPE never triggers an error. + # The setting below controls message printing for termination by all other signals. + termination_signal: true + } + + # datetime_format determines what a datetime rendered in the shell would look like. + # Behavior without this configuration point will be to "humanize" the datetime display, + # showing something like "a day ago." + datetime_format: { + # normal: '%a, %d %b %Y %H:%M:%S %z' # shows up in displays of variables or other datetime's outside of tables + # 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 + } + + explore: { + status_bar_background: { fg: "#1D1F21", bg: "#C4C9C6" }, + command_bar_text: { fg: "#C4C9C6" }, + highlight: { fg: "black", bg: "yellow" }, + status: { + error: { fg: "white", bg: "red" }, + warn: {} + info: {} + }, + selected_cell: { bg: light_blue }, + } + + history: { + max_size: 100_000 # Session has to be reloaded for this to take effect + sync_on_enter: true # Enable to share history between multiple sessions, else you have to close the session to write history to file + file_format: "plaintext" # "sqlite" or "plaintext" + 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. + } + + completions: { + case_sensitive: false # set to true to enable case-sensitive completions + quick: true # set this to false to prevent auto-selecting completions when only one remains + partial: true # set this to false to prevent partial filling of the prompt + algorithm: "prefix" # prefix or fuzzy + sort: "smart" # "smart" (alphabetical for prefix matching, fuzzy score for fuzzy matching) or "alphabetical" + external: { + 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 + max_results: 100 # setting it lower can improve completion performance at the cost of omitting some options + completer: null # check 'carapace_completer' above as an example + } + use_ls_colors: true # set this to true to enable file/path/directory completions using LS_COLORS + } + + filesize: { + metric: false # true => KB, MB, GB (ISO standard), false => KiB, MiB, GiB (Windows standard) + format: "auto" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, auto + } + + cursor_shape: { + emacs: line # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (line is the default) + vi_insert: block # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (block is the default) + vi_normal: underscore # block, underscore, line, blink_block, blink_underscore, blink_line, inherit to skip setting cursor shape (underscore is the default) + } + + color_config: $dark_theme # if you want a more interesting theme, you can replace the empty record with `$dark_theme`, `$light_theme` or another custom record + footer_mode: 25 # always, never, number_of_rows, auto + float_precision: 2 # the precision for displaying floats in tables + buffer_editor: null # command that will be used to edit the current line buffer with ctrl+o, if unset fallback to $env.EDITOR and $env.VISUAL + use_ansi_coloring: true + bracketed_paste: true # enable bracketed paste, currently useless on windows + edit_mode: emacs # emacs, vi + shell_integration: { + # osc2 abbreviates the path if in the home_dir, sets the tab/window title, shows the running command in the tab/window title + osc2: true + # osc7 is a way to communicate the path to the terminal, this is helpful for spawning new tabs in the same directory + osc7: true + # 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 + osc8: true + # 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 + osc9_9: false + # osc133 is several escapes invented by Final Term which include the supported ones below. + # 133;A - Mark prompt start + # 133;B - Mark prompt end + # 133;C - Mark pre-execution + # 133;D;exit - Mark execution finished with exit code + # 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 + osc133: true + # osc633 is closely related to osc133 but only exists in visual studio code (vscode) and supports their shell integration features + # 633;A - Mark prompt start + # 633;B - Mark prompt end + # 633;C - Mark pre-execution + # 633;D;exit - Mark execution finished with exit code + # 633;E - Explicitly set the command line with an optional nonce + # 633;P;Cwd=<path> - Mark the current working directory and communicate it to the terminal + # and also helps with the run recent menu in vscode + osc633: true + # reset_application_mode is escape \x1b[?1l and was added to help ssh work better + reset_application_mode: true + } + 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. + use_kitty_protocol: false # enables keyboard enhancement protocol implemented by kitty console, only if your terminal support this. + highlight_resolved_externals: false # true enables highlighting of external commands in the repl resolved by which. + recursion_limit: 50 # the maximum number of times nushell allows recursion before stopping it + + plugins: {} # Per-plugin configuration. See https://www.nushell.sh/contributor-book/plugins.html#configuration. + + plugin_gc: { + # Configuration for plugin garbage collection + default: { + enabled: true # true to enable stopping of inactive plugins + stop_after: 10sec # how long to wait after a plugin is inactive to stop it + } + plugins: { + # alternate configuration for specific plugins, by name, for example: + # + # gstat: { + # enabled: false + # } + } + } + + hooks: { + pre_prompt: [{ null }] # run before the prompt is shown + pre_execution: [{ null }] # run before the repl input is run + env_change: { + PWD: [{|before, after| null }] # run if the PWD environment is different since the last repl input + } + display_output: "if (term size).columns >= 100 { table -e } else { table }" # run to display the output of a pipeline + command_not_found: { null } # return an error message when a command is not found + } + + menus: [ + # Configuration for default nushell menus + # Note the lack of source parameter + { + name: completion_menu + only_buffer_difference: false + marker: "| " + type: { + layout: columnar + columns: 4 + col_width: 20 # Optional value. If missing all the screen width is used to calculate column width + col_padding: 2 + } + style: { + text: green + selected_text: { attr: r } + description_text: yellow + match_text: { attr: u } + selected_match_text: { attr: ur } + } + } + { + name: ide_completion_menu + only_buffer_difference: false + marker: "| " + type: { + layout: ide + min_completion_width: 0, + max_completion_width: 50, + max_completion_height: 10, # will be limited by the available lines in the terminal + padding: 0, + border: true, + cursor_offset: 0, + description_mode: "prefer_right" + min_description_width: 0 + max_description_width: 50 + max_description_height: 10 + description_offset: 1 + # If true, the cursor pos will be corrected, so the suggestions match up with the typed text + # + # C:\> str + # str join + # str trim + # str split + correct_cursor_pos: false + } + style: { + text: green + selected_text: { attr: r } + description_text: yellow + match_text: { attr: u } + selected_match_text: { attr: ur } + } + } + { + name: history_menu + only_buffer_difference: true + marker: "? " + type: { + layout: list + page_size: 10 + } + style: { + text: green + selected_text: green_reverse + description_text: yellow + } + } + { + name: help_menu + only_buffer_difference: true + marker: "? " + type: { + layout: description + columns: 4 + col_width: 20 # Optional value. If missing all the screen width is used to calculate column width + col_padding: 2 + selection_rows: 4 + description_rows: 10 + } + style: { + text: green + selected_text: green_reverse + description_text: yellow + } + } + ] + + keybindings: [ + { + name: completion_menu + modifier: none + keycode: tab + mode: [emacs vi_normal vi_insert] + event: { + until: [ + { send: menu name: completion_menu } + { send: menunext } + { edit: complete } + ] + } + } + { + name: completion_previous_menu + modifier: shift + keycode: backtab + mode: [emacs, vi_normal, vi_insert] + event: { send: menuprevious } + } + { + name: ide_completion_menu + modifier: control + keycode: space + mode: [emacs vi_normal vi_insert] + event: { + until: [ + { send: menu name: ide_completion_menu } + { send: menunext } + { edit: complete } + ] + } + } + { + name: history_menu + modifier: control + keycode: char_r + mode: [emacs, vi_insert, vi_normal] + event: { send: menu name: history_menu } + } + { + name: help_menu + modifier: none + keycode: f1 + mode: [emacs, vi_insert, vi_normal] + event: { send: menu name: help_menu } + } + { + name: next_page_menu + modifier: control + keycode: char_x + mode: emacs + event: { send: menupagenext } + } + { + name: undo_or_previous_page_menu + modifier: control + keycode: char_z + mode: emacs + event: { + until: [ + { send: menupageprevious } + { edit: undo } + ] + } + } + { + name: escape + modifier: none + keycode: escape + mode: [emacs, vi_normal, vi_insert] + event: { send: esc } # NOTE: does not appear to work + } + { + name: cancel_command + modifier: control + keycode: char_c + mode: [emacs, vi_normal, vi_insert] + event: { send: ctrlc } + } + { + name: quit_shell + modifier: control + keycode: char_d + mode: [emacs, vi_normal, vi_insert] + event: { send: ctrld } + } + { + name: clear_screen + modifier: control + keycode: char_l + mode: [emacs, vi_normal, vi_insert] + event: { send: clearscreen } + } + { + name: search_history + modifier: control + keycode: char_q + mode: [emacs, vi_normal, vi_insert] + event: { send: searchhistory } + } + { + name: open_command_editor + modifier: control + keycode: char_o + mode: [emacs, vi_normal, vi_insert] + event: { send: openeditor } + } + { + name: move_up + modifier: none + keycode: up + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: menuup } + { send: up } + ] + } + } + { + name: move_down + modifier: none + keycode: down + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: menudown } + { send: down } + ] + } + } + { + name: move_left + modifier: none + keycode: left + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: menuleft } + { send: left } + ] + } + } + { + name: move_right_or_take_history_hint + modifier: none + keycode: right + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: historyhintcomplete } + { send: menuright } + { send: right } + ] + } + } + { + name: move_one_word_left + modifier: control + keycode: left + mode: [emacs, vi_normal, vi_insert] + event: { edit: movewordleft } + } + { + name: move_one_word_right_or_take_history_hint + modifier: control + keycode: right + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: historyhintwordcomplete } + { edit: movewordright } + ] + } + } + { + name: move_to_line_start + modifier: none + keycode: home + mode: [emacs, vi_normal, vi_insert] + event: { edit: movetolinestart } + } + { + name: move_to_line_start + modifier: control + keycode: char_a + mode: [emacs, vi_normal, vi_insert] + event: { edit: movetolinestart } + } + { + name: move_to_line_end_or_take_history_hint + modifier: none + keycode: end + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: historyhintcomplete } + { edit: movetolineend } + ] + } + } + { + name: move_to_line_end_or_take_history_hint + modifier: control + keycode: char_e + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: historyhintcomplete } + { edit: movetolineend } + ] + } + } + { + name: move_to_line_start + modifier: control + keycode: home + mode: [emacs, vi_normal, vi_insert] + event: { edit: movetolinestart } + } + { + name: move_to_line_end + modifier: control + keycode: end + mode: [emacs, vi_normal, vi_insert] + event: { edit: movetolineend } + } + { + name: move_down + modifier: control + keycode: char_n + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: menudown } + { send: down } + ] + } + } + { + name: move_up + modifier: control + keycode: char_p + mode: [emacs, vi_normal, vi_insert] + event: { + until: [ + { send: menuup } + { send: up } + ] + } + } + { + name: delete_one_character_backward + modifier: none + keycode: backspace + mode: [emacs, vi_insert] + event: { edit: backspace } + } + { + name: delete_one_word_backward + modifier: control + keycode: backspace + mode: [emacs, vi_insert] + event: { edit: backspaceword } + } + { + name: delete_one_character_forward + modifier: none + keycode: delete + mode: [emacs, vi_insert] + event: { edit: delete } + } + { + name: delete_one_character_forward + modifier: control + keycode: delete + mode: [emacs, vi_insert] + event: { edit: delete } + } + { + name: delete_one_character_backward + modifier: control + keycode: char_h + mode: [emacs, vi_insert] + event: { edit: backspace } + } + { + name: delete_one_word_backward + modifier: control + keycode: char_w + mode: [emacs, vi_insert] + event: { edit: backspaceword } + } + { + name: move_left + modifier: none + keycode: backspace + mode: vi_normal + event: { edit: moveleft } + } + { + name: newline_or_run_command + modifier: none + keycode: enter + mode: emacs + event: { send: enter } + } + { + name: move_left + modifier: control + keycode: char_b + mode: emacs + event: { + until: [ + { send: menuleft } + { send: left } + ] + } + } + { + name: move_right_or_take_history_hint + modifier: control + keycode: char_f + mode: emacs + event: { + until: [ + { send: historyhintcomplete } + { send: menuright } + { send: right } + ] + } + } + { + name: redo_change + modifier: control + keycode: char_g + mode: emacs + event: { edit: redo } + } + { + name: undo_change + modifier: control + keycode: char_z + mode: emacs + event: { edit: undo } + } + { + name: paste_before + modifier: control + keycode: char_y + mode: emacs + event: { edit: pastecutbufferbefore } + } + { + name: cut_word_left + modifier: control + keycode: char_w + mode: emacs + event: { edit: cutwordleft } + } + { + name: cut_line_to_end + modifier: control + keycode: char_k + mode: emacs + event: { edit: cuttolineend } + } + { + name: cut_line_from_start + modifier: control + keycode: char_u + mode: emacs + event: { edit: cutfromstart } + } + { + name: swap_graphemes + modifier: control + keycode: char_t + mode: emacs + event: { edit: swapgraphemes } + } + { + name: move_one_word_left + modifier: alt + keycode: left + mode: emacs + event: { edit: movewordleft } + } + { + name: move_one_word_right_or_take_history_hint + modifier: alt + keycode: right + mode: emacs + event: { + until: [ + { send: historyhintwordcomplete } + { edit: movewordright } + ] + } + } + { + name: move_one_word_left + modifier: alt + keycode: char_b + mode: emacs + event: { edit: movewordleft } + } + { + name: move_one_word_right_or_take_history_hint + modifier: alt + keycode: char_f + mode: emacs + event: { + until: [ + { send: historyhintwordcomplete } + { edit: movewordright } + ] + } + } + { + name: delete_one_word_forward + modifier: alt + keycode: delete + mode: emacs + event: { edit: deleteword } + } + { + name: delete_one_word_backward + modifier: alt + keycode: backspace + mode: emacs + event: { edit: backspaceword } + } + { + name: delete_one_word_backward + modifier: alt + keycode: char_m + mode: emacs + event: { edit: backspaceword } + } + { + name: cut_word_to_right + modifier: alt + keycode: char_d + mode: emacs + event: { edit: cutwordright } + } + { + name: upper_case_word + modifier: alt + keycode: char_u + mode: emacs + event: { edit: uppercaseword } + } + { + name: lower_case_word + modifier: alt + keycode: char_l + mode: emacs + event: { edit: lowercaseword } + } + { + name: capitalize_char + modifier: alt + keycode: char_c + mode: emacs + event: { edit: capitalizechar } + } + # The following bindings with `*system` events require that Nushell has + # been compiled with the `system-clipboard` feature. + # If you want to use the system clipboard for visual selection or to + # paste directly, uncomment the respective lines and replace the version + # using the internal clipboard. + { + name: copy_selection + modifier: control_shift + keycode: char_c + mode: emacs + event: { edit: copyselection } + # event: { edit: copyselectionsystem } + } + { + name: cut_selection + modifier: control_shift + keycode: char_x + mode: emacs + event: { edit: cutselection } + # event: { edit: cutselectionsystem } + } + # { + # name: paste_system + # modifier: control_shift + # keycode: char_v + # mode: emacs + # event: { edit: pastesystem } + # } + { + name: select_all + modifier: control_shift + keycode: char_a + mode: emacs + event: { edit: selectall } + } + ] +} + +if ($"($env.HOME)/.cache/wal/sequences" | path exists) { ^cat ~/.cache/wal/sequences } +source ~/.cache/zoxide.nu +if ($"($env.HOME)/.cache/starship.nu" | path exists) { source ~/.cache/starship.nu } +if ($"($env.HOME)/.cache/carapace.nu" | path exists) { source ~/.cache/carapace.nu } + +$env.K9S_DEFAULT_PF_ADDRESS = "0.0.0.0" +$env.config.show_banner = false + +alias p = pnsh-nvim +alias k = kubectl +alias d = docker +alias t = terraform + +let pistarchio_dir = $"($env.HOME)/Programming/Pionative/pistarchio" +$env.PISTARCHIO_STACKS_DIR = $pistarchio_dir + "/stacks" +$env.PISTARCHIO_LIBRARY_DIR = $pistarchio_dir + "/library" +$env.PISTARCHIO_VENDOR_DESTINATION_DIR = $pistarchio_dir + "/../clients" diff --git a/mut/nushell/env.nu b/mut/nushell/env.nu new file mode 100644 index 0000000..e158cc8 --- /dev/null +++ b/mut/nushell/env.nu @@ -0,0 +1,117 @@ +# Nushell Environment Config File +# +# version = "0.99.1" + +def create_left_prompt [] { + let dir = match (do --ignore-errors { $env.PWD | path relative-to $nu.home-path }) { + null => $env.PWD + '' => '~' + $relative_pwd => ([~ $relative_pwd] | path join) + } + + let path_color = (if (is-admin) { ansi red_bold } else { ansi green_bold }) + let separator_color = (if (is-admin) { ansi light_red_bold } else { ansi light_green_bold }) + let path_segment = $"($path_color)($dir)(ansi reset)" + + $path_segment | str replace --all (char path_sep) $"($separator_color)(char path_sep)($path_color)" +} + +def create_right_prompt [] { + # create a right prompt in magenta with green separators and am/pm underlined + let time_segment = ([ + (ansi reset) + (ansi magenta) + (date now | format date '%x %X') # try to respect user's locale + ] | str join | str replace --regex --all "([/:])" $"(ansi green)${1}(ansi magenta)" | + str replace --regex --all "([AP]M)" $"(ansi magenta_underline)${1}") + + let last_exit_code = if ($env.LAST_EXIT_CODE != 0) {([ + (ansi rb) + ($env.LAST_EXIT_CODE) + ] | str join) + } else { "" } + + ([$last_exit_code, (char space), $time_segment] | str join) +} + +# Use nushell functions to define your right and left prompt +$env.PROMPT_COMMAND = {|| create_left_prompt } +# FIXME: This default is not implemented in rust code as of 2023-09-08. +$env.PROMPT_COMMAND_RIGHT = {|| create_right_prompt } + +# The prompt indicators are environmental variables that represent +# the state of the prompt +$env.PROMPT_INDICATOR = {|| "> " } +$env.PROMPT_INDICATOR_VI_INSERT = {|| ": " } +$env.PROMPT_INDICATOR_VI_NORMAL = {|| "> " } +$env.PROMPT_MULTILINE_INDICATOR = {|| "::: " } + +# If you want previously entered commands to have a different prompt from the usual one, +# you can uncomment one or more of the following lines. +# This can be useful if you have a 2-line prompt and it's taking up a lot of space +# because every command entered takes up 2 lines instead of 1. You can then uncomment +# the line below so that previously entered commands show with a single `🚀`. +# $env.TRANSIENT_PROMPT_COMMAND = {|| "🚀 " } +# $env.TRANSIENT_PROMPT_INDICATOR = {|| "" } +# $env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = {|| "" } +# $env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = {|| "" } +# $env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = {|| "" } +# $env.TRANSIENT_PROMPT_COMMAND_RIGHT = {|| "" } + +# Specifies how environment variables are: +# - converted from a string to a value on Nushell startup (from_string) +# - converted from a value back to a string when running external commands (to_string) +# Note: The conversions happen *after* config.nu is loaded +$env.ENV_CONVERSIONS = { + "PATH": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } + "Path": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } +} + +# Directories to search for scripts when calling source or use +# The default for this is $nu.default-config-dir/scripts +$env.NU_LIB_DIRS = [ + ($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts + ($nu.data-dir | path join 'completions') # default home for nushell completions +] + +# Directories to search for plugin binaries when calling register +# The default for this is $nu.default-config-dir/plugins +$env.NU_PLUGIN_DIRS = [ + ($nu.default-config-dir | path join 'plugins') # add <nushell-config-dir>/plugins +] + +# To add entries to PATH (on Windows you might use Path), you can use the following pattern: +# $env.PATH = ($env.PATH | split row (char esep) | prepend '/some/path') +# An alternate way to add entries to $env.PATH is to use the custom command `path add` +# which is built into the nushell stdlib: +# use std "path add" +# $env.PATH = ($env.PATH | split row (char esep)) +# path add /some/path +# path add ($env.CARGO_HOME | path join "bin") +# path add ($env.HOME | path join ".local" "bin") +# $env.PATH = ($env.PATH | uniq) + +# To load from a custom file you can use: +# source ($nu.default-config-dir | path join 'custom.nu') + +if (which carapace | is-not-empty) { + $env.CARAPACE_BRIDGES = 'zsh,fish,bash,inshellisense' # optional + mkdir ~/.cache/carapace + carapace _carapace nushell | save --force ~/.cache/carapace.nu +} +mkdir ~/.cache/zoxide +zoxide init nushell --cmd=cd | save --force ~/.cache/zoxide.nu +starship init nu | save --force ~/.cache/starship.nu + +if not ("/var/run/docker.sock" | path exists) { + $env.DOCKER_HOST = $"unix://($env | default $"/run/($env.USER)" XDG_RUNTIME_DIR | get XDG_RUNTIME_DIR)/docker.sock" +} + +$env.XDG_CACHE_HOME = $"($env.HOME)/.cache" +$env.XDG_DATA_HOME = $"($env.HOME)/.local/share" diff --git a/mut/nushell/login.nu b/mut/nushell/login.nu new file mode 100644 index 0000000..4ca972e --- /dev/null +++ b/mut/nushell/login.nu @@ -0,0 +1,14 @@ +def load-posix-env [p: string] { + bash -c $"source ($p) && env" + | lines + | parse "{n}={v}" + | filter { |x| ($x.n not-in $env) or $x.v != ($env | get $x.n) } + | where n not-in ["_", "LAST_EXIT_CODE", "DIRS_POSITION"] + | transpose --header-row + | into record + | load-env +} + +load-posix-env /etc/profile +# load-posix-env $"($env.HOME)/.profile" +$env.PATH = $env.PATH ++ [$"($env.HOME)/.local/bin"] diff --git a/mut/nushell/scripts/task.nu b/mut/nushell/scripts/task.nu new file mode 100644 index 0000000..6c7968b --- /dev/null +++ b/mut/nushell/scripts/task.nu @@ -0,0 +1,434 @@ +# Spawn a task to run in the background, even when the shell is closed. +# +# Note that a fresh Nushell interpreter is spawned to execute the +# given task, so it won't inherit the current scope's variables, +# custom commands and alias definitions. +# +# It will only inherit environment variables which can be converted to a string. +# +# Note that the closure can't take arguments. +# +# Example usage: task spawn { echo "Hello, World!" } +export def spawn [ + command: closure # The closure to run. + --working-directory (-w): directory # Specify the working directory the task will be run in. + --immediate (-i) # Immediately start the task. + --stashed (-s) # Create the task in Stashed state. Useful to avoid immediate execution if the queue is empty + --delay (-d): duration # Queue the task for execution only after the duration. + --group (-g): string # The group to spawn the task under. + --after (-a): int # Start the task once all specified tasks have successfully finished. As soon as one of the dependencies fails, this task will fail as well. + --priority (-o): string # Start this task with a higher priority. The higher the number, the faster it will be processed. + --label (-l): string # Label the task. This string will be shown in the `status` column of `task status`. +] -> int { + mut args = [] + + if $working_directory != null { + $args = ($args | prepend ["--working-directory", $working_directory]) + } + if $immediate { + $args = ($args | prepend "--immediate") + } + if $stashed { + $args = ($args | prepend "--stashed") + } + if $delay != null { + $args = ($args | prepend ["--delay" ($delay | format duration sec | parse "{secs} {_}" | get 0.secs)]) + } + if $group != null { + $args = ($args | prepend ["--group" $group]) + } + if $after != null { + $args = ($args | prepend ["--after" $after]) + } + if $priority != null { + $args = ($args | prepend ["--priority" $priority]) + } + if $label != null { + $args = ($args | prepend ["--label" $label]) + } + + let source_path = mktemp --tmpdir --suffix "-nu-task" + + ( + view source $command + | str trim --left --char "{" + | str trim --right --char "}" + ) + | save --force $source_path + + (pueue add --print-task-id ...$args $"nu --config '($nu.config-path)' --env-config '($nu.env-path)' ($source_path)") +} + +# Remove tasks from the queue. +# Running or paused tasks need to be killed first. +export def remove [ + ...ids: int # IDs of the tasks to remove from the status list. +] { + pueue remove ...$ids +} + +# Switches the queue position of two tasks. +# Only works for queued or stashed tasks. +export def switch [ + task_id_1: int # The first task ID. + task_id_2: int # The second task ID. +] { + pueue switch $task_id_1 $task_id_2 +} + +# Stash a task that is not currently running. +# +# Stashed tasks won't be automatically started. +# You will have to queue them or start them by hand. +export def stash [ + ...ids: int # IDs of the tasks to stash. +] { + pueue stash ...$ids +} + +# Queue stashed tasks for execution. +export def queue [ + ...ids: int # IDs of the tasks to queue. + --delay (-d): duration # Queue only after the specified delay. +] { + let args = if $delay != null { + ["--delay" ($delay | format duration sec | parse '{secs} {_}' | get 0.secs)] + } else { + [] + } + + pueue enqueue ...$args ...$ids +} + +# Resume operation of specific tasks or groups of tasks. +# +# By default, this resumes the default group and all its tasks. +# It can also be used force-start specific tasks or start whole groups. +export def start [ + ...ids: int # IDs of the tasks to start. By default all the tasks in the default group will be started. + --group (-g): string # Resume a specific group and all paused tasks in it. The group will be set to running and its paused tasks will be resumed. + --all (-a) # Resume all groups. All groups will be set to running and paused tasks will be resumed. +] { + mut args = [] + + if $group != null { + $args = ($args | prepend ["--group" $group]) + } + if $all { + $args = ($args | prepend "--all") + } + + pueue start ...$args +} + +# Restart failed or successful task(s). +# +# By default, identical tasks will be created and +# enqueued, but it's possible to restart in-place. +# +# You can also edit a few properties, such as +# the path and the command of the task, before restarting. +export def restart [ + ...ids: int # IDs of the tasks to restart. + --all-failed (-a) # Restart all failed tasks across all groups. Nice to use in combination with `--in-place/i`. + --failed-in-group (-g): string # Like `--all-failed`, but only restart tasks failed tasks of a specific group. The group will be set to running and its paused tasks will be resumed. + --start-immediately (-k) # Immediately start the tasks, no matter how many open slots there are. This will ignore any dependencies tasks may have. + --stashed (-s) # Set the restarted task to a "Stashed" state. Useful to avoid immediate execution. + --in-place (-i) # Restart the tasks by reusing the already existing tasks. + --not-in-place (-n) # Opposite of `--in-place`. This is already the default unless you have `restart_in_place` set to true. + --edit (-e) # Edit the tasks' commands before restarting + --edit-path (-p) # Edit the tasks' paths before restarting + --edit-label (-l) # Edit the tasks' labels before restarting +] { + mut args = [] + + if $all_failed { + $args = ($args | prepend "--all-failed") + } + if $failed_in_group != null { + $args = ($args | prepend "--failed-in-group") + } + if $start_immediately { + $args = ($args | prepend "--start-immediately") + } + if $stashed { + $args = ($args | prepend "--stashed") + } + if $in_place { + $args = ($args | prepend "--in-place") + } + if $not_in_place { + $args = ($args | prepend "--not-in-place") + } + if $edit { + $args = ($args | prepend "--edit") + } + if $edit_path { + $args = ($args | prepend "--edit-path") + } + if $edit_label { + $args = ($args | prepend "--edit-label") + } + + pueue restart ...$args ...$ids +} + +# Either pause a running tasks or a specific groups of tasks. +# +# By default, pauses the default group and all its tasks. +# +# A paused group won't start any new tasks automatically. +export def pause [ + ...ids: int # IDs of the tasks to pause. + --group (-g) # Pause a specific group + --all (-a) # Pause all groups. + --wait (-w) # Only pause the specified group and let already running tasks finish by themselves +] { + mut args = [] + + if $group != null { + $args = ($args | prepend "--group") + } + if $all != null { + $args = ($args | prepend "--all") + } + if $wait != null { + $args = ($args | prepend "--wait") + } + + pueue pause ...$args ...$ids +} + +# Kill specific running tasks or whole task groups. +# +# Kills all tasks of the default group when no ids or a specific group are provided. +export def kill [ + ...ids: int # IDs of the tasks to kill. + --group (-g): string # Kill all running tasks in a group. This also pauses the group. + --all (-a) # Kill all running tasks across ALL groups. This also pauses all groups. + --signal (-s): string # Send a UNIX signal instead of simply killing the process. DISCLAIMER: This bypasses Pueue's process handling logic! You might enter weird invalid states, use at your own descretion. +] { + mut args = [] + + if $group != null { + $args = ($args | prepend ["--group" $group]) + } + if $all { + $args = ($args | prepend "--all") + } + if $signal != null { + $args = ($args | prepend ["--signal" $signal]) + } + + pueue kill ...$args ...$ids +} + +# Send something to a task. Useful for sending confirmations such as "y\n". +export def send [ + id: int # ID of the task to send something to. + input: string # The input that should be sent to the process. +] { + pueue send $id $input +} + +# Edit the command, path or label of a stashed or queued task. +# +# By default only the command is edited. +# +# Multiple properties can be added in one go. +export def edit [ + id: int # ID of the task to edit. + --command (-c) # Edit the task's command + --path (-p) # Edit the task's path + --label (-l) # Edit the task's label +] { + mut args = [] + + if $command { + $args = ($args | prepend "--command") + } + if $path { + $args = ($args | prepend "--path") + } + if $label { + $args = ($args | prepend "--label") + } + + pueue edit ...$args $id +} + +# Use this to add or remove groups. +# +# By default, this will simply display all known groups. +export def group [] { + pueue group --json | from json +} + +# Create a new group with a name. +export def "group add" [ + name: string # The name of the new group. + --parallel (-p): int # The amount of parallel tasks the group can run at one time. +] { + let args = if $parallel != null { + ["--parallel" $parallel] + } else { + [] + } + + pueue group add ...$args $name +} + +# Remove a group with a name. +export def "group remove" [ + name: string # The name of the group to be removed. +] { + pueue group remove $name +} + +# Display the current status of all tasks. +export def status [ + --detailed (-d) # Return a table with more detailed information. +] { + let output = ( + pueue status --json + | from json + | get tasks + | transpose --ignore-titles status + | flatten + ) + + # TODO: Rename the Done column to done. + if not $detailed { + $output | select id label group Done? status? start? end? + } else { + $output + } +} + +# Display the output of tasks. +# +# Only the last few lines will be shown by default for multiple tasks. +# If you want to follow the output, use `--tail/-t`. +export def log [ + ...ids: int # The tasks to check the outputs of. + --last (-l): int # Only print the last N lines of each task's output. This is done by default if you're looking at multiple tasks. + --tail (-t) # Follow the output as it is printing. Only works with 1 task. When used in conjunction with `--last`, the last N lines will be printed before starting to wait for output. + --detailed (-d) # Include all fields, don't simplify output. +] { + def process_raw [raw: string] { + let full = ( + $raw + | from json + | transpose -i info + | flatten --all + | flatten --all + ) + + if $detailed { + $full + } else { + $full | select id label group Done? status? start? end? + } + } + + if (($ids | length) == 1) { + if $tail { + let args = if $last != null { + ["--lines" $last] + } else { + [] + } + + pueue follow ...$ids + } else { + let args = if $last != null { + ["--lines" $last] + } else { + [] + } + + process_raw (pueue log --full --json ...$args ...$ids) + | first + } + } else { + if $tail { + echo $"(ansi red)--tail can only be used with one task.(ansi reset)" + return + } + + let args = if $last != null { + ["--lines" $last] + } else { + [] + } + + process_raw (pueue log --full --json ...$args ...$ids) + } +} + +# Wait until the provided tasks are finished. +# +# This is like join() or await in many languages. +export def wait [ + ...ids: int # IDs of the tasks to wait for. + --group (-g): string # Wait for all tasks in a specific group. + --all (-a) # Wait for all tasks across all groups and the default group. + --quiet (-q) # Don't show any log output while waiting. + --status (-s): string # Wait for tasks to reach a specific task status. +] { + mut args = [] + + if $group != null { + $args = ($args | prepend ["--group" $group]) + } + if $all { + $args = ($args | prepend $all) + } + if $quiet { + $args = ($args | prepend $quiet) + } + if $status != null { + $args = ($args | prepend ["--status" $status]) + } + + pueue wait ...$args ...$ids +} + +# Remove tasks from the status list. +export def clean [ + --successful-only (-s) # Only clean tasks that finished successfully + --group (-g): string # Only clean tasks of a specific group +] { + mut args = [] + + if $successful_only { + $args = ($args | prepend "--successful-only") + } + if $group != null { + $args = ($args | prepend ["--group" $group]) + } + + pueue clean ...$args +} + +# Shutdown pueue and thus this module. +export def shutdown [] { + pueue shutdown +} + +# Set the maximum parallel tasks for a group. +# +# Note that no tasks will be stopped if the number is lowered. +# The limit only applies when schelduing. +export def set-parallel-limit [ + max: int # The maximum parallel tasks allowed for a group when schelduing. + --group (-g): string # The group to set the limit for. By default this is `default`. +] { + let args = if $group != null { + ["--group" $group] + } else { + [] + } + + pueue parallel ...$args $max +} |
