0
# Configuration
1
2
## Overview
3
4
Xonsh provides extensive configuration through environment variables, aliases, and xontribs (extensions). The environment system enhances standard environment variables with type validation, conversion functions, and event-driven updates. Configuration can be managed through the interactive shell, configuration files, or programmatically.
5
6
## Environment Management
7
8
### Environment Class
9
```python { .api }
10
from xonsh.environ import Env
11
from xonsh.built_ins import XSH
12
13
class Env:
14
"""Enhanced environment variable management."""
15
16
def __init__(self, **kwargs):
17
"""Initialize environment.
18
19
Parameters
20
----------
21
**kwargs
22
Initial environment variables
23
"""
24
25
def __getitem__(self, key: str) -> object:
26
"""Get environment variable value.
27
28
Parameters
29
----------
30
key : str
31
Variable name
32
33
Returns
34
-------
35
object
36
Variable value (type-converted)
37
"""
38
39
def __setitem__(self, key: str, value: object) -> None:
40
"""Set environment variable.
41
42
Parameters
43
----------
44
key : str
45
Variable name
46
value : object
47
Variable value (will be type-validated)
48
"""
49
50
def get(self, key: str, default=None) -> object:
51
"""Get environment variable with default.
52
53
Parameters
54
----------
55
key : str
56
Variable name
57
default : object, optional
58
Default value if key not found
59
60
Returns
61
-------
62
object
63
Variable value or default
64
"""
65
66
def setdefault(self, key: str, default: object) -> object:
67
"""Set default value if key doesn't exist.
68
69
Parameters
70
----------
71
key : str
72
Variable name
73
default : object
74
Default value to set
75
76
Returns
77
-------
78
object
79
Existing or newly set value
80
"""
81
82
def swap(self, **kwargs):
83
"""Context manager for temporary environment changes.
84
85
Parameters
86
----------
87
**kwargs
88
Temporary variable assignments
89
90
Returns
91
-------
92
contextmanager
93
Context manager for temporary changes
94
"""
95
96
# Environment usage examples
97
env = XSH.env
98
99
# Basic variable access
100
home = env['HOME']
101
path = env.get('PATH', '')
102
103
# Type-converted variables
104
debug = env['XONSH_DEBUG'] # Auto-converts to bool
105
history_size = env['HISTSIZE'] # Auto-converts to int
106
107
# Temporary environment changes
108
with env.swap(DEBUG=True, VERBOSE=1):
109
# Code runs with temporary environment
110
print(f"Debug mode: {env['DEBUG']}")
111
# Environment restored after context
112
```
113
114
### Key Environment Variables
115
```python { .api }
116
from xonsh.built_ins import XSH
117
118
env = XSH.env
119
120
# Shell behavior
121
env['SHELL_TYPE'] = 'prompt_toolkit' # Shell backend ('prompt_toolkit', 'readline', 'dumb')
122
env['XONSH_SHOW_TRACEBACK'] = True # Show Python tracebacks on errors
123
env['XONSH_STORE_STDOUT'] = False # Store command output in history
124
env['XONSH_DEBUG'] = 0 # Debug level (0-2)
125
126
# Prompt configuration
127
env['PROMPT'] = '{cwd} $ ' # Primary prompt format
128
env['MULTILINE_PROMPT'] = ' ' # Continuation prompt
129
env['TITLE'] = '{user}@{hostname}: {cwd}' # Terminal title format
130
131
# History settings
132
env['HISTSIZE'] = 8128 # Number of commands to store
133
env['HISTFILE'] = '~/.xonsh_history' # History file location
134
env['XONSH_HISTORY_BACKEND'] = 'json' # History storage backend
135
136
# Completion configuration
137
env['CASE_SENSITIVE_COMPLETIONS'] = False # Case sensitivity for completions
138
env['COMPLETIONS_CONFIRM'] = True # Confirm ambiguous completions
139
env['COMPLETION_QUERY_LIMIT'] = 100 # Max completions to show
140
env['COMPLETIONS_DISPLAY_VALUE'] = 'single' # Completion display mode
141
env['COMPLETIONS_MENU_ROWS'] = 5 # Completion menu height
142
143
# Subprocess behavior
144
env['RAISE_SUBPROC_ERROR'] = False # Raise exceptions on command failure
145
env['XONSH_SUBPROC_CAPTURED_PRINT_STDERR'] = True # Print captured stderr
146
env['XONSH_PROC_FREQUENCY'] = 1e-4 # Process polling frequency
147
148
# Color and styling
149
env['FORCE_POSIX_PATHS'] = False # Force POSIX path separators on Windows
150
env['INTENSIFY_COLORS_ON_WIN'] = True # Enhance colors on Windows
151
env['XONSH_COLOR_STYLE'] = 'default' # Color style theme
152
```
153
154
### Environment Variable Types
155
```python { .api }
156
# Xonsh automatically handles type conversion for environment variables
157
158
# Boolean variables (accept: True/False, 1/0, "true"/"false", "yes"/"no")
159
env['XONSH_DEBUG'] = True
160
env['CASE_SENSITIVE_COMPLETIONS'] = "false" # Converted to False
161
162
# Integer variables
163
env['HISTSIZE'] = 1000
164
env['COMPLETION_QUERY_LIMIT'] = "50" # Converted to 50
165
166
# Float variables
167
env['XONSH_PROC_FREQUENCY'] = 0.001
168
169
# Path variables (support expansion and validation)
170
env['HISTFILE'] = '~/.xonsh_history' # Expands ~ to home directory
171
env['XONSHRC'] = '${HOME}/.xonshrc' # Expands environment variables
172
173
# List variables (colon-separated on Unix, semicolon on Windows)
174
env['PATH'] = ['/usr/bin', '/usr/local/bin'] # List of paths
175
env['XONTRIBS'] = ['vox', 'whole_word_jumping'] # List of xontrib names
176
177
# Dictionary variables (JSON or key=value format)
178
env['LS_COLORS'] = {'*.py': 'bold blue', '*.txt': 'green'}
179
```
180
181
## Aliases
182
183
### Alias Management
184
```python { .api }
185
from xonsh.aliases import FuncAlias, aliases
186
from xonsh.built_ins import XSH
187
188
class FuncAlias:
189
"""Function-based alias."""
190
191
def __init__(self, name: str, func: callable = None):
192
"""Create function alias.
193
194
Parameters
195
----------
196
name : str
197
Alias name
198
func : callable, optional
199
Function to wrap
200
"""
201
202
def __call__(self, args=None, stdin=None, stdout=None,
203
stderr=None, spec=None, stack=None, decorators=None):
204
"""Execute alias with subprocess-like interface.
205
206
Parameters
207
----------
208
args : list[str], optional
209
Command line arguments
210
stdin : file-like, optional
211
Input stream
212
stdout : file-like, optional
213
Output stream
214
stderr : file-like, optional
215
Error stream
216
spec : SubprocSpec, optional
217
Subprocess specification
218
stack : list, optional
219
Call stack
220
decorators : list, optional
221
Decorators to apply
222
223
Returns
224
-------
225
object
226
Alias execution result
227
"""
228
229
# Access alias registry
230
aliases = XSH.aliases
231
232
# Simple function alias
233
def ll_func(args, stdin=None):
234
"""List files in long format."""
235
from xonsh.built_ins import subproc_uncaptured
236
subproc_uncaptured(['ls', '-la'] + (args or []))
237
238
aliases['ll'] = FuncAlias('ll', ll_func)
239
240
# Python function alias with return value
241
def count_files(args, stdin=None):
242
"""Count files in directory."""
243
import os
244
directory = args[0] if args else '.'
245
count = len(os.listdir(directory))
246
return f"Files in {directory}: {count}"
247
248
aliases['countfiles'] = FuncAlias('countfiles', count_files)
249
```
250
251
### String and Executable Aliases
252
```python { .api }
253
from xonsh.built_ins import XSH
254
255
aliases = XSH.aliases
256
257
# String aliases (simple command replacement)
258
aliases['l'] = 'ls -CF'
259
aliases['la'] = 'ls -A'
260
aliases['ll'] = 'ls -alF'
261
aliases['grep'] = 'grep --color=auto'
262
263
# Executable aliases (path to external programs)
264
aliases['vi'] = '/usr/bin/vim'
265
aliases['python'] = '/usr/bin/python3'
266
267
# Complex string aliases with arguments
268
aliases['mygrep'] = 'grep -n --color=auto'
269
aliases['diskusage'] = 'df -h'
270
aliases['meminfo'] = 'cat /proc/meminfo'
271
272
# Conditional aliases based on platform
273
import sys
274
if sys.platform.startswith('linux'):
275
aliases['open'] = 'xdg-open'
276
elif sys.platform == 'darwin':
277
aliases['open'] = '/usr/bin/open'
278
elif sys.platform.startswith('win'):
279
aliases['open'] = 'start'
280
```
281
282
### Dynamic Aliases
283
```python { .api }
284
from xonsh.aliases import FuncAlias
285
286
def create_git_alias(subcommand: str) -> FuncAlias:
287
"""Create git subcommand alias.
288
289
Parameters
290
----------
291
subcommand : str
292
Git subcommand name
293
294
Returns
295
-------
296
FuncAlias
297
Configured git alias
298
"""
299
def git_func(args, stdin=None):
300
from xonsh.built_ins import subproc_uncaptured
301
cmd = ['git', subcommand] + (args or [])
302
subproc_uncaptured(cmd)
303
304
git_func.__name__ = f'git_{subcommand}'
305
git_func.__doc__ = f'Git {subcommand} shortcut'
306
307
return FuncAlias(f'g{subcommand[0]}', git_func)
308
309
# Create git aliases dynamically
310
git_commands = ['status', 'add', 'commit', 'push', 'pull', 'branch']
311
for cmd in git_commands:
312
aliases[f'g{cmd[0]}'] = create_git_alias(cmd)
313
314
# Usage: gs -> git status, ga -> git add, etc.
315
```
316
317
## Xontribs (Extensions)
318
319
### Loading and Managing Xontribs
320
```python { .api }
321
from xonsh.xontribs import xontribs_load, get_xontribs, Xontrib
322
323
def xontribs_load(names: list[str]) -> list[str]:
324
"""Load xontribs by name.
325
326
Parameters
327
----------
328
names : list[str]
329
List of xontrib names to load
330
331
Returns
332
-------
333
list[str]
334
List of successfully loaded xontrib names
335
"""
336
337
def get_xontribs() -> dict[str, Xontrib]:
338
"""Get available xontribs.
339
340
Returns
341
-------
342
dict[str, Xontrib]
343
Dictionary mapping names to xontrib metadata
344
"""
345
346
class Xontrib:
347
"""Xontrib metadata container."""
348
349
module: str # Module name
350
distribution: object = None # Package distribution info
351
352
@property
353
def is_loaded(self) -> bool:
354
"""Check if xontrib is loaded."""
355
356
@property
357
def is_auto_loaded(self) -> bool:
358
"""Check if xontrib is auto-loaded."""
359
360
def get_description(self) -> str:
361
"""Get xontrib description."""
362
363
# Load xontribs
364
loaded = xontribs_load(['vox', 'whole_word_jumping'])
365
print(f"Loaded: {loaded}")
366
367
# List available xontribs
368
available = get_xontribs()
369
for name, xontrib in available.items():
370
print(f"{name}: {xontrib.get_description()}")
371
372
# Check xontrib status
373
vox_info = available.get('vox')
374
if vox_info:
375
print(f"Vox loaded: {vox_info.is_loaded}")
376
```
377
378
### Popular Xontribs
379
```python { .api }
380
# Virtual environment management
381
xontribs_load(['vox'])
382
# Usage: vox new myenv, vox activate myenv, vox deactivate
383
384
# Enhanced navigation
385
xontribs_load(['whole_word_jumping'])
386
# Enables Alt+Left/Right word jumping
387
388
# Directory bookmarks
389
xontribs_load(['jump'])
390
# Usage: jump add mybook /path/to/directory, jump mybook
391
392
# Auto-completion enhancements
393
xontribs_load(['fzf-widgets'])
394
# Adds fuzzy finding widgets
395
396
# Package manager integration
397
xontribs_load(['apt', 'dnf', 'homebrew'])
398
# Auto-completion for package managers
399
400
# Git integration
401
xontribs_load(['gitinfo'])
402
# Adds git status to prompt
403
404
# Performance monitoring
405
xontribs_load(['schedule'])
406
# Task scheduling functionality
407
```
408
409
### Creating Custom Xontribs
410
```python { .api }
411
# File: my_xontrib.py
412
"""Custom xontrib example."""
413
414
from xonsh.built_ins import XSH
415
416
def _load_xontrib_(xsh, **kwargs):
417
"""Load custom xontrib.
418
419
Parameters
420
----------
421
xsh : XonshSession
422
Current xonsh session
423
**kwargs
424
Additional loading arguments
425
"""
426
427
# Add custom aliases
428
def hello(args, stdin=None):
429
name = args[0] if args else 'World'
430
print(f"Hello, {name}!")
431
432
xsh.aliases['hello'] = hello
433
434
# Add custom environment variable
435
xsh.env['MY_XONTRIB_LOADED'] = True
436
437
# Register custom completer
438
def my_completer(context):
439
if context.command and context.command.name == 'hello':
440
return {'Alice', 'Bob', 'Charlie'}
441
return set()
442
443
xsh.completers['my_completer'] = my_completer
444
445
print("My custom xontrib loaded!")
446
447
def _unload_xontrib_(xsh, **kwargs):
448
"""Unload custom xontrib."""
449
# Clean up aliases
450
if 'hello' in xsh.aliases:
451
del xsh.aliases['hello']
452
453
# Clean up environment
454
if 'MY_XONTRIB_LOADED' in xsh.env:
455
del xsh.env['MY_XONTRIB_LOADED']
456
457
# Clean up completers
458
if 'my_completer' in xsh.completers:
459
del xsh.completers['my_completer']
460
461
print("My custom xontrib unloaded!")
462
463
# Load the custom xontrib
464
# xontribs_load(['my_xontrib'])
465
```
466
467
## Configuration Files
468
469
### RC File Loading
470
```python { .api }
471
from xonsh.environ import get_home_xonshrc_path, xonshrc_context
472
473
def get_home_xonshrc_path() -> str:
474
"""Get default xonshrc file path.
475
476
Returns
477
-------
478
str
479
Path to default xonshrc file
480
"""
481
482
def xonshrc_context() -> dict:
483
"""Get context for xonshrc execution.
484
485
Returns
486
-------
487
dict
488
Execution context for RC files
489
"""
490
491
# Default RC file locations (in order of preference):
492
# 1. ~/.config/xonsh/rc.xsh
493
# 2. ~/.xonshrc
494
# 3. ~/.config/xonsh/rc.py
495
# 4. ~/.xonshrc.py
496
497
# Example xonshrc content
498
"""
499
# ~/.xonshrc
500
501
# Environment configuration
502
$EDITOR = 'vim'
503
$PAGER = 'less'
504
$BROWSER = 'firefox'
505
506
# Aliases
507
aliases['ll'] = 'ls -la'
508
aliases['grep'] = 'grep --color=auto'
509
aliases['..'] = 'cd ..'
510
511
# Load xontribs
512
xontribs = ['vox', 'whole_word_jumping']
513
for xontrib in xontribs:
514
try:
515
xontrib_load([xontrib])
516
except Exception as e:
517
print(f"Failed to load {xontrib}: {e}")
518
519
# Custom prompt
520
$PROMPT = '{env_name}{BOLD_GREEN}{user}@{hostname}{BOLD_BLUE} {cwd}{RESET} {BOLD_RED}{git_branch}{RESET} $ '
521
522
# Custom functions
523
def mkcd(args):
524
\"\"\"Create directory and change to it.\"\"\"
525
if args:
526
mkdir -p @(args[0])
527
cd @(args[0])
528
else:
529
print("Usage: mkcd <directory>")
530
531
aliases['mkcd'] = mkcd
532
"""
533
```
534
535
### Dynamic Configuration
536
```python { .api }
537
from xonsh.built_ins import XSH
538
import os
539
import platform
540
541
def configure_environment():
542
"""Configure environment based on system."""
543
env = XSH.env
544
545
# Platform-specific configuration
546
if platform.system() == 'Darwin': # macOS
547
env['HOMEBREW_PREFIX'] = '/opt/homebrew' if os.path.exists('/opt/homebrew') else '/usr/local'
548
env.setdefault('BROWSER', 'open')
549
elif platform.system() == 'Linux':
550
env.setdefault('BROWSER', 'xdg-open')
551
elif platform.system() == 'Windows':
552
env.setdefault('BROWSER', 'start')
553
554
# Development environment
555
if 'VIRTUAL_ENV' in env:
556
env['VIRTUAL_ENV_PROMPT'] = f"({os.path.basename(env['VIRTUAL_ENV'])})"
557
558
# Git configuration
559
if os.path.exists(os.path.expanduser('~/.gitconfig')):
560
env['GIT_CONFIGURED'] = True
561
562
def load_project_config():
563
"""Load project-specific configuration."""
564
project_config = os.path.join(os.getcwd(), '.xonshrc')
565
if os.path.exists(project_config):
566
from xonsh.codecache import run_script_with_cache
567
run_script_with_cache(project_config)
568
569
# Auto-load configuration
570
configure_environment()
571
load_project_config()
572
```
573
574
Configuration in xonsh is highly flexible, supporting everything from simple environment variables to complex dynamic configuration that adapts to the current system and project context.