ed8de40d46
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.
202 lines
7.9 KiB
Fish
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
|