Repository: sublimelsp/LSP

Issue:
get_project_path() incorrectly determines path
If you have multiple sibling directories in a workspace with common prefix characters, it will incorrectly use a partial path for this.

I have two directories open, which are `~/Projects/example1` and `~/Projects/example2`. `os.path.commonprefix()` will hence return `~/Projects/example`, which is not a directory that exists. (The Python docs note that `os.path.commonpath()` should be used instead.)

This approach is generally problematic anyway. I have two subdirectories deep inside a common directory, and even without the partial filename problem, this is still problematic for me as it causes **a lot** more files than I care about to be indexed. This causes the initial parsing to take roughly *forever*.

VS Code is currently working on adding multi-root support (https://github.com/Microsoft/vscode/issues/28344), so I suspect they'll add support to the Language Server protocol at some point. The current behaviour in the beta is just to index the first directory in the project. IMO, this is the best behaviour until the protocol actually supports multi-root.


Discussion:
> I suspect they'll add support to the Language Server protocol at some point

It appears they've got early work underway on this: https://github.com/Microsoft/vscode-languageserver-node/commit/c3a880f9584d69125b479ef75160e67df780bb5c
Thanks for the detailed bug report, sounds like `commonpath` is the intended behaviour.

I am myself not convinced of LSP's shared-root-of-multiple-folders approach, but would only supporting the first folder be an improvement?
> would only supporting the first folder be an improvement?

I definitely think so; the way I use Sublime projects typically is by having a main directory with multiple auxiliary directories for easy access (for example, a component of a large system along with the core library for said system). Having all of it integrated would be nice, but in lieu of that, just using the first folder I think is the best behaviour (and matches VS Code's current behaviour).

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -570,18 +570,28 @@ def get_project_path(window: sublime.Window) -> 'Optional[str]':
     """
     if len(window.folders()):
         folder_paths = window.folders()
-        return os.path.commonprefix(folder_paths)
+        return folder_paths[0]
     else:
         debug("Couldn't determine project directory")
         return None
 
 
+def get_common_parent(paths: 'List[str]') -> str:
+    """
+    Get the common parent directory of multiple paths.
+
+    Python 3.5+ includes os.path.commonpath which does this, however Sublime
+    currently embeds Python 3.3.
+    """
+    return os.path.commonprefix([path + '/' for path in paths]).rstrip('/')
+
+
 def is_in_workspace(window: sublime.Window, file_path: str) -> bool:
     workspace_path = get_project_path(window)
     if workspace_path is None:
         return False
 
-    common_dir = os.path.commonprefix([workspace_path, file_path])
+    common_dir = get_common_parent([workspace_path, file_path])
     return workspace_path == common_dir
 
 


Test patch: