Sublime Forum

Opening the same file with path containing a symlink opens a new tab instead of focussing on existing one

#1

Hello everyone :slight_smile: , I would love to get some help on this issue:

Sublime treats files opened via paths containing symbolic links as different from one another. Here is an example to clarify -
Lets say I’m working on a file named file.cpp. This file can be accessed in three ways:

  1. Using the file’s absolute path:

/home/user1/documents/examples/file.cpp

  1. Using a symbolic link to the file itself:

/home/user1/file.cpp -> documents/examples/file.cpp

  1. Using a symbolic link in one of the directories in the middle:

/home/user2/user1_docs/file.cpp
(Assuming /home/user2/user1_docs -> ../user1/documents/)

An attempt to open the file file.cpp using the three ways together is expected to result in a single new tab. Unfortunately, the actual result is a new tab per each way, with a total of 3 tabs to the same file (no matter the order of ways you try)!

Technical Details

I’m using SublimeText build 3126, non portable, with Ubuntu 14.04.

Technical findings

While trying to investigate the issue, I examined each of the view objects who’s their file_name() method directed to file.cpp, and found out that:

  1. Each of the views returned true from the method is_primary()
  2. Each of the views returned the same buffer id from the method buffer_id()

This means that Sublime truely thinks that the 3 views direct to separate files, but is capable to understand that they actually refer to the same one.

Solution?

I tried to write a plugin as a workaround: @Gist

import sublime
import sublime_plugin

import os.path

import logging
logger = logging.getLogger(__name__)


# Maintains a list of the currently open files.
# It is more efficient to update it live than to create it from scratch per
# each trigger of `on_load` event 
open_files_paths = []


def plugin_loaded():
    global open_files_paths
    open_files_paths = [
        view.file_name()
        for view in sublime.active_window().views()
        if view.file_name()]
    logger.debug("Obtained list of opened files: {}".format(open_files_paths))


class OpenedFilesListener(sublime_plugin.EventListener):
    def on_load(self, view):
        open_files_paths.append(view.file_name())
        logger.debug(
            "Adding opened file to list of opened files: {}".format(
                view.file_name()))

        # Check whether someone is trying to open an already opened file from
        # a different path (this logic seems missing from SublimeText)
        for opened_file_path in open_files_paths:
            if (view.file_name() != opened_file_path and
                    os.path.samefile(view.file_name(), opened_file_path)):
                logger.debug("Closed path:  \"{}\"".format(view.file_name()))
                logger.debug("Focused path: \"{}\"".format(opened_file_path))
                opened_file_path_view = (
                    sublime.active_window().find_open_file(opened_file_path))
                view.close()
                sublime.active_window().focus_view(opened_file_path_view)
                break

    def on_close(self, view):
        open_files_paths.remove(view.file_name())
        logger.debug(
            "Removing closed file from list of opened files: {}".format(
                view.file_name()))

This works beautilfuly as long as the opening of a file does not involve a quick panel. When a quick panel is used, it immediatley closes when my plugin performs a focus_view(). I tried hard to figure out a way to overcome this but got nothing so far.

I discovered the below issue on SublimeTextIssues, which describes this exact problem but for unknown reason narrows it to a specific case related to F4 navigation and regex.

Final Questions

  1. Does the above issue describe an actual bug, or am I expecting a wrong behaviour?
  2. In case this is a bug, is it planned to be solved in the near future?
  3. Would you please help me find a workaround until this issue is fixed? :stuck_out_tongue:
3 Likes