Files
fish-config/functions/edit.fish
T
rootiest ed8de40d46 feat(edit): replace edit wrapper with multi-editor launcher
Rewrite functions/edit.fish as a flexible launcher supporting GUI and
terminal editors with rich fallback chains, clipboard/text temp files,
new-window flags, and verbose/silent output control.

- --visual/--terminal force mode; default auto-detects via tty
- GUI chain: zed → antigravity-ide → code → kate → kwrite → gnome-text-editor → gedit
- Terminal chain: nvim → vim → micro → nano → vi
- --clipboard reuses the existing p function; --text opens a literal string
- --new maps to per-editor new-window flags (best-effort)
- C1 guard falls back to legacy bare-editor behavior when disabled

Docs: update fish-config.md function entry + C1 table, README and AGENTS C1 shadow lists.
2026-06-19 00:58:40 -04:00

202 lines
7.9 KiB
Fish

# Copyright (C) 2026 Rootiest
# SPDX-License-Identifier: AGPL-3.0-or-later
# SYNOPSIS
# edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...]
#
# DESCRIPTION
# Opens files in a text editor, choosing a terminal or GUI editor and
# resolving a rich chain of fallbacks. With no --visual/--terminal flag the
# mode is auto-detected: interactive terminals get the terminal editor
# ($EDITOR), while detached invocations (desktop shortcuts) get the GUI
# editor ($VISUAL). Clipboard contents and literal strings can be opened as
# throwaway temp files. Editor output is suppressed unless --verbose.
#
# GUI fallback chain: zed → antigravity-ide → code → kate → kwrite →
# gnome-text-editor → gedit
# Terminal fallback chain: nvim → vim → micro → nano → vi
#
# ARGUMENTS
# FILE... Files to open (any number)
# -V, --visual Force the GUI editor ($VISUAL or fallbacks)
# -t, --terminal Force the terminal editor ($EDITOR or fallbacks)
# -e, --editor=X Use a specific editor binary X
# -c, --clipboard Open the clipboard contents (as a temp file)
# -x, --text=STR Open STR as the contents of a new temp file
# -n, --new Force a new window/instance (best-effort, where supported)
# -v, --verbose Print the launch command and let editor output through
# -s, --silent Suppress all output, including the editor's
# -h, --help Show this help message
#
# RETURNS
# 0 Editor launched successfully
# 1 Conflicting flags, no editor found, or clipboard read failed
#
# EXAMPLE
# edit notes.txt
# edit --visual ~/.config/fish/config.fish
# edit --terminal --new todo.md
# edit --editor=code --clipboard
# edit --text="hello world"
function edit --description 'Open files in a terminal or GUI editor with fallbacks'
set -l c_head (set_color --bold cyan)
set -l c_cmd (set_color --bold white)
set -l c_flag (set_color yellow)
set -l c_err (set_color red)
set -l c_dim (set_color brblack)
set -l c_reset (set_color normal)
# Opinionated guard (C1): fall back to the legacy bare-editor behavior.
if not __fish_config_op_enabled __fish_config_op_aliases
if set -q EDITOR; and test -n "$EDITOR"
$EDITOR $argv
else if type -q nvim
nvim $argv
else if type -q nano
nano $argv
else
vi $argv
end
return $status
end
argparse h/help V/visual t/terminal 'e/editor=' c/clipboard 'x/text=' \
n/new v/verbose s/silent -- $argv
or return 1
if set -q _flag_help
echo "$c_head""Usage:$c_reset $c_cmd""edit$c_reset $c_flag""[-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s]$c_reset $c_dim""[FILE...]$c_reset"
echo
echo " Open files in a terminal or GUI editor, with auto-detection and fallbacks."
echo
echo "$c_head""Options:$c_reset"
echo " $c_flag-V$c_reset, $c_flag--visual$c_reset Force the GUI editor (\$VISUAL or fallbacks)"
echo " $c_flag-t$c_reset, $c_flag--terminal$c_reset Force the terminal editor (\$EDITOR or fallbacks)"
echo " $c_flag-e$c_reset, $c_flag--editor$c_reset $c_dim""X$c_reset Use a specific editor binary X"
echo " $c_flag-c$c_reset, $c_flag--clipboard$c_reset Open the clipboard contents (as a temp file)"
echo " $c_flag-x$c_reset, $c_flag--text$c_reset $c_dim""STR$c_reset Open STR as the contents of a new temp file"
echo " $c_flag-n$c_reset, $c_flag--new$c_reset Force a new window/instance (best-effort)"
echo " $c_flag-v$c_reset, $c_flag--verbose$c_reset Print the launch command and editor output"
echo " $c_flag-s$c_reset, $c_flag--silent$c_reset Suppress all output, including the editor's"
echo " $c_flag-h$c_reset, $c_flag--help$c_reset Show this help message"
return 0
end
# Mutually exclusive flag pairs.
if set -q _flag_visual; and set -q _flag_terminal
echo "$c_err""edit: --visual and --terminal are mutually exclusive$c_reset" >&2
return 1
end
if set -q _flag_verbose; and set -q _flag_silent
echo "$c_err""edit: --verbose and --silent are mutually exclusive$c_reset" >&2
return 1
end
# ──────────────────────── Resolve editor mode ────────────────────────
set -l mode
if set -q _flag_visual
set mode gui
else if set -q _flag_terminal
set mode term
else if status is-interactive; and isatty stdout
set mode term
else
set mode gui
end
# ─────────────────────── Resolve editor binary ───────────────────────
set -l bin
if set -q _flag_editor
if not type -q $_flag_editor
echo "$c_err""edit: editor not found: $_flag_editor$c_reset" >&2
return 1
end
set bin $_flag_editor
else if test "$mode" = gui
if set -q VISUAL; and test -n "$VISUAL"
set bin $VISUAL
else
for c in zed antigravity-ide code kate kwrite gnome-text-editor gedit
if type -q $c
set bin $c
break
end
end
end
else
if set -q EDITOR; and test -n "$EDITOR"
set bin $EDITOR
else
for c in nvim vim micro nano vi
if type -q $c
set bin $c
break
end
end
end
end
if test -z "$bin"
echo "$c_err""edit: no editor found for $mode mode$c_reset" >&2
return 1
end
# ─────────────────── Assemble the list of files ──────────────────────
# Positional args first, then synthetic temp files from clipboard/text.
# Temp files are intentionally left for the OS to reap from /tmp: GUI
# editors are detached, so we cannot safely remove them mid-edit.
# ponytail: leak-to-/tmp — add explicit cleanup only if it ever matters.
set -l files $argv
if set -q _flag_clipboard
set -l clip (mktemp --suffix=.txt)
if p >$clip 2>/dev/null
set files $files $clip
else
echo "$c_err""edit: could not read clipboard$c_reset" >&2
command rm -f $clip
return 1
end
end
if set -q _flag_text
set -l txt (mktemp --suffix=.txt)
printf '%s\n' "$_flag_text" >$txt
set files $files $txt
end
# ──────────── Best-effort new-window flag for known editors ───────────
set -l launch $bin
if set -q _flag_new
switch (path basename $bin)
case kate kwrite
set launch $launch --new
case code codium code-insiders zed
set launch $launch -n
case gnome-text-editor
set launch $launch --new-window
# Unknown editors: --new is ignored (best-effort).
end
end
set launch $launch $files
if set -q _flag_verbose
echo "$c_dim→ launching:$c_reset $launch"
end
# ───────────────────────────── Launch ────────────────────────────────
if test "$mode" = gui
# Detach GUI editors so the shell stays free.
if set -q _flag_verbose
command $launch &
else
command $launch &>/dev/null &
end
disown
else
# Terminal editors must stay in the foreground.
if set -q _flag_silent
command $launch 2>/dev/null
else
command $launch
end
end
end