Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rework SEL_OPENWITH, add example plugin openwith #2007

Closed
wants to merge 1 commit into from

Conversation

Darukutsu
Copy link
Contributor

@Darukutsu Darukutsu commented Feb 27, 2025

This solves 3 problems which user might have upon pressing 'o' key:

  1. forgot name or typo of gui/cli program, can use fzf, rofi... instead
  2. exec arbitrary commands over selection let's say git add or anything more complicated
  3. no more need for custom patch [Question] Open command always in CLI mode, don't prompt for cli/gui #1350

Script openwith doesn't clear .selection because I was not sure if I should give it $NNN_SEL.

What do you think?

printf "%s/%s" "$2" "$1" >"$selection"
fi

xargs -0 -I{} $command <"$selection"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we should maybe do to allow using xargs within xargs

xargs -0 -I{} sh -c "$command" <"$selection"

Copy link
Collaborator

@N-R-K N-R-K left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This takes away a built-in functionality and turns it into a plugin with external dependencies. This is a severe regression. Not everyone has plugins installed or might be using nnn in a remote environment with no configuration.

Why can't this be a regular plugin, which you can bind to o and then invoke with alt+key (alt+o in this case)?

Also, nnn already supports running arbitrary shell commands over selection via the builtin shell prompt (bound to ]). E.g echo "%j" will run the command for each file and "%J" will run it for all files at once.

@Darukutsu
Copy link
Contributor Author

This takes away a built-in functionality...

if variable isn't defined it works as previous implementation

echo "%j" will run the command for each file and "%J" will run it for all files at once.

That's great, didn't know about this. I see now, it's documented wiki/Concepts#prompts

Surely this can be plugin but not everyone uses 'o' key and this could extend functionality. I know this is matter of person, for me 'o' was dead key, because of limited auto-completion (almost none). Most of the time in my workflow I do ! ^] Shell to spawn to original shell (i use ble.sh) which has was more capability.

Plugin itself is half-baked nothing interesting to add, just provides fzf with $PATH or history, then you can edit command in your editor and run it over selection. I just wanted to provide example how to work with selection. I think it solves 1) and 3) definitely, no more custom patches.

Maybe you should make repository/directory with not only plugins in one place, but also custom patches, would be nice. I like idea that nnn feels like lego, you start minimal you grow to something bigger. I could go over my free time, collect all interesting patches from issues, discussion... if you're interested

echo "%j" will run the command for each file and "%J" will run it for all files at once.

You spawned idea in my head. Instead of doing plugin like I did, I could define %j and %J in blesh, something like this:

#.bashrc
  ## we could bind this to enter
  function ble/widget/my_custom/nnn_complete() {
    ble/widget/vi_nmap/copy-current-line
    readline_line="${_ble_edit_kill_ring[0]}"
    ble/widget/kill-line

    if echo "$readline_line" | grep "%j" >/dev/null; then
      ble/widget/insert-string "cat ${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection} | xargs -0 -I%j sh -c \"$readline_line\""
    elif echo "$readline_line" | grep "%J" >/dev/null; then
      #elif echo "$READLINE_LINE" | grep -E "(?<!\\)%J"; then
      readline_line=$(echo "$readline_line" | sed 's/%J//')
      ble/widget/insert-string "cat ${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection} | xargs -0 $readline_line"
    else
      ble/widget/insert-string "$readline_line"
      ## or comment this out and don't bind it to enter
      # echo '%j %J not specified, aborting'
    fi
    unset readline_line
    ble/widget/accept-line
  }

  ble-bind -m vi_nmap -f 'C-/ C-n' my_custom/nnn_complete
  ble-bind -m vi_imap -f 'RET' my_custom/nnn_complete

@N-R-K
Copy link
Collaborator

N-R-K commented Feb 28, 2025

if variable isn't defined it works as previous implementation

Ah, you're right, I missed the fall though.

But in any case, I'm still not convinced that this should be built in. A plugin would also solve problem 1 & 3. In fact plugin system exists precisely so that we don't have to support every little preference of every user, they get to write a local plugin that caters to their needs.

@N-R-K N-R-K closed this Feb 28, 2025
@N-R-K
Copy link
Collaborator

N-R-K commented Feb 28, 2025

Instead of doing plugin like I did, I could define %j and %J in blesh, something like this:

You could also just use a function like this in your shellrc (I'm assuming posix like syntax):

nnnxargs()
{
    xargs -0 "$@" < "$NNN_SEL" 
}

Then use this inside of the nnn spawned shell. Less hacky although a bit more typing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants