jas*_*yan 7 shell zsh function
我一直在慢慢地从 Bash 迁移到 Zsh,并且已经到了我所移动的一切都运行良好的地步,只有一个例外。
我有几个函数,我.bashrc每天使用几十次,其中两个在 Zsh 下不起作用。这三个功能构成了一个基本的笔记功能。
他们目前在.config/zsh/functions:
function n() {
local arg files=(); for arg; do files+=( ~/".notes/$arg" ); done
${EDITOR:-vi} "${files[@]}"
}
function nls() {
tree -CR --noreport $HOME/.notes | awk '{
if (NF==1) print $1;
else if (NF==2) print $2;
else if (NF==3) printf " %s\n", $3
}'
}
# TAB completion for notes
function _notes() {
local files=($HOME/.notes/**/"$2"*)
[[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]##~/.notes/}" )
}
complete -o default -F _notes nRun Code Online (Sandbox Code Playgroud)
我的来源.zshrc是这样的:
autoload bashcompinit
bashcompinit
# source zshrc functions file
source "$HOME/.config/zsh/functions"Run Code Online (Sandbox Code Playgroud)
nls按预期工作,但既不是n也没有Tab完成工作。
我读到man zshcompsys它说:
bashcompinit 函数提供了与 bash 的可编程完成系统的兼容性。运行时,它将定义与具有相同名称的 bash 内置函数相对应的函数 compgen 和 complete。然后就可以使用为 bash 编写的完成规范和函数。
然而,当我尝试 Tab完成时,没有任何反应,当我输入时n notename,Vim/home在文件浏览器模式下打开我的- 不是预期的行为。
定义的所有其他函数都运行良好。如何将这些功能迁移到 Zsh 下工作?
local是内置函数,而不是关键字,因此local files=(…)不被解析为数组赋值,而是解析为字符串赋值。将赋值与声明分开编写。(已被 llua 发现,但请注意,您需要初始化files为空数组或使用 声明变量typeset -a,否则数组以虚假空元素开头。)${files[0]}必须写成$files[1]. 或者,告诉 zsh 以与 ksh 和 bash 更兼容的方式运行:放在emulate -L ksh函数的开头。emulate条路线,否则你的_notes函数将打印zsh: no matches found: foo*如果没有完成foo,因为默认情况下不匹配的 glob 会触发错误。添加glob限定符 N,如果不匹配则获取一个空数组,并测试该数组是否为空。_notes函数中还有另一个错误会影响子目录中的注释:您必须删除前缀直到完成,以便如果 eg~/notes/foo/bar存在并且您键入n b<TAB>,COMPREPLY则设置为 contains b,而不是foo/b。如果你想保留一个 bash 和 zsh 都可读的文件:
type emulate >/dev/null 2>/dev/null || alias emulate=true
function n() {
emulate -L ksh
local arg; typeset -a files
for arg; do files+=( ~/".notes/$arg" ); done
${EDITOR:-vi} "${files[@]}"
}
function nls() {
tree -CR --noreport $HOME/.notes | awk '{
if (NF==1) print $1;
else if (NF==2) print $2;
else if (NF==3) printf " %s\n", $3
}'
}
# TAB completion for notes
function _notes() {
emulate -L ksh
local x files
files=($HOME/.notes/**/"$2"*)
[[ -e ${files[0]} ]] || return 1
COMPREPLY=()
for x in "${files[@]}"; do
COMPREPLY+=("$2${x#$HOME/.notes*/$2}")
done
}
complete -o default -F _notes n
Run Code Online (Sandbox Code Playgroud)
如果要将代码移植到 zsh:
function n() {
local files
files=(${@/#/~/.notes/})
${EDITOR:-vi} $files
}
function nls() {
tree -CR --noreport $HOME/.notes | awk '{
if (NF==1) print $1;
else if (NF==2) print $2;
else if (NF==3) printf " %s\n", $3
}'
}
# TAB completion for notes
function _notes() {
setopt local_options bare_glob_qual
local files
files=(~/.notes/**/$2*(N))
((#files)) && COMPREPLY=($2${^files##~/.notes*/$2})
}
complete -o default -F _notes n
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10948 次 |
| 最近记录: |