
Some checks failed
Build and Test / Validate Setup (push) Has been cancelled
Build and Test / Build (darwin-amd64) (push) Has been cancelled
Build and Test / Build (darwin-arm64) (push) Has been cancelled
Build and Test / Build (linux-amd64) (push) Has been cancelled
Build and Test / Build (windows-amd64) (push) Has been cancelled
Build and Test / Build (linux-arm64) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Package Results (push) Has been cancelled
Build and Test / Quality Gate (push) Has been cancelled
## Major Features Added - **Complete distribution infrastructure**: Build, package, and distribute Nushell binary alongside plugins - **Zero-prerequisite installation**: Bootstrap installers work on fresh systems without Rust/Cargo/Nushell - **Cross-platform support**: Linux, macOS, Windows (x86_64, ARM64) - **Self-contained packages**: Everything needed for complete Nushell environment ## New Components ### Build System - `scripts/build_nushell.nu` - Build nushell with all workspace plugins - `scripts/collect_full_binaries.nu` - Collect nu binary + all plugins - `justfiles/full_distro.just` - 40+ new recipes for distribution workflows ### Bootstrap Installers (Zero Prerequisites) - `installers/bootstrap/install.sh` - Universal POSIX installer (900+ lines) - `installers/bootstrap/install.ps1` - Windows PowerShell installer (800+ lines) - Complete platform detection, PATH setup, plugin registration ### Distribution System - `scripts/create_distribution_packages.nu` - Multi-platform package creator - `scripts/install_full_nushell.nu` - Advanced nu-based installer - `scripts/verify_installation.nu` - Installation verification suite - `scripts/lib/common_lib.nu` - Shared utilities and logging ### Configuration Management - `scripts/templates/default_config.nu` - Complete nushell configuration (500+ lines) - `scripts/templates/default_env.nu` - Cross-platform environment setup - `etc/distribution_config.toml` - Central distribution settings - `scripts/templates/uninstall.sh` & `uninstall.ps1` - Clean removal ## Key Workflows ```bash just build-full # Build nushell + all plugins just pack-full-all # Create packages for all platforms just verify-full # Verify installation just release-full-cross # Complete cross-platform release ``` ## Installation Experience - One-liner: `curl -sSf https://your-url/install.sh | sh` - Multiple modes: user, system, portable installation - Automatic plugin registration with verification - Professional uninstall capability ## Benefits - ✅ Solves bootstrap problem - no prerequisites needed - ✅ Production-ready distribution system - ✅ Complete cross-platform support - ✅ Professional installation experience - ✅ Integrates seamlessly with existing plugin workflows - ✅ Enterprise-grade verification and logging
1102 lines
30 KiB
Plaintext
1102 lines
30 KiB
Plaintext
# 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
|
||
} |