Closed lacygoill closed 11 months ago
Never mind. It's only for the few default snippets which are not read from any file. So, closing.
A more annoying issue is the fact that the editor specified in $VISUAL
is started in a broken way, when we press ctrl-o
after navi has been called from a command substitution:
$ bash --norc --noprofile
$ echo $(navi --path=$HOME/.local/share/navi/)
# press: C-o
I need --path=$HOME/.local/share/navi/
because that's where I put my navi files.
It's broken because the editor's UI is never drawn, and the latter seems stuck, which is very confusing when $VISUAL
is nano(1)
(less confusing with Vim, which at least prints some message "Vim: Warning: Output is not to a terminal"). To kill the editor, we need to press ctrl-c
.
For now, as a workaround, I remove the ctrl-o
key from the fzf option --expect
in the navi YAML config file:
overrides: >-
--no-expect
--expect ctrl-y,enter
Note that we need to specify --no-expect
before resetting the option, because:
If --expect option is specified multiple times, fzf will expect the union of the keys. --no-expect will clear the list.
Source: fzf man page.
For now, as a workaround, I remove the
ctrl-o
key from the fzf option--expect
in the navi YAML config file
Better way: leave --expect
alone, but reconnect the stdout of navi to the terminal:
$ echo $(navi --path=$HOME/.local/share/navi/ --print >$(tty))
^-----^
This example might look contrived, but it's a simplification of this fish code:
bind \cg\cg shell-snippets
function shell-snippets
set -f current_process $(commandline --current-process)
set -f leading_whitespace $(string match --regex -- '^\s*' $current_process)
set -f current_process $(string trim -- $current_process)
if test -z "$current_process"
# `--print` makes navi print the chosen snippet to stdout, instead of executing it.{{{
#
# This lets us insert the snippet on the command-line, using
# `commandline --insert` and a command substitution.
#}}}
# `>$(tty)`: for `C-o` to work as expected.{{{
#
# Without, the editor specified in $VISUAL is started in a broken way,
# when we press `C-o`. MRE:
#
# $ bash --norc --noprofile
# $ echo $(navi --path=$HOME/.local/share/navi/)
# # press: C-o
#
# It's broken because the editor's UI is never drawn, and the latter
# seems stuck, until we kill it by pressing `C-c`.
#}}}
commandline --insert -- $(navi --path=$HOME/.local/share/navi/ --print >$(tty))
commandline --function repaint
return
end
set -f snippet $(navi $options --query="$current_process")
commandline --replace --current-process "$(string join -- '' $leading_whitespace $snippet)"
commandline --function repaint
end
Better way: leave
--expect
alone, but reconnect the stdout of navi to the terminal:
Actually, that's a bad idea. While it fixed C-o
, it also breaks Enter
.
So, I ended up removing ctrl-o
from --expect
, as explained before, and installing a M-e
key binding which correctly handles the case where navi is started from a command substitution:
finder:
command: fzf
# https://github.com/denisidoro/navi/blob/master/docs/customization.md#overriding-fzf-options
# `--no-expect`, `--expect ctrl-y,enter`{{{
#
# Problem: Pressing `C-o` might start `$VISUAL` in a broken way.
# Solution: Make navi ignore `C-o`.
#
# By default, navi sets `--expect` to `ctrl-y,ctrl-o,enter`:
#
# $ cd <navi source code>
# $ rg ctrl-o
# src/finder/mod.rs:106:51: command.args(["--expect", "ctrl-y,ctrl-o,enter"]);
# ^----^
#
# The purpose is to make navi starts `$VISUAL` to edit the file containing the
# definition of the currently selected snippet. However, it doesn't work as
# expected when navi is started from a command substitution:
#
# Vim: Warning: Output is not to a terminal
#
# The editor is stuck, and never draws its TUI (`C-c` needs to be pressed).
#
# To avoid this, we remove `C-o` from `--expect`. But before resetting the
# option, we first need to clear it; hence `--no-expect`:
#
# > If --expect option is specified multiple times, fzf will expect the union of
# > the keys. --no-expect will clear the list.
#
# MRE:
#
# $ bash --norc --noprofile
# $ echo $(navi --path=$HOME/.local/share/navi/)
# # press: C-o (make sure to select a snippet which comes a file; a few hard-coded and navi-related don't)
#
# ---
#
# Besides, we often press `C-o` by accident while navi is running; e.g.:
#
# start navi
# v-----v
# C-g C-g C-o
# ^^^
# accident
#
# Instead of:
#
# C-g C-o
# ^-----^
# run fish omni-TUI function
#
# When that happens, it's better for navi not to react.
#}}}
# `--bind='alt-e:execute(editor ...)'`{{{
#
# Problem: We can't edit the file containing the currently selected snippet.
# Solution: Install a (new) key binding.
#
# Contrary to `C-o`, it correctly handles the case where navi has been started
# from a command substitution, because we reconnect the editor's stdout to the
# terminal:
#
# --bind='alt-e:execute(editor ... >"$(tty)")'
# ^-------^
#}}}
overrides: >-
--no-expect
--expect ctrl-y,enter
--bind='alt-e:execute(editor "$HOME/.local/share/navi/$(sed --quiet "s/\([-_a-zA-Z0-9]\+\).*/\1/p" <<<{})".cheat >"$(tty)")'
# `>-` is a syntax which lets us split a long string on multiple lines.{{{
#
# It's called “Line Folding”: https://yaml.org/spec/1.2.2/#65-line-folding
#}}}
For anyone reading this: if your cheat files are in the default location, you might need to replace $HOME/.local/share/navi/
with $(navi info cheats-path)
.
Describe the bug
Pressing
ctrl-o
makes navi crash.To Reproduce
Steps to reproduce the behavior:
$ navi
in a terminal emulatorctrl-o
Expected behavior
No crash.
Screenshots
N/A
Versions:
Additional context
Here is a full backtrace:
It seems the issue ends at this block of code:
https://github.com/denisidoro/navi/blob/06a72c5dceccd54dba95ac0af9d8ff76d1da9a29/src/commands/core/actor.rs#L208-L212
I can reproduce with no navi config, no shell config, and no terminal config.