denisidoro / navi

An interactive cheatsheet tool for the command-line
Apache License 2.0
14.93k stars 498 forks source link

How to escape dollar or colon? #841

Open Kossak-esky opened 1 year ago

Kossak-esky commented 1 year ago

Describe the bug I can't use snippet defined in cheat file:

# envss
$DISPLAY = ':0'

because navi interprets it as variable definition instead of inserting $DISPLAY = ':0' into command line. How can I escape either dollar or colon sign?

To Reproduce

  1. Add:

    # envss
    $DISPLAY = ':0'

    to any of your cheat files.

  2. Now run navi and anter query envss

  3. Observe that our snippet is not being found

Expected behavior in step 3 I want to see my snippet, which should insert $DISPLAY = ':0' into command line.

Versions:

welcome[bot] commented 1 year ago

Thanks for opening your first issue here! In case you're facing a bug, please update navi to the latest version first. Maybe the bug is already solved! :)

Kossak-esky commented 1 year ago

I'm already on lastest version. Good bot :)

lacygoill commented 1 year ago

Try to add a space in front of the command:

# envss
 $DISPLAY = ':0'
^

Ignore the caret. It's just there to point to the space above.


How can I escape either dollar or colon sign?

I suppose you meant "semicolon" instead of "colon".

Anyway, I agree that using the semicolon as the comment leader can be problematic.

navi had a similar issue when it had to find a syntax to separate a shell command producing default values for an argument, from optional parameters. It chose ---. I think the rationale is that it extends the -- syntax which is a widely used convention among a lof of Linux commands. FWIW, I would be in favor of doing the same with #, which is often used as a comment leader (navi itself uses it for the command descriptions). navi could use ## for meta-comments, and keep ; as a legacy syntax.

lacygoill commented 1 year ago

and keep ; as a legacy syntax.

Never mind. Keeping ; as a legacy syntax would maintain the issue, unless it's hidden behind a configuration option. I guess it's too late to change that now without breaking people's cheats.

Kossak-esky commented 1 year ago

I suppose you meant "semicolon" instead of "colon".

No, I meant escaping literal colon which is : char (or dollar $- either one should work), because it is used by navi to define snippet variables (eg: $ var: echo 'test') and it can also be used in shell variable as its value (eg for xonsh: $var = ':test'). Navi misbehaves in this case, because it probably thinks it is snippet/navi variable definition (since the line contains both $ and :) and doesn't let me insert my snippet into terminal :(

In other words, this snippet works:

# envss
$DISPLAY = '0'

but this one doesn't work:

# envss
$DISPLAY = ':0'

Anyway I just found a workaround: this snippet inserts what I want into the terminal:

# envss
$DISPLAY = '<colon>0'
$ colon: echo ':'
lacygoill commented 1 year ago

Anyway I just found a workaround: this snippet inserts what I want into the terminal:

I still think that prefixing the command with a space is simpler to read and maintain. That said, if you want to bypass the fzf prompt, you might be interested in passing --select-1 to fzf(1):

# envss
$DISPLAY = '<colon>0'
$ colon: echo ':' --- --fzf-overrides --select-1
Kossak-esky commented 1 year ago

I still think that prefixing the command with a space is simpler to read and maintain.

Yes, it would be simpler for other shells, but I if use multiline statements in xonsh and prefix them with space, it throws error:

$>  $TEST=':0'
 $TEST='a'

xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
  File "<stdin>", line 2
    $TEST='a'
SyntaxError: ('code:  ',)

Probably because it's python shell, so - like in python - every space prefix matters.

That said, if you want to bypass the fzf prompt, you might be interested in passing (...)

Fzf prompt is not invoked in $ colon: echo ':' (for me at least), because variable has only one value. If I added more values (separated by eg new line), then I would see fzf prompt.

Thank you.

lacygoill commented 1 year ago

I if use multiline statements in xonsh and prefix them with space, it throws error:

Understood. I'm not familiar with xonsh.

Fzf prompt is not invoked here (for me at least)

OK, I guess --select-1 is included in your FZF_DEFAULT_OPTS, because by default fzf does give a prompt:

$ env --ignore-environment bash --noprofile --norc -c "echo ':' | $(type --path fzf)"
Kossak-esky commented 1 year ago

I don't have $FZF_DEFAULT_OPTS env var in xonsh nor in bash. Maybe my fzf version 0.39.0 (20230402) has better defaults or the setting is somewhere else.

So we have a workaround for this problem. Not sure if anybody wants to introduce some method of escaping dollars/colons - if not I can close this issue.

lacygoill commented 1 year ago

I don't have $FZF_DEFAULT_OPTS env var in xonsh nor in bash. Maybe my fzf version 0.39.0 (20230402) has better defaults or the setting is somewhere else.

It must be somewhere else, because I can reproduce on master in a freshly installed virtual machine.

So we have a workaround for this problem.

Yes, we might want to document this.

Not sure if anybody wants to introduce some method of escaping dollars/colons - if not I can close this issue.

IMO, it is definitely an issue. I encountered this as soon as I started using navi, but with the semicolon character. I sometimes write this kind of multi-line command:

command 1 \
; command 2 \
; command 3

For me, with the fish shell, the solution was to indent the subsequent commands:

command 1 \
    ; command 2 \
    ; command 3

Not sure about xonsh.

A similar issue might affect the angle bracket characters.