From 23644cbdf5f3d796b2666b73b4e13733ac2ab41b Mon Sep 17 00:00:00 2001 From: Vaclav Tvrdik Date: Sun, 6 Sep 2026 11:09:05 +0200 Subject: [PATCH] Fix review findings in project-folder terminal command Co-Authored-By: Claude Fable 5 --- Architecture.md | 4 +++- vterm.sublime-settings | 8 ++++---- vterm/commands.py | 30 +++++++++++++++++++----------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Architecture.md b/Architecture.md index a131f57..319284f 100644 --- a/Architecture.md +++ b/Architecture.md @@ -331,7 +331,9 @@ replaces both together. **Plugin settings** (`vterm.sublime-settings`, read through the cached `settings()` handle): `auto_close`, `scrollback_history_size`, `honor_erase_scrollback`, `min_columns`, -`max_columns`, `theme`, `ansi_colors`, `debug`. `honor_erase_scrollback` is off, so ED 3 +`max_columns`, `theme`, `ansi_colors`, `terminal`, `parameters`, `debug`. `terminal` and +`parameters` name the external terminal spawned by *vterm: Open Terminal in Project +Folder* (`%CWD%` in `parameters` becomes the project folder). `honor_erase_scrollback` is off, so ED 3 blanks the screen without dropping the scrollback: pi and Claude Code repaint by erasing saved lines, which would take the history with them (`cmd+shift+k` still empties the tab). Changing `theme` fires `SchemeManager.reload`, which rebuilds the palette and restyles open terminals in place. diff --git a/vterm.sublime-settings b/vterm.sublime-settings index 5d44d38..25b9e4e 100644 --- a/vterm.sublime-settings +++ b/vterm.sublime-settings @@ -23,12 +23,12 @@ // External terminal for "vterm: Open Terminal in Project Folder". // %CWD% in parameters is replaced with the project folder. - "terminal": "/opt/homebrew/bin/kitty", - "parameters": ["-d", "%CWD%"], - - // Apple Terminal instead of kitty: // "terminal": "/usr/bin/open", // "parameters": ["-a", "Terminal", "%CWD%"], + // kitty instead of Apple Terminal: + "terminal": "/opt/homebrew/bin/kitty", + "parameters": ["-d", "%CWD%"], + "debug": false } diff --git a/vterm/commands.py b/vterm/commands.py index b9f0e39..999867a 100644 --- a/vterm/commands.py +++ b/vterm/commands.py @@ -67,15 +67,16 @@ class VtermOpenTerminalProjectFolderCommand(sublime_plugin.WindowCommand): def run(self): """Resolve the folder, substitute %CWD%, spawn the configured terminal.""" + folders = self.window.folders() + if not folders: + return + cwd = folders[0] view = self.window.active_view() if view and view.file_name(): path = view.file_name() - folders = [f for f in self.window.folders() if path.find(f + os.sep) == 0] - cwd = folders[0] if folders else os.path.dirname(path) - elif self.window.folders(): - cwd = self.window.folders()[0] - else: - return + matches = [f for f in folders if path.find(f.rstrip(os.sep) + os.sep) == 0] + if matches: + cwd = max(matches, key=len) s = settings() terminal = s.get("terminal") @@ -83,12 +84,19 @@ class VtermOpenTerminalProjectFolderCommand(sublime_plugin.WindowCommand): sublime.error_message('vterm: set "terminal" in vterm.sublime-settings') return - parameters = [p.replace("%CWD%", cwd) for p in s.get("parameters", [])] + parameters = s.get("parameters", []) + if not isinstance(parameters, list) or not all(isinstance(p, str) for p in parameters): + sublime.error_message('vterm: "parameters" must be a list of strings') + return + parameters = [p.replace("%CWD%", cwd) for p in parameters] try: - subprocess.Popen([terminal] + parameters, cwd=cwd) + subprocess.Popen( + [terminal] + parameters, cwd=cwd, start_new_session=True, + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, + ) except OSError: LOG.exception("failed to start external terminal: terminal=%s", terminal) - sublime.error_message(f"vterm: could not start {terminal}") + sublime.error_message("vterm: could not start {}".format(terminal)) def is_visible(self): """Hide the palette entry when there is no project folder.""" @@ -201,7 +209,7 @@ class VtermSelectThemeCommand(sublime_plugin.WindowCommand): items = [["No theme", "follow the Sublime color scheme"]] for name in self.choices[1:]: theme = THEMES[name] - items.append([name, f"{theme["foreground"]} on {theme["background"]}"]) + items.append([name, "{} on {}".format(theme["foreground"], theme["background"])]) current = self.choices.index(self.original) if self.original in self.choices else 0 self.window.show_quick_panel(items, self._done, selected_index=current, on_highlight=self._preview) @@ -262,7 +270,7 @@ class VtermCleanupCommand(sublime_plugin.TextCommand): terminal.process.isalive() exitstatus = terminal.process.exitstatus if exitstatus is not None: - view.run_command("append", {"characters": f"\n[process exited with code {exitstatus}]"}) + view.run_command("append", {"characters": "\n[process exited with code {}]".format(exitstatus)}) view.sel().clear()