leo-arch/clifm

2-step symbolic link creation

Closed this issue ยท 10 comments

Is your feature request related to a problem? Please describe.
Please allow a two step creation of symbolic links:

  • Step 1: get the target of the designated link and keep it in mind

(then change the directory to the place where the link should be)

  • Step 2: place the link there

Describe the solution you'd like
clifm has, like other "single window" file managers, the problem that the creation of a symbolic link gets difficult when it should then be located in another directory. If you have a file you can use l to create a link to that file. But the link will be placed in the current directory directly beside the file itself (see alternatives below). And moving that new symlink afterwards to another place is not easy, the m command will probably not support this.

I suggest the following:

  • Step 1: allow the user to pick a file or directory name (an ELN) for creating a link later, keep that name (and it's path) somewhere in an internal variable. This could be done by a "remember name" command, something like rn filename or rn dirname or rn ELN.

  • Step 2: allow the user create an ordinary symlink wherever he wants (also in another workspace) using the informations from the 1st step, this second operation could also be repeated on more than one place as long as the informations from the 1st step are still valid. This could be done
    -- using a parameter for l which represents that remembered name, for instance l -n or l -n link
    -- or with a new command like ln or ln link
    -- or with a special symbol which represents the name, l @ or l @ link

The last idea, a special symbol, would allow to use a remembered name also in other commands. Imagine you want to start a program in a concrete directory but with a filename from another directory as parameter. Or you want to copy a file you found somewhere here into the current directory: c @ .

This principle (the 2-step link creation) is used by a Windows software called Link Shell Extension which is an extension for the Explorer which also has only a single window (see the pictures there).

Describe alternatives you've considered
Yes, of course the user could specify a concrete destination path for l to place the designated link where he wants. But this could be difficult and error-prone. And because you don't see the target directory in that moment you can place a link somewhere at a wrong place and do not notice this.

Just an idea.

Hi @muellerto. I don't think we need to change anything: you can just select the desired target file, and then pass it to the l command using the sel keyword. Example:

sel target_file
cd some_dir
l sel link

In case you have multiple selected files, you can use TAB to pick a single file: l sel<TAB>.

Note: the s: expression can also be used to expand selected files. In this case, l s:<TAB>.

Ahm ...

... you could (because of it's usefulness) mention this in the documentation(s). I just pressed F2, l and le don't mention any selection.

I will. Thanks for pointing this out.

On Windows it's as follows:

  1. I selected a directory, this is then shown in the selection box.
  2. Then I changed the workspace where I had a totally different directory but on the same partition.
  3. l sel or l sel link or l s:<TAB> make then not a symlink at this place but an ordinary directory with some (but by far not all) files. A bit mysterious. How should some files be copied and others not.

l filename, l dirname or l ELN (the one step principle) make indeed a symlink either onto a file or directory but in the same original directory.

I've made a few tests, and what I got is just our old friend: symlinkat(2) (just as symlink(2)), two syscalls used to create symbolic links, do not know how to create symbolic links on MSYS/MinGW (while they can without any issue on Cygwin).

Btw, the same thing happens if you use the coreutils ln(1), because both, ln and Clifm's l, do the same thing under the hood: calling symlink(2).

In case you want to take a look at it, here's our function:

symlink_file(char **args)

I've found this article, according to which the symlinks feature under MSYS2/MinGW needs to be enabled first via an environment variable. And it works!

Try running clifm as follows:

MSYS="winsymlinks:native" clifm

Here, some recommend using nativestrict instead of native, to prevent the creation of dangling symlinks (target does not exist), which seems to be problematic on MSYS2 (I've experienced no issue in this regard though).

However, it should be stressed what, at this point, is obvious: despite this trick (which is just that, a trick), MSYS2, and unlike Cygwin (even when MSYS2 is based on Cywin!), does not like symlinks. So, I'd not expect not to experience some new symlinks issue in the future.

Oh, thanks a lot for this investigation. An environment variable is something I hadn't in mind at all. Why that???? - I'll put this environment variable just into my clifm.bat start batch, no problem:

@echo off
set PATH=c:\usr\Utils\__replacements;%PATH%
set PAGER=bat
set MSYS="winsymlinks:native"
c:\usr\local\msys64\usr\local\bin\clifm.exe --no-bold %1 %2 %3 %4 %5 %6 %7 %8 %9

I don't want to give Windows more importance than the whole group of Unix like OSes, and sure: clifm on Windows is still exotic, but probably it would be good to have a paragraph in chapter 21 of the PDF file, Miscellaneous Notes, for Windows and it's special needs.

However, it should be stressed what, at this point, is obvious: despite this trick (which is just that, a trick), MSYS2, and unlike Cygwin (even when MSYS2 is based on Cywin!), does not like symlinks.

I don't understand that. Symbolic links have been a feature on NTFS since it's beginnings in the late 90s. Microsoft himself uses symbolic links (and hard links) in their system directories. Some of the most important directories, Program Files and Users, are symlinked for decades to language specific names, on a German speaking OS they are symlinked to Programme and Benutzer, on millions of machines and the Explorer uses consequently these names. What I want to say is: symlinks are just reality, for decades, also on Windows.

A special aspect of this symlink topic is that the basic C functions are not completely provided by Microsoft's C runtime libs, and that's the base of all other implementations. So, when you want to provide symlink functionality (like Cygwin and MinGW do in their gcc C runtime libs) you must do it on your own using Windows API functions. Could be that another compiler like clang does it differently. When you have a look at other symlink function implementations as in the C++ boost library you find again other specific problems and need quirks.

So, I'd not expect not to experience some new symlinks issue in the future.

I give my best :)

Oh, thanks a lot for this investigation

You're welcome @muellerto! I just enjoy learning, that's it.

probably it would be good to have a paragraph in chapter 21 of the PDF file, Miscellaneous Notes, for Windows and it's special needs

I will. Are you willing to make a little list of these needs? Since you're an actual Windows user, you're clearly more qualified than me in this specific regard.

I don't understand that. Symbolic links have been a feature on NTFS since it's beginnings in the late 90s.

I do not refer to Windows as such, but to MSYS2, which as a matter of fact (and because of some reason I just ignore) disables/replaces the symlink(2) syscall by default.

I give my best :)

I know you do, and I'm thankful for that.

have a look at the following, I wrote this for the Windows user, hope this is not to long


Windows users who did manage compiling clifm sources successfully under Cygwin or MinGW will be confronted with some additional pitfalls.

Note that it's a good idea to make a start batch file for clifm from the following steps, for instance clifm.bat, and to use this rather than clifm.exe directly.

Note furthermore that creating symbolic links depends on most Windows machines on a local security policy which must be switched on manually (since symbolic links are damned dangerous and not for everyone ...)

  1. clifm needs some external help, especially find, fzf, cp, rm, ln, sh and/or others. A problem is find since Windows has it's own find, find.exe, a rather primitive tool for text searching in files. And because of the location of find.exe is very early in the generated PATH environment variable and the user has no chance to change this later a workaround is needed. A good place for this is directly before clifm will be started. The principle is as follows:

    a) make a directory somewhere
    b) place a symbolic link in it pointing to the concrete implementation of a UNIX find you want to use (probably from Cygwin or MSYS), note: this link should be named find.exe
    c) modify your local PATH environment variable: set PATH=directory;%PATH

    With that you have the desired find before all other finds in PATH. When clifm starts with this PATH it will find the desired find for sure. Keep in mind that this PATH is also present in all child processes of clifm.

  2. At least the MSYS implementation of ln (make a symbolic link) seems to require an environment variable to work properly. Put the following line in the start batch file:

    set MSYS="winsymlinks:native"

  3. clifm uses for some purposes an external pager application like more, less, bat or others. Define the pager you want to use in an environment variable:

    set PAGER=bat

    Note that the given name must be found in PATH. If you need a symbolic link in the directory from 1. make one there.

  4. Some Windows "terminals" use strange fonts and Cleartype or other font smoothing algorithms. Not all do look good. clifm uses also bold fonts for some purposes which can lead to readability problems under some conditions. If you want to avoid bold fonts in your display start clifm in your start batch using the --no-bold parameter:

    c:\...\clifm.exe --no-bold %1 %2 %3 %4 %5 %6 %7 %8 %9

  5. clifm shows text in a lot of colors with a sophisticated shading algorithm. Not all Windows "terminals" are able to show this properly. A well known candidate for problems is ConEmu (with several derivates having other names). ConEmu has own color schemes and the merge result of two colors gets sometimes hard to interpret. Good and useful terminals for Windows are mintty and wt (the Windows Terminal).

Thanks @muellerto! I'll move this to the wiki.

EDIT: Done.