本文档详细介绍了 TheFuck officially 支持的 Shell 以及它们是如何集成到应用程序中的。TheFuck 通过一个通用接口设计,可以与多个 Shell 配合使用,并在需要时提供特定于 Shell 的实现。有关 Shell 别名的信息,请参阅 Shell Aliases,有关实验性的即时模式功能,请参阅 Instant Mode。
TheFuck 通过实现一个 Shell 抽象层来支持多个 Shell。每个支持的 Shell 都扩展了一个通用的 Shell 接口,并重写特定的方法来处理特定于 Shell 的行为。
来源:thefuck/shells/generic.py thefuck/shells/bash.py thefuck/shells/zsh.py thefuck/shells/fish.py thefuck/shells/tcsh.py
TheFuck officially 支持以下 Shell:
| Shell | 类 | 配置文件 | 历史文件 | 别名实现 |
|---|---|---|---|---|
| Bash | Bash | ~/.bashrc 或 ~/.bash_profile | ~/.bash_history | 基于函数 |
| Zsh | Zsh | ~/.zshrc | ~/.zsh_history | 基于函数 |
| Fish | Fish | ~/.config/fish/config.fish | ~/.config/fish/fish_history | 基于函数 |
| Tcsh | Tcsh | ~/.tcshrc | ~/.history | 基于别名 |
来源:thefuck/shells/bash.py68-70 thefuck/shells/zsh.py73-75 thefuck/shells/fish.py85-86 thefuck/shells/tcsh.py28-30
来源:thefuck/shells/bash.py75-86 thefuck/shells/zsh.py86-90 thefuck/shells/fish.py103-107 thefuck/shells/tcsh.py35-39
每个 Shell 都有其特定方法来处理 Shell 特有的行为。下面我们详细介绍支持的 Shell 之间的主要区别。
每个 Shell 都以不同的方式实现 app_alias 方法,以适应 Shell 别名和函数特定的语法。
Bash 将别名实现为一个函数,该函数捕获前一个命令,将其传递给 TheFuck,并评估更正后的命令。
function {name} () {
TF_PYTHONIOENCODING=$PYTHONIOENCODING;
export TF_SHELL=bash;
export TF_ALIAS={name};
export TF_SHELL_ALIASES=$(alias);
export TF_HISTORY=$(fc -ln -10);
export PYTHONIOENCODING=utf-8;
TF_CMD=$(
thefuck {argument_placeholder} "$@"
) && eval "$TF_CMD";
unset TF_HISTORY;
export PYTHONIOENCODING=$TF_PYTHONIOENCODING;
{alter_history}
}
来源:thefuck/shells/bash.py14-35
Zsh 的实现与 Bash 类似,但有一些细微的语法差异。
{name} () {
TF_PYTHONIOENCODING=$PYTHONIOENCODING;
export TF_SHELL=zsh;
export TF_ALIAS={name};
TF_SHELL_ALIASES=$(alias);
export TF_SHELL_ALIASES;
TF_HISTORY="$(fc -ln -10)";
export TF_HISTORY;
export PYTHONIOENCODING=utf-8;
TF_CMD=$(
thefuck {argument_placeholder} $@
) && eval $TF_CMD;
unset TF_HISTORY;
export PYTHONIOENCODING=$TF_PYTHONIOENCODING;
{alter_history}
}
Fish 由于其不同的语法,需要更专业的实现。
function {0} -d "Correct your previous console command"
set -l fucked_up_command $history[1]
env TF_SHELL=fish TF_ALIAS={0} PYTHONIOENCODING=utf-8 thefuck $fucked_up_command {2} $argv | read -l unfucked_command
if [ "$unfucked_command" != "" ]
eval $unfucked_command
{1}
end
end
来源:thefuck/shells/fish.py51-66
Tcsh 使用更传统的别名语法。
alias {0} 'setenv TF_SHELL tcsh && setenv TF_ALIAS {0} && set fucked_cmd=`history -h 2 | head -n 1` && eval `thefuck ${{fucked_cmd}}`'
来源:thefuck/shells/tcsh.py11-14
来源:thefuck/shells/bash.py34-35 thefuck/shells/zsh.py37-38 thefuck/shells/fish.py53-55 thefuck/shells/tcsh.py32-33
每个 Shell 的历史管理方式不同。
history -s 命令将条目添加到历史记录。历史文件通常是 ~/.bash_history。print -s 命令添加到历史记录。历史文件通常是 ~/.zsh_history。~/.config/fish/fish_history。~/.history。Shell 历史文件具有 TheFuck 需要处理的不同格式。
: {timestamp}:{command}- cmd: {command}\n when: {timestamp}#+{timestamp}\n{command}来源:thefuck/shells/bash.py72-73 thefuck/shells/zsh.py77-84 thefuck/shells/fish.py88-95 thefuck/shells/tcsh.py32-33
每个 Shell 都有其自身检索和解析别名的方法。
alias 命令的输出,该输出存储在 TF_SHELL_ALIASES 中。TF_SHELL_ALIASES。functions 和 alias 命令来检索已定义的函数和别名。alias 命令的输出。来源: thefuck/shells/bash.py56-66 thefuck/shells/zsh.py61-71 thefuck/shells/fish.py13-37 thefuck/shells/tcsh.py16-26
来源: thefuck/shells/generic.py22-32 thefuck/shells/fish.py75-83
TheFuck 提供了一个实验性的“即时模式”功能,该功能在每个 shell 中实现方式不同。
来源: thefuck/shells/bash.py37-54 thefuck/shells/zsh.py40-59 thefuck/shells/generic.py42-44
TheFuck 通过 how_to_configure 方法提供 shell 特定配置说明。这使得用户可以轻松地将 TheFuck 与他们的 shell 集成。
来源: thefuck/shells/generic.py149-154 thefuck/shells/bash.py75-86 thefuck/shells/zsh.py86-90 thefuck/shells/fish.py103-107 thefuck/shells/tcsh.py35-39
TheFuck 为每个支持的 shell 包含全面的测试,以确保兼容性。
功能测试验证了:
来源: tests/functional/test_bash.py tests/functional/test_zsh.py tests/functional/test_fish.py tests/functional/test_tcsh.py
要为新 shell 添加支持,开发者需要创建一个扩展 Generic 类并实现以下关键方法:
app_alias:定义如何创建 shell 别名。get_aliases:检索 shell 中定义的别名。_get_history_file_name:指定 shell 历史文件的位置。_get_history_line:格式化 shell 历史记录的命令。how_to_configure:提供配置说明。