get_history_correction aligns a failed script with near-identical
history commands segment by segment (shell_ast words with byte-true
offsets) and splices the corrected tokens back in place. It only
returns a fix when exactly one candidate matches the structure with
at most two diverged tokens, each at least 80 percent similar;
looser or ambiguous matches decline so the asking history rule
stays in charge of them.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Consult a PATH-resolved binary's own --help (mtime-cached, LC_ALL=C,
2s timeout with kill) when a segment's first non-flag token is not a
listed subcommand, and splice the unique close match (ratio >= 0.8,
same first character). Ambiguity, sudo heads, flat-fallback artifact
heads, valid subcommands and nested levels all decline to the rest of
the chain; only <binary> --help is ever run.
put_to_history wrote entries without a trailing newline, so fixed
commands concatenated onto one line, and backslash-continued
multiline entries were read back as broken fragments. Join
continuations when reading and terminate entries with a newline,
matching the fish adapter convention.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
parse() turns a script into pipeline command segments via bashlex,
keeping byte-true char offsets for every word (quotes included as
typed, redirects and env assignments excluded from words), and
splice() rebuilds a corrected script from (start, end, text)
replacements applied right-to-left. When bashlex is missing or
rejects the script, a flat split(' ') segment keeps the old view.
bashlex (GPL-3+) powers upcoming structural command analysis: parsing
pipelines into segments with word offsets so a typo anywhere in a
command can be fixed as confidently as one at the start. Because the
license is incompatible with distributing the MIT-licensed app, the
dependency is import-guarded: thefuck/shell_ast.py exposes
AST_AVAILABLE, which is False when bashlex is missing or under python 2
(the py2.7 CI requirements.txt deliberately omits it), so all new
behavior must gate on it and the fork stays personal-use only.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
tests/entrypoints/test_fix_command.py sets TF_HISTORY, which makes the
real _get_raw_command call get_all_executables() and memoize the
machine's actual PATH. TestGetValidHistoryWithoutCurrent then mocks
thefuck.utils.Path to plant a fake café binary, but gets the stale
memoized list, so the café history line is filtered out and the four
parametrized cases fail whenever the entrypoint tests ran first.
Use the existing no_memoize fixture, like the neighboring
executables tests already do.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
When no learned correction matches, fuzzy-match the mistyped token
against executables from $PATH and shell aliases. A guess is auto-run
and recorded into the learned-corrections db only when it is
unambiguous: the token is not an existing executable, contains no
path separators or extensions, shares its first character with the
candidate, has similarity of at least 0.8, and exactly one candidate
survives. Asking the user stays the last resort.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Record user-accepted corrections in a shelve-backed store and replay
them on future matching mistakes, bypassing rule evaluation entirely.
Two-level matching: exact full-command lookup, then word-level
reconstruction that generalises to different arguments (e.g. learning
'git psuh origin main' also fixes 'git psuh origin dev').
* Add git clone missing rule
* Clean up tests and improve matching
* Make rules behave correctly?
* Improve tests and redo matcher
* Remove unnecessary tests
* Improvements as per code review
* Remove dead tests
* Improve match function for git clone missing
* Improve tests
* Fix more tests
* Fix failing test
* Add Macos's /bin/sh command output to match
* Add output for lines uncovered by tests
Co-authored-by: Pablo Santiago Blum de Aguiar <scorphus@gmail.com>
* fix: Update output for brew_install test: fixed
* chore: fixing flake8 styles
* feat: show more suggestions
* test: new functions added and multi suggestions
* refactor: rename to _get_suggestions
* added updatedb(mlocate) to sudo rules
* Add test
Co-authored-by: phk <phk@terminal21.de>
Co-authored-by: Pablo Santiago Blum de Aguiar <scorphus@gmail.com>
Using the `force_command` argument will run into issues as the
`_get_raw_command` method simply returns the value of `force_command`
(which is a string) while it should actually return a list.
Fix#1240
* Resolve paths before checking app identity
Commands entered with a path do not match is_app. I encountered this
when working with a test for the rm_dir rule. This rule did not use the
@for_app decorator, but when I migrated it, the test for "./bin/hdfs.."
failed because 'hdfs' was recognized as a command, while "./bin/hdfs"
was not.
This commit addresses the false negative by resolving path names in the
command, via os.path.basename.
* Remove paths from for_app invocations in rules
I presume that the `./` in `./gradlew` was used here because thefuck
would not find an app match on just `gradlew`, and thus no fucks would
be given on the most common and idiomatic way of invoking gradlew.
After 8faf9b1, thefuck does not distinguish between commands with
paths and those without. Therefore, the tests for this rule are now
broken because thefuck strips paths from the _user_'s command, but not
from the for_app decoration.
This commit addresses that problem by changing the for_app decoration to
this rule.
* fix fuckup `branch 0v` by...
...deleting branch `0v` and running `git branch -v` as the user intended
* use quotes consistently
* provide new solution implementation based on feedback on PR
* rename files to more accurately reflect their more generic contents
* update import statement to match new file name
* update command name in README.md
* separate out matching tests so the pattern is clear for those who add matches in the future
Improves performance in WSL
Fix#1036
* Add excluded_search_path_prefixes setting
Allows filtering the paths used to search for commands
Can be useful to filter out /mnt/ in WSL for performance
* Add test for excluded_search_path_prefixes
* Apply suggestions from code review
Co-authored-by: Pablo Aguiar <scorphus@gmail.com>
Co-authored-by: Pablo Aguiar <scorphus@gmail.com>
* adding in files for the cd-cs feature
* Updated thefuck/rules/cd_cs.py comments to be more verbose
Thanks Scorphus!
Co-authored-by: Pablo Aguiar <scorphus@gmail.com>
* Updating the rules file to exclude the \xe2 character
This character(–) has lead to the commit failing some of the tests.
I am removing it from the code and we should see the tests pass now.
* Setting the encoding in thefuck/rules/cd_cs.py
Co-authored-by: Pablo Aguiar <scorphus@gmail.com>
Co-authored-by: SID SHARDANAND <sshardan@deakin.edu.au>
Co-authored-by: Pablo Aguiar <scorphus@gmail.com>