Author Topic: cd_to_buffer that resolves symlinks first?  (Read 685 times)

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
cd_to_buffer that resolves symlinks first?
« on: March 05, 2024, 02:25:42 PM »
In the existing Slick-C macro cd_to_buffer() in dir.e, I would like a slight variation that resolves all symlinks to the current buffer and then cds to that directory.

For example lets say my buffer has file:

$HOME/dir1/file.c

but $HOME/dir1 is a symlink to $HOME/dir2

so the "realpath" of the file is actually $HOME/dir2/file.c

I would like a variant of cd_to_buffer() that will cd to $HOME/dir2 instead of $HOME/dir1.

Does such a variant exist?

If not any tips on how to create one?

Clark

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 6877
  • Hero Points: 530
Re: cd_to_buffer that resolves symlinks first?
« Reply #1 on: March 05, 2024, 03:23:51 PM »
There is definitely no option like that.

The code that handles def_switchbuf_cd isn't obvious due to performance optimizations.

Code is here in codehelp.e:
Code: [Select]
void _CodeHelp(bool AlwaysUpdate=false)
{
   if (gpending_switchbuf) {
      gpending_switchbuf=false;
      buf_name:=gpending_switchbuf_buf_name;
      if (_isUnix()) {
          // If this buffer name has a valid path
          if (substr(buf_name,1,1)=="/") {
             _str path;
             if (_get_filetype_dir_parts(buf_name,path,auto ft_file)) {
             } else {
                path = _strip_filename(buf_name,'N');
             }
             // We don't want buffer order changed when if build window
             // buffer is activate so here we change the load options before
             // calling cd().
             old_load_options := def_load_options;
             def_load_options=stranslate(lowcase(def_load_options)," ","+bp");
             cwd := getcwd();
             _maybe_append_filesep(cwd);
             _maybe_append_filesep(path);
             if (!_file_eq(path,cwd)) {
                cd("-a "_maybe_quote_filename(path),"q");
             }
             def_load_options=old_load_options;

You could resolve "path" using absolute(), in the call to cd(). Changing cd() might be too much of a sledgehammer.

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: cd_to_buffer that resolves symlinks first?
« Reply #2 on: March 05, 2024, 06:20:56 PM »
I tried using absolute() but it is not resolving a directory in the path that is a symlink.

For example the buffer is in directory:

/home/me/<symlinkdir>/dira/dirb/file.c

When I do:

absolute(/home/me/<symlinkdir>/dira/dirb/file.c)

It is not resolving the <symlinkdir> in the middle of the path and absolute returns:

/home/me/<symlinkdir>/dira/dirb/file.c

which is not the path I want. I would like <symlinkdir> to be resolved.

Is there anything in Slick-C like the realpath() function in linux?

Here is the function I created:

Code: [Select]
_command int cd_to_realpath_buffer,cdb() name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY|VSARG2_NOEXIT_SCROLL|VSARG2_MARK)
{
    int status=PATH_NOT_FOUND_RC;
    dsay("p_buf_name: " p_buf_name);
    dsay("absolute(p_buf_name): " absolute(p_buf_name));
    if (p_buf_name != '') {
        directory := _strip_filename(absolute(p_buf_name), 'NE');
        if(isdirectory(directory)){
            status=cd(directory);
        }
    }
    return(status);
}

Clark

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 6877
  • Hero Points: 530
Re: cd_to_buffer that resolves symlinks first?
« Reply #3 on: March 05, 2024, 09:25:04 PM »
The third parameter to absolute specifies whether to resolve symbolic links. It's off by default because it's expensive.

rowbearto

  • Senior Community Member
  • Posts: 2335
  • Hero Points: 132
Re: cd_to_buffer that resolves symlinks first?
« Reply #4 on: March 06, 2024, 06:58:03 PM »
Thanks Clark, that works.

For future reference the function is:

Code: [Select]
/**
 *  Changes the current working directory to the path after
 *  resolving symlinks containing the active document.
 *  @see cd
 *  @categories File_Functions
 */
_command int cd_to_realpath_buffer,cdb() name_info(','VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY|VSARG2_NOEXIT_SCROLL|VSARG2_MARK)
{
    int status=PATH_NOT_FOUND_RC;
    if (p_buf_name != '') {
        // 3rd parameter of absolute() as 'true' will resolve symlinks in all directories of the p_buf_name.
        // See SlickEdit Help->Index->absolute for "absolute()" parameter documentation.
        // Also see: https://community.slickedit.com/index.php/topic,19407.0.html
        directory := _strip_filename(absolute(p_buf_name,null,true), 'NE');
        if(isdirectory(directory)){
            status=cd(directory);
        }
    }
    return(status);
}