diff --git a/docs/sessions.rst b/docs/sessions.rst index 1c32b45d4..5de4ad656 100644 --- a/docs/sessions.rst +++ b/docs/sessions.rst @@ -187,12 +187,13 @@ Making newly created windows join an existing session Normally, after activating a session, if you create new windows/tabs they don't belong to the session. If you would prefer to have them belong -to the currently active session, you can use the :option:`launch --add-to-session` -option, like this: +to the currently active session, you can use the :ac:`new_window_with_cwd` +and :ac:`new_tab_with_cwd` actions instead, like this:: - map kitty_mod+enter launch --add-to-session=. + map kitty_mod+enter new_window_with_cwd + map kitty_mod+t new_tab_with_cwd -This will cause newly created windows to belong to the currently active +This will cause newly created windows and tabs to belong to the currently active session, if any. Note that adding a window to a session in this way is temporary, it does not edit the session file. If you wish to update the session file of the currently active session, you can use the following @@ -201,6 +202,9 @@ mapping for it:: map f5 save_as_session --relocatable --use-foreground-process --match=session:. . The two can be combined, using the :ac:`combine` action. +For even more control of what session a window is added to use +the :doc:`launch ` command with the :option:`launch --add-to-session` +flag. Sessions with remote connections diff --git a/kitty/boss.py b/kitty/boss.py index ff4b9eb99..1e0dc4b8b 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -644,7 +644,14 @@ class Boss: else: sw = self.args_to_special_window(args, cwd_from) if args else None startup_session = next(create_sessions(get_options(), special_window=sw, cwd_from=cwd_from)) - return self.add_os_window(startup_session) + startup_session.session_name = '' + ans = self.add_os_window(startup_session) + if cwd_from is not None and (sow := cwd_from.window) and (tm := self.os_window_map.get(ans)) and sow.created_in_session_name: + for tab in tm: + tab.created_in_session_name = sow.created_in_session_name + for w in tab: + w.created_in_session_name = sow.created_in_session_name + return ans @ac('win', 'New OS Window') def new_os_window(self, *args: str) -> None: @@ -2758,11 +2765,14 @@ class Boss: args = args[1:] allow_remote_control = True if args: - return tab.new_special_window( + w = tab.new_special_window( self.args_to_special_window(args, cwd_from=cwd_from), location=location, allow_remote_control=allow_remote_control) else: - return tab.new_window(cwd_from=cwd_from, location=location, allow_remote_control=allow_remote_control) + w = tab.new_window(cwd_from=cwd_from, location=location, allow_remote_control=allow_remote_control) + if cwd_from is not None and (sw := cwd_from.window): + w.created_in_session_name = sw.created_in_session_name + return w @ac('win', 'Create a new window') def new_window(self, *args: str) -> None: diff --git a/kitty/launch.py b/kitty/launch.py index 0cc98a7e4..948fcb05e 100644 --- a/kitty/launch.py +++ b/kitty/launch.py @@ -26,6 +26,7 @@ class LaunchSpec(NamedTuple): args: list[str] +# Options definition {{{ env_docs = '''\ type=list Environment variables to set in the child process. Can be specified multiple @@ -148,10 +149,13 @@ flag to prevent the new window from closing when the connection is terminated. --add-to-session Add the newly created window/tab to the specified session. Use :code:`.` to add -to the currently active session, if any. See :ref:`sessions` -for what a session is and how to use one. Adding a newly created window to a session -is purely temporary, it does not change the actual session file, for that you have -to resave the session. Note that using this flag in a launch +to the session of the :option:`source window `, if any. See :ref:`sessions` +for what a session is and how to use one. By default, the window is added to the +session of the :option:`source window ` when :option:`launch --cwd` +is set to use the the working directory from that window, otherwise the newly created window +does not belong to any session. To force adding to no session, use the value :code:`!`. +Adding a newly created window to a session is purely temporary, it does not change the actual +session file, for that you have to resave the session. Note that using this flag in a launch command within a session file has no effect as the window is always added to the session belonging to that file. @@ -415,6 +419,7 @@ When using :option:`--cwd`:code:`=current` or similar from a window that is runn the new window will run a local shell after disconnecting from the remote host, when this option is specified. """ +# }}} def parse_launch_args(args: Sequence[str] | None = None) -> LaunchSpec: @@ -781,8 +786,14 @@ def _launch( child_death_callback(0, None) else: add_to_session = opts.add_to_session or '' - if add_to_session == '.': - add_to_session = boss.active_session + match add_to_session: + case '.': + add_to_session = source_window.created_in_session_name if source_window else '' + case '!': + add_to_session = '' + case '': + if kw['cwd_from'] is not None and source_window: + add_to_session = source_window.created_in_session_name kw['hold'] = opts.hold if force_target_tab and target_tab is not None: tab = target_tab diff --git a/kitty/options/definition.py b/kitty/options/definition.py index d792f81d9..6162ff2e0 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -1473,6 +1473,8 @@ use :code:`{sup.index}`. All data available is: The current layout name. :code:`session_name` The name of the kitty session file from which this tab was created, if any. +:code:`active_session_name` + The name of the kitty session file from which the active window in this tab was created, if any. :code:`num_windows` The number of windows in the tab. :code:`num_window_groups` diff --git a/kitty/tab_bar.py b/kitty/tab_bar.py index 35aeec1c7..51804201f 100644 --- a/kitty/tab_bar.py +++ b/kitty/tab_bar.py @@ -52,6 +52,7 @@ class TabBarData(NamedTuple): total_progress: int last_focused_window_with_progress_id: int session_name: str + active_session_name: str class DrawData(NamedTuple): @@ -278,6 +279,8 @@ def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int, eval_locals = { 'index': index, 'layout_name': tab.layout_name, + 'session_name': tab.session_name, + 'active_session_name': tab.active_session_name, 'num_windows': tab.num_windows, 'num_window_groups': tab.num_window_groups, 'title': tab.title, diff --git a/kitty/tabs.py b/kitty/tabs.py index c0d8b07e3..c242fa692 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -977,6 +977,11 @@ class Tab: # {{{ def num_window_groups(self) -> int: return self.windows.num_groups + @property + def active_session_name(self) -> str: + w = self.active_window + return '' if w is None else w.created_in_session_name + def __contains__(self, window: Window) -> bool: return window in self.windows @@ -1297,11 +1302,19 @@ class TabManager: # {{{ cwd_from: CwdRequest | None = None, as_neighbor: bool = False, empty_tab: bool = False, - location: str = 'last' + location: str = 'last', ) -> Tab: idx = len(self.tabs) orig_active_tab_idx = self.active_tab_idx - self._add_tab(Tab(self, no_initial_window=True) if empty_tab else Tab(self, special_window=special_window, cwd_from=cwd_from)) + session_name = '' + if cwd_from is not None and (sw := cwd_from.window): + session_name = sw.created_in_session_name + t = Tab(self, no_initial_window=True, session_name=session_name) if empty_tab else Tab( + self, special_window=special_window, cwd_from=cwd_from, session_name=session_name) + if not empty_tab and session_name: + for w in t: + w.created_in_session_name = session_name + self._add_tab(t) if as_neighbor: location = 'after' if location == 'neighbor': @@ -1392,7 +1405,7 @@ class TabManager: # {{{ has_activity_since_last_focus, t.active_fg, t.active_bg, t.inactive_fg, t.inactive_bg, t.num_of_windows_with_progress, t.total_progress, t.last_focused_window_with_progress_id, - t.created_in_session_name, + t.created_in_session_name, t.active_session_name, )) return ans