# Nushell Configuration Template # Default configuration for Nushell + Plugins distribution # Created by nushell-plugins full distribution system # ============================================================================= # CORE CONFIGURATION # ============================================================================= $env.config = { # Show banner on startup show_banner: false # Editing mode (emacs, vi) edit_mode: emacs # Shell integration features shell_integration: true # Use ansi coloring use_ansi_coloring: true # Bracketed paste mode bracketed_paste: true # Render right prompt on the last line of the prompt render_right_prompt_on_last_line: false # ============================================================================= # TABLE CONFIGURATION # ============================================================================= table: { # Table rendering mode mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other # Index column mode index_mode: always # always, never, auto # Show empty tables show_empty: true # Table padding padding: { left: 1, right: 1 } # Trim table content trim: { methodology: wrapping # wrapping, truncating wrapping_try_keep_words: true truncating_suffix: "..." } # Header styling header_on_separator: false } # ============================================================================= # ERROR HANDLING # ============================================================================= error_style: "fancy" # fancy, plain # ============================================================================= # DATETIME FORMATTING # ============================================================================= datetime_format: { # Normal datetime format normal: '%a, %d %b %Y %H:%M:%S %z' # Tue, 1 Jan 2023 12:00:00 +0000 # Table datetime format (shorter for table display) table: '%m/%d/%y %I:%M:%S%p' # 01/01/23 12:00:00AM } # ============================================================================= # COMPLETIONS CONFIGURATION # ============================================================================= completions: { # Case sensitivity for completions case_sensitive: false # Quick completions (don't wait for all to be calculated) quick: true # Partial completions (complete common prefix) partial: true # Completion algorithm algorithm: "prefix" # prefix, fuzzy # External completer command external: { enable: true max_results: 100 completer: null } } # ============================================================================= # FILE SIZE FORMATTING # ============================================================================= filesize: { # Use metric units (KB, MB, GB) vs binary (KiB, MiB, GiB) metric: false # Filesize format format: "auto" # auto, b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib } # ============================================================================= # CURSOR SHAPE CONFIGURATION # ============================================================================= cursor_shape: { # Cursor shapes for different modes emacs: line # line, block, underscore, blink_line, blink_block, blink_underscore vi_insert: block vi_normal: underscore } # ============================================================================= # COLOR CONFIGURATION # ============================================================================= color_config: { # Separator color separator: white # Leading trailing space leading_trailing_space_bg: { attr: n } # Header colors header: green_bold # Empty cell empty: blue # Boolean values bool: { true: light_cyan false: light_gray } # Integer types int: white float: white # String and date types string: white date: purple # Duration duration: white # File sizes filesize: { b: white kb: cyan mb: blue gb: green tb: red pb: purple } # Range range: white # Binary binary: cyan_bold # Lists list: white record: white # Nothing nothing: white # Block block: white # Hints hints: dark_gray # Search result search_result: { fg: white bg: red } # Shape colors shape_garbage: { fg: white bg: red attr: b} shape_binary: purple_bold shape_bool: light_cyan shape_int: purple_bold shape_float: purple_bold shape_range: yellow_bold shape_internalcall: cyan_bold shape_external: cyan shape_externalarg: green_bold shape_literal: blue shape_operator: yellow shape_signature: green_bold shape_string: green shape_string_interpolation: cyan_bold shape_datetime: cyan_bold shape_list: cyan_bold shape_table: blue_bold shape_record: cyan_bold shape_block: blue_bold shape_filepath: cyan shape_directory: cyan shape_globpattern: cyan_bold shape_variable: purple shape_flag: blue_bold shape_custom: green shape_nothing: light_cyan shape_matching_brackets: { attr: u } } # ============================================================================= # HISTORY CONFIGURATION # ============================================================================= history: { # Maximum number of history entries max_size: 100_000 # Sync history on enter sync_on_enter: true # History file format file_format: "plaintext" # sqlite, plaintext # Isolation mode isolation: false } # ============================================================================= # KEYBINDINGS # ============================================================================= 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: 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: completion_previous modifier: shift keycode: backtab mode: [emacs, vi_normal, vi_insert] event: { send: menuprevious } } { name: next_page modifier: control keycode: char_x mode: emacs event: { send: menupagenext } } { name: undo_or_previous_page modifier: control keycode: char_z mode: emacs event: { until: [ { send: menupageprevious } { edit: undo } ] } } { name: escape modifier: none keycode: escape mode: [emacs, vi_insert] event: { send: esc } } { name: cancel_command modifier: control keycode: char_c mode: [emacs, vi_insert, vi_normal] event: { send: ctrlc } } { name: quit_shell modifier: control keycode: char_d mode: [emacs, vi_insert, vi_normal] event: { send: ctrld } } { name: clear_screen modifier: control keycode: char_l mode: [emacs, vi_insert, vi_normal] event: { send: clearscreen } } { name: search_history modifier: control keycode: char_q mode: [emacs, vi_insert, vi_normal] event: { send: searchhistory } } { name: open_command_editor modifier: control keycode: char_o mode: [emacs, vi_insert, vi_normal] event: { send: openeditor } } { name: move_up modifier: none keycode: up mode: [emacs, vi_insert, vi_normal] event: { until: [ { send: menuup } { send: up } ] } } { name: move_down modifier: none keycode: down mode: [emacs, vi_insert, vi_normal] event: { until: [ { send: menudown } { send: down } ] } } { name: move_left modifier: none keycode: left mode: [emacs, vi_insert, vi_normal] event: { until: [ { send: menuleft } { send: left } ] } } { name: move_right_or_take_history_hint modifier: none keycode: right mode: [emacs, vi_insert, vi_normal] event: { until: [ { send: historyhintcomplete } { send: menuright } { send: right } ] } } { name: move_one_word_left modifier: control keycode: left mode: [emacs, vi_insert, vi_normal] event: { edit: movewordleft } } { name: move_one_word_right_or_take_history_hint modifier: control keycode: right mode: [emacs, vi_insert, vi_normal] event: { until: [ { send: historyhintwordcomplete } { edit: movewordright } ] } } { name: move_to_line_start modifier: none keycode: home mode: [emacs, vi_insert, vi_normal] event: { edit: movetolinestart } } { name: move_to_line_start_alt modifier: control keycode: char_a mode: [emacs, vi_insert] event: { edit: movetolinestart } } { name: move_to_line_end_or_take_history_hint modifier: none keycode: end mode: [emacs, vi_insert, vi_normal] event: { until: [ { send: historyhintcomplete } { edit: movetolineend } ] } } { name: move_to_line_end_alt modifier: control keycode: char_e mode: [emacs, vi_insert] event: { until: [ { send: historyhintcomplete } { edit: movetolineend } ] } } { name: move_to_line_start_vi modifier: none keycode: char_0 mode: vi_normal event: { edit: movetolinestart } } { name: move_to_line_end_vi modifier: none keycode: char_4 mode: vi_normal event: { edit: movetolineend } } { name: move_up_vi modifier: none keycode: char_k mode: vi_normal event: { send: up } } { name: move_down_vi modifier: none keycode: char_j mode: vi_normal event: { send: down } } { name: backspace modifier: none keycode: backspace mode: [emacs, vi_insert] event: { edit: backspace } } { name: delete_char modifier: none keycode: delete mode: [emacs, vi_insert] event: { edit: delete } } { name: delete_word modifier: control keycode: char_w mode: [emacs, vi_insert] event: { edit: backspaceword } } { name: cut_word_to_right modifier: control keycode: char_k mode: emacs event: { edit: cuttoend } } { name: cut_line_to_right modifier: control keycode: char_k mode: vi_insert event: { edit: cuttoend } } { name: cut_line_from_start modifier: control keycode: char_u mode: [emacs, vi_insert] event: { edit: cutfromstart } } { name: swap_graphemes modifier: control keycode: char_t mode: emacs event: { edit: swapgraphemes } } { name: move_one_word_left_vi modifier: none keycode: char_b mode: vi_normal event: { edit: movewordleft } } { name: move_one_word_right_vi modifier: none keycode: char_w mode: vi_normal event: { edit: movewordright } } { name: move_one_word_right_end_vi modifier: none keycode: char_e mode: vi_normal event: { edit: movewordrightend } } { name: move_one_big_word_left_vi modifier: shift keycode: char_b mode: vi_normal event: { edit: movebigwordleft } } { name: move_one_big_word_right_vi modifier: shift keycode: char_w mode: vi_normal event: { edit: movebigwordright } } { name: move_one_big_word_right_end_vi modifier: shift keycode: char_e mode: vi_normal event: { edit: movebigwordrightend } } { name: delete_one_character_backward_vi modifier: none keycode: char_x mode: vi_normal event: { edit: backspace } } { name: delete_one_word_backward_vi modifier: none keycode: char_X mode: vi_normal event: { edit: backspaceword } } { name: delete_to_end_of_line_vi modifier: shift keycode: char_d mode: vi_normal event: { edit: cuttoend } } { name: delete_line_vi modifier: none keycode: char_dd mode: vi_normal event: { edit: cutline } } { name: change_to_end_of_line_vi modifier: shift keycode: char_c mode: vi_normal event: [ { edit: cuttoend } { edit: insertmode } ] } { name: change_line_vi modifier: none keycode: char_cc mode: vi_normal event: [ { edit: cutline } { edit: insertmode } ] } { name: open_line_above_vi modifier: shift keycode: char_o mode: vi_normal event: [ { edit: insertcharafter } { edit: newline } { edit: moveup } { edit: insertmode } ] } { name: open_line_below_vi modifier: none keycode: char_o mode: vi_normal event: [ { edit: insertcharafter } { edit: newline } { edit: insertmode } ] } { name: enter_vi_insert_mode modifier: none keycode: char_i mode: vi_normal event: { edit: insertmode } } { name: enter_vi_append_mode modifier: none keycode: char_a mode: vi_normal event: [ { edit: moveright } { edit: insertmode } ] } { name: enter_vi_append_mode_at_end_of_line modifier: shift keycode: char_a mode: vi_normal event: [ { edit: movetolineend } { edit: insertmode } ] } { name: enter_vi_insert_mode_at_start_of_line modifier: shift keycode: char_i mode: vi_normal event: [ { edit: movetolinestart } { edit: insertmode } ] } { name: yank_vi modifier: none keycode: char_y mode: vi_normal event: { edit: yank } } { name: yank_to_end_of_line_vi modifier: shift keycode: char_y mode: vi_normal event: { edit: yanktoend } } { name: yank_line_vi modifier: none keycode: char_yy mode: vi_normal event: { edit: yankline } } { name: paste_after_vi modifier: none keycode: char_p mode: vi_normal event: { edit: pasteafter } } { name: paste_before_vi modifier: shift keycode: char_p mode: vi_normal event: { edit: pastebefore } } { name: undo_vi modifier: none keycode: char_u mode: vi_normal event: { edit: undo } } { name: redo_vi modifier: control keycode: char_r mode: vi_normal event: { edit: redo } } { name: enter_vi_normal_mode modifier: none keycode: escape mode: vi_insert event: { edit: normalmode } } ] # ============================================================================= # MENU CONFIGURATION # ============================================================================= menus: [ # Completion menu { name: completion_menu only_buffer_difference: false marker: "| " type: { layout: columnar columns: 4 col_width: 20 col_padding: 2 } style: { text: green selected_text: { attr: r } description_text: yellow match_text: { attr: u } selected_match_text: { attr: ur } } } # History menu { name: history_menu only_buffer_difference: true marker: "? " type: { layout: list page_size: 10 } style: { text: green selected_text: green_reverse description_text: yellow } } # Help menu { name: help_menu only_buffer_difference: true marker: "? " type: { layout: description columns: 4 col_width: 20 col_padding: 2 selection_rows: 4 description_rows: 10 } style: { text: green selected_text: green_reverse description_text: yellow } } ] # ============================================================================= # HOOKS CONFIGURATION # ============================================================================= hooks: { pre_prompt: [ # Update terminal title with current directory {|| print -n $"\e]0;($env.PWD | path basename) - Nushell\e\\" } ] pre_execution: [ # Add timestamp to long-running commands {|| let start_time = (date now | format date '%Y-%m-%d %H:%M:%S') $env.COMMAND_START_TIME = $start_time } ] env_change: { PWD: [ # Auto-activate direnv if available {|before, after| if (which direnv | is-not-empty) { direnv export json | from json | default {} | load-env } } ] } command_not_found: { # Suggest alternatives for command not found |cmd_name| ( try { if (which thefuck | is-not-empty) { $"💡 Did you mean: (thefuck --alias | str trim)" } else { $"❌ Command not found: ($cmd_name)" } } catch { $"❌ Command not found: ($cmd_name)" } ) } display_output: { # Custom output formatting |output| ( if ($output | describe) == "table" { $output | table --expand } else { $output } ) } } # ============================================================================= # PLUGIN CONFIGURATION # ============================================================================= plugins: { # Plugin loading timeout (in seconds) timeout: 60 # Auto-register plugins on startup auto_register: true # Plugin search paths search_paths: [ ($nu.config-path | path dirname | path join "plugins") ] } # ============================================================================= # PERFORMANCE SETTINGS # ============================================================================= # Buffer size for commands buffer_editor: null # Use LSP for completions if available use_lsp: true # Maximum recursion depth recursion_limit: 50 # Plugin call timeout plugin_timeout: 60_000 # milliseconds # ============================================================================= # EXTERNAL INTEGRATIONS # ============================================================================= # Carapace (external completer) carapace: { enable: false cache_dir: ($env.HOME | path join ".cache" "carapace") } # Starship prompt starship: { enable: (which starship | is-not-empty) config: ($nu.config-path | path dirname | path join "starship.toml") } # Zoxide integration zoxide: { enable: (which zoxide | is-not-empty) hook: "pwd" # none, prompt, pwd } # ============================================================================= # DEVELOPMENT AND DEBUG # ============================================================================= # Debug mode debug_mode: false # Log level log_level: "warn" # error, warn, info, debug, trace # Profiling profile: false } # ============================================================================= # PLUGIN LOADING AND REGISTRATION # ============================================================================= # Auto-load common plugins if they're available let plugin_binaries = [ "nu_plugin_clipboard" "nu_plugin_desktop_notifications" "nu_plugin_hashes" "nu_plugin_highlight" "nu_plugin_image" "nu_plugin_kcl" "nu_plugin_tera" "nu_plugin_custom_values" "nu_plugin_example" "nu_plugin_formats" "nu_plugin_gstat" "nu_plugin_inc" "nu_plugin_polars" "nu_plugin_query" ] # Register plugins that are available for plugin in $plugin_binaries { try { # Check if plugin is already registered if (plugin list | where name == $plugin | is-empty) { # Try to find and register the plugin let plugin_path = (which $plugin | get path.0?) if ($plugin_path | is-not-empty) { plugin add $plugin_path } } } catch { # Silently ignore plugin loading errors } } # ============================================================================= # CUSTOM FUNCTIONS AND ALIASES # ============================================================================= # Enhanced ls with better colors and formatting def --env la [...rest] { ls -la $rest | sort-by type name } # Quick directory navigation def --env .. [] { cd .. } def --env ... [] { cd ../.. } def --env .... [] { cd ../../.. } # Git shortcuts (if git is available) if (which git | is-not-empty) { def gs [] { git status --short } def ga [...files] { git add $files } def gc [message: string] { git commit -m $message } def gp [] { git push } def gl [] { git log --oneline -10 } } # System information def sysinfo [] { { OS: $nu.os-info.name Arch: $nu.os-info.arch Version: $nu.os-info.version Kernel: $nu.os-info.kernel_version Hostname: (hostname) Shell: $"Nushell (version)" Plugins: (plugin list | length) Config: $nu.config-path } } # Plugin management helpers def plugin-info [] { plugin list | select name version is_running pid } def plugin-restart [name: string] { plugin stop $name plugin use $name } # Quick file operations def --env take [name: string] { mkdir $name cd $name } def trash [path: string] { if (which trash | is-not-empty) { ^trash $path } else { print $"⚠️ No trash command available, use 'rm ($path)' to delete permanently" } } # Enhanced which command def which-all [command: string] { which -a $command | select path } # ============================================================================= # PROMPT CONFIGURATION # ============================================================================= # Custom prompt function (used if starship is not available) def create_left_prompt [] { let home = $nu.home-path let dir = ([ ($env.PWD | str substring 0..($home | str length) | str replace $home "~") ($env.PWD | str substring ($home | str length)..) ] | str join) let path_color = (if (is-admin) { ansi red_bold } else { ansi green_bold }) let separator_color = (ansi light_gray) let path_segment = $"($path_color)($dir)" # Git information if in a git repo let git_info = if (ls -la | where name == .git | is-not-empty) { try { let branch = (git branch --show-current 2>/dev/null | str trim) if not ($branch | is-empty) { let git_color = ansi yellow $" ($git_color)($branch)(ansi reset)" } else { "" } } catch { "" } } else { "" } $"($path_segment)($git_info)($separator_color) ❯ (ansi reset)" } def create_right_prompt [] { # Show current time and execution duration let time_segment = (date now | format date '%H:%M:%S') let duration = if "COMMAND_START_TIME" in $env { let start = ($env.COMMAND_START_TIME | into datetime) let duration = ((date now) - $start) if ($duration > 1sec) { $" took (ansi yellow)($duration)(ansi reset)" } else { "" } } else { "" } $"(ansi light_gray)($time_segment)($duration)(ansi reset)" } # Set prompt functions if starship is not available if not (which starship | is-not-empty) { $env.PROMPT_COMMAND = { || create_left_prompt } $env.PROMPT_COMMAND_RIGHT = { || create_right_prompt } } # ============================================================================= # STARTUP MESSAGE # ============================================================================= # Uncomment to show welcome message # print $"🚀 Welcome to Nushell + Plugins!" # print $"📦 (plugin list | length) plugins loaded" # print $"💡 Type 'help' for commands or 'sysinfo' for system information" # print "" # ============================================================================= # USER CUSTOMIZATION # ============================================================================= # Load user-specific configuration if it exists let user_config_file = ($nu.config-path | path dirname | path join "user_config.nu") if ($user_config_file | path exists) { source $user_config_file } # Load local project configuration if it exists let local_config_file = (pwd | path join ".nu_config") if ($local_config_file | path exists) { source $local_config_file }