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

Bookmarks for directories #76

Closed
gokcehan opened this issue Apr 17, 2017 · 9 comments
Closed

Bookmarks for directories #76

gokcehan opened this issue Apr 17, 2017 · 9 comments

Comments

@gokcehan
Copy link
Owner

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:

  1. It should work with few keystrokes (e.g. 2 keys, one for the command, another for the bookmark key)
  2. It should list available saved bookmarks to choose from when it is activated
  3. It should allow using letters and numbers as the bookmark key
  4. It should be persistent across restarts (and I guess shared among all clients)
  5. (Maybe) it should have visible marks in the ui?

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.

@lenormf
Copy link

lenormf commented Apr 18, 2017

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.

@mibli
Copy link

mibli commented May 23, 2017

I've written a crude temporary implementation, while I wait for it being added as a feature. Feel free to use and modify.

@mibli
Copy link

mibli commented May 23, 2017

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.

@gokcehan
Copy link
Owner Author

@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.

@gokcehan gokcehan changed the title Implement bookmarks for directories Bookmarks for directories Sep 18, 2017
gokcehan added a commit that referenced this issue Jul 12, 2018
gokcehan added a commit that referenced this issue Jul 12, 2018
@gokcehan
Copy link
Owner Author

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.

gokcehan added a commit that referenced this issue Jul 17, 2018
@wpcarro
Copy link

wpcarro commented Mar 14, 2019

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/).

@gokcehan
Copy link
Owner Author

@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.

@ahrm
Copy link

ahrm commented Apr 3, 2022

I added a simple searchable bookmark list in windows using the following scripts:

bookmark.py:

import os
import sys

BOOKMARK_DIR = "D:\\lf_scripts\\bookmarks"

def bookmark(path, name):
    path = os.path.dirname(path)

    with open(os.path.join(BOOKMARK_DIR, name), "w") as f:
        f.write(path)

if __name__ == '__main__':
    bookmark(sys.argv[1], sys.argv[2])

goto_bookmark.py

import os
import sys
import subprocess

BOOKMARK_DIR = "D:\\lf_scripts\\bookmarks"

def goto_bookmark():
    output = subprocess.run(['D:\\lf_scripts\\findbookmark.bat'], capture_output=True)
    selected = output.stdout.decode('utf8').split('\n')[-2]
    selected = os.path.join(BOOKMARK_DIR, selected)

    with open(selected, 'r') as f:
        file_path = f.read()
        # escape characters
        file_path = file_path.replace('\\', '\\\\')

    subprocess.run(['lf', '-remote', 'send {id} {command} "{selected}"'.format(id=sys.argv[1], selected=file_path, command='cd')])

if __name__ == '__main__':
    goto_bookmark()

findbookmark.bat:

C:\msys64\usr\bin\find.exe D:\lf_scripts\bookmarks\ -type f -printf "%%f\n" | fzf

lfrc:

cmd bookmark %sh -c 'python D:/lf_scripts/bookmark.py %f% $0'
cmd goto_bookmark push $python<space>D:/lf_scripts/goto_bookmark.py<space>%id%<enter>
map B push :bookmark<space>
map b push :goto_bookmark<enter>

@rickalex21
Copy link

Hello,

Is there a way or command to save marks as $HOME/path or ~/path instead of /home/username/path ?

Thanks

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

No branches or pull requests

6 participants