lf icon indicating copy to clipboard operation
lf copied to clipboard

[Feature request] Expose menu drawing command

Open mibli opened this issue 8 years ago • 18 comments

I'd like to be able to create commands that use built in menu. Instead of flashing with confusing shell prompts, it would be cool to allow user to request input using lf gui.

mibli avatar May 23 '17 08:05 mibli

Do you mean like shell's select statement but something that uses the builtin ui instead? There are no control flows implemented in the interpreter. We should discuss more details about this before we can decide on the feasibility of this approach. I'm guessing one of the use cases is to implement bookmarks as a custom command. Are there other use cases you have in mind?

gokcehan avatar May 25 '17 10:05 gokcehan

I've had mostly bookmarks in mind. Of course it would open up many personalization possibilities though. For example renaming, or implementing directory tree searching command with result selection. Kind of like the select statement.

mibli avatar May 29 '17 08:05 mibli

Another use case would be mounting drives without flashing shell. I wrote for this a little shell script, which parses lsblk output and let's user select the drive to mount. If menu drawing was exposed, I would not need to rely on tmux or something to keep lf visible during the process.

Chrysostomus avatar Sep 16 '18 10:09 Chrysostomus

@Chrysostomus That sounds cool and I'm sure there are many other things builtin menus could be used for. The problem is that it is not very obvious how to implement such a feature. For example how would you want to write your mount drive command as a lf command? Regular commands are simply shell commands so it is not possible to pass the selection. Remote commands helps a little but still it is not easy to pass information back and forth. Other programs usually try to embed a full scripting language for such purposes or they are already written in a dynamic language such as python (e.g. ranger) so it is possible to add user written code in the runtime. Unfortunately our commands are much more limited in this respect.

So I'm open to suggestions about the implementation. It would help a lot to have some example commands written using a hypothetical interface, whether it be a command line flag or whatever.

gokcehan avatar Sep 17 '18 10:09 gokcehan

Unfortunately I have zero knowledge in go, I know only bash and python, so I have little to offer when it comes to solutions. At the moment tmux is probably the best solution then =). Love your work btw, I'm considering adding it as alternative file manager in bspwm edition.

Chrysostomus avatar Sep 17 '18 11:09 Chrysostomus

I'll try.

I imagine menu command could take list of tuples as argument. First item of pair would be string with key, second - command name and third - any valid lf command.

cmd mount-menu \
  "m" "mount pendrive" ${{ mount /dev/sda1 /foo }} \
  "c" "visit mount dir" :{{ cd /mnt }}

map <f3> :mount-menu

TeddyDD avatar Sep 17 '18 11:09 TeddyDD

Sorry for late reply.

@Chrysostomus I'm glad to hear you like lf. Also, manjaro is one of the better distros out there so thanks for working on it =)

For this issue, I'm not asking for the implementation part within the go source but I just need to see example shell commands with example use cases. Implementation in the go within the codebase may or may not be a problem but that is a consideration for later.

@TeddyDD You can achieve something similar to that by utilizing the keybinding menu:

map <f-3>m $mount /dev/sda1 /foo
map <f-3>c cd /mnt

Or if you like to display option names you can have something like:

map <f-3>m ${{
    # mount pendrive
    mount /dev/sda1 /foo
}}

map <f-3>c :{{
    # visit mount dir
    cd /mnt
}}

Though : does not show the the option name since comments are simply skipped by the lexer. We can probably do something about this if necessary.

The other issue is that if you need to change the menu key, you need to change it in all mappings. So this is more like a workaround than a full replacement for your suggestion. Maybe we can add a mechanism to add custom key names, kind of like <leader> key in vim. This would probably be easier to implement.

gokcehan avatar Sep 19 '18 19:09 gokcehan

I'll come up with some example shell code when I have time.

I like how fzf/fzy/dmenu do menus: you input items separated by newlines, you select a line and it is printed to standard out. You can do practically anything with that model. For example, pipe lsblk to menu, select a line, extract the device name out of it and mount the device with udisksctl and lf -remote cd there. That's what my current script does using fzf-tmux. For the menu, any pattern matching like fzf has would be unnecessary.

In an optimal case for scripting, you could have two new commands that take input and give out put: lf -remote menu and lf -remote input. Menu would work as described above, like fzf but without any matching or input. Lf -remote would except input written in lf and then pass it on to the shell it was called in. Although that might not be necessary, as it is already possible to just echo and input from a script when it is run with ui from lf...

Chrysostomus avatar Sep 19 '18 21:09 Chrysostomus

Another use case would be mounting drives without flashing shell. I wrote for this a little shell script, which parses lsblk output and let's user select the drive to mount. If menu drawing was exposed, I would not need to rely on tmux or something to keep lf visible during the process.

Like this but use built in menu ui instead of fzf

cmd umount ${{ echo "Available devices are: Name Size Lable" x="$(lsblk -ro 'name,type,size,label,mountpoint' | awk '$2 !~ /^disk$/ && NF<=4 { print $1,$3,$4 }' | fzf --layout=reverse --prompt='Available devices are: Name Size Lable:' | awk -F ' ' '{ print $1 }')" if [ "$x" ]; then mkdir -p ~/mnt/device-$x $WHEEL mount /dev/$x ~/mnt/device-$x -o uid=$(id -u),gid=$(id -g) lf -remote "send $id cd ~/mnt" notify-send "device-$x mounted" else exit 0 fi }}

cmd uumount ${{ lf -remote "send $id cd ~" x="$(ls ~/mnt | fzf --layout=reverse --prompt='Available devices are: Name Size Lable:')"
if [ $x ]; then $WHEEL umount ~/mnt/$x rm -rf ~/mnt/$x lf -remote "send $id reload" notify-send "$x removed" else exit 0 fi }}

ghost avatar Oct 04 '23 10:10 ghost

$wheel is exported from bash profile

ghost avatar Oct 04 '23 10:10 ghost

@Chrysostomus That sounds cool and I'm sure there are many other things builtin menus could be used for. The problem is that it is not very obvious how to implement such a feature. For example how would you want to write your mount drive command as a lf command? Regular commands are simply shell commands so it is not possible to pass the selection. Remote commands helps a little but still it is not easy to pass information back and forth. Other programs usually try to embed a full scripting language for such purposes or they are already written in a dynamic language such as python (e.g. ranger) so it is possible to add user written code in the runtime. Unfortunately our commands are much more limited in this respect.

So I'm open to suggestions about the implementation. It would help a lot to have some example commands written using a hypothetical interface, whether it be a command line flag or whatever.

wishing this feature too. i think there's two ways :

  1. just give a choice to increase the heighth of cmd line. (this is for fzf/mime-open --ask like program, we can't distract the menu out from the program)
  2. a bultin cmd to receive a list and show it in built-menu. ( this is for rifle -l or custom-bookmark like program, the output and input are 2 things, we only need a place to display it, without flashing the lf instance. )

superiums avatar Nov 28 '23 11:11 superiums