def loop(self, handler): select = self.sel.select tb = None waiting_for_write = True with closing(self.sel), TermManager(self.input_fd, self.output_fd) as term_manager: signal.signal(signal.SIGWINCH, self._on_sigwinch) signal.signal(signal.SIGTERM, self._on_sigterm) signal.signal(signal.SIGINT, self._on_sigint) handler.write_buf = [] handler._term_manager = term_manager keep_going = True try: handler._initialize(screen_size(), self.quit, self.wakeup, self.start_job) with handler: while keep_going: has_data_to_write = bool(handler.write_buf) if not has_data_to_write and not self.read_allowed: break if has_data_to_write != waiting_for_write: waiting_for_write = has_data_to_write self._modify_output_selector(waiting_for_write) events = select() for key, mask in events: key.data(handler) except Exception: import traceback tb = traceback.format_exc() self.return_code = 1 keep_going = False if tb is not None: self._report_error_loop(tb, term_manager)
def print_help_for_seq(seq, usage, message, appname): from kitty.icat import screen_size screen_size.changed = True try: linesz = min(screen_size().cols, 76) except EnvironmentError: linesz = 76 blocks = [] a = blocks.append def wa(text, indent=0, leading_indent=None): if leading_indent is None: leading_indent = indent j = '\n' + (' ' * indent) lines = [] for l in text.splitlines(): if l: lines.extend(wrap(l, limit=linesz - indent)) else: lines.append('') a((' ' * leading_indent) + j.join(lines)) usage = '[program-to-run ...]' if usage is None else usage optstring = '[options] ' if seq else '' a('{}: {} {}{}'.format(title('Usage'), bold(yellow(appname)), optstring, usage)) a('') message = message or ( 'Run the |G {appname}| terminal emulator. You can also specify the |_ program| to run inside |_ {appname}| as normal' ' arguments following the |_ options|. For example: {appname} /bin/sh' ).format(appname=appname) wa(prettify(message)) a('') if seq: a('{}:'.format(title('Options'))) for opt in seq: if isinstance(opt, str): a('{}:'.format(title(opt))) continue a(' ' + ', '.join(map(green, sorted(opt['aliases'])))) if not opt.get('type', '').startswith('bool-'): blocks[-1] += '={}'.format(italic(opt['dest'].upper())) if opt.get('help'): defval = opt.get('default') t = opt['help'].replace('%default', str(defval)) wa(prettify(t.strip()), indent=4) if defval is not None: wa('Default: {}'.format(defval), indent=4) if 'choices' in opt: wa('Choices: {}'.format(', '.join(opt['choices'])), indent=4) a('') text = '\n'.join(blocks) + '\n\n' + version() if print_help_for_seq.allow_pager and sys.stdout.isatty(): p = subprocess.Popen(['less', '-isRXF'], stdin=subprocess.PIPE) p.communicate(text.encode('utf-8')) raise SystemExit(p.wait()) else: print(text)
def _wakeup_ready(self, handler): data = os.read(self.wakeup_read_fd) if b'r' in data: screen_size.changed = True handler.on_resize(screen_size()) if b't' in data: handler.on_term() if b'i' in data: handler.on_interrupt()
def _report_error_loop(self, tb): select = self.sel.select waiting_for_write = False handler = UnhandledException(tb) handler.write_buf = [] handler.initialize(screen_size(), self.quit, self.wakeup) while True: has_data_to_write = bool(handler.write_buf) if not has_data_to_write and not self.read_allowed: break if has_data_to_write != waiting_for_write: waiting_for_write = has_data_to_write self._modify_output_selector(waiting_for_write) events = select() for key, mask in events: key.data(handler)
def _wakeup_ready(self, handler): data = os.read(self.wakeup_read_fd, 1024) if b'r' in data: screen_size.changed = True handler.on_resize(screen_size()) if b't' in data: handler.on_term() if b'i' in data: handler.on_interrupt() if b'j' in data: while True: try: entry = self.jobs_queue.get_nowait() except Empty: break else: job_id = entry.pop('id') handler.on_job_done(job_id, entry) if b'1' in data: handler.on_wakeup()
def print_help_for_seq(seq): from kitty.icat import screen_size try: linesz = min(screen_size().cols, 76) except EnvironmentError: linesz = 76 blocks = [] a = blocks.append def wa(text, indent=0, leading_indent=None): if leading_indent is None: leading_indent = indent j = '\n' + (' ' * indent) a((' ' * leading_indent) + j.join(wrap(text, limit=linesz - indent))) a('{}: {} [options] [program-to-run ...]'.format(title('Usage'), bold(yellow(appname)))) a('') wa('Run the {appname} terminal emulator. You can also specify the {program} to run inside {appname} as normal' ' arguments following the {options}. For example: {appname} /bin/sh'. format(appname=italic(appname), options=italic('options'), program=italic('program'))) a('') a('{}:'.format(title('Options'))) for opt in seq: if isinstance(opt, str): a('{}:'.format(title(opt))) continue a(' ' + ', '.join(map(green, sorted(opt['aliases'])))) if opt.get('help'): t = opt['help'].replace('%default', str(opt.get('default'))) wa(prettify(t), indent=4) text = '\n'.join(blocks) + '\n\n' + version() if sys.stdout.isatty(): p = subprocess.Popen(['less', '-isR'], stdin=subprocess.PIPE) p.communicate(text.encode('utf-8')) raise SystemExit(p.wait()) else: print(text)