mirror of
https://github.com/DictXiong/dotfiles.git
synced 2026-10-15 09:18:15 +08:00
[dev] GPG agent forwarding; improve riot, sagt, tmux and zsh (#46)
* feat(riot): support literal ipv6 addresses (with or without ports given) feat(riot): -v, -4, and -6 fix(riot): do not call external binaries if possible * feat(riot): command git * build(riot-config): nasp.fit -> jump.nasp.fit * feat: add bnd and nor and completions * fix(zshrc): bnd exit when build error * fix(tmux): press ^a twice to send ^a * feat(riot): sshl supports specifying local port and unix sock * feat(riot): sshr for ssh -R * feat(riot): -o ServerAliveInterval=60 * feat(riot): conditionally RequestTTY * feat: zsh completion for beam and beaml * fix(frigg): ddns get ip * fix(riot): tmux error with window number and spaces The fix to spaces is just a workaround. Issue may still exist when command contains spaces. * feat(riot): ControlPersist=60s * fix(ci): riot * feat(tmux): prevent tmux from exiting copy mode after selection with mouse see: - https://www.reddit.com/r/tmux/comments/v73005/how_to_prevent_tmux_from_exiting_copy_mode_after/ - https://www.reddit.com/r/tmux/comments/1ltms6a/how_to_select_text_in_tmux_without_having_it_jump/ * feat(tmux): F12 to passthru * fix(riot): ControlPersist 60s -> 5s * feat: sne: search and edit * feat(ssh): add key ip17/sep * feat(tmux): press ESC to exit copy mode * feat(ssh): add key sk1/piv/9a * feat(ssh): add key sk1/fido2 * feat(ssh): add key openpgp:0x8774BF70 and remove key ip14/sep and ltp2 (asu127) * feat(sagent): sagt gpg; improve code * feat(sagent): check pinentry and give notes * feat(riot): add GPG agent forwarding Signed-off-by: Dict Xiong <me@beardic.cn> * feat: gitconf add gpg signature; remove macos from ci * feat(eid): add sk1 9a cert * feat(riot): better help and fix option quite->quiet * feat(riot): separate command options from riot options * feat(sagt): gpg-pin and associated tests * feat(riot): zsh completions * fix: Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix(riot): simplify and secure * fix: syntax --------- Signed-off-by: Dict Xiong <me@beardic.cn> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
99
functions/_beam
Normal file
99
functions/_beam
Normal file
@@ -0,0 +1,99 @@
|
||||
#compdef beam
|
||||
|
||||
# =============================================================================
|
||||
# Beam-Go Zsh Completion Script
|
||||
# =============================================================================
|
||||
|
||||
_beam() {
|
||||
local context state state_descr line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
'1: :_beam_commands' \
|
||||
'*:: :->args'
|
||||
|
||||
case $state in
|
||||
(args)
|
||||
case $line[1] in
|
||||
(serve) _beam_serve ;;
|
||||
(add) _beam_add ;;
|
||||
(list) _beam_list ;;
|
||||
(del) _beam_del ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# --- Subcommand Definitions ---
|
||||
|
||||
(( $+functions[_beam_commands] )) ||
|
||||
_beam_commands() {
|
||||
local -a commands
|
||||
commands=(
|
||||
'serve:Start the beam server daemon'
|
||||
'add:Share a file or directory'
|
||||
'list:List active shares'
|
||||
'del:Delete a share by path or code'
|
||||
)
|
||||
_describe -t commands 'beam command' commands
|
||||
}
|
||||
|
||||
_beam_serve() {
|
||||
_arguments \
|
||||
'(-d --database)'{-d,--database}'=[Database directory (Required)]:directory:_path_files -/' \
|
||||
'(-p --port)'{-p,--port}'=[Port to listen on (default :8280)]:port:' \
|
||||
'(-s --socket)'{-s,--socket}'=[Socket path]:socket path:_files' \
|
||||
'--subpath=[Enable subpath sharing]'
|
||||
}
|
||||
|
||||
_beam_add() {
|
||||
_arguments \
|
||||
'(-d --days)'{-d,--days}'=[Expiration days (default 7)]:days:' \
|
||||
'(-s --socket)'{-s,--socket}'=[Socket path]:socket path:_files' \
|
||||
'1:file to share:_files'
|
||||
}
|
||||
|
||||
_beam_list() {
|
||||
_arguments \
|
||||
'(-s --socket)'{-s,--socket}'=[Socket path]:socket path:_files'
|
||||
}
|
||||
|
||||
_beam_del() {
|
||||
_arguments \
|
||||
'(-s --socket)'{-s,--socket}'=[Socket path]:socket path:_files' \
|
||||
'(-c --code)'{-c,--code}'=[Share code]:share code:_beam_active_codes' \
|
||||
'1:shared path:_files'
|
||||
}
|
||||
|
||||
# --- Helpers ---
|
||||
|
||||
# 动态获取当前的 Share Code
|
||||
# 它会尝试读取用户当前输入的 -s 参数,去连接正确的 socket
|
||||
_beam_active_codes() {
|
||||
local socket_path=""
|
||||
|
||||
# 从 Zsh 解析的参数中提取 socket 路径
|
||||
if [[ -n ${opt_args[-s]} ]]; then
|
||||
socket_path=${opt_args[-s]}
|
||||
elif [[ -n ${opt_args[--socket]} ]]; then
|
||||
socket_path=${opt_args[--socket]}
|
||||
fi
|
||||
|
||||
# 构造查询命令
|
||||
local cmd_args=()
|
||||
cmd_args+=("list")
|
||||
[[ -n $socket_path ]] && cmd_args+=("-s" "$socket_path")
|
||||
|
||||
# 调用 beam list,跳过前两行表头,提取 Code($1) 和 Path($3)
|
||||
# 2>/dev/null 防止服务未启动时报错打印到终端
|
||||
local -a shares
|
||||
shares=("${(@f)$(beam "${cmd_args[@]}" 2>/dev/null | awk 'NR>2 {print $1":"$2" "$3" "$4}')}")
|
||||
|
||||
if [[ ${#shares} -gt 0 ]]; then
|
||||
_describe -t shares 'active share' shares
|
||||
else
|
||||
_message 'no active shares or server not running'
|
||||
fi
|
||||
}
|
||||
|
||||
_beam "$@"
|
||||
35
functions/_beaml
Normal file
35
functions/_beaml
Normal file
@@ -0,0 +1,35 @@
|
||||
#compdef beaml
|
||||
|
||||
_beaml() {
|
||||
local context state line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
'1: :->cmds' \
|
||||
'2: :->args'
|
||||
|
||||
case $state in
|
||||
cmds)
|
||||
local commands; commands=(
|
||||
'add:Add a new item'
|
||||
'del:Delete an item'
|
||||
'list:List all items'
|
||||
)
|
||||
_describe -t commands 'beaml commands' commands
|
||||
;;
|
||||
args)
|
||||
case $line[1] in
|
||||
add)
|
||||
_files
|
||||
;;
|
||||
del)
|
||||
local -a items
|
||||
items=( /pss/lite/*(N:t) )
|
||||
_describe -t items 'item to delete' items
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_beaml "$@"
|
||||
3
functions/_nixos_config_hosts
Normal file
3
functions/_nixos_config_hosts
Normal file
@@ -0,0 +1,3 @@
|
||||
#compdef bnd nor
|
||||
|
||||
compadd -- /root/NixOS-Config/hosts/*(/:t)
|
||||
105
functions/_riot
Normal file
105
functions/_riot
Normal file
@@ -0,0 +1,105 @@
|
||||
#compdef riot
|
||||
|
||||
_riot() {
|
||||
local context state state_descr line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C -s \
|
||||
'(-4 -6)-4[Force ssh to use IPv4 addresses only]' \
|
||||
'(-4 -6)-6[Force ssh to use IPv6 addresses only]' \
|
||||
'(-D --dry-run)'{-D,--dry-run}'[Print commands without executing them]' \
|
||||
'(-d --dev)'{-d,--dev}'[Enable shell execution tracing]' \
|
||||
'(-g --gpg)'{-g,--gpg}'[Forward the local GPG agent for an interactive login]' \
|
||||
'(-h --help)'{-h,--help}'[Display help and exit]' \
|
||||
'(-l --lite)'{-l,--lite}'[Enable dotfiles lite mode]' \
|
||||
'*-o[Pass an option to ssh]:SSH option:' \
|
||||
'(-p --password)'{-p,--password}'[Use password authentication]' \
|
||||
'(-q --quiet)'{-q,--quiet}'[Enable dotfiles quiet mode]' \
|
||||
'(-t --trust)'{-t,--trust}'[Trust the remote and enable forwarding]' \
|
||||
'*-v[Enable verbose ssh output]' \
|
||||
'--color[Force colored output]' \
|
||||
'--tmux[Open SSH sessions in tmux windows]' \
|
||||
'1:remote:_riot_remotes' \
|
||||
'2:command:_riot_commands' \
|
||||
'*::command argument:->command-args'
|
||||
|
||||
case $state in
|
||||
command-args)
|
||||
case $line[2] in
|
||||
ssh|tmux|zssh)
|
||||
_riot_complete_with _ssh ssh "$line[1]" "${line[@]:2}"
|
||||
;;
|
||||
git)
|
||||
_riot_complete_with _git git "${line[@]:2}"
|
||||
;;
|
||||
sftp)
|
||||
_riot_complete_with _sftp sftp "$line[1]" "${line[@]:2}"
|
||||
;;
|
||||
scp)
|
||||
_riot_complete_with _scp scp "${line[@]:2}"
|
||||
;;
|
||||
sshl|sshr)
|
||||
_message 'forwarding specification'
|
||||
;;
|
||||
sshd)
|
||||
_guard '[0-9]#' 'local port'
|
||||
;;
|
||||
rm|ping|ping4|ping6)
|
||||
_message 'no more arguments'
|
||||
;;
|
||||
*)
|
||||
_default
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_riot_commands() {
|
||||
local -a commands=(
|
||||
'ssh:Open an SSH session (default)'
|
||||
'tmux:Open SSH sessions in tmux windows'
|
||||
'git:Run git on the remote host'
|
||||
'sshl:Create local port forwarding with ssh -L'
|
||||
'sshr:Create remote port forwarding with ssh -R'
|
||||
'sshd:Create dynamic port forwarding with ssh -D'
|
||||
'zssh:Open a zssh session'
|
||||
'sftp:Open an SFTP session'
|
||||
'scp:Copy files to or from the remote host'
|
||||
'rm:Remove the remote host key from known_hosts'
|
||||
'ping:Ping the remote host'
|
||||
'ping4:Ping the remote host over IPv4'
|
||||
'ping6:Ping the remote host over IPv6'
|
||||
)
|
||||
_describe -t commands 'riot command' commands
|
||||
}
|
||||
|
||||
_riot_presets() {
|
||||
local -a config_files presets
|
||||
local file
|
||||
|
||||
[[ -z $DOTFILES ]] || config_files+=("$DOTFILES/riot-config.sh")
|
||||
config_files+=("$HOME/.config/riot-config.sh" "$PWD/riot-config.sh")
|
||||
for file in "${config_files[@]}"; do
|
||||
[[ -r $file ]] || continue
|
||||
presets+=("${(@f)$(sed -nE 's/^([[:alnum:]_.-]+)\.(remote|batch)\(\).*/\1/p' "$file" 2>/dev/null)}")
|
||||
done
|
||||
presets=(${(u)presets})
|
||||
_describe -t presets 'riot preset' presets
|
||||
}
|
||||
|
||||
_riot_remotes() {
|
||||
_alternative \
|
||||
'presets:riot preset:_riot_presets' \
|
||||
'hosts:host:_hosts'
|
||||
}
|
||||
|
||||
_riot_complete_with() {
|
||||
local completer=$1
|
||||
shift
|
||||
local -a words=("$@")
|
||||
local CURRENT=$#words
|
||||
"$completer"
|
||||
}
|
||||
|
||||
_riot "$@"
|
||||
3
functions/_sagt
Normal file
3
functions/_sagt
Normal file
@@ -0,0 +1,3 @@
|
||||
#compdef sagt
|
||||
|
||||
compadd -- gpg gpg-pin kill ls op piv reset
|
||||
3
functions/_use
Normal file
3
functions/_use
Normal file
@@ -0,0 +1,3 @@
|
||||
#compdef use
|
||||
|
||||
compadd -- $(nix eval --impure --expr 'builtins.attrNames ( (import <nixpkgs>) {} )' 2>/dev/null | tr '[]"' ' ')
|
||||
Reference in New Issue
Block a user