Allow creating new OS windows in session files

Fixes #1514
This commit is contained in:
Kovid Goyal 2019-04-02 19:57:09 +05:30
parent 58bb5a7d1f
commit 4baf7b5bba
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 39 additions and 21 deletions

View File

@ -24,6 +24,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
multi-character ligatures under the cursor to make editing easier multi-character ligatures under the cursor to make editing easier
(:iss:`461`) (:iss:`461`)
- Allow creating new OS windows in session files (:iss:`1514`)
- Allow specifying a value of ``none`` for the :opt:`selection_foreground` - Allow specifying a value of ``none`` for the :opt:`selection_foreground`
which will cause kitty to not change text color in selections (:iss:`1358`) which will cause kitty to not change text color in selections (:iss:`1358`)

View File

@ -342,6 +342,10 @@ For example:
# Set the current layout # Set the current layout
layout stack layout stack
launch zsh launch zsh
# Create a new OS window
new_os_window
launch sh
# Make the current window the active (focused) window # Make the current window the active (focused) window
focus focus
launch emacs launch emacs

View File

@ -30,7 +30,7 @@ from .keys import get_shortcut, shortcut_matches
from .layout import set_draw_borders_options from .layout import set_draw_borders_options
from .remote_control import handle_cmd from .remote_control import handle_cmd
from .rgb import Color, color_from_int from .rgb import Color, color_from_int
from .session import create_session from .session import create_sessions
from .tabs import SpecialWindow, SpecialWindowInstance, TabManager from .tabs import SpecialWindow, SpecialWindowInstance, TabManager
from .utils import ( from .utils import (
func_name, get_editor, get_primary_selection, is_path_in_temp_dir, func_name, get_editor, get_primary_selection, is_path_in_temp_dir,
@ -128,16 +128,18 @@ class Boss:
) )
set_boss(self) set_boss(self)
self.opts, self.args = opts, args self.opts, self.args = opts, args
startup_session = create_session(opts, args, default_session=opts.startup_session) startup_sessions = create_sessions(opts, args, default_session=opts.startup_session)
self.keymap = self.opts.keymap.copy() self.keymap = self.opts.keymap.copy()
if new_os_window_trigger is not None: if new_os_window_trigger is not None:
self.keymap.pop(new_os_window_trigger, None) self.keymap.pop(new_os_window_trigger, None)
self.add_os_window(startup_session, os_window_id=os_window_id) for startup_session in startup_sessions:
if args.start_as != 'normal': os_window_id = self.add_os_window(startup_session, os_window_id=os_window_id)
if args.start_as == 'fullscreen': if args.start_as != 'normal':
self.toggle_fullscreen() if args.start_as == 'fullscreen':
else: self.toggle_fullscreen()
change_os_window_state(args.start_as) else:
change_os_window_state(args.start_as)
os_window_id = None
if is_macos: if is_macos:
from .fast_data_types import cocoa_set_notification_activated_callback from .fast_data_types import cocoa_set_notification_activated_callback
cocoa_set_notification_activated_callback(self.notification_activated) cocoa_set_notification_activated_callback(self.notification_activated)
@ -246,7 +248,7 @@ class Boss:
sw = args sw = args
else: else:
sw = self.args_to_special_window(args, cwd_from) if args else None sw = self.args_to_special_window(args, cwd_from) if args else None
startup_session = create_session(self.opts, special_window=sw, cwd_from=cwd_from) startup_session = next(create_sessions(self.opts, special_window=sw, cwd_from=cwd_from))
return self.add_os_window(startup_session) return self.add_os_window(startup_session)
def new_os_window(self, *args): def new_os_window(self, *args):
@ -304,10 +306,10 @@ class Boss:
opts = create_opts(args) opts = create_opts(args)
if not os.path.isabs(args.directory): if not os.path.isabs(args.directory):
args.directory = os.path.join(msg['cwd'], args.directory) args.directory = os.path.join(msg['cwd'], args.directory)
session = create_session(opts, args, respect_cwd=True) for session in create_sessions(opts, args, respect_cwd=True):
os_window_id = self.add_os_window(session, wclass=args.cls, wname=args.name, opts_for_size=opts, startup_id=startup_id) os_window_id = self.add_os_window(session, wclass=args.cls, wname=args.name, opts_for_size=opts, startup_id=startup_id)
if msg.get('notify_on_os_window_death'): if msg.get('notify_on_os_window_death'):
self.os_window_death_actions[os_window_id] = partial(self.notify_on_os_window_death, msg['notify_on_os_window_death']) self.os_window_death_actions[os_window_id] = partial(self.notify_on_os_window_death, msg['notify_on_os_window_death'])
else: else:
log_error('Unknown message received from peer, ignoring') log_error('Unknown message received from peer, ignoring')

View File

@ -78,6 +78,13 @@ def resolved_shell(opts):
def parse_session(raw, opts, default_title=None): def parse_session(raw, opts, default_title=None):
def finalize_session(ans):
for t in ans.tabs:
if not t.windows:
t.windows.append(resolved_shell(opts))
return ans
ans = Session(default_title) ans = Session(default_title)
ans.add_tab(opts) ans.add_tab(opts)
for line in raw.splitlines(): for line in raw.splitlines():
@ -87,6 +94,10 @@ def parse_session(raw, opts, default_title=None):
cmd, rest = cmd.strip(), rest.strip() cmd, rest = cmd.strip(), rest.strip()
if cmd == 'new_tab': if cmd == 'new_tab':
ans.add_tab(opts, rest) ans.add_tab(opts, rest)
elif cmd == 'new_os_window':
yield finalize_session(ans)
ans = Session(default_title)
ans.add_tab(opts, rest)
elif cmd == 'layout': elif cmd == 'layout':
ans.set_layout(rest) ans.set_layout(rest)
elif cmd == 'launch': elif cmd == 'launch':
@ -101,16 +112,14 @@ def parse_session(raw, opts, default_title=None):
ans.set_next_title(rest) ans.set_next_title(rest)
else: else:
raise ValueError('Unknown command in session file: {}'.format(cmd)) raise ValueError('Unknown command in session file: {}'.format(cmd))
for t in ans.tabs: yield finalize_session(ans)
if not t.windows:
t.windows.append(resolved_shell(opts))
return ans
def create_session(opts, args=None, special_window=None, cwd_from=None, respect_cwd=False, default_session=None): def create_sessions(opts, args=None, special_window=None, cwd_from=None, respect_cwd=False, default_session=None):
if args and args.session: if args and args.session:
with open(args.session) as f: with open(args.session) as f:
return parse_session(f.read(), opts, getattr(args, 'title', None)) yield from parse_session(f.read(), opts, getattr(args, 'title', None))
return
if default_session and default_session != 'none': if default_session and default_session != 'none':
try: try:
with open(default_session) as f: with open(default_session) as f:
@ -118,7 +127,8 @@ def create_session(opts, args=None, special_window=None, cwd_from=None, respect_
except EnvironmentError: except EnvironmentError:
log_error('Failed to read from session file, ignoring: {}'.format(default_session)) log_error('Failed to read from session file, ignoring: {}'.format(default_session))
else: else:
return parse_session(session_data, opts, getattr(args, 'title', None)) yield from parse_session(session_data, opts, getattr(args, 'title', None))
return
ans = Session() ans = Session()
current_layout = opts.enabled_layouts[0] if opts.enabled_layouts else 'tall' current_layout = opts.enabled_layouts[0] if opts.enabled_layouts else 'tall'
ans.add_tab(opts) ans.add_tab(opts)
@ -135,4 +145,4 @@ def create_session(opts, args=None, special_window=None, cwd_from=None, respect_
k['override_title'] = args.title k['override_title'] = args.title
special_window = SpecialWindow(cmd, **k) special_window = SpecialWindow(cmd, **k)
ans.add_special_window(special_window) ans.add_special_window(special_window)
return ans yield ans