So this was first discussed in #62. Some of the things discussed there are duplicated here.
If bookmarks can be implemented properly as custom commands then there is not much to discuss here anyway. If we can come up with a brief/simple example and it implements a generally acceptable/expected behaviour we can add the sample to our example config file. If not, we can leave it here.
In general following are some of the thing which should be possible in bookmarks:
Currently we're using regular maps as bookmarks (e.g. map gh cd ~). This is good enough for some but not for others. So ideally, there should be a way to manage bookmarks dynamically rather than statically in the config file.
As for example, I like ranger's implementation. Basically they use the concept of marks in vim as bookmarks (e.g. m for marking a directory, and ' for jumping to a mark). When jumping to a mark, they list all available bookmarks to the user to choose from, which is not possible in vim without calling :marks explicitly.
So I was thinking we could implement a similar behavior in lf using custom commands as follows. Bookmarked directories can be saved within a file similar to ranger (we can also be compatible so they can be shared). A mark-save command (e.g. possibly bound to m key) can list all available bookmarks and ask the user for a key to save the current directory as a bookmark. Similarly another mark-load or mark-jump command (e.g. possibly bound to ' key) displays available bookmarks and ask the user for a key. read builtin in bash allows reading a single character at a time without the enter key. It is a little tricky in posix shell but it is still possible (as in our code for the "press any key" implementation). Therefore, we can accomplish almost all point I have mentioned above.
Considering how unelegant a shell implementation would be (major UI flashes when spawning processes, unability to read only a single character from stdin in a POSIX manner, complicated code to handle the bookmarks database…), I would be in favor of a builtin implementation. It looks like everything that is needed to implement this feature is there already, isn't it?
As for the cross compatibility with ranger and the similarity of the mappings used, it's a tad more sophisticated than I had imagined (one digit that serves as identifier, and a single key that jump to a given identifier), but I guess that's fine.
I've written a crude temporary implementation, while I wait for it being added as a feature. Feel free to use and modify.
Alternatively if menu drawing command gets exposed, we could implement bookmars quite cleanly, but for full ranger-like implementation, we'd still need to hook into a builtin cd command.
@mibli Thanks for the example. I haven't tried it but it looks like it assumes bash for the shell interpreter. Posix compatible character reading is quite ugly so we should definitely add this as a builtin feature somehow.
I have finally found an acceptable way to implement bookmarks in the code. Two commands have been added mark-save (default m) and mark-load (default '). Marks are written to a marks file on quit (e.g. ~/.local/share/lf/marks) which is compatible with ranger's marks file so I think one can symlink these to each other.
Marks file is read once at startup and written on quit. When multiple clients add their own marks, both should be added to the file. Feel free to report any issues regarding this behavior. Note that there is an unhandled case in which an existing mark is changed in one client and it quits before another client in which case the change would be lost. It is not very obvious how to handle this case, though this should not happen often.
Closing this issue for now.
This is a bit of a nit, but is there anyway to define marks in the lfrc? I'd prefer to manage just one configuration file instead of two -- especially if the second configuration file is stored in a separate directory (i.e. ~/.local/share/lf/ vs. ~/.config/lf/).
@wpcarro I still mostly use the previous workaround for bookmarks, that is assigning keybindings with cd command:
map gx cd /path/to/xxx
map gy cd /path/to/yyy
If you want to use ' key for mappings, you need to clear the default mapping first (you need to quote single quote with double quotes):
map "'"
And then you can use this key for your mappings:
map "'x" cd /path/to/xxx
map "'y" cd /path/to/yyy
You can also consider using a symbolic link for your marks file if you want to keep it in ~/.config/lf:
touch ~/.config/lf/marks
ln -s ~/.config/lf/marks ~/.local/share/lf/marks
Hope this helps.
Most helpful comment
@wpcarro I still mostly use the previous workaround for bookmarks, that is assigning keybindings with
cdcommand:If you want to use
'key for mappings, you need to clear the default mapping first (you need to quote single quote with double quotes):And then you can use this key for your mappings:
You can also consider using a symbolic link for your marks file if you want to keep it in
~/.config/lf:Hope this helps.