[Feature request] Expose menu drawing command
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.
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?
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.
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 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.
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.
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
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.
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...
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
}}
$wheel is exported from bash profile
@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 :
- just give a choice to increase the heighth of cmd line. (this is for
fzf/mime-open --asklike program, we can't distract the menu out from the program) - a bultin cmd to receive a list and show it in built-menu. ( this is for
rifle -lorcustom-bookmarklike program, the output and input are 2 things, we only need a place to display it, without flashing the lf instance. )