diff --git a/docs/changelog.rst b/docs/changelog.rst index 7a0ec2c8d..74f1d0890 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,9 @@ To update |kitty|, :doc:`follow the instructions `. - Allow choosing OpenType features for individual fonts via the :opt:`font_features` option. +- Allow opening new tabs/windows before the current tab/window as well as after + it with the :option:`launch --location` option. + - Add a :opt:`resize_in_steps` option that can be used to resize the OS window in steps as large as character cells (:pull:`2131`) diff --git a/kitty/launch.py b/kitty/launch.py index 6e98ff696..8b1afdc33 100644 --- a/kitty/launch.py +++ b/kitty/launch.py @@ -73,11 +73,12 @@ def options_spec(): --location type=choices default=last -choices=first,neighbor,last +choices=first,after,before,neighbor,last Where to place the newly created window when it is added to a tab which -already has existing windows in it. Also applies to creating a new tab, -where the value of neighbor will cause the new tab to be placed next to -the current tab instead of at the end. +already has existing windows in it. :code:`after` and :code:`before` place the new +window before or after the active window. :code:`neighbor` is a synonym for :code:`after`. +Also applies to creating a new tab, where the value of :code:`after` +will cause the new tab to be placed next to the current tab instead of at the end. --allow-remote-control @@ -118,7 +119,7 @@ def options_spec(): --marker Create a marker that highlights text in the newly created window. The syntax is -the same as for the :opt:`toggle_marker` map action. +the same as for the :code:`toggle_marker` map action (see :doc:`/marks`). ''' options_spec.ans = OPTIONS return options_spec.ans @@ -147,7 +148,7 @@ def get_env(opts, active_child): def tab_for_window(boss, opts, target_tab=None): if opts.type == 'tab': tm = boss.active_tab_manager - tab = tm.new_tab(empty_tab=True, as_neighbor=opts.location == 'neighbor') + tab = tm.new_tab(empty_tab=True, location=opts.location) if opts.tab_title: tab.set_title(opts.tab_title) elif opts.type == 'os-window': diff --git a/kitty/layout.py b/kitty/layout.py index e3fe2e8a3..15540ecf8 100644 --- a/kitty/layout.py +++ b/kitty/layout.py @@ -279,8 +279,12 @@ def add_window(self, all_windows, window, current_active_window_idx, location=No all_windows[i] = window active_window_idx = i elif location is not None: - if location == 'neighbor' and current_active_window_idx is not None and len(all_windows) > 1: + if location == 'neighbor': + location = 'after' + if location == 'after' and current_active_window_idx is not None and len(all_windows) > 1: active_window_idx = min(current_active_window_idx + 1, len(all_windows)) + elif location == 'before' and current_active_window_idx is not None and len(all_windows) > 1: + active_window_idx = current_active_window_idx elif location == 'first': active_window_idx = 0 if active_window_idx is not None: diff --git a/kitty/tabs.py b/kitty/tabs.py index 2b54e57b2..07e55ecd9 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -615,17 +615,26 @@ def move_tab(self, delta=1): self._set_active_tab(nidx) self.mark_tab_bar_dirty() - def new_tab(self, special_window=None, cwd_from=None, as_neighbor=False, empty_tab=False): - nidx = self.active_tab_idx + 1 + def new_tab(self, special_window=None, cwd_from=None, as_neighbor=False, empty_tab=False, location='last'): 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)) self._set_active_tab(idx) - if len(self.tabs) > 2 and as_neighbor and idx != nidx: - for i in range(idx, nidx, -1): - self.tabs[i], self.tabs[i-1] = self.tabs[i-1], self.tabs[i] - swap_tabs(self.os_window_id, i, i-1) - self._set_active_tab(nidx) - idx = nidx + if as_neighbor: + location = 'after' + if location == 'neighbor': + location = 'after' + if len(self.tabs) > 1 and location != 'last': + if location == 'first': + desired_idx = 0 + else: + desired_idx = orig_active_tab_idx + (0 if location == 'before' else 1) + if idx != desired_idx: + for i in range(idx, desired_idx, -1): + self.tabs[i], self.tabs[i-1] = self.tabs[i-1], self.tabs[i] + swap_tabs(self.os_window_id, i, i-1) + self._set_active_tab(desired_idx) + idx = desired_idx self.mark_tab_bar_dirty() return self.tabs[idx]