nushell-plugins/scripts/templates/default_config.nu
Jesús Pérez 41455c5b3e
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
feat: Add complete Nushell full distribution system
## 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
2025-09-24 18:52:07 +01:00

1102 lines
30 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
}