prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  LS always starts in first folder of workspace
  LSP always starts a language server in the first project of your workspace, regardless of which one you're working on. For example, with the following workspace:
  
  ![screenshot_20181201_151846](https://user-images.githubusercontent.com/12202230/49332984-74da1800-f57c-11e8-9702-e1a0e8c8dc91.png)
  
  When I open any Rust files in `bserver`, RLS is still started in `LSP`, since it appears first in the list. This causes RLS to throw a warning:
  
  ![screenshot_20181201_151010](https://user-images.githubusercontent.com/12202230/49332910-59bad880-f57b-11e8-890f-83adf38399b3.png)
  
  and effectively breaks all useful functionality of the LSP plugin--nothing works, because RLS is staring at the wrong directory.
  
  I'm still digging as to why this is, but it looks like the issue is [an oversight with branching right here](https://github.com/tomv564/LSP/blob/master/plugin/core/workspace.py#L16). I'll submit a PR shortly.
  
  </issue>
  <code>
  [start of plugin/core/workspace.py]
  1 import os
  2 try:
  3     from typing import List, Optional, Any
  4     assert List and Optional and Any
  5 except ImportError:
  6     pass
  7 
  8 from .logging import debug
  9 # from .types import WindowLike
  10 
  11 
  12 def get_project_path(window: 'Any') -> 'Optional[str]':
  13     """
  14     Returns the first project folder or the parent folder of the active view
  15     """
  16     if len(window.folders()):
  17         folder_paths = window.folders()
  18         return folder_paths[0]
  19     else:
  20         view = window.active_view()
  21         if view:
  22             filename = view.file_name()
  23             if filename:
  24                 project_path = os.path.dirname(filename)
  25                 debug("Couldn't determine project directory since no folders are open!",
  26                       "Using", project_path, "as a fallback.")
  27                 return project_path
  28             else:
  29                 debug("Couldn't determine project directory since no folders are open",
  30                       "and the current file isn't saved on the disk.")
  31                 return None
  32         else:
  33             debug("No view is active in current window")
  34             return None  # https://github.com/tomv564/LSP/issues/219
  35 
  36 
  37 def get_common_parent(paths: 'List[str]') -> str:
  38     """
  39     Get the common parent directory of multiple paths.
  40 
  41     Python 3.5+ includes os.path.commonpath which does this, however Sublime
  42     currently embeds Python 3.3.
  43     """
  44     return os.path.commonprefix([path + '/' for path in paths]).rstrip('/')
  45 
  46 
  47 def is_in_workspace(window: 'Any', file_path: str) -> bool:
  48     workspace_path = get_project_path(window)
  49     if workspace_path is None:
  50         return False
  51 
  52     common_dir = get_common_parent([workspace_path, file_path])
  53     return workspace_path == common_dir
  54 
  55 
  56 def enable_in_project(window, config_name: str) -> None:
  57     project_data = window.project_data()
  58     if isinstance(project_data, dict):
  59         project_settings = project_data.setdefault('settings', dict())
  60         project_lsp_settings = project_settings.setdefault('LSP', dict())
  61         project_client_settings = project_lsp_settings.setdefault(config_name, dict())
  62         project_client_settings['enabled'] = True
  63         window.set_project_data(project_data)
  64     else:
  65         debug('non-dict returned in project_settings: ', project_data)
  66 
  67 
  68 def disable_in_project(window, config_name: str) -> None:
  69     project_data = window.project_data()
  70     if isinstance(project_data, dict):
  71         project_settings = project_data.setdefault('settings', dict())
  72         project_lsp_settings = project_settings.setdefault('LSP', dict())
  73         project_client_settings = project_lsp_settings.setdefault(config_name, dict())
  74         project_client_settings['enabled'] = False
  75         window.set_project_data(project_data)
  76     else:
  77         debug('non-dict returned in project_settings: ', project_data)
  78 
  79 
  80 def get_project_config(window: 'Any') -> dict:
  81     project_data = window.project_data() or dict()
  82     if isinstance(project_data, dict):
  83         project_settings = project_data.setdefault('settings', dict())
  84         project_lsp_settings = project_settings.setdefault('LSP', dict())
  85         return project_lsp_settings
  86     else:
  87         debug('non-dict returned in project_settings: ', project_data)
  88         return dict()
  89
  [end of plugin/core/workspace.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/plugin/core/workspace.py b/plugin/core/workspace.py
  --- a/plugin/core/workspace.py
  +++ b/plugin/core/workspace.py
  @@ -1,37 +1,69 @@
   import os
   try:
  -    from typing import List, Optional, Any
  -    assert List and Optional and Any
  +    from typing import List, Optional, Any, Iterable
  +    assert List and Optional and Any and Iterable
   except ImportError:
       pass
   
   from .logging import debug
  -# from .types import WindowLike
  +from .types import ViewLike
  +
  +
  +def get_filename_from_view(view: ViewLike) -> 'Optional[str]':
  +    if not view:
  +        debug("No view is active in current window")
  +        return None  # https://github.com/tomv564/LSP/issues/219
  +    filename = view.file_name()
  +    if not filename:
  +        debug("Couldn't determine project directory since no folders are open",
  +              "and the current file isn't saved on the disk.")
  +    return filename
  +
  +
  +def get_directory_name(view: ViewLike) -> 'Optional[str]':
  +    filename = get_filename_from_view(view)
  +    if filename:
  +        project_path = os.path.dirname(filename)
  +        return project_path
  +    return None
  +
  +
  +def find_path_among_multi_folders(folders: 'Iterable[str]',
  +                                  view: ViewLike) -> 'Optional[str]':
  +    filename = get_filename_from_view(view)
  +    if not filename:
  +        return None
  +    folders = [os.path.realpath(f) for f in folders]
  +    file = view.file_name()
  +    if not file:
  +        return None
  +    file = os.path.realpath(file)
  +    while file not in folders:
  +        file = os.path.dirname(file)
  +        if os.path.dirname(file) == file:
  +            # We're at the root of the filesystem.
  +            file = None
  +            break
  +    debug('project path is', file)
  +    return file
   
   
   def get_project_path(window: 'Any') -> 'Optional[str]':
       """
  -    Returns the first project folder or the parent folder of the active view
  +    Returns the project folder or the parent folder of the active view
       """
  -    if len(window.folders()):
  +    if not window:
  +        return None
  +    num_folders = len(window.folders())
  +    if num_folders == 0:
  +        return get_directory_name(window.active_view())
  +    elif num_folders == 1:
           folder_paths = window.folders()
           return folder_paths[0]
  -    else:
  -        view = window.active_view()
  -        if view:
  -            filename = view.file_name()
  -            if filename:
  -                project_path = os.path.dirname(filename)
  -                debug("Couldn't determine project directory since no folders are open!",
  -                      "Using", project_path, "as a fallback.")
  -                return project_path
  -            else:
  -                debug("Couldn't determine project directory since no folders are open",
  -                      "and the current file isn't saved on the disk.")
  -                return None
  -        else:
  -            debug("No view is active in current window")
  -            return None  # https://github.com/tomv564/LSP/issues/219
  +    else:  # num_folders > 1
  +        return find_path_among_multi_folders(
  +            window.folders(),
  +            window.active_view())
   
   
   def get_common_parent(paths: 'List[str]') -> str:
  
verification_info: {"golden_diff": "diff --git a/plugin/core/workspace.py b/plugin/core/workspace.py\n--- a/plugin/core/workspace.py\n+++ b/plugin/core/workspace.py\n@@ -1,37 +1,69 @@\n import os\n try:\n-    from typing import List, Optional, Any\n-    assert List and Optional and Any\n+    from typing import List, Optional, Any, Iterable\n+    assert List and Optional and Any and Iterable\n except ImportError:\n     pass\n \n from .logging import debug\n-# from .types import WindowLike\n+from .types import ViewLike\n+\n+\n+def get_filename_from_view(view: ViewLike) -> 'Optional[str]':\n+    if not view:\n+        debug(\"No view is active in current window\")\n+        return None  # https://github.com/tomv564/LSP/issues/219\n+    filename = view.file_name()\n+    if not filename:\n+        debug(\"Couldn't determine project directory since no folders are open\",\n+              \"and the current file isn't saved on the disk.\")\n+    return filename\n+\n+\n+def get_directory_name(view: ViewLike) -> 'Optional[str]':\n+    filename = get_filename_from_view(view)\n+    if filename:\n+        project_path = os.path.dirname(filename)\n+        return project_path\n+    return None\n+\n+\n+def find_path_among_multi_folders(folders: 'Iterable[str]',\n+                                  view: ViewLike) -> 'Optional[str]':\n+    filename = get_filename_from_view(view)\n+    if not filename:\n+        return None\n+    folders = [os.path.realpath(f) for f in folders]\n+    file = view.file_name()\n+    if not file:\n+        return None\n+    file = os.path.realpath(file)\n+    while file not in folders:\n+        file = os.path.dirname(file)\n+        if os.path.dirname(file) == file:\n+            # We're at the root of the filesystem.\n+            file = None\n+            break\n+    debug('project path is', file)\n+    return file\n \n \n def get_project_path(window: 'Any') -> 'Optional[str]':\n     \"\"\"\n-    Returns the first project folder or the parent folder of the active view\n+    Returns the project folder or the parent folder of the active view\n     \"\"\"\n-    if len(window.folders()):\n+    if not window:\n+        return None\n+    num_folders = len(window.folders())\n+    if num_folders == 0:\n+        return get_directory_name(window.active_view())\n+    elif num_folders == 1:\n         folder_paths = window.folders()\n         return folder_paths[0]\n-    else:\n-        view = window.active_view()\n-        if view:\n-            filename = view.file_name()\n-            if filename:\n-                project_path = os.path.dirname(filename)\n-                debug(\"Couldn't determine project directory since no folders are open!\",\n-                      \"Using\", project_path, \"as a fallback.\")\n-                return project_path\n-            else:\n-                debug(\"Couldn't determine project directory since no folders are open\",\n-                      \"and the current file isn't saved on the disk.\")\n-                return None\n-        else:\n-            debug(\"No view is active in current window\")\n-            return None  # https://github.com/tomv564/LSP/issues/219\n+    else:  # num_folders > 1\n+        return find_path_among_multi_folders(\n+            window.folders(),\n+            window.active_view())\n \n \n def get_common_parent(paths: 'List[str]') -> str:\n", "issue": "LS always starts in first folder of workspace\nLSP always starts a language server in the first project of your workspace, regardless of which one you're working on. For example, with the following workspace:\r\n\r\n![screenshot_20181201_151846](https://user-images.githubusercontent.com/12202230/49332984-74da1800-f57c-11e8-9702-e1a0e8c8dc91.png)\r\n\r\nWhen I open any Rust files in `bserver`, RLS is still started in `LSP`, since it appears first in the list. This causes RLS to throw a warning:\r\n\r\n![screenshot_20181201_151010](https://user-images.githubusercontent.com/12202230/49332910-59bad880-f57b-11e8-890f-83adf38399b3.png)\r\n\r\nand effectively breaks all useful functionality of the LSP plugin--nothing works, because RLS is staring at the wrong directory.\r\n\r\nI'm still digging as to why this is, but it looks like the issue is [an oversight with branching right here](https://github.com/tomv564/LSP/blob/master/plugin/core/workspace.py#L16). I'll submit a PR shortly.\n", "before_files": [{"content": "import os\ntry:\n    from typing import List, Optional, Any\n    assert List and Optional and Any\nexcept ImportError:\n    pass\n\nfrom .logging import debug\n# from .types import WindowLike\n\n\ndef get_project_path(window: 'Any') -> 'Optional[str]':\n    \"\"\"\n    Returns the first project folder or the parent folder of the active view\n    \"\"\"\n    if len(window.folders()):\n        folder_paths = window.folders()\n        return folder_paths[0]\n    else:\n        view = window.active_view()\n        if view:\n            filename = view.file_name()\n            if filename:\n                project_path = os.path.dirname(filename)\n                debug(\"Couldn't determine project directory since no folders are open!\",\n                      \"Using\", project_path, \"as a fallback.\")\n                return project_path\n            else:\n                debug(\"Couldn't determine project directory since no folders are open\",\n                      \"and the current file isn't saved on the disk.\")\n                return None\n        else:\n            debug(\"No view is active in current window\")\n            return None  # https://github.com/tomv564/LSP/issues/219\n\n\ndef get_common_parent(paths: 'List[str]') -> str:\n    \"\"\"\n    Get the common parent directory of multiple paths.\n\n    Python 3.5+ includes os.path.commonpath which does this, however Sublime\n    currently embeds Python 3.3.\n    \"\"\"\n    return os.path.commonprefix([path + '/' for path in paths]).rstrip('/')\n\n\ndef is_in_workspace(window: 'Any', file_path: str) -> bool:\n    workspace_path = get_project_path(window)\n    if workspace_path is None:\n        return False\n\n    common_dir = get_common_parent([workspace_path, file_path])\n    return workspace_path == common_dir\n\n\ndef enable_in_project(window, config_name: str) -> None:\n    project_data = window.project_data()\n    if isinstance(project_data, dict):\n        project_settings = project_data.setdefault('settings', dict())\n        project_lsp_settings = project_settings.setdefault('LSP', dict())\n        project_client_settings = project_lsp_settings.setdefault(config_name, dict())\n        project_client_settings['enabled'] = True\n        window.set_project_data(project_data)\n    else:\n        debug('non-dict returned in project_settings: ', project_data)\n\n\ndef disable_in_project(window, config_name: str) -> None:\n    project_data = window.project_data()\n    if isinstance(project_data, dict):\n        project_settings = project_data.setdefault('settings', dict())\n        project_lsp_settings = project_settings.setdefault('LSP', dict())\n        project_client_settings = project_lsp_settings.setdefault(config_name, dict())\n        project_client_settings['enabled'] = False\n        window.set_project_data(project_data)\n    else:\n        debug('non-dict returned in project_settings: ', project_data)\n\n\ndef get_project_config(window: 'Any') -> dict:\n    project_data = window.project_data() or dict()\n    if isinstance(project_data, dict):\n        project_settings = project_data.setdefault('settings', dict())\n        project_lsp_settings = project_settings.setdefault('LSP', dict())\n        return project_lsp_settings\n    else:\n        debug('non-dict returned in project_settings: ', project_data)\n        return dict()\n", "path": "plugin/core/workspace.py"}]}