feat(edit): multi-editor launcher with GUI/terminal fallbacks #59
@@ -257,7 +257,7 @@ If you'd rather set them by hand, each category is controlled by a universal var
|
||||
|
||||
| Variable | Disables |
|
||||
|---|---|
|
||||
| `__fish_config_op_aliases` | Command shadows: `ls`→eza, `cat`→bat, `cd`→zoxide, `rm`→trash, `top`→btop, and friends; `grep`/`cp`/`mv`/`wget` flag injection |
|
||||
| `__fish_config_op_aliases` | Command shadows: `ls`→eza, `cat`→bat, `cd`→zoxide, `rm`→trash, `top`→btop, `edit`→multi-editor launcher, and friends; `grep`/`cp`/`mv`/`wget` flag injection |
|
||||
| `__fish_config_op_autoexec` | Startup side-effects: Fisher bootstrap, theme apply, `paru`/`yay` wrapper generation, auto venv activation, WakaTime hook |
|
||||
| `__fish_config_op_overrides` | Vi mode, `exit`→`smart_exit`, `$PAGER`/`$MANPAGER`/`$CDPATH`, bang-bang history expansion, autopair, puffer, Starship prompt, theme colors |
|
||||
| `__fish_config_op_integrations` | Kitty/WezTerm window abbreviations, `done` notifications, `spwin`/`tab`/`split`, `hist`, `logs`, `upgrade`, WakaTime |
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ if type -q nvim
|
||||
else
|
||||
set -gx EDITOR (command -s vi)
|
||||
end
|
||||
set -gx VISUAL $EDITOR
|
||||
# set -gx VISUAL $EDITOR # <- Use local.fish to set your preferred GUI editor.
|
||||
set -gx SUDO_EDITOR $EDITOR
|
||||
|
||||
# ──────────────────────────── GPG variables ─────────────────────────────
|
||||
|
||||
+30
-3
@@ -159,7 +159,8 @@ Tools that respect XDG are directed to these paths rather than polluting $HOME.
|
||||
## Editor and Pager
|
||||
|
||||
EDITOR nvim (falls back to vi if nvim is absent)
|
||||
VISUAL same as EDITOR
|
||||
VISUAL unset by default; set a GUI editor via local.fish (the edit
|
||||
function falls back to a GUI chain when VISUAL is empty)
|
||||
SUDO_EDITOR same as EDITOR
|
||||
PAGER ov (falls back to less)
|
||||
|
||||
@@ -698,10 +699,35 @@ Add -i (interactive confirmation) to destructive commands:
|
||||
|
||||
### edit
|
||||
|
||||
Synopsis: edit [args...]
|
||||
Opens files in nvim. Falls back to $EDITOR, nano, vi.
|
||||
Synopsis: edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...]
|
||||
|
||||
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 use the terminal editor
|
||||
($EDITOR), while detached invocations (e.g. desktop shortcuts) use 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
|
||||
|
||||
Options:
|
||||
-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)
|
||||
-v, --verbose Print the launch command and editor output
|
||||
-s, --silent Suppress all output, including the editor's
|
||||
-h, --help Show this help message
|
||||
|
||||
edit ~/.config/fish/config.fish
|
||||
edit --visual notes.txt
|
||||
edit --terminal --new todo.md
|
||||
edit --editor=code --clipboard
|
||||
edit --text="hello world"
|
||||
|
||||
### fc
|
||||
|
||||
@@ -1632,6 +1658,7 @@ all of these commands.
|
||||
dir / vdir forced --color=auto system dir / vdir
|
||||
help config intercepts "help config" → config-help fish builtin help
|
||||
claude auto-links AGENTS.md as CLAUDE.md before launch command claude
|
||||
edit multi-editor launcher (GUI/term + fallbacks) $EDITOR/nvim/nano/vi
|
||||
|
||||
When C1 is disabled, `rm` uses bare `command rm` with no wrapper — files
|
||||
are permanently deleted, not trashed. There is no intermediate safety net.
|
||||
|
||||
+188
-13
@@ -2,25 +2,200 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# SYNOPSIS
|
||||
# edit [args...]
|
||||
# edit [-V|-t] [-e EDITOR] [-c] [-x TEXT] [-n] [-v|-s] [FILE...]
|
||||
#
|
||||
# DESCRIPTION
|
||||
# Opens files in nvim, falling back to $EDITOR, nano, or vi if nvim is not
|
||||
# installed.
|
||||
# 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
|
||||
# args... Files and options forwarded to the editor
|
||||
# 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 ~/.config/fish/config.fish
|
||||
function edit --wraps='nvim' --description 'alias edit=nvim'
|
||||
if type -q nvim
|
||||
nvim $argv
|
||||
else if set -q EDITOR
|
||||
$EDITOR $argv
|
||||
else if type -q nano
|
||||
nano $argv
|
||||
# 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
|
||||
vi $argv
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user