Esempio n. 1
0
def open_(editor, args):
    """Open file"""
    if args is None:
        from editxt.commands import show_command_bar
        show_command_bar(editor, "open ")
    elif all(p is None for p in args.paths):
        raise CommandError("please specify a file path")
    else:
        open_files(args.paths, editor.project)
Esempio n. 2
0
def doc(editor, args):
    """Navigate the document tree"""
    if args is None:
        from editxt.commands import show_command_bar
        show_command_bar(editor, doc.name + " ")
        return
    if args.name is not None:
        new_editor = args.file
        if new_editor is None:
            new_editor = args.name
        if new_editor is not EditorTreeItem.NO_MATCH and \
                editor.window.focus(new_editor):
            return
    elif editor.window.focus(args.direction, args.offset):
        return
    beep()
Esempio n. 3
0
def pathfind(editor, args):
    """Find file by path"""
    if args is None and editor is not None:
        args = Options(
            path_pattern=get_selection_regex(editor),
            search_path=base_path(editor),
            unrestricted=False,
        )
    if not (args and args.path_pattern):
        from editxt.commands import show_command_bar
        return show_command_bar(editor, "pathfind ")
    pattern = args.path_pattern
    search_path = args.search_path
    if not search_path:
        return "please specify search path"
    ag_path = editor.app.config.for_command("ag")["path"]
    view = editor.get_output_view()
    line_proc = make_path_processor(view, pattern, ag_path, search_path, editor)
    command = [
        ag_path,
        '--files-with-matches',
        '--file-search-regex', pattern,
        '.',  # match every file (even empty files when unrestricted)
    ]
    if args.unrestricted:
        command.insert(-1, "--unrestricted")
    view.process = threaded_exec_shell(command, cwd=search_path, **line_proc)
Esempio n. 4
0
def python(editor, args):
    """Run the contents of the editor or selection in Python

    executable may be a python interpreter executable or a directory
    such as a virtualenv containing `bin/python`.
    """
    if args is None:
        from editxt.commands import show_command_bar
        show_command_bar(editor, "python ")
        return
    python = args.executable
    if not python:
        raise CommandError("please specify python executable")
    if os.path.isdir(python):
        bin = os.path.join(python, "bin", "python")
        if os.path.exists(bin):
            python = bin
        else:
            raise CommandError("not found: %s" % bin)
    if args.scope == "selection":
        code = editor.document.text_storage[editor.selection]
    else:
        code = editor.document.text
    code = print_last_line(dedent(code))
    cwd = editor.dirname()
    command = [python] + [o for o in args.options if o] + ["-c", code]
    env = dict(os.environ)
    env.pop("PYTHONHOME", None)
    env.pop("PYTHONPATH", None)
    env.pop("PYTHONDONTWRITEBYTECODE", None)
    env.pop("EXECUTABLEPATH", None)
    env.pop("RESOURCEPATH", None)
    result = exec_shell(command, cwd=cwd, env=env)
    if result.returncode == 0:
        msg_type = const.INFO
        message = str(result)
        if message.endswith("\n"):
            message = message[:-1]
    else:
        msg_type = const.ERROR
        message = result or result.err
    if message:
        editor.message(message, msg_type=msg_type)
    else:
        return "no output"
Esempio n. 5
0
def python(editor, args):
    """Run the contents of the editor or selection in Python

    executable may be a python interpreter executable or a directory
    such as a virtualenv containing `bin/python`.
    """
    if args is None:
        from editxt.commands import show_command_bar
        show_command_bar(editor, "python ")
        return
    if not args.executable:
        try:
            python = editor.app.config.for_command("python")["executable"]
        except KeyError:
            python = "python"
    else:
        python = args.executable
        if os.path.isdir(python):
            bin = os.path.join(python, "bin", "python")
            if os.path.exists(bin):
                python = bin
    if args.scope == "selection":
        code = editor.document.text_storage[editor.selection]
    else:
        code = editor.document.text
    cwd = editor.dirname()
    command = [python] + [o for o in args.options if o] + ["-c", code]
    env = dict(os.environ)
    env.pop("PYTHONHOME", None)
    env.pop("PYTHONPATH", None)
    env.pop("PYTHONDONTWRITEBYTECODE", None)
    env.pop("EXECUTABLEPATH", None)
    env.pop("RESOURCEPATH", None)
    result = exec_shell(command, cwd=cwd, env=env)
    if result.returncode == 0:
        msg_type = const.INFO
        message = str(result)
    else:
        msg_type = const.ERROR
        message = result or result.err
    if message:
        editor.message(message, msg_type=msg_type)
    else:
        return "no output"
Esempio n. 6
0
def grab(editor, args):
    """Collect lines matching a pattern"""
    if args is None:
        from editxt.commands import show_command_bar
        show_command_bar(editor, "grab ")
        return
    elif args.pattern is None:
        raise CommandError("please specify a pattern to match")
    if args.invert:
        norm = lambda m: not m
    else:
        norm = lambda m: m
    scope = editor.selection if args.scope == "selection" else (0,)
    regex = re.compile(args.pattern, args.pattern.flags)
    lines = []
    for line in iterlines(editor.document.text, scope):
        if norm(regex.search(line)):
            lines.append(line)
    if lines:
        return "".join(lines)
    beep()
Esempio n. 7
0
def ag(editor, args):
    """Search for files matching pattern"""
    if args is None:
        from editxt.commands import show_command_bar
        show_command_bar(editor, "ag ")
        return
    elif args.pattern is None:
        raise CommandError("please specify a pattern to match")
    pattern = args.pattern
    if "-i" in args.options or "--ignore-case" in args.options:
        pattern = RegexPattern(pattern, pattern.flags | re.IGNORECASE)
    elif pattern.flags & re.IGNORECASE:
        args.options.append("--ignore-case")
    ag_path = editor.app.config.for_command("ag")["path"]
    options = editor.app.config.for_command("ag")["options"]
    options = DEFAULT_OPTIONS + shlex.split(options)
    cwd = args.path or editor.dirname()
    view = editor.get_output_view()
    line_processor = make_line_processor(view, pattern, ag_path, cwd)
    command = [ag_path, pattern] + [o for o in args.options if o] + options
    view.process = threaded_exec_shell(command, cwd=cwd, **line_processor)
Esempio n. 8
0
def pathfind(editor, args):
    """Find file by path"""
    if args is None and editor is not None:
        args = Options(
            path_pattern=get_selection_regex(editor),
            search_path=base_path(editor),
            open="open-single-match",
        )
    if not (args and args.path_pattern):
        from editxt.commands import show_command_bar
        return show_command_bar(editor, "pathfind ")
    pattern = args.path_pattern
    search_path = args.search_path
    regex = re.compile(pattern, pattern.flags)
    if not search_path:
        return "please specify search path"
    paths = []
    exclude = editor.app.config.for_command("pathfind")["exclude_patterns"]
    if args.open == "all-matched-paths":
        is_excluded = lambda path: False
    else:
        excluders = [make_matcher(pattern) for pattern in exclude]
        def is_excluded(path):
            filename = basename(path)
            return any(x(filename) for x in excluders)
    for dirpath, dirnames, filenames in os.walk(search_path):
        if is_excluded(dirpath):
            continue
        for name in filenames:
            path = join(dirpath, name)
            if regex.search(path) and not is_excluded(path):
                paths.append(path)
    if len(paths) == 1 and args.open == "open-single-match":
        editor.project.window.open_paths(paths, focus=True)
    elif paths and args.open == "open-first-match":
        editor.project.window.open_paths(paths[:1], focus=True)
    elif paths:
        link = partial(path_link, editor=editor)
        message = markdown("\n".join(link(path) for path in paths), pre=True)
        editor.message(message)
    else:
        return "no match for pattern: {}".format(args.path_pattern)
Esempio n. 9
0
def blame(editor, args):
    """Invoke `git gui blame` on file path

    Example configuration:

        command:
          blame:
            git_path: /opt/local/bin/git
    """
    if not args:
        from editxt.commands import show_command_bar
        return show_command_bar(editor, "blame ")
    if not (args.path and isfile(args.path)):
        raise CommandError("cannot blame file without path")
    git_path = editor.app.config.for_command("blame")["git_path"]
    command = [git_path, "gui", "blame", args.path]
    output = []
    def got_output(text, returncode):
        if returncode is None:
            output.append(text)
        else:
            if returncode:
                if git_path == "git":
                    try:
                        command[0] = subprocess.check_output(
                            ["which", "git"], universal_newlines=True).strip()
                    except subprocess.CalledProcessError:
                        pass
                output.insert(0, " ".join(command) + "\n")
                output.append("\nexit code: {}".format(returncode))
                view.append_message("".join(output), msg_type=const.ERROR)
            view.process_completed()
    view = editor.get_output_view()
    view.process = threaded_exec_shell(
        command,
        cwd=dirname(realpath(args.path)),
        got_output=got_output,
        kill_on_cancel=False,
    )
Esempio n. 10
0
def github_url(editor, args):
    """Get GitHub URL"""
    if not args:
        from editxt.commands import show_command_bar
        return show_command_bar(editor, "github-url ")
    if not (editor and editor.file_path):
        raise CommandError("cannot get github URL without path")
    info = get_git_info(editor)
    if not args.remote:
        if info.remotes:
            remote = info.remotes[0]
        else:
            raise CommandError("cannot get github URL without remote name")
    else:
        remote = {r.name: r for r in info.remotes}.get(args.remote)
    if remote is None:
        raise CommandError("unknown remote: {}".format(args.remote))
    if args.rev == "HEAD":
        rev = rev_parse(info.git_dir, "--abbrev-ref")
        if rev == "HEAD":
            rev = rev_parse(info.git_dir)
    else:
        rev = args.rev
    lines = get_selected_lines(editor)
    if lines:
        if ":" in lines:
            lines = lines.replace(":", "-L")
        lines = "#L" + lines
    link = "https://github.com/{user}/{repo}/blob/{rev}/{path}{line}".format(
        user=remote.user,
        repo=remote.repo,
        rev=rev,
        path=git_relative_path(editor.file_path, info),
        line=lines,
    )
    editor.message(html_string("<a href='{0}'>{0}</a>".format(link)))