예제 #1
0
from itertools import repeat

from kitty.cli import parse_args
from kitty.cli_stub import HintsCLIOptions
from kitty.fast_data_types import set_clipboard_string
from kitty.key_encoding import key_defs as K, backspace_key, enter_key
from kitty.utils import screen_size_function

from ..tui.handler import Handler, result_handler
from ..tui.loop import Loop
from ..tui.operations import faint, styled

URL_PREFIXES = 'http https file ftp'.split()
DEFAULT_HINT_ALPHABET = string.digits + string.ascii_lowercase
DEFAULT_REGEX = r'(?m)^\s*(.+)\s*$'
screen_size = screen_size_function()
ESCAPE = K['ESCAPE']


class Mark:

    __slots__ = ('index', 'start', 'end', 'text', 'groupdict')

    def __init__(self, index, start, end, text, groupdict):
        self.index, self.start, self.end = index, start, end
        self.text = text
        self.groupdict = groupdict


@lru_cache(maxsize=2048)
def encode_hint(num, alphabet):
예제 #2
0
파일: main.py 프로젝트: tomaskrizek/kitty
def parse_input(text: str) -> str:
    try:
        cols = int(os.environ['OVERLAID_WINDOW_COLS'])
    except KeyError:
        cols = screen_size_function()().cols
    return convert_text(text, cols)
예제 #3
0
def main(args=sys.argv):
    global screen_size
    args, items = parse_args(args[1:], options_spec, usage, help_text,
                             '{} +kitten icat'.format(appname))

    if args.print_window_size:
        screen_size_function.ans = None
        with open(os.ctermid()) as tty:
            ss = screen_size_function(tty)()
        print('{}x{}'.format(ss.width, ss.height), end='')
        raise SystemExit(0)

    if not sys.stdout.isatty():
        sys.stdout = open(os.ctermid(), 'w')
    screen_size = screen_size_function()
    signal.signal(signal.SIGWINCH,
                  lambda signum, frame: setattr(screen_size, 'changed', True))
    if screen_size().width == 0:
        if args.detect_support:
            raise SystemExit(1)
        raise SystemExit(
            'Terminal does not support reporting screen sizes via the TIOCGWINSZ ioctl'
        )
    try:
        args.place = parse_place(args.place)
    except Exception:
        raise SystemExit('Not a valid place specification: {}'.format(
            args.place))

    if args.detect_support:
        if not detect_support(wait_for=args.detection_timeout, silent=True):
            raise SystemExit(1)
        print('file' if detect_support.has_files else 'stream',
              end='',
              file=sys.stderr)
        return
    if args.transfer_mode == 'detect':
        if not detect_support(wait_for=args.detection_timeout):
            raise SystemExit(
                'This terminal emulator does not support the graphics protocol, use a terminal emulator such as kitty that does support it'
            )
    else:
        detect_support.has_files = args.transfer_mode == 'file'
    errors = []
    if args.clear:
        sys.stdout.buffer.write(clear_images_on_screen(delete_data=True))
        if not items:
            return
    if not items:
        raise SystemExit('You must specify at least one file to cat')
    if args.place:
        if len(items) > 1 or os.path.isdir(items[0]):
            raise SystemExit(
                'The --place option can only be used with a single image')
        sys.stdout.buffer.write(b'\0337')  # save cursor
    for item in items:
        try:
            if os.path.isdir(item):
                for x in scan(item):
                    process(item, args)
            else:
                process(item, args)
        except NoImageMagick as e:
            raise SystemExit(str(e))
        except ConvertFailed as e:
            raise SystemExit(str(e))
        except OpenFailed as e:
            errors.append(e)
    if args.place:
        sys.stdout.buffer.write(b'\0338')  # restore cursor
    if not errors:
        return
    for err in errors:
        print(err, file=sys.stderr)
    raise SystemExit(1)
예제 #4
0
파일: cli.py 프로젝트: phongnh/kitty
    def __call__(self, seq: OptionSpecSeq, usage: Optional[str],
                 message: Optional[str], appname: str) -> None:
        from kitty.utils import screen_size_function
        screen_size = screen_size_function()
        try:
            linesz = min(screen_size().cols, 76)
        except OSError:
            linesz = 76
        blocks: List[str] = []
        a = blocks.append

        def wa(text: str,
               indent: int = 0,
               leading_indent: Optional[int] = None) -> None:
            if leading_indent is None:
                leading_indent = indent
            j = '\n' + (' ' * indent)
            lines: List[str] = []
            for ln in text.splitlines():
                if ln:
                    lines.extend(wrap(ln, 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 default_msg
        wa(prettify(message))
        a('')
        if seq:
            a('{}:'.format(title('Options')))
        for opt in seq:
            if isinstance(opt, str):
                a(f'{title(opt)}:')
                continue
            help_text = opt['help']
            if help_text == '!':
                continue  # hidden option
            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 = help_text.replace('%default', str(defval))
                wa(prettify(t.strip()), indent=4)
                if defval is not None:
                    wa(f'Default: {defval}', indent=4)
                if opt.get('choices'):
                    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():
            import subprocess
            p = subprocess.Popen(['less', '-isRXF'], stdin=subprocess.PIPE)
            try:
                p.communicate(text.encode('utf-8'))
            except KeyboardInterrupt:
                raise SystemExit(1)
            raise SystemExit(p.wait())
        else:
            print(text)
예제 #5
0
파일: main.py 프로젝트: wenyuesr/kitty
def main(args: List[str] = sys.argv) -> None:
    global can_transfer_with_files
    cli_opts, items_ = parse_args(args[1:], options_spec, usage, help_text, '{} +kitten icat'.format(appname), result_class=IcatCLIOptions)
    items: List[Union[str, bytes]] = list(items_)

    if cli_opts.print_window_size:
        screen_size_function.cache_clear()
        with open(os.ctermid()) as tty:
            ss = screen_size_function(tty)()
        print('{}x{}'.format(ss.width, ss.height), end='')
        raise SystemExit(0)

    if not sys.stdout.isatty():
        sys.stdout = open(os.ctermid(), 'w')
    stdin_data = None
    if cli_opts.stdin == 'yes' or (not sys.stdin.isatty() and cli_opts.stdin == 'detect'):
        stdin_data = sys.stdin.buffer.read()
        if stdin_data:
            items.insert(0, stdin_data)
        sys.stdin.close()
        sys.stdin = open(os.ctermid(), 'r')

    screen_size = get_screen_size_function()
    signal.signal(signal.SIGWINCH, lambda signum, frame: setattr(screen_size, 'changed', True))
    if screen_size().width == 0:
        if cli_opts.detect_support:
            raise SystemExit(1)
        raise SystemExit(
            'Terminal does not support reporting screen sizes via the TIOCGWINSZ ioctl'
        )
    parsed_opts = ParsedOpts()
    if cli_opts.place:
        try:
            parsed_opts.place = parse_place(cli_opts.place)
        except Exception:
            raise SystemExit('Not a valid place specification: {}'.format(cli_opts.place))

    try:
        parsed_opts.z_index = parse_z_index(cli_opts.z_index)
    except Exception:
        raise SystemExit('Not a valid z-index specification: {}'.format(cli_opts.z_index))

    if cli_opts.detect_support:
        if not detect_support(wait_for=cli_opts.detection_timeout, silent=True):
            raise SystemExit(1)
        print('file' if can_transfer_with_files else 'stream', end='', file=sys.stderr)
        return
    if cli_opts.transfer_mode == 'detect':
        if not detect_support(wait_for=cli_opts.detection_timeout, silent=cli_opts.silent):
            raise SystemExit('This terminal emulator does not support the graphics protocol, use a terminal emulator such as kitty that does support it')
    else:
        can_transfer_with_files = cli_opts.transfer_mode == 'file'
    errors = []
    if cli_opts.clear:
        sys.stdout.write(clear_images_on_screen(delete_data=True))
        if not items:
            return
    if not items:
        raise SystemExit('You must specify at least one file to cat')
    if parsed_opts.place:
        if len(items) > 1 or (isinstance(items[0], str) and os.path.isdir(items[0])):
            raise SystemExit(f'The --place option can only be used with a single image, not {items}')
        sys.stdout.buffer.write(b'\0337')  # save cursor
    url_pat = re.compile(r'(?:https?|ftp)://', flags=re.I)
    for item in items:
        try:
            process_single_item(item, cli_opts, parsed_opts, url_pat)
        except NoImageMagick as e:
            raise SystemExit(str(e))
        except ConvertFailed as e:
            raise SystemExit(str(e))
        except OpenFailed as e:
            errors.append(e)
    if parsed_opts.place:
        sys.stdout.buffer.write(b'\0338')  # restore cursor
    if errors:
        for err in errors:
            print(err, file=sys.stderr)
    if cli_opts.hold:
        with open(os.ctermid()) as tty:
            with raw_mode(tty.fileno()):
                tty.buffer.read(1)
    raise SystemExit(1 if errors else 0)
예제 #6
0
파일: main.py 프로젝트: wenyuesr/kitty
def get_screen_size_function() -> ScreenSizeGetter:
    global screen_size
    if screen_size is None:
        screen_size = screen_size_function()
    return screen_size