Esempio n. 1
0
    def _resize(self, view: View, defx: Defx, context: Context) -> None:
        if not context.args:
            return

        view._context = view._context._replace(winwidth=int(context.args[0]))
        view._init_window()
        view.redraw(True)
Esempio n. 2
0
def _rename(view: View, defx: Defx, context: Context) -> None:
    """
    Rename the file or directory.
    """

    if len(context.targets) > 1:
        # ex rename
        view._vim.call('defx#exrename#create_buffer',
                       [{'action__path': str(x['action__path'])}
                        for x in context.targets],
                       {'buffer_name': 'defx'})
        return

    for target in context.targets:
        old = target['action__path']
        new_filename = cwd_input(
            view._vim, defx._cwd,
            f'Old name: {old}\nNew name: ', str(old), 'file')
        view._vim.command('redraw')
        if not new_filename:
            return
        new = Path(defx._cwd).joinpath(new_filename)
        if not new or new == old:
            continue
        if str(new).lower() != str(old).lower() and new.exists():
            error(view._vim, f'{new} already exists')
            continue

        old.rename(new)

        view.redraw(True)
        view.search_file(new, defx._index)
Esempio n. 3
0
def _paste(view: View, defx: Defx, context: Context) -> None:
    action = view._clipboard.action
    for index, candidate in enumerate(view._clipboard.candidates):
        path = candidate['action__path']
        dest = Path(defx._cwd).joinpath(path.name)
        if dest.exists():
            overwrite = check_overwrite(view, dest, path)
            if overwrite == Path(''):
                continue
            dest = Path(defx._cwd).joinpath(overwrite.name)

        if path == dest:
            continue

        view.print_msg(
            f'[{index + 1}/{len(view._clipboard.candidates)}] {path}')
        if action == ClipboardAction.COPY:
            if path.is_dir():
                shutil.copytree(str(path), dest)
            else:
                shutil.copy2(str(path), dest)
        elif action == ClipboardAction.MOVE:
            shutil.move(str(path), defx._cwd)
        view._vim.command('redraw')
    view._vim.command('echo')
Esempio n. 4
0
def _preview_image(view: View, defx: Defx,
                   context: Context, candidate: Candidate) -> None:
    has_nvim = view._vim.call('has', 'nvim')
    filepath = str(candidate['action__path'])

    if view._previewed_job:
        # Stop previous job
        view._vim.call('jobstop' if has_nvim else 'job_stop',
                       view._previewed_job)
        view._previewed_job = None

    preview_image_sh = Path(__file__).parent.parent.joinpath(
        'preview_image.sh')
    if has_nvim:
        jobfunc = 'jobstart'
        jobopts = {}
    else:
        jobfunc = 'job_start'
        jobopts = {'in_io': 'null', 'out_io': 'null', 'err_io': 'null'}

    wincol = context.wincol + view._vim.call('winwidth', 0)
    if wincol + context.preview_width > view._vim.options['columns']:
        wincol -= 2 * context.preview_width
    args = ['bash', str(preview_image_sh), filepath,
            wincol, 1, context.preview_width]
    # Note: view._previewed_job is None when Vim8.
    # Because, job_start() returns job object.
    view._previewed_job = view._vim.call(jobfunc, args, jobopts)
Esempio n. 5
0
    def _new_directory(self, view: View, defx: Defx, context: Context) -> None:
        """
        Create a new directory.
        """
        candidate = view.get_cursor_candidate(context.cursor)
        if not candidate:
            return

        if candidate['is_opened_tree'] or candidate['is_root']:
            cwd = str(candidate['action__path'])
        else:
            cwd = str(Path(candidate['action__path']).parent)

        new_filename = self.input(view, defx, cwd,
                                  'Please input a new directory name: ', '',
                                  'file')
        if not new_filename:
            return
        filename = self.path_maker(cwd).joinpath(new_filename)

        if not filename:
            return
        if filename.exists():
            error(view._vim, f'{filename} already exists')
            return

        filename.mkdir(parents=True)
        view.redraw(True)
        view.search_recursive(filename, defx._index)
Esempio n. 6
0
def _cd(view: View, defx: Defx, context: Context) -> None:
    """
    Change the current directory.
    """
    source_name = defx._source.name
    is_parent = context.args and context.args[0] == '..'
    prev_cwd = Path(defx._cwd)

    if is_parent:
        path = prev_cwd.parent
    else:
        if context.args:
            if len(context.args) > 1:
                source_name = context.args[0]
                path = Path(context.args[1])
            else:
                path = Path(context.args[0])
        else:
            path = Path.home()
        path = prev_cwd.joinpath(path)
        if not readable(path):
            error(view._vim, f'{path} is invalid.')
        path = path.resolve()
        if source_name == 'file' and not path.is_dir():
            error(view._vim, f'{path} is invalid.')
            return

    view.cd(defx, source_name, str(path), context.cursor)
    if is_parent:
        view.search_file(prev_cwd, defx._index)
Esempio n. 7
0
def _yank_path(view: View, defx: Defx, context: Context) -> None:
    yank = '\n'.join([str(x['action__path']) for x in context.targets])
    view._vim.call('setreg', '"', yank)
    if (view._vim.call('has', 'clipboard')
            or view._vim.call('has', 'xterm_clipboard')):
        view._vim.call('setreg', '+', yank)
    view.print_msg('Yanked:\n' + yank)
Esempio n. 8
0
    def _add_session(self, view: View, defx: Defx, context: Context) -> None:
        path = context.args[0] if context.args else defx._cwd
        if path[-1] == '/':
            # Remove the last slash
            path = path[:-1]

        opened_candidates = [] if context.args else list(
            defx._opened_candidates)
        opened_candidates.sort()

        session: Session
        if path in view._sessions:
            old_session = view._sessions[path]
            session = Session(name=old_session.name,
                              path=old_session.path,
                              opened_candidates=opened_candidates)
        else:
            name = Path(path).name
            session = Session(name=name,
                              path=path,
                              opened_candidates=opened_candidates)
            view.print_msg(f'session "{name}" is created')

        view._sessions[session.path] = session

        self._save_session(view, defx, context)
Esempio n. 9
0
def _drop(view: View, defx: Defx, context: Context) -> None:
    """
    Open like :drop.
    """
    command = context.args[0] if context.args else 'edit'

    for target in context.targets:
        path = target['action__path']

        if path.is_dir():
            view.cd(defx, defx._source.name, str(path), context.cursor)
            continue

        bufnr = view._vim.call('bufnr', f'^{path}$')
        winids = view._vim.call('win_findbuf', bufnr)

        if winids:
            view._vim.call('win_gotoid', winids[0])
        else:
            if context.prev_winid != view._winid and view._vim.call(
                    'win_id2win', context.prev_winid):
                view._vim.call('win_gotoid', context.prev_winid)
            else:
                view._vim.command('wincmd w')
            view._vim.call('defx#util#execute_path', command, str(path))

        view.restore_previous_buffer()
Esempio n. 10
0
def _check_redraw(view: View, defx: Defx, context: Context) -> None:
    root = defx.get_root_candidate()['action__path']
    if not root.exists():
        return
    mtime = root.stat().st_mtime
    if mtime != defx._mtime:
        view.redraw(True)
Esempio n. 11
0
def _new_file(view: View, defx: Defx, context: Context) -> None:
    """
    Create a new file and it's parent directories.
    """
    candidate = view.get_cursor_candidate(context.cursor)
    if not candidate:
        return

    if candidate['is_opened_tree'] or candidate['is_root']:
        cwd = str(candidate['action__path'])
    else:
        cwd = str(Path(candidate['action__path']).parent)

    new_filename = cwd_input(
        view._vim, cwd,
        'Please input a new filename: ', '', 'file')
    if not new_filename:
        return
    isdir = new_filename[-1] == '/'
    filename = Path(cwd).joinpath(new_filename)

    if not filename:
        return
    if filename.exists():
        error(view._vim, f'{filename} already exists')
        return

    if isdir:
        filename.mkdir(parents=True)
    else:
        filename.parent.mkdir(parents=True, exist_ok=True)
        filename.touch()

    view.redraw(True)
    view.search_recursive(filename, defx._index)
Esempio n. 12
0
def _toggle_select(view: View, defx: Defx, context: Context) -> None:
    index = context.cursor - 1
    if index in view._selected_candidates:
        view._selected_candidates.remove(index)
    else:
        view._selected_candidates.append(index)
    view.redraw()
Esempio n. 13
0
def _execute_command(view: View, defx: Defx, context: Context) -> None:
    """
    Execute the command.
    """

    command = context.args[0] if context.args else view._vim.call(
        'defx#util#input', 'Command: ', '', 'shellcmd')
    if not command:
        return

    view._vim.command('redraw')

    def parse_argument(arg: str) -> str:
        if not arg.startswith('%'):
            return arg
        arg = arg[1:]
        m = re.match(r'((:.)*)(.*)', arg)
        target_path = str(target['action__path'])
        if not m:
            return target_path
        return fnamemodify(view._vim, target_path, m.group(2)) + m.group(3)

    for target in context.targets:
        args = [parse_argument(x) for x in shlex.split(command)]
        output = subprocess.check_output(args, cwd=defx._cwd)
        if output:
            view.print_msg(output)
Esempio n. 14
0
def _drop(view: View, defx: Defx, context: Context) -> None:
    """
    Open like :drop.
    """
    cwd = view._vim.call('getcwd')
    command = context.args[0] if context.args else 'edit'

    for target in context.targets:
        path = target['action__path']

        if path.is_dir():
            view.cd(defx, str(path), context.cursor)
            continue

        bufnr = view._vim.call('bufnr', f'^{path}$')
        winids = view._vim.call('win_findbuf', bufnr)

        if winids:
            view._vim.call('win_gotoid', winids[0])
        else:
            if context.prev_winid != view._winid and view._vim.call(
                    'win_id2win', context.prev_winid):
                view._vim.call('win_gotoid', context.prev_winid)
            else:
                view._vim.command('wincmd w')
            try:
                path = path.relative_to(cwd)
            except ValueError:
                pass
            view._vim.call('defx#util#execute_path', command, str(path))
Esempio n. 15
0
def _new_multiple_files(view: View, defx: Defx, context: Context) -> None:
    """
    Create multiple files.
    """

    save_cwd = view._vim.call('getcwd')
    view._vim.command(f'silent lcd {defx._cwd}')

    str_filenames: str = view._vim.call('input',
                                        'Please input new filenames: ', '',
                                        'file')
    view._vim.command(f'silent lcd {save_cwd}')

    if not str_filenames:
        return None

    for name in str_filenames.split():
        is_dir = name[-1] == '/'

        filename = Path(defx._cwd).joinpath(name).resolve()
        if filename.exists():
            error(view._vim, f'{filename} already exists')
            continue

        if is_dir:
            filename.mkdir(parents=True)
        else:
            if not filename.parent.exists():
                filename.parent.mkdir(parents=True)
            filename.touch()

    view.redraw(True)
    view.search_file(filename, defx._index)
Esempio n. 16
0
def _move(view: View, defx: Defx, context: Context) -> None:
    message = 'Move to the clipboard: {}'.format(
        str(context.targets[0]['action__path']) if len(context.targets) ==
        1 else str(len(context.targets)) + ' files')
    view.print_msg(message)

    view._clipboard.action = ClipboardAction.MOVE
    view._clipboard.candidates = context.targets
Esempio n. 17
0
def _open_directory(view: View, defx: Defx, context: Context) -> None:
    """
    Open the directory.
    """
    for target in context.targets:
        path = target['action__path']

        if path.is_dir():
            view.cd(defx, str(path), context.cursor)
Esempio n. 18
0
def _toggle_select_all(view: View, defx: Defx, context: Context) -> None:
    for [index, candidate] in enumerate(view._candidates):
        if (not candidate.get('is_root', False) and
                candidate['_defx_index'] == defx._index):
            if index in view._selected_candidates:
                view._selected_candidates.remove(index)
            else:
                view._selected_candidates.append(index)
    view.redraw()
Esempio n. 19
0
    def _search(self, view: View, defx: Defx, context: Context) -> None:
        if not context.args or not context.args[0]:
            return

        search_path = Path(context.args[0])
        if not search_path.is_absolute():
            # Use relative directory instead.
            search_path = Path(Path(defx._cwd).joinpath(context.args[0]))

        view.search_file(search_path, defx._index)
Esempio n. 20
0
 def _yank_path(self, view: View, defx: Defx, context: Context) -> None:
     mods = context.args[0] if context.args else ''
     paths = [str(x['action__path']) for x in context.targets]
     if mods:
         paths = [view._vim.call('fnamemodify', x, mods) for x in paths]
     yank = '\n'.join(paths)
     view._vim.call('setreg', '"', yank)
     if (view._vim.call('has', 'clipboard')
             or view._vim.call('has', 'xterm_clipboard')):
         view._vim.call('setreg', '+', yank)
     view.print_msg('Yanked:\n' + yank)
Esempio n. 21
0
def _copy(view: View, defx: Defx, context: Context) -> None:
    if not context.targets:
        return

    message = 'Copy to the clipboard: {}'.format(
        str(context.targets[0]['action__path']) if len(context.targets) ==
        1 else str(len(context.targets)) + ' files')
    view.print_msg(message)

    view._clipboard.action = ClipboardAction.COPY
    view._clipboard.candidates = context.targets
Esempio n. 22
0
def _open_directory(view: View, defx: Defx, context: Context) -> None:
    """
    Open the directory.
    """
    if context.args:
        path = Path(context.args[0])
    else:
        for target in context.targets:
            path = target['action__path']

    if path.is_dir():
        view.cd(defx, 'file', str(path), context.cursor)
Esempio n. 23
0
def do_action(view: View, defx: Defx,
              action_name: str, context: Context) -> bool:
    """
    Do "action_name" action.
    """
    if action_name not in DEFAULT_ACTIONS:
        return True
    action = DEFAULT_ACTIONS[action_name]
    action.func(view, defx, context)
    if ActionAttr.REDRAW in action.attr:
        view.redraw(True)
    return False
Esempio n. 24
0
def _cd(view: View, defx: Defx, context: Context) -> None:
    """
    Change the current directory.
    """
    path = context.args[0] if context.args else expand('~')
    path = os.path.normpath(os.path.join(defx._cwd, path))
    if not os.path.isdir(path):
        error(view._vim, '{} is not directory'.format(path))
        return

    view.cd(defx, path, context.cursor)
    view._selected_candidates = []
Esempio n. 25
0
    def _move(self, view: View, defx: Defx, context: Context) -> None:
        if not context.targets:
            return

        message = 'Move to the clipboard: {}'.format(
            str(context.targets[0]['action__path']) if len(context.targets) ==
            1 else str(len(context.targets)) + ' files')
        view.print_msg(message)

        view._clipboard.action = ClipboardAction.MOVE
        view._clipboard.candidates = context.targets
        view._clipboard.source_name = defx._source.name
Esempio n. 26
0
def _toggle_columns(view: View, defx: Defx, context: Context) -> None:
    """
    Toggle the current columns.
    """
    columns = (context.args[0] if context.args else '').split(':')
    if not columns:
        return
    current_columns = [x.name for x in view._columns]
    if columns == current_columns:
        # Use default columns
        columns = context.columns.split(':')
    view._init_columns(columns)
Esempio n. 27
0
class Rplugin:
    def __init__(self, vim: Nvim) -> None:
        self._vim = vim

    def init_channel(self) -> None:
        self._vim.vars['defx#_channel_id'] = self._vim.channel_id

    def start(self, args: typing.List) -> None:
        self._view = View(self._vim, args[0], args[1])

    def do_action(self, args: typing.List) -> None:
        self._view.do_action(args[0], args[1], args[2])
Esempio n. 28
0
def _new_directory(view: View, defx: Defx, context: Context) -> None:
    """
    Create a new directory.
    """
    filename = cwd_input(view._vim, defx._cwd,
                         'Please input a new directory: ', '', 'dir')
    if os.path.exists(filename):
        error(view._vim, '{} is already exists'.format(filename))
        return

    os.mkdir(filename)
    view.redraw(True)
    view.search_file(filename, defx._index)
Esempio n. 29
0
def _link(view: View, defx: Defx, context: Context) -> None:
    if not context.targets:
        return

    message = 'Link to the clipboard: {}'.format(
        str(context.targets[0]['action__path'])
        if len(context.targets) == 1
        else str(len(context.targets)) + ' files')
    view.print_msg(message)

    view._clipboard.action = ClipboardAction.LINK
    view._clipboard.candidates = context.targets
    view._clipboard.source_name = 'file'
Esempio n. 30
0
def check_overwrite(view: View, dest: Path, src: Path) -> Path:
    s_stat = src.stat()
    s_mtime = s_stat.st_mtime
    view.print_msg(f' src: {src} {s_stat.st_size} bytes')
    view.print_msg(f'      {time.strftime("%c", time.localtime(s_mtime))}')
    d_stat = dest.stat()
    d_mtime = d_stat.st_mtime
    view.print_msg(f'dest: {dest} {d_stat.st_size} bytes')
    view.print_msg(f'      {time.strftime("%c", time.localtime(d_mtime))}')

    choice: int = view._vim.call('confirm',
                                 f'{dest} already exists.  Overwrite?',
                                 '&Force\n&No\n&Rename\n&Time\n&Underbar', 0)
    ret: Path = Path('')
    if choice == 1:
        ret = src
    elif choice == 2:
        ret = Path('')
    elif choice == 3:
        ret = Path(
            view._vim.call('input', f'{src} -> ', str(src),
                           ('dir' if src.is_dir() else 'file')))
    elif choice == 4 and d_mtime < s_mtime:
        ret = src
    elif choice == 5:
        ret = Path(str(src) + '_')
    return ret