Magnificent app which corrects your previous console command
Common utility functions, decorators, and helper tools used throughout the application for caching, string matching, command manipulation, and application detection. These utilities provide essential functionality that supports the core correction system.
Functions for improving performance through result caching and memoization.
def memoize(fn):
"""
Decorator for function result caching.
Parameters:
- fn (callable): Function to memoize
Returns:
callable: Memoized version of the function
Caches function results based on arguments to avoid repeated computation.
Cache can be disabled by setting memoize.disabled = True.
Example:
@memoize
def expensive_function(arg1, arg2):
# Expensive computation
return result
"""
def cache(*depends_on):
"""
File-based caching decorator with dependency tracking.
Parameters:
- *depends_on (str): Files to monitor for cache invalidation
Returns:
callable: Decorator function that caches results
Caches function result in temporary file. Cache will be expired when
modification date of files from depends_on will be changed. Function
wrapped in cache should be arguments agnostic.
Example:
@cache('~/.thefuck/settings.py')
def get_expensive_settings():
# Expensive computation
return result
"""Functions for detecting system capabilities and applications.
def which(program):
"""
Returns program path or None.
Parameters:
- program (str): Program name to locate
Returns:
str or None: Full path to program if found, None otherwise
Cross-platform implementation of 'which' command functionality.
Searches PATH for executable programs.
"""
def is_app(command, *app_names):
"""
Returns True if command is call to one of passed app names.
Parameters:
- command (Command): Command object to check
- *app_names (str): Application names to check against
Returns:
bool: True if command matches any of the app names
Checks if the command script starts with any of the specified
application names, handling both bare commands and commands with arguments.
Example:
cmd = Command("git status", "", "")
if is_app(cmd, 'git'):
print("This is a git command")
"""
def for_app(*app_names):
"""
Decorator that specifies matching script is for one of app names.
Parameters:
- *app_names (str): Application names to match against
Returns:
callable: Decorator function
Uses is_app internally to check if the command matches any of the
specified application names. Returns False if no match.
Example:
@for_app('docker', 'podman')
def container_correction(command, settings):
# Container-specific correction logic
return corrected_command
"""Functions for intelligent string matching and similarity detection.
def get_closest(word, possibilities, n=3, cutoff=0.6, fallback_to_first=True):
"""
Returns closest match or just first from possibilities.
Parameters:
- word (str): Word to find matches for
- possibilities (list): List of possible matches
- n (int): Maximum number of matches to consider (default: 3)
- cutoff (float): Minimum similarity score (0.0-1.0, default: 0.6)
- fallback_to_first (bool): Return first possibility if no close match
Returns:
str or None: Best match or first possibility if fallback enabled
Uses difflib.get_close_matches for intelligent fuzzy matching.
Useful for correcting typos in command names and arguments.
"""
def get_all_executables():
"""
Returns list of all available executables and shell aliases.
Returns:
list: List of executable names and shell aliases
Searches PATH directories for executable files and includes shell aliases.
Excludes the thefuck alias itself to avoid self-reference. Results are
memoized for performance.
Used for intelligent command suggestions and corrections.
"""Functions for analyzing and modifying command strings.
def replace_argument(script, from_, to):
"""
Replaces command line argument.
Parameters:
- script (str): Original command string
- from_ (str): Argument to replace
- to (str): Replacement argument
Returns:
str: Command with argument replaced
First tries to replace at the end of the command, then in the middle
with space boundaries to avoid partial replacements.
Example: replace_argument('git pul origin', 'pul', 'pull')
"""
def replace_command(command, broken, matched):
"""
Helper for *_no_command rules.
Parameters:
- command (Command): Command object containing the script
- broken (str): Broken command name to replace
- matched (list): List of possible correct command names
Returns:
list: List of corrected command strings
Uses fuzzy matching to find close matches and generates multiple
correction suggestions by replacing the broken command with matches.
"""
def eager(fn, *args, **kwargs):
"""
Decorator that converts generator to list.
Parameters:
- fn (callable): Function that returns a generator
- *args: Arguments to pass to function
- **kwargs: Keyword arguments to pass to function
Returns:
list: List containing all generator results
Forces immediate evaluation of generator functions.
"""
def get_all_matched_commands(stderr, separator='Did you mean'):
"""
Extracts command suggestions from error output.
Parameters:
- stderr (str): Error output containing suggestions
- separator (str): Text that indicates start of suggestions
Returns:
list: List of suggested commands
Parses command line tool error messages to extract suggested
corrections. Commonly used with tools that provide "did you mean"
style suggestions.
"""
def wrap_settings(params):
"""
Adds default values to settings if it not presented.
Parameters:
- params (dict): Default parameter values to add to settings
Returns:
callable: Decorator function
Decorator that ensures rule functions have access to default
settings values. Commonly used in rules that need specific
application paths or configuration values.
Example:
@wrap_settings({'apt': '/usr/bin/apt'})
def match(command, settings):
print(settings.apt)
"""Utility constants and functions for platform compatibility.
DEVNULL = open(os.devnull, 'w')
"""
File object for null output redirection.
Cross-platform equivalent of /dev/null.
"""
def quote(text):
"""
Shell-safe quoting function.
Parameters:
- text (str): Text to quote for shell safety
Returns:
str: Properly quoted text
Platform-specific implementation:
- Python 2: Uses pipes.quote
- Python 3: Uses shlex.quote
"""from thefuck.utils import memoize
@memoize
def expensive_git_operation(repo_path):
"""Expensive operation that benefits from caching."""
# Simulate expensive operation
import subprocess
result = subprocess.run(['git', 'log', '--oneline'],
cwd=repo_path, capture_output=True, text=True)
return result.stdout.split('\n')
# First call: executes operation
commits1 = expensive_git_operation('/path/to/repo')
# Second call: returns cached result
commits2 = expensive_git_operation('/path/to/repo') # Much faster
# Disable caching temporarily
from thefuck.utils import memoize
memoize.disabled = True
commits3 = expensive_git_operation('/path/to/repo') # Executes again
memoize.disabled = Falsefrom thefuck.utils import which, is_app, for_app
# Check if programs are available
git_path = which('git')
if git_path:
print(f"Git found at: {git_path}")
docker_path = which('docker')
if docker_path:
print(f"Docker found at: {docker_path}")
# Use decorators for app-specific functions
@for_app('git')
def handle_git_command(command, settings):
print(f"Handling git command: {command.script}")
@is_app('npm')
def handle_npm_command(command, settings):
print(f"Handling npm command: {command.script}")from thefuck.utils import get_closest, get_all_matched
# Find closest match for typos
git_commands = ['push', 'pull', 'commit', 'checkout', 'branch', 'merge']
closest = get_closest('pul', git_commands)
print(f"Did you mean: {closest}") # "pull"
# Get all possible matches
typo = 'comit'
all_matches = get_all_matched(typo, git_commands, cutoff=0.4)
print(f"Possible matches: {all_matches}") # ['commit']
# Directory name correction
dirs = ['Documents', 'Downloads', 'Desktop', 'Pictures']
corrected = get_closest('Documnets', dirs)
print(f"Corrected directory: {corrected}") # "Documents"from thefuck.utils import replace_argument, replace_command, add_argument
# Fix command typos
original = "git pul origin main"
fixed = replace_argument(original, 'pul', 'pull')
print(f"Fixed: {fixed}") # "git pull origin main"
# Fix command name typos
typo_cmd = "gti status"
fixed_cmd = replace_command(typo_cmd, 'gti', 'git')
print(f"Fixed command: {fixed_cmd}") # "git status"
# Add missing arguments
incomplete = "docker run image"
complete = add_argument(incomplete, '--rm')
print(f"Complete: {complete}") # "docker run --rm image"from thefuck.utils import get_valid_history_without_current
from thefuck.types import Command
# Get relevant history
current_cmd = Command("git push origin main", "", "error output")
history = get_valid_history_without_current(current_cmd)
print("Recent commands (excluding current):")
for cmd in history[:5]: # Show last 5
print(f" {cmd}")from thefuck.utils import quote
# Safely quote arguments for shell execution
filename = "file with spaces.txt"
safe_filename = quote(filename)
command = f"cat {safe_filename}"
print(f"Safe command: {command}") # cat 'file with spaces.txt'
# Handle special characters
special_arg = "arg with $pecial char&"
safe_arg = quote(special_arg)
print(f"Safe argument: {safe_arg}")from thefuck.utils import cache
import requests
@cache
def fetch_api_data(url):
"""Expensive API call that benefits from persistent caching."""
response = requests.get(url)
return response.json()
# First call: makes HTTP request
data1 = fetch_api_data('https://api.example.com/data')
# Second call (even in different session): uses cached data
data2 = fetch_api_data('https://api.example.com/data') # No HTTP requestThese utilities form the foundation that enables thefuck's intelligent command correction and provide the performance optimizations necessary for responsive user experience.
Install with Tessl CLI
npx tessl i tessl/pypi-thefuck