diff --git a/kittens/ask/main.py b/kittens/ask/main.py index 4265df63b..0d8efd55e 100644 --- a/kittens/ask/main.py +++ b/kittens/ask/main.py @@ -2,16 +2,15 @@ # vim:fileencoding=utf-8 # License: GPL v3 Copyright: 2018, Kovid Goyal -import json import os -import readline -import sys from kitty.cli import parse_args from kitty.constants import cache_dir from ..tui.operations import alternate_screen, styled +readline = None + def get_history_items(): return list(map(readline.get_history_item, range(1, readline.get_current_history_length() + 1))) @@ -81,7 +80,13 @@ be used for completions and via the browse history readline bindings. ''' -def real_main(args): +def main(args): + # For some reason importing readline in a key handler in the main kitty process + # causes a crash of the python interpreter, probably because of some global + # lock + global readline + import readline as rl + readline = rl msg = 'Ask the user for input' try: args, items = parse_args(args[1:], option_text, '', msg, 'kitty ask') @@ -91,6 +96,7 @@ def real_main(args): raise SystemExit(1) readline.read_init_file() + ans = {'items': items} with alternate_screen(), HistoryCompleter(args.name): if args.message: @@ -98,17 +104,13 @@ def real_main(args): prompt = '> ' try: - ans = input(prompt) + ans['response'] = input(prompt) except (KeyboardInterrupt, EOFError): - return - print('OK:', json.dumps(ans)) + pass + return ans -def main(args=sys.argv): - try: - real_main(args) - except Exception as e: - import traceback - traceback.print_exc(file=sys.stdout) - input('Press enter to quit...') - raise SystemExit(1) +def handle_result(args, data, target_window_id, boss): + if 'response' in data: + func, *args = data['items'] + getattr(boss, func)(data['response'], *args) diff --git a/kitty/boss.py b/kitty/boss.py index 426c78f1b..120063e37 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -470,9 +470,6 @@ class Boss: cmd = ['kitty', '+runpy', 'import os, sys, time; time.sleep(0.05); os.execvp(sys.argv[1], sys.argv[1:])'] + editor + [confpath] self.new_os_window(*cmd) - def input_unicode_character(self): - self.run_kitten('none', 'unicode_input') - def get_output(self, source_window, num_lines=1): output = '' s = source_window.screen @@ -482,35 +479,10 @@ class Boss: output += str(s.linebuf.line(i)) return output - def set_tab_title(self): + def _run_kitten(self, kitten, args, type_of_input='none'): w = self.active_window tab = self.active_tab if w is not None and tab is not None and w.overlay_for is None: - args = ['--name=tab-title', '--message', _('Enter the new title for this tab below.')] - overlay_window = tab.new_special_window( - SpecialWindow( - ['kitty', '+runpy', 'from kittens.ask.main import main; main()'] + args, - overlay_for=w.id)) - overlay_window.action_on_close = partial(self.do_set_tab_title, tab.id) - - def do_set_tab_title(self, tab_id, source_window): - output = self.get_output(source_window) - if output.startswith('OK: '): - title = json.loads(output.partition(' ')[2].strip()) - tm = self.active_tab_manager - if tm is not None and title: - for tab in tm.tabs: - if tab.id == tab_id: - tab.set_title(title) - break - - def run_kitten(self, type_of_input, kitten, *args): - import shlex - w = self.active_window - tab = self.active_tab - if w is not None and tab is not None and w.overlay_for is None: - cmdline = args[0] if args else '' - args = shlex.split(cmdline) if cmdline else [] orig_args = args[:] args[0:0] = [config_dir, kitten] if type_of_input in ('text', 'history', 'ansi', 'ansi-history'): @@ -528,12 +500,36 @@ class Boss: overlay_for=w.id)) overlay_window.action_on_close = partial(self.on_kitten_finish, w.id, end_kitten) + def run_kitten(self, type_of_input, kitten, *args): + import shlex + cmdline = args[0] if args else '' + args = shlex.split(cmdline) if cmdline else [] + self._run_kitten(kitten, args, type_of_input) + def on_kitten_finish(self, target_window_id, end_kitten, source_window): output = self.get_output(source_window, num_lines=None) if output.startswith('OK: '): data = json.loads(output.partition(' ')[2].strip()) end_kitten(data, target_window_id, self) + def input_unicode_character(self): + self._run_kitten('unicode_input') + + def set_tab_title(self): + tab = self.active_tab + if tab: + args = ['--name=tab-title', '--message', _('Enter the new title for this tab below.'), 'do_set_tab_title', str(tab.id)] + self._run_kitten('ask', args) + + def do_set_tab_title(self, title, tab_id): + tm = self.active_tab_manager + if tm is not None and title: + tab_id = int(tab_id) + for tab in tm.tabs: + if tab.id == tab_id: + tab.set_title(title) + break + def kitty_shell(self, window_type): cmd = ['kitty', '@'] if window_type == 'tab':