prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Side by side option for symbol action links in hover popup doesn't work if location is in same file
  **Describe the bug**
  The side by side icon link for "Definition" / "Type Definition" / "Declaration" from the hover popup doesn't work if the location of the definition/declaration is in the same file.
  
  **To Reproduce**
  Steps to reproduce the behavior:
  1. Have `"show_symbol_action_links": true` in the settings (this is the default value)
  2. Hover over symbol (e.g. function call) which has a definition in the same file
  3. Click on ◨ next to "Definition", or use <kbd>Ctrl</kbd> + click on the text link
  4. See that the view scrolls to the location, instead of opening the location in a new tab to the right
  
  **Expected behavior**
  LSP should open the definition in a new new to the right, similar to how the built-in definitions popup from ST does
  
  **Environment (please complete the following information):**
  - OS: Win 10
  - LSP version: main
  
  **Additional context**
  
  Seems like the `flags` argument which includes the "side_by_side" information is lost/ignored here:
  https://github.com/sublimelsp/LSP/blob/1bcd518102c1516c9d808c974b7d2a5eba7d0b80/plugin/core/open.py#L30-L31
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `plugin/core/open.py`
  Content:
  ```
  1 from .logging import exception_log
  2 from .promise import Promise
  3 from .promise import ResolveFunc
  4 from .protocol import DocumentUri
  5 from .protocol import Range
  6 from .protocol import RangeLsp
  7 from .typing import Dict, Tuple, Optional
  8 from .url import parse_uri
  9 from .views import range_to_region
  10 import os
  11 import sublime
  12 import subprocess
  13 
  14 
  15 opening_files = {}  # type: Dict[str, Tuple[Promise[Optional[sublime.View]], ResolveFunc[Optional[sublime.View]]]]
  16 
  17 
  18 def open_file(
  19     window: sublime.Window, uri: DocumentUri, flags: int = 0, group: int = -1
  20 ) -> Promise[Optional[sublime.View]]:
  21     """
  22     Open a file asynchronously.
  23     It is only safe to call this function from the UI thread.
  24     The provided uri MUST be a file URI
  25     """
  26     file = parse_uri(uri)[1]
  27     # window.open_file brings the file to focus if it's already opened, which we don't want.
  28     # So we first check if there's already a view for that file.
  29     view = window.find_open_file(file)
  30     if view:
  31         return Promise.resolve(view)
  32 
  33     view = window.open_file(file, flags, group)
  34     if not view.is_loading():
  35         # It's already loaded. Possibly already open in a tab.
  36         return Promise.resolve(view)
  37 
  38     # Is the view opening right now? Then return the associated unresolved promise
  39     for fn, value in opening_files.items():
  40         if fn == file or os.path.samefile(fn, file):
  41             # Return the unresolved promise. A future on_load event will resolve the promise.
  42             return value[0]
  43 
  44     # Prepare a new promise to be resolved by a future on_load event (see the event listener in main.py)
  45     def fullfill(resolve: ResolveFunc[Optional[sublime.View]]) -> None:
  46         global opening_files
  47         # Save the promise in the first element of the tuple -- except we cannot yet do that here
  48         opening_files[file] = (None, resolve)  # type: ignore
  49 
  50     promise = Promise(fullfill)
  51     tup = opening_files[file]
  52     # Save the promise in the first element of the tuple so that the for-loop above can return it
  53     opening_files[file] = (promise, tup[1])
  54     return promise
  55 
  56 
  57 def center_selection(v: sublime.View, r: RangeLsp) -> sublime.View:
  58     selection = range_to_region(Range.from_lsp(r), v)
  59     v.run_command("lsp_selection_set", {"regions": [(selection.a, selection.a)]})
  60     window = v.window()
  61     if window:
  62         window.focus_view(v)
  63     if int(sublime.version()) >= 4124:
  64         v.show_at_center(selection, animate=False)
  65     else:
  66         # TODO: remove later when a stable build lands
  67         v.show_at_center(selection)  # type: ignore
  68     return v
  69 
  70 
  71 def open_externally(uri: str, take_focus: bool) -> bool:
  72     """
  73     A blocking function that invokes the OS's "open with default extension"
  74     """
  75     try:
  76         # TODO: handle take_focus
  77         if sublime.platform() == "windows":
  78             os.startfile(uri)  # type: ignore
  79         elif sublime.platform() == "osx":
  80             subprocess.check_call(("/usr/bin/open", uri))
  81         else:  # linux
  82             subprocess.check_call(("xdg-open", uri))
  83         return True
  84     except Exception as ex:
  85         exception_log("Failed to open {}".format(uri), ex)
  86         return False
  87
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/plugin/core/open.py b/plugin/core/open.py
  --- a/plugin/core/open.py
  +++ b/plugin/core/open.py
  @@ -24,11 +24,15 @@
       The provided uri MUST be a file URI
       """
       file = parse_uri(uri)[1]
  -    # window.open_file brings the file to focus if it's already opened, which we don't want.
  -    # So we first check if there's already a view for that file.
  +    # window.open_file brings the file to focus if it's already opened, which we don't want (unless it's supposed
  +    # to open as a separate view).
       view = window.find_open_file(file)
       if view:
  -        return Promise.resolve(view)
  +        opens_in_current_group = group == -1 or window.active_group() == group
  +        opens_as_new_selection = (flags & (sublime.ADD_TO_SELECTION | sublime.REPLACE_MRU)) != 0
  +        return_existing_view = opens_in_current_group and not opens_as_new_selection
  +        if return_existing_view:
  +            return Promise.resolve(view)
   
       view = window.open_file(file, flags, group)
       if not view.is_loading():
  
verification_info: {"golden_diff": "diff --git a/plugin/core/open.py b/plugin/core/open.py\n--- a/plugin/core/open.py\n+++ b/plugin/core/open.py\n@@ -24,11 +24,15 @@\n     The provided uri MUST be a file URI\n     \"\"\"\n     file = parse_uri(uri)[1]\n-    # window.open_file brings the file to focus if it's already opened, which we don't want.\n-    # So we first check if there's already a view for that file.\n+    # window.open_file brings the file to focus if it's already opened, which we don't want (unless it's supposed\n+    # to open as a separate view).\n     view = window.find_open_file(file)\n     if view:\n-        return Promise.resolve(view)\n+        opens_in_current_group = group == -1 or window.active_group() == group\n+        opens_as_new_selection = (flags & (sublime.ADD_TO_SELECTION | sublime.REPLACE_MRU)) != 0\n+        return_existing_view = opens_in_current_group and not opens_as_new_selection\n+        if return_existing_view:\n+            return Promise.resolve(view)\n \n     view = window.open_file(file, flags, group)\n     if not view.is_loading():\n", "issue": "Side by side option for symbol action links in hover popup doesn't work if location is in same file\n**Describe the bug**\r\nThe side by side icon link for \"Definition\" / \"Type Definition\" / \"Declaration\" from the hover popup doesn't work if the location of the definition/declaration is in the same file.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Have `\"show_symbol_action_links\": true` in the settings (this is the default value)\r\n2. Hover over symbol (e.g. function call) which has a definition in the same file\r\n3. Click on \u25e8 next to \"Definition\", or use <kbd>Ctrl</kbd> + click on the text link\r\n4. See that the view scrolls to the location, instead of opening the location in a new tab to the right\r\n\r\n**Expected behavior**\r\nLSP should open the definition in a new new to the right, similar to how the built-in definitions popup from ST does\r\n\r\n**Environment (please complete the following information):**\r\n- OS: Win 10\r\n- LSP version: main\r\n\r\n**Additional context**\r\n\r\nSeems like the `flags` argument which includes the \"side_by_side\" information is lost/ignored here:\r\nhttps://github.com/sublimelsp/LSP/blob/1bcd518102c1516c9d808c974b7d2a5eba7d0b80/plugin/core/open.py#L30-L31\n", "before_files": [{"content": "from .logging import exception_log\nfrom .promise import Promise\nfrom .promise import ResolveFunc\nfrom .protocol import DocumentUri\nfrom .protocol import Range\nfrom .protocol import RangeLsp\nfrom .typing import Dict, Tuple, Optional\nfrom .url import parse_uri\nfrom .views import range_to_region\nimport os\nimport sublime\nimport subprocess\n\n\nopening_files = {}  # type: Dict[str, Tuple[Promise[Optional[sublime.View]], ResolveFunc[Optional[sublime.View]]]]\n\n\ndef open_file(\n    window: sublime.Window, uri: DocumentUri, flags: int = 0, group: int = -1\n) -> Promise[Optional[sublime.View]]:\n    \"\"\"\n    Open a file asynchronously.\n    It is only safe to call this function from the UI thread.\n    The provided uri MUST be a file URI\n    \"\"\"\n    file = parse_uri(uri)[1]\n    # window.open_file brings the file to focus if it's already opened, which we don't want.\n    # So we first check if there's already a view for that file.\n    view = window.find_open_file(file)\n    if view:\n        return Promise.resolve(view)\n\n    view = window.open_file(file, flags, group)\n    if not view.is_loading():\n        # It's already loaded. Possibly already open in a tab.\n        return Promise.resolve(view)\n\n    # Is the view opening right now? Then return the associated unresolved promise\n    for fn, value in opening_files.items():\n        if fn == file or os.path.samefile(fn, file):\n            # Return the unresolved promise. A future on_load event will resolve the promise.\n            return value[0]\n\n    # Prepare a new promise to be resolved by a future on_load event (see the event listener in main.py)\n    def fullfill(resolve: ResolveFunc[Optional[sublime.View]]) -> None:\n        global opening_files\n        # Save the promise in the first element of the tuple -- except we cannot yet do that here\n        opening_files[file] = (None, resolve)  # type: ignore\n\n    promise = Promise(fullfill)\n    tup = opening_files[file]\n    # Save the promise in the first element of the tuple so that the for-loop above can return it\n    opening_files[file] = (promise, tup[1])\n    return promise\n\n\ndef center_selection(v: sublime.View, r: RangeLsp) -> sublime.View:\n    selection = range_to_region(Range.from_lsp(r), v)\n    v.run_command(\"lsp_selection_set\", {\"regions\": [(selection.a, selection.a)]})\n    window = v.window()\n    if window:\n        window.focus_view(v)\n    if int(sublime.version()) >= 4124:\n        v.show_at_center(selection, animate=False)\n    else:\n        # TODO: remove later when a stable build lands\n        v.show_at_center(selection)  # type: ignore\n    return v\n\n\ndef open_externally(uri: str, take_focus: bool) -> bool:\n    \"\"\"\n    A blocking function that invokes the OS's \"open with default extension\"\n    \"\"\"\n    try:\n        # TODO: handle take_focus\n        if sublime.platform() == \"windows\":\n            os.startfile(uri)  # type: ignore\n        elif sublime.platform() == \"osx\":\n            subprocess.check_call((\"/usr/bin/open\", uri))\n        else:  # linux\n            subprocess.check_call((\"xdg-open\", uri))\n        return True\n    except Exception as ex:\n        exception_log(\"Failed to open {}\".format(uri), ex)\n        return False\n", "path": "plugin/core/open.py"}], "after_files": [{"content": "from .logging import exception_log\nfrom .promise import Promise\nfrom .promise import ResolveFunc\nfrom .protocol import DocumentUri\nfrom .protocol import Range\nfrom .protocol import RangeLsp\nfrom .typing import Dict, Tuple, Optional\nfrom .url import parse_uri\nfrom .views import range_to_region\nimport os\nimport sublime\nimport subprocess\n\n\nopening_files = {}  # type: Dict[str, Tuple[Promise[Optional[sublime.View]], ResolveFunc[Optional[sublime.View]]]]\n\n\ndef open_file(\n    window: sublime.Window, uri: DocumentUri, flags: int = 0, group: int = -1\n) -> Promise[Optional[sublime.View]]:\n    \"\"\"\n    Open a file asynchronously.\n    It is only safe to call this function from the UI thread.\n    The provided uri MUST be a file URI\n    \"\"\"\n    file = parse_uri(uri)[1]\n    # window.open_file brings the file to focus if it's already opened, which we don't want (unless it's supposed\n    # to open as a separate view).\n    view = window.find_open_file(file)\n    if view:\n        opens_in_current_group = group == -1 or window.active_group() == group\n        opens_as_new_selection = (flags & (sublime.ADD_TO_SELECTION | sublime.REPLACE_MRU)) != 0\n        return_existing_view = opens_in_current_group and not opens_as_new_selection\n        if return_existing_view:\n            return Promise.resolve(view)\n\n    view = window.open_file(file, flags, group)\n    if not view.is_loading():\n        # It's already loaded. Possibly already open in a tab.\n        return Promise.resolve(view)\n\n    # Is the view opening right now? Then return the associated unresolved promise\n    for fn, value in opening_files.items():\n        if fn == file or os.path.samefile(fn, file):\n            # Return the unresolved promise. A future on_load event will resolve the promise.\n            return value[0]\n\n    # Prepare a new promise to be resolved by a future on_load event (see the event listener in main.py)\n    def fullfill(resolve: ResolveFunc[Optional[sublime.View]]) -> None:\n        global opening_files\n        # Save the promise in the first element of the tuple -- except we cannot yet do that here\n        opening_files[file] = (None, resolve)  # type: ignore\n\n    promise = Promise(fullfill)\n    tup = opening_files[file]\n    # Save the promise in the first element of the tuple so that the for-loop above can return it\n    opening_files[file] = (promise, tup[1])\n    return promise\n\n\ndef center_selection(v: sublime.View, r: RangeLsp) -> sublime.View:\n    selection = range_to_region(Range.from_lsp(r), v)\n    v.run_command(\"lsp_selection_set\", {\"regions\": [(selection.a, selection.a)]})\n    window = v.window()\n    if window:\n        window.focus_view(v)\n    if int(sublime.version()) >= 4124:\n        v.show_at_center(selection, animate=False)\n    else:\n        # TODO: remove later when a stable build lands\n        v.show_at_center(selection)  # type: ignore\n    return v\n\n\ndef open_externally(uri: str, take_focus: bool) -> bool:\n    \"\"\"\n    A blocking function that invokes the OS's \"open with default extension\"\n    \"\"\"\n    try:\n        # TODO: handle take_focus\n        if sublime.platform() == \"windows\":\n            os.startfile(uri)  # type: ignore\n        elif sublime.platform() == \"osx\":\n            subprocess.check_call((\"/usr/bin/open\", uri))\n        else:  # linux\n            subprocess.check_call((\"xdg-open\", uri))\n        return True\n    except Exception as ex:\n        exception_log(\"Failed to open {}\".format(uri), ex)\n        return False\n", "path": "plugin/core/open.py"}]}