Python-powered shell providing superset of Python with shell primitives for cross-platform command execution and automation.
Xonsh provides a sophisticated tab completion system with pluggable completers for commands, paths, Python objects, and custom contexts. The completion system supports both simple string completions and rich completions with descriptions, styling, and advanced filtering.
from xonsh.completer import Completer
from xonsh.parsers.completion_context import CompletionContext
class Completer:
"""Main completion engine for xonsh."""
def __init__(self):
"""Initialize completer with context parser."""
self.context_parser = CompletionContextParser()
def parse(self, text: str, cursor_index: int = None, ctx: dict = None) -> CompletionContext:
"""Parse text to create completion context.
Parameters
----------
text : str
Multi-line text to parse
cursor_index : int, optional
Cursor position (defaults to end of text)
ctx : dict, optional
Execution context
Returns
-------
CompletionContext
Parsed completion context
"""
def complete(self, prefix: str, line: str, begidx: int, endidx: int,
ctx: dict = None, multiline_text: str = None,
cursor_index: int = None,
completion_context: CompletionContext = None) -> list[str]:
"""Generate completions for given context.
Parameters
----------
prefix : str
Text to complete
line : str
Full line containing prefix
begidx : int
Start index of prefix in line
endidx : int
End index of prefix in line
ctx : dict, optional
Execution context
multiline_text : str, optional
Complete multi-line text
cursor_index : int, optional
Cursor position
completion_context : CompletionContext, optional
Pre-parsed completion context
Returns
-------
list[str]
List of completion strings or RichCompletion objects
"""
def complete_line(self, text: str) -> list[str]:
"""Complete when cursor is at end of line.
Parameters
----------
text : str
Text to complete
Returns
-------
list[str]
List of completions
"""
# Usage examples
completer = Completer()
# Simple completion
completions = completer.complete("gi", "git status", 0, 2)
# Line completion (cursor at end)
completions = completer.complete_line("ls /usr/")
# Advanced completion with context
ctx = {'myvar': 'value'}
completions = completer.complete("myv", "print(myvar)", 6, 9, ctx=ctx)from xonsh.completers.tools import RichCompletion, Completion
class RichCompletion(str):
"""Enhanced completion with metadata and styling."""
def __init__(self, value: str,
prefix_len: int = None,
display: str = None,
description: str = "",
style: str = "",
append_closing_quote: bool = True,
append_space: bool = False):
"""Create rich completion.
Parameters
----------
value : str
Actual completion text
prefix_len : int, optional
Length of prefix to replace
display : str, optional
Text to display in completion menu
description : str, default ""
Detailed description of completion
style : str, default ""
Style string for prompt-toolkit
append_closing_quote : bool, default True
Whether to append closing quote
append_space : bool, default False
Whether to append space after completion
"""
# Rich completion examples
basic_completion = RichCompletion("status", description="Show repository status")
styled_completion = RichCompletion("branch",
display="branch (git)",
description="List, create, or delete branches",
style="bold blue")
path_completion = RichCompletion("/home/user/",
prefix_len=5, # Replace last 5 chars
append_space=False)from xonsh.completers.commands import complete_command
def complete_command(prefix: str, line: str, start: int, end: int,
ctx: dict) -> set[str]:
"""Complete command names.
Parameters
----------
prefix : str
Command prefix to complete
line : str
Full command line
start : int
Start position of prefix
end : int
End position of prefix
ctx : dict
Execution context
Returns
-------
set[str]
Set of command completions
"""
# Command completion automatically handles:
# - Executable files in PATH
# - Python functions and variables in context
# - Xonsh aliases
# - Built-in commandsfrom xonsh.completers.path import complete_path
def complete_path(prefix: str, line: str, start: int, end: int,
ctx: dict) -> set[RichCompletion]:
"""Complete file and directory paths.
Parameters
----------
prefix : str
Path prefix to complete
line : str
Full command line
start : int
Start position of prefix
end : int
End position of prefix
ctx : dict
Execution context
Returns
-------
set[RichCompletion]
Set of path completions with metadata
"""
# Path completion features:
# - File and directory names
# - Hidden file support (when prefix starts with .)
# - Tilde expansion (~/)
# - Environment variable expansion ($VAR/)
# - Quote handling for spacesfrom xonsh.completers.python import complete_python
def complete_python(prefix: str, line: str, start: int, end: int,
ctx: dict) -> set[str]:
"""Complete Python expressions.
Parameters
----------
prefix : str
Python expression prefix
line : str
Full line
start : int
Start position
end : int
End position
ctx : dict
Execution context with available names
Returns
-------
set[str]
Python attribute/name completions
"""
# Python completion handles:
# - Variable names from context
# - Module attributes (os.path.*)
# - Object methods and attributes
# - Import statements
# - Function signaturesfrom xonsh.completers.tools import contextual_completer, exclusive_completer
@contextual_completer
def my_completer(context: CompletionContext) -> set[str]:
"""Custom contextual completer.
Parameters
----------
context : CompletionContext
Completion context with command and argument info
Returns
-------
set[str]
Set of completions for this context
"""
if context.command and context.command.arg_index == 1:
# Complete first argument to any command
return {'option1', 'option2', 'option3'}
return set()
@exclusive_completer
def exclusive_completer_example(context: CompletionContext) -> set[str]:
"""Exclusive completer that prevents other completers.
Returns
-------
set[str]
Exclusive set of completions
"""
if context.command and context.command.name == 'mycommand':
return {'exclusive1', 'exclusive2'}
return set()
# Register completers
from xonsh.built_ins import XSH
XSH.completers['my_completer'] = my_completer
XSH.completers['exclusive'] = exclusive_completer_examplefrom xonsh.built_ins import XSH
def register_completer(name: str, completer_func):
"""Register a completer function.
Parameters
----------
name : str
Completer name
completer_func : callable
Completer function
"""
XSH.completers[name] = completer_func
def unregister_completer(name: str):
"""Remove a completer.
Parameters
----------
name : str
Completer name to remove
"""
if name in XSH.completers:
del XSH.completers[name]
# Example: Git branch completer
def git_branch_completer(context):
"""Complete git branch names."""
if (context.command and
context.command.name == 'git' and
len(context.command.args) > 0 and
context.command.args[0] in ['checkout', 'branch', 'merge']):
try:
from xonsh.built_ins import subproc_captured_stdout
branches = subproc_captured_stdout(['git', 'branch'])
return {b.strip('* ') for b in branches.split('\n') if b.strip()}
except:
return set()
return set()
register_completer('git_branches', git_branch_completer)from xonsh.parsers.completion_context import CompletionContext, CommandContext
def analyze_completion_context(context: CompletionContext):
"""Analyze completion context for decision making.
Parameters
----------
context : CompletionContext
Context to analyze
"""
# Check if completing a command name
if context.command and context.command.arg_index == 0:
print("Completing command name")
# Check if completing command arguments
elif context.command and context.command.arg_index > 0:
print(f"Completing argument {context.command.arg_index}")
print(f"Command: {context.command.name}")
print(f"Previous args: {context.command.args}")
# Check if completing Python expression
elif context.python:
print("Completing Python expression")
print(f"Prefix: {context.python.prefix}")
# Access line context
print(f"Line: {context.line}")
print(f"Cursor position: {context.cursor_index}")from xonsh.completers.bash_completion import bash_complete_line
def load_bash_completions():
"""Load bash completion scripts."""
# Bash completion integration
try:
completions = bash_complete_line("git che", 7)
return completions
except:
return []
def load_external_completions(command: str) -> list[str]:
"""Load completions from external sources.
Parameters
----------
command : str
Command to get completions for
Returns
-------
list[str]
External completions
"""
# Could integrate with:
# - Bash completion scripts
# - Zsh completion functions
# - Command-specific completion APIs
# - Online completion services
external_completions = []
# Example: Load from completion file
completion_file = f"/usr/share/completions/{command}"
try:
with open(completion_file) as f:
external_completions = f.read().strip().split('\n')
except:
pass
return external_completionsfrom xonsh.completers.tools import get_filter_function
def filter_completions(completions: list[str], prefix: str) -> list[str]:
"""Filter completions based on prefix and settings.
Parameters
----------
completions : list[str]
Raw completions to filter
prefix : str
Prefix to match against
Returns
-------
list[str]
Filtered completions
"""
filter_func = get_filter_function() # Respects CASE_SENSITIVE_COMPLETIONS
return [c for c in completions if filter_func(c, prefix)]
def rank_completions(completions: list[str], prefix: str) -> list[str]:
"""Rank completions by relevance.
Parameters
----------
completions : list[str]
Completions to rank
prefix : str
User input prefix
Returns
-------
list[str]
Ranked completions (best first)
"""
# Simple ranking by prefix match quality
exact_matches = [c for c in completions if c.startswith(prefix)]
fuzzy_matches = [c for c in completions if prefix.lower() in c.lower() and c not in exact_matches]
return sorted(exact_matches) + sorted(fuzzy_matches)from xonsh.built_ins import XSH
# Key completion settings
env = XSH.env
env['CASE_SENSITIVE_COMPLETIONS'] = False # Case sensitivity
env['COMPLETIONS_CONFIRM'] = True # Confirm ambiguous completions
env['COMPLETION_QUERY_LIMIT'] = 100 # Max completions to show
env['COMPLETIONS_DISPLAY_VALUE'] = 'single' # Display mode
env['COMPLETIONS_MENU_ROWS'] = 5 # Menu height
env['BASH_COMPLETIONS'] = ['/usr/share/bash-completion/bash_completion'] # Bash completion filesfrom xonsh.built_ins import XSH
# List available completers
available_completers = list(XSH.completers.keys())
# Enable/disable specific completers
def toggle_completer(name: str, enabled: bool):
"""Enable or disable a completer."""
if enabled and name in XSH.completers:
# Completer is already registered
pass
elif not enabled and name in XSH.completers:
# Temporarily disable by removing
backup_completer = XSH.completers.pop(name)
# Store for potential re-enabling
XSH._disabled_completers = getattr(XSH, '_disabled_completers', {})
XSH._disabled_completers[name] = backup_completer
# Get completion statistics
def get_completion_stats():
"""Get completion system statistics."""
return {
'total_completers': len(XSH.completers),
'completer_names': list(XSH.completers.keys()),
'case_sensitive': XSH.env.get('CASE_SENSITIVE_COMPLETIONS'),
'query_limit': XSH.env.get('COMPLETION_QUERY_LIMIT'),
}The completion system provides extensive customization options for creating domain-specific completion experiences, integrating with external tools, and providing rich interactive feedback to users.
Install with Tessl CLI
npx tessl i tessl/pypi-xonsh