prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Provide a way to save all modified files after applying workspace edits
  **Is your feature request related to a problem? Please describe.**
  
  When applying refactorings (like renames) it's often the case that multiple files are modified. It's a chore to then have to find and save all those modified files.
  
  **Describe the solution you'd like**
  
  We could provide a dialog after more than one file was modified asking the user whether all modified files should be saved. Note that some people don't like dialogs (#1922).
  
  Or maybe even show a "tree view" in a sheet, showing all modified files and allowing the user to navigate to them and save all at once.
  
  **Describe alternatives you've considered**
  
  - Saving all edited files one by one.
  - Using "save all" command but that fails when there is some unsaved buffer in the window (for example I like to have some to keep notes in them)
  
  
  --- 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/save_command.py`
  Content:
  ```
  1 from .core.registry import LspTextCommand
  2 from .core.settings import userprefs
  3 from .core.typing import Callable, List, Type
  4 from abc import ABCMeta, abstractmethod
  5 import sublime
  6 import sublime_plugin
  7 
  8 
  9 class SaveTask(metaclass=ABCMeta):
  10     """
  11     Base class for tasks that run on save.
  12 
  13     Note: The whole task runs on the async thread.
  14     """
  15 
  16     @classmethod
  17     @abstractmethod
  18     def is_applicable(cls, view: sublime.View) -> bool:
  19         pass
  20 
  21     def __init__(self, task_runner: LspTextCommand, on_done: Callable[[], None]):
  22         self._task_runner = task_runner
  23         self._on_done = on_done
  24         self._completed = False
  25         self._cancelled = False
  26         self._status_key = type(self).__name__
  27 
  28     def run_async(self) -> None:
  29         self._erase_view_status()
  30         sublime.set_timeout_async(self._on_timeout, userprefs().on_save_task_timeout_ms)
  31 
  32     def _on_timeout(self) -> None:
  33         if not self._completed and not self._cancelled:
  34             self._set_view_status('LSP: Timeout processing {}'.format(self.__class__.__name__))
  35             self._cancelled = True
  36             self._on_done()
  37 
  38     def cancel(self) -> None:
  39         self._cancelled = True
  40 
  41     def _set_view_status(self, text: str) -> None:
  42         self._task_runner.view.set_status(self._status_key, text)
  43         sublime.set_timeout_async(self._erase_view_status, 5000)
  44 
  45     def _erase_view_status(self) -> None:
  46         self._task_runner.view.erase_status(self._status_key)
  47 
  48     def _on_complete(self) -> None:
  49         assert not self._completed
  50         self._completed = True
  51         if not self._cancelled:
  52             self._on_done()
  53 
  54     def _purge_changes_async(self) -> None:
  55         # Supermassive hack that will go away later.
  56         listeners = sublime_plugin.view_event_listeners.get(self._task_runner.view.id(), [])
  57         for listener in listeners:
  58             if listener.__class__.__name__ == 'DocumentSyncListener':
  59                 listener.purge_changes_async()  # type: ignore
  60                 break
  61 
  62 
  63 class LspSaveCommand(LspTextCommand):
  64     """
  65     A command used as a substitute for native save command. Runs code actions and document
  66     formatting before triggering the native save command.
  67     """
  68     _tasks = []  # type: List[Type[SaveTask]]
  69 
  70     @classmethod
  71     def register_task(cls, task: Type[SaveTask]) -> None:
  72         assert task not in cls._tasks
  73         cls._tasks.append(task)
  74 
  75     def __init__(self, view: sublime.View) -> None:
  76         super().__init__(view)
  77         self._pending_tasks = []  # type: List[SaveTask]
  78 
  79     def run(self, edit: sublime.Edit) -> None:
  80         if self._pending_tasks:
  81             for task in self._pending_tasks:
  82                 task.cancel()
  83             self._pending_tasks = []
  84         sublime.set_timeout_async(self._trigger_on_pre_save_async)
  85         for Task in self._tasks:
  86             if Task.is_applicable(self.view):
  87                 self._pending_tasks.append(Task(self, self._on_task_completed_async))
  88         if self._pending_tasks:
  89             sublime.set_timeout_async(self._run_next_task_async)
  90         else:
  91             self._trigger_native_save()
  92 
  93     def _trigger_on_pre_save_async(self) -> None:
  94         # Supermassive hack that will go away later.
  95         listeners = sublime_plugin.view_event_listeners.get(self.view.id(), [])
  96         for listener in listeners:
  97             if listener.__class__.__name__ == 'DocumentSyncListener':
  98                 listener.trigger_on_pre_save_async()  # type: ignore
  99                 break
  100 
  101     def _run_next_task_async(self) -> None:
  102         current_task = self._pending_tasks[0]
  103         current_task.run_async()
  104 
  105     def _on_task_completed_async(self) -> None:
  106         self._pending_tasks.pop(0)
  107         if self._pending_tasks:
  108             # Even though we are on the async thread already, we want to give ST a chance to notify us about
  109             # potential document changes.
  110             sublime.set_timeout_async(self._run_next_task_async)
  111         else:
  112             self._trigger_native_save()
  113 
  114     def _trigger_native_save(self) -> None:
  115         # Triggered from set_timeout to preserve original semantics of on_pre_save handling
  116         sublime.set_timeout(lambda: self.view.run_command('save', {"async": True}))
  117 
  118 
  119 class LspSaveAllCommand(sublime_plugin.WindowCommand):
  120     def run(self) -> None:
  121         done = set()
  122         for view in self.window.views():
  123             buffer_id = view.buffer_id()
  124             if buffer_id in done:
  125                 continue
  126             if not view.is_dirty():
  127                 continue
  128             done.add(buffer_id)
  129             view.run_command("lsp_save", None)
  130
  ```
  --- 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/save_command.py b/plugin/save_command.py
  --- a/plugin/save_command.py
  +++ b/plugin/save_command.py
  @@ -117,7 +117,7 @@
   
   
   class LspSaveAllCommand(sublime_plugin.WindowCommand):
  -    def run(self) -> None:
  +    def run(self, only_files: bool = False) -> None:
           done = set()
           for view in self.window.views():
               buffer_id = view.buffer_id()
  @@ -125,5 +125,7 @@
                   continue
               if not view.is_dirty():
                   continue
  +            if only_files and view.file_name() is None:
  +                continue
               done.add(buffer_id)
               view.run_command("lsp_save", None)
  
verification_info: {"golden_diff": "diff --git a/plugin/save_command.py b/plugin/save_command.py\n--- a/plugin/save_command.py\n+++ b/plugin/save_command.py\n@@ -117,7 +117,7 @@\n \n \n class LspSaveAllCommand(sublime_plugin.WindowCommand):\n-    def run(self) -> None:\n+    def run(self, only_files: bool = False) -> None:\n         done = set()\n         for view in self.window.views():\n             buffer_id = view.buffer_id()\n@@ -125,5 +125,7 @@\n                 continue\n             if not view.is_dirty():\n                 continue\n+            if only_files and view.file_name() is None:\n+                continue\n             done.add(buffer_id)\n             view.run_command(\"lsp_save\", None)\n", "issue": "Provide a way to save all modified files after applying workspace edits\n**Is your feature request related to a problem? Please describe.**\r\n\r\nWhen applying refactorings (like renames) it's often the case that multiple files are modified. It's a chore to then have to find and save all those modified files.\r\n\r\n**Describe the solution you'd like**\r\n\r\nWe could provide a dialog after more than one file was modified asking the user whether all modified files should be saved. Note that some people don't like dialogs (#1922).\r\n\r\nOr maybe even show a \"tree view\" in a sheet, showing all modified files and allowing the user to navigate to them and save all at once.\r\n\r\n**Describe alternatives you've considered**\r\n\r\n- Saving all edited files one by one.\r\n- Using \"save all\" command but that fails when there is some unsaved buffer in the window (for example I like to have some to keep notes in them)\r\n\n", "before_files": [{"content": "from .core.registry import LspTextCommand\nfrom .core.settings import userprefs\nfrom .core.typing import Callable, List, Type\nfrom abc import ABCMeta, abstractmethod\nimport sublime\nimport sublime_plugin\n\n\nclass SaveTask(metaclass=ABCMeta):\n    \"\"\"\n    Base class for tasks that run on save.\n\n    Note: The whole task runs on the async thread.\n    \"\"\"\n\n    @classmethod\n    @abstractmethod\n    def is_applicable(cls, view: sublime.View) -> bool:\n        pass\n\n    def __init__(self, task_runner: LspTextCommand, on_done: Callable[[], None]):\n        self._task_runner = task_runner\n        self._on_done = on_done\n        self._completed = False\n        self._cancelled = False\n        self._status_key = type(self).__name__\n\n    def run_async(self) -> None:\n        self._erase_view_status()\n        sublime.set_timeout_async(self._on_timeout, userprefs().on_save_task_timeout_ms)\n\n    def _on_timeout(self) -> None:\n        if not self._completed and not self._cancelled:\n            self._set_view_status('LSP: Timeout processing {}'.format(self.__class__.__name__))\n            self._cancelled = True\n            self._on_done()\n\n    def cancel(self) -> None:\n        self._cancelled = True\n\n    def _set_view_status(self, text: str) -> None:\n        self._task_runner.view.set_status(self._status_key, text)\n        sublime.set_timeout_async(self._erase_view_status, 5000)\n\n    def _erase_view_status(self) -> None:\n        self._task_runner.view.erase_status(self._status_key)\n\n    def _on_complete(self) -> None:\n        assert not self._completed\n        self._completed = True\n        if not self._cancelled:\n            self._on_done()\n\n    def _purge_changes_async(self) -> None:\n        # Supermassive hack that will go away later.\n        listeners = sublime_plugin.view_event_listeners.get(self._task_runner.view.id(), [])\n        for listener in listeners:\n            if listener.__class__.__name__ == 'DocumentSyncListener':\n                listener.purge_changes_async()  # type: ignore\n                break\n\n\nclass LspSaveCommand(LspTextCommand):\n    \"\"\"\n    A command used as a substitute for native save command. Runs code actions and document\n    formatting before triggering the native save command.\n    \"\"\"\n    _tasks = []  # type: List[Type[SaveTask]]\n\n    @classmethod\n    def register_task(cls, task: Type[SaveTask]) -> None:\n        assert task not in cls._tasks\n        cls._tasks.append(task)\n\n    def __init__(self, view: sublime.View) -> None:\n        super().__init__(view)\n        self._pending_tasks = []  # type: List[SaveTask]\n\n    def run(self, edit: sublime.Edit) -> None:\n        if self._pending_tasks:\n            for task in self._pending_tasks:\n                task.cancel()\n            self._pending_tasks = []\n        sublime.set_timeout_async(self._trigger_on_pre_save_async)\n        for Task in self._tasks:\n            if Task.is_applicable(self.view):\n                self._pending_tasks.append(Task(self, self._on_task_completed_async))\n        if self._pending_tasks:\n            sublime.set_timeout_async(self._run_next_task_async)\n        else:\n            self._trigger_native_save()\n\n    def _trigger_on_pre_save_async(self) -> None:\n        # Supermassive hack that will go away later.\n        listeners = sublime_plugin.view_event_listeners.get(self.view.id(), [])\n        for listener in listeners:\n            if listener.__class__.__name__ == 'DocumentSyncListener':\n                listener.trigger_on_pre_save_async()  # type: ignore\n                break\n\n    def _run_next_task_async(self) -> None:\n        current_task = self._pending_tasks[0]\n        current_task.run_async()\n\n    def _on_task_completed_async(self) -> None:\n        self._pending_tasks.pop(0)\n        if self._pending_tasks:\n            # Even though we are on the async thread already, we want to give ST a chance to notify us about\n            # potential document changes.\n            sublime.set_timeout_async(self._run_next_task_async)\n        else:\n            self._trigger_native_save()\n\n    def _trigger_native_save(self) -> None:\n        # Triggered from set_timeout to preserve original semantics of on_pre_save handling\n        sublime.set_timeout(lambda: self.view.run_command('save', {\"async\": True}))\n\n\nclass LspSaveAllCommand(sublime_plugin.WindowCommand):\n    def run(self) -> None:\n        done = set()\n        for view in self.window.views():\n            buffer_id = view.buffer_id()\n            if buffer_id in done:\n                continue\n            if not view.is_dirty():\n                continue\n            done.add(buffer_id)\n            view.run_command(\"lsp_save\", None)\n", "path": "plugin/save_command.py"}], "after_files": [{"content": "from .core.registry import LspTextCommand\nfrom .core.settings import userprefs\nfrom .core.typing import Callable, List, Type\nfrom abc import ABCMeta, abstractmethod\nimport sublime\nimport sublime_plugin\n\n\nclass SaveTask(metaclass=ABCMeta):\n    \"\"\"\n    Base class for tasks that run on save.\n\n    Note: The whole task runs on the async thread.\n    \"\"\"\n\n    @classmethod\n    @abstractmethod\n    def is_applicable(cls, view: sublime.View) -> bool:\n        pass\n\n    def __init__(self, task_runner: LspTextCommand, on_done: Callable[[], None]):\n        self._task_runner = task_runner\n        self._on_done = on_done\n        self._completed = False\n        self._cancelled = False\n        self._status_key = type(self).__name__\n\n    def run_async(self) -> None:\n        self._erase_view_status()\n        sublime.set_timeout_async(self._on_timeout, userprefs().on_save_task_timeout_ms)\n\n    def _on_timeout(self) -> None:\n        if not self._completed and not self._cancelled:\n            self._set_view_status('LSP: Timeout processing {}'.format(self.__class__.__name__))\n            self._cancelled = True\n            self._on_done()\n\n    def cancel(self) -> None:\n        self._cancelled = True\n\n    def _set_view_status(self, text: str) -> None:\n        self._task_runner.view.set_status(self._status_key, text)\n        sublime.set_timeout_async(self._erase_view_status, 5000)\n\n    def _erase_view_status(self) -> None:\n        self._task_runner.view.erase_status(self._status_key)\n\n    def _on_complete(self) -> None:\n        assert not self._completed\n        self._completed = True\n        if not self._cancelled:\n            self._on_done()\n\n    def _purge_changes_async(self) -> None:\n        # Supermassive hack that will go away later.\n        listeners = sublime_plugin.view_event_listeners.get(self._task_runner.view.id(), [])\n        for listener in listeners:\n            if listener.__class__.__name__ == 'DocumentSyncListener':\n                listener.purge_changes_async()  # type: ignore\n                break\n\n\nclass LspSaveCommand(LspTextCommand):\n    \"\"\"\n    A command used as a substitute for native save command. Runs code actions and document\n    formatting before triggering the native save command.\n    \"\"\"\n    _tasks = []  # type: List[Type[SaveTask]]\n\n    @classmethod\n    def register_task(cls, task: Type[SaveTask]) -> None:\n        assert task not in cls._tasks\n        cls._tasks.append(task)\n\n    def __init__(self, view: sublime.View) -> None:\n        super().__init__(view)\n        self._pending_tasks = []  # type: List[SaveTask]\n\n    def run(self, edit: sublime.Edit) -> None:\n        if self._pending_tasks:\n            for task in self._pending_tasks:\n                task.cancel()\n            self._pending_tasks = []\n        sublime.set_timeout_async(self._trigger_on_pre_save_async)\n        for Task in self._tasks:\n            if Task.is_applicable(self.view):\n                self._pending_tasks.append(Task(self, self._on_task_completed_async))\n        if self._pending_tasks:\n            sublime.set_timeout_async(self._run_next_task_async)\n        else:\n            self._trigger_native_save()\n\n    def _trigger_on_pre_save_async(self) -> None:\n        # Supermassive hack that will go away later.\n        listeners = sublime_plugin.view_event_listeners.get(self.view.id(), [])\n        for listener in listeners:\n            if listener.__class__.__name__ == 'DocumentSyncListener':\n                listener.trigger_on_pre_save_async()  # type: ignore\n                break\n\n    def _run_next_task_async(self) -> None:\n        current_task = self._pending_tasks[0]\n        current_task.run_async()\n\n    def _on_task_completed_async(self) -> None:\n        self._pending_tasks.pop(0)\n        if self._pending_tasks:\n            # Even though we are on the async thread already, we want to give ST a chance to notify us about\n            # potential document changes.\n            sublime.set_timeout_async(self._run_next_task_async)\n        else:\n            self._trigger_native_save()\n\n    def _trigger_native_save(self) -> None:\n        # Triggered from set_timeout to preserve original semantics of on_pre_save handling\n        sublime.set_timeout(lambda: self.view.run_command('save', {\"async\": True}))\n\n\nclass LspSaveAllCommand(sublime_plugin.WindowCommand):\n    def run(self, only_files: bool = False) -> None:\n        done = set()\n        for view in self.window.views():\n            buffer_id = view.buffer_id()\n            if buffer_id in done:\n                continue\n            if not view.is_dirty():\n                continue\n            if only_files and view.file_name() is None:\n                continue\n            done.add(buffer_id)\n            view.run_command(\"lsp_save\", None)\n", "path": "plugin/save_command.py"}]}