Пример #1
0
    def __init__(self, vim):
        self.vim = vim
        self.inited = False
        self.bufs = {}
        self.wd2bufnum = {}
        self.pinnedRoots = set()
        self.picked_nodes = defaultdict(set)
        self.cut_nodes, self.copied_nodes = defaultdict(set), defaultdict(set)
        self.bookmarkUI = None
        self.helpUI = None
        self.sortUI = None
        self.askUI = None
        self.onuiquit = None
        self.onuiquitNumArgs = 0
        self.fs = FS()
        self.rclone = None

        self.initVimVariables()
        self.initKeymaps()
        Shell.mkdir(default.variables['NETRRootDir'])
        self.rifle = Rifle(self.vim, VimVar('NETRRifleFile'))
        ignore_pat = list(VimVar('NETRIgnore'))
        self.vim.vars['NETRemoteCacheDir'] = os.path.expanduser(
            VimVar('NETRemoteCacheDir'))
        if '.*' not in ignore_pat:
            ignore_pat.append('.*')
            self.vim.vars['NETRIgnore'] = ignore_pat
Пример #2
0
    def __init__(self, vim, path):
        self.vim = vim
        self.rules = []

        if not os.path.isfile(path):
            Shell.cp(
                '{}/../../../config/rifle.conf'.format(
                    os.path.dirname(__file__)), path)

        with open(path, 'r') as f:
            for i, line in enumerate(f):
                line = line.strip()
                if len(line) == 0 or line[0] == '#':
                    continue
                sp = line.split('=')
                if len(sp) != 2:
                    VimErrorMsg(
                        self.vim,
                        'invalid rule: rifle.conf line {}'.format(i + 1))
                    continue

                tests = []
                for test in sp[0].strip().split(','):
                    testSp = [e for e in test.split(' ') if e != '']
                    tests.append(globals()[testSp[0]](testSp[1]))
                command = sp[1].strip()
                self.rules.append((tests, command))
Пример #3
0
def do_test(fn=None, fn_remote=None):
    """
    Note on the mecahnism of testing rclone on localhost:
    1. Tester run rclone to create a "local" remote named netrtest (must be exact this name)
    2. In default.py, the vim variable 'NETRemoteRoots' is set to
       {test_remote_name: test_remote_dir}, which defaults to
       {'netrtest', '/tmp/netrtest/remote'}.
    3. 'NETRemoteRoots' is passed to Rclone constructor, so that the rpath
       of the netrtest remote is mapped to '/tmp/netrtest/remote'.
    4. This just works in netranger. In cmd line, running 'rclone lsl netranger:/'
       still shows you the content of the root directory of the localhost.
    """
    old_cwd = os.getcwd()
    Shell.run('rm -rf {}'.format(test_dir))

    def prepare_test_dir(dirname):
        Shell.mkdir(dirname)
        os.chdir(dirname)
        Shell.mkdir('dir/subdir')
        Shell.mkdir('dir/subdir/subsubdir')
        Shell.mkdir('dir/subdir2')
        Shell.touch('dir/a')
        Shell.touch('.a')
        Shell.mkdir('dir2/')

        # The following should be removed when rclone fix "not copying empty directories" bug.
        Shell.touch('dir/subdir/subsubdir/placeholder')
        Shell.touch('dir/subdir2/placeholder')
        Shell.touch('dir/subdir2/placeholder')

    prepare_test_dir(test_local_dir)
    if fn is not None:
        nvim.command('silent tabe {}'.format(test_local_dir))
        fn()
        nvim.command('bwipeout')
        print('== {} success =='.format(str(fn.__name__)))

    prepare_test_dir(test_remote_dir)
    if fn_remote is not None:
        nvim.command('NETRemoteList')
        found_remote = False
        for i, line in enumerate(nvim.current.buffer):
            if re.findall('.+(netrtest)', line):
                nvim.command('call cursor({}, 1)'.format(i + 1))
                found_remote = True
                break

        assert found_remote, 'You must set up an rclone remote named "{}" to test remote function'.format(
            test_remote_name)
        nvim.input('l')
        nvim.command('NETRemotePull')
        nvim.command('call cursor(2, 1)')
        fn_remote()
        nvim.command('bwipeout')
        print('== {} success =='.format(str(fn_remote.__name__)))

    os.chdir(old_cwd)
Пример #4
0
 def exec_fs_server_cmd(self, cmd, src_arr, dst=None, on_exit=None):
     src = ' '.join(['"{}"'.format(s) for s in src_arr])
     if dst:
         dst = '"{}"'.format(dst)
         cmd = 'python {} {} {} {}'.format(FS.FScmds, cmd, src, dst)
         Shell.run_async(cmd, on_exit=on_exit)
     else:
         cmd = 'python {} {} {}'.format(FS.FScmds, cmd, src)
         Shell.run_async(cmd, on_exit=on_exit)
Пример #5
0
def test_detect_fs_change():
    Shell.touch('newfile')
    nvim.command('split new')
    nvim.command('quit')
    assert_num_content_line(3)

    nvim.input('l')
    Shell.rm('newfile')
    nvim.input('h')
    assert_num_content_line(2)
Пример #6
0
 def init(self):
     self.inited = True
     self.initVimVariables()
     self.initKeymaps()
     self.rclone = None
     self.bookmarkUI = None
     self.helpUI = None
     self.isEditing = False
     self.onuiquit = None
     self.onuiquitNumArgs = 0
     Shell.mkdir(default.variables['NETRRootDir'])
     self.rifle = Rifle(self.vim, self.vim.vars['NETRRifleFile'])
Пример #7
0
    def ls(self, dirname, cheap_remote_ls=False):
        if not cheap_remote_ls and len(dirname) > len(self.root_dir):
            local_files = set([
                name
                for name in Shell.run('ls -p {}'.format(dirname)).split('\n')
                if len(name) > 0
            ])
            remote_files = set([
                name for name in Shell.run('rclone lsf "{}"'.format(
                    self.rpath(dirname))).split('\n') if len(name) > 0
            ])

            for name in remote_files.difference(local_files):
                if name[-1] == '/':
                    Shell.mkdir(os.path.join(dirname, name))
                else:
                    Shell.touch(os.path.join(dirname, name))

            for name in local_files.difference(remote_files):
                log('rclone copyto "{}" "{}"'.format(
                    os.path.join(dirname, name),
                    os.path.join(self.rpath(dirname), name)))
                Shell.run('rclone copyto "{}" "{}"'.format(
                    os.path.join(dirname, name),
                    os.path.join(self.rpath(dirname), name)))
        return super(Rclone, self).ls(dirname)
Пример #8
0
    def __init__(self, lpath, path):
        Shell.mkdir(lpath)
        self.lpath = lpath

        self.child = {}
        self.cached = False
        self.path = path

        if path is None:
            remotes = Shell.run('rclone listremotes').split(':\n')
            log(remotes)
            for remote in remotes:
                if len(remote)==0:
                    continue
                self.child[remote] = RcloneDir(os.path.join(lpath, remote), remote+':/')
            self.cached = True
Пример #9
0
    def lsl(self):
        info = Shell.run('rclone lsl {} --max-depth 1'.format(self.path))

        for line in info.split('\n'):
            line = line.strip()
            if len(line)>0:
                name = line.split()[-1]
                self.child[name] = RcloneFile(os.path.join(self.lpath, name), os.path.join(self.path, name))
Пример #10
0
 def NETROpen(self):
     if self.curNode.isHeader:
         return
     fullpath = self.curNode.fullpath
     if self.curNode.isDir:
         self.set_cwd(fullpath)
     else:
         if type(self.fs) is RClone:
             self.fs.download(fullpath)
         cmd = self.rifle.decide_open_cmd(fullpath)
         # TODO: fix white space in fullpath issue
         if not cmd:
             if self.vim.vars['NETROpenInBuffer']:
                 self.vim.command('edit {}'.format(fullpath))
             else:
                 self.vim.command('tab drop {}'.format(fullpath))
         else:
             Shell.spawn('{} {}'.format(cmd, fullpath))
Пример #11
0
 def __init__(self, vim, cwd, fs, prevcwd=None):
     self.vim = vim
     self.cwd = cwd
     self.fs = fs
     self.nodes = self.createNodes(cwd)
     self.nodes.insert(0, Node(self.cwd, self.vim.vars['NETRHiCWD']))
     self.initClineNo(prevcwd)
     self.nodes[self.clineNo].cursor_on()
     self.mtime = Shell.mtime(cwd)
Пример #12
0
def test_sort():
    # only test extension, mtime, size
    # extension: [a, a.a, a.b]
    # size: [a.b, a.a, a]
    # mtime: [a, a.b, a.a]
    Shell.run('echo {} > dir/{}'.format('a' * 3, 'a'))
    Shell.run('echo {} > dir/{}'.format('a' * 2, 'a.a'))
    Shell.run('echo {} > dir/{}'.format('a' * 1, 'a.b'))
    time.sleep(0.01)
    Shell.run('touch dir/a.a')

    nvim.input(' Se')
    assert_content('dir', ind=0, hi='dir', level=0)
    assert_content('a', ind=3, hi='file', level=1)
    assert_content('a.a', ind=4, hi='file', level=1)
    assert_content('a.b', ind=5, hi='file', level=1)
    assert_content('dir2', ind=6, hi='dir', level=0)

    nvim.input('SE')
    assert_content('dir2', ind=0, hi='dir', level=0)
    assert_content('dir', ind=1, hi='dir', level=0)
    assert_content('a.b', ind=2, hi='file', level=1)
    assert_content('a.a', ind=3, hi='file', level=1)
    assert_content('a', ind=4, hi='file', level=1)

    nvim.input('Ss')
    assert_content('dir2', ind=0, hi='dir', level=0)
    assert_content('dir', ind=1, hi='dir', level=0)
    assert_content('a.b', ind=4, hi='file', level=1)
    assert_content('a.a', ind=5, hi='file', level=1)
    assert_content('a', ind=6, hi='file', level=1)

    nvim.input('SS')
    assert_content('dir', ind=0, hi='dir', level=0)
    assert_content('a', ind=1, hi='file', level=1)
    assert_content('a.a', ind=2, hi='file', level=1)
    assert_content('a.b', ind=3, hi='file', level=1)
    assert_content('dir2', ind=6, hi='dir', level=0)

    nvim.input('Sm')
    assert_content('dir2', ind=0, hi='dir', level=0)
    assert_content('dir', ind=1, hi='dir', level=0)
    assert_content('a', ind=4, hi='file', level=1)
    assert_content('a.b', ind=5, hi='file', level=1)
    assert_content('a.a', ind=6, hi='file', level=1)

    nvim.input('SM')
    assert_content('dir', ind=0, hi='dir', level=0)
    assert_content('a.a', ind=1, hi='file', level=1)
    assert_content('a.b', ind=2, hi='file', level=1)
    assert_content('a', ind=3, hi='file', level=1)
    assert_content('dir2', ind=6, hi='dir', level=0)
Пример #13
0
    def __init__(self, root_dir, remote_remap):
        if root_dir[-1] == '/':
            root_dir = root_dir[:-1]

        self.root_dir = root_dir
        self.rplen = len(root_dir) + 1
        for remote, root in remote_remap.items():
            if root[-1] != '/':
                remote_remap[remote] += '/'
        self.remote_remap = remote_remap
        Shell.mkdir(root_dir)
        remotes = set(Shell.run('rclone listremotes').split(':\n'))
        local_remotes = set(super(Rclone, self).ls(root_dir))
        for remote in remotes.difference(local_remotes):
            Shell.mkdir(os.path.join(root_dir, remote))
        for remote in local_remotes.difference(remotes):
            super(Rclone, self).rm(os.path.join(root_dir, remote), True)

        self.has_remote = len(remotes) > 0
        self.ls_time_stamp = {}
Пример #14
0
    def valid_or_install(cls, vim):
        import platform
        import zipfile

        if Shell.isinPATH('rclone'):
            return True
        else:
            rclone_dir = VimUserInput(
                'Rclone not in PATH. Install it at (modify/enter)',
                os.path.expanduser('~/rclone'))
            Shell.mkdir(rclone_dir)

            system = platform.system().lower()
            processor = 'amd64'
            if '386' in platform.processor():
                processor = '386'
            else:
                # Should support arm??
                pass

            url = 'https://downloads.rclone.org/rclone-current-{}-{}.zip'.format(
                system, processor)
            zip_fname = os.path.join(rclone_dir, 'rclone.zip')
            Shell.urldownload(url, zip_fname)
            zip_ref = zipfile.ZipFile(zip_fname, 'r')
            zip_ref.extractall(rclone_dir)
            for entry in zip_ref.NameToInfo:
                if entry.endswith('rclone'):
                    Shell.cp(os.path.join(rclone_dir, entry), rclone_dir)
                    Shell.chmod(os.path.join(rclone_dir, 'rclone'), 755)

            zip_ref.close()
            os.remove(zip_fname)

            shellrc = VimUserInput(
                'Update PATH in (leave blank to set manually later)',
                Shell.shellrc())
            if len(shellrc) > 0:
                with open(shellrc, 'a') as f:
                    f.write('PATH={}:$PATH\n'.format(rclone_dir))
            os.environ['PATH'] += ':' + rclone_dir
Пример #15
0
def test_size_display():
    width = nvim.current.window.width

    def cLine_ends_with(s):
        # line[-4:] = 
        return nvim.current.line[:-4].endswith(s)

    assert cLine_ends_with('3'), 'size display dir fail: {}'.format(
        'a' + nvim.current.line[-1] + 'a')
    Shell.run('echo {} > {}'.format('a' * 1035, 'a' * width + '.pdf'))
    Shell.run('echo {} > {}'.format('b' * 1024, 'b' * width))

    nvim.command('edit .')
    nvim.input('Gk')
    assert cLine_ends_with(
        '~.pdf 1.01 K'), 'size display abbreviation fail: a~.pdf {}'.format(
            nvim.current.line[-10:])
    nvim.input('j')
    assert cLine_ends_with(
        'b~    1 K'), 'size display abbreviation fail: b~ {}'.format(
            nvim.current.line[-10:])
Пример #16
0
    def NETROpen(self, open_cmd=None, rifle_cmd=None, use_rifle=True):
        """
        The real work for opening directories is handled in on_bufenter. For openning files, we check if there's rifle rule to open the file. Otherwise, open it in vim.
        """
        curNode = self.curNode
        if curNode.isINFO:
            return

        if open_cmd is None:
            if curNode.isDir:
                open_cmd = 'edit'
            else:
                open_cmd = VimVar('NETROpenCmd')

        fullpath = curNode.fullpath
        if curNode.isDir:
            if curNode.size == '?' or curNode.size == '':
                VimErrorMsg('Permission Denied: {}'.format(curNode.name))
                return
            self.vim.command('silent {} {}'.format(open_cmd, fullpath))
            # manually call on_bufenter as vim might not trigger BufEnter with the above command
            self.on_bufenter(self.vim.eval("winnr()"))
        else:
            if self.rclone is not None and self.isRemotePath(fullpath):
                self.rclone.ensure_downloaded(fullpath)

            if rifle_cmd is None:
                rifle_cmd = self.rifle.decide_open_cmd(fullpath)

            if use_rifle and rifle_cmd is not None:
                Shell.run_async(rifle_cmd.format(fullpath))
            else:
                try:
                    self.vim.command('{} {}'.format(open_cmd, fullpath))
                except Exception as e:
                    err_msg = str(e)
                    if 'E325' not in err_msg:
                        VimErrorMsg(err_msg)
Пример #17
0
def assert_fs(d, expected):
    """
    Test whether 'expected' exists in directory cwd/d, where
    cwd is /tmp/netrtest/local when testing local functions and
    cwd is /tmp/netrtest/remote when testing remote functions.
    """
    real = None
    for i in range(10):
        real = Shell.run('ls --group-directories-first ' + d).split()
        if real == expected:
            return
        time.sleep(0.05)

    assert real == expected, 'expected: {}, real: {}'.format(expected, real)
Пример #18
0
    def __init__(self, vim, path):
        self.vim = vim
        self.rules = []

        if not os.path.isfile(path):
            Shell.cp(os.path.join(config_dir, 'rifle.conf'), path)

        with open(path, 'r') as f:
            for i, line in enumerate(f):
                try:
                    # remove things after the first # (including)
                    line = line[:line.index('#')]
                except ValueError:
                    pass

                line = line.strip()
                if len(line) == 0:
                    continue
                sp = line.split('=')
                if len(sp) != 2:
                    VimErrorMsg(
                        'invalid rule: rifle.conf line {}. There should be one and only one "=" for each line'
                        .format(i + 1))
                    continue

                tests = []
                for test in sp[0].strip().split(','):
                    testSp = [e for e in test.split(' ') if e != '']
                    tests.append(globals()[testSp[0]](testSp[1]))
                command = sp[1].strip()

                # simple case, used specify only the command
                # For sophisicated command like bash -c "command {}"
                # user should add '{}' themselves
                if '{}' not in command:
                    command = command + ' {}'
                self.rules.append((tests, command))
Пример #19
0
def test_detect_fs_change():
    nvim.input(' ')
    Shell.touch('dir/b')
    Shell.mkdir('dir3')
    nvim.command('split new')
    nvim.command('quit')
    assert_content('dir', ind=0, hi='dir')
    assert_content('b', ind=4, level=1, hi='file')
    assert_content('dir3', ind=6, hi='dir')
    assert_num_content_line(7)

    Shell.rm('dir3')
    nvim.input('lh')
    assert_num_content_line(6)
Пример #20
0
def test_bookmark():
    bookmarkfile = default.variables['NETRBookmarkFile']
    copy = '{}/{}bak'.format(os.path.dirname(bookmarkfile),
                             os.path.basename(bookmarkfile))

    if os.path.isfile(bookmarkfile):
        Shell.run('mv {} {}'.format(bookmarkfile, copy))

    Shell.run('rm -f {}'.format(bookmarkfile))

    nvim.input('mal')
    nvim.input("'a")
    assert_content('dir')

    nvim.input('lemjrb')
    nvim.command('exit')
    nvim.input("'b")
    assert_content('dir')

    Shell.run('rm -f {}'.format(bookmarkfile))
    if os.path.isfile(copy):
        Shell.run('mv {} {}'.format(copy, bookmarkfile))
Пример #21
0
 def __init__(self, fullpath):
     super(HeaderNode, self).__init__(fullpath,
                                      Shell.abbrevuser(fullpath),
                                      default.color['cwd'],
                                      level=0)
     self.re_stat()
Пример #22
0
    def prepare_test_dir(dirname):
        Shell.mkdir(dirname)
        os.chdir(dirname)
        Shell.mkdir('dir/subdir')
        Shell.mkdir('dir/subdir/subsubdir')
        Shell.mkdir('dir/subdir2')
        Shell.touch('dir/a')
        Shell.touch('.a')
        Shell.mkdir('dir2/')

        # The following should be removed when rclone fix "not copying empty directories" bug.
        Shell.touch('dir/subdir/subsubdir/placeholder')
        Shell.touch('dir/subdir2/placeholder')
        Shell.touch('dir/subdir2/placeholder')
Пример #23
0
def test_edit():
    nvim.input('iz')
    nvim.input('')

    assert_fs(lambda: 'zdir' in Shell.run('ls').split())
    assert_content('dir2')
Пример #24
0
 def download(self):
     if self.downloaded:
         return
     else:
         Shell.run('rclone copyto "{}" "{}"'.format(self.path, self.lpath))
         self.downloaded = True
Пример #25
0
 def rmf(self, target):
     Shell.run('rm -r {}'.format(target))
Пример #26
0
 def cp(self, src, dst):
     if os.path.isdir(src) and src[-1]!='/':
         src = src+'/'
     if os.path.isdir(dst) and dst[-1]!='/':
         dst = dst+'/'
     Shell.run('cp -r "{}" "{}"'.format(src, dst))
Пример #27
0
def test_delete():
    nvim.input('vD')
    assert_fs(lambda: Shell.run('ls').split()[0] == 'dir2')
    nvim.input('XX')
    assert_fs(lambda: Shell.run('ls') == '')
Пример #28
0
 def __call__(self, fname):
     return Shell.isinPATH(self.arg)
Пример #29
0
def do_test(fn, wipe_on_done=True):
    old_cwd = os.getcwd()
    test_root = os.path.expanduser('~/netranger_test_dir')
    Shell.run('rm -rf {}'.format(test_root))
    Shell.mkdir(test_root)

    os.chdir(test_root)
    Shell.mkdir(os.path.join(test_root, 'dir/subdir'))
    Shell.mkdir(os.path.join(test_root, 'dir/subdir/subsubdir'))
    Shell.mkdir(os.path.join(test_root, 'dir/subdir2'))
    Shell.run('touch {}/dir/a'.format(test_root))
    Shell.run('touch {}/.a'.format(test_root))
    Shell.mkdir(os.path.join(test_root, 'dir2/'))

    nvim.command('tabe {}'.format(test_root))
    fn()
    if wipe_on_done:
        nvim.command('bwipeout')

    os.chdir(old_cwd)
    print('== {} success =='.format(str(fn.__name__)))
Пример #30
0
 def is_dirty(self):
     return Shell.mtime(self.cwd) > self.mtime