def on_bufenter(self, bufnum): """ There are four cases on bufenter: 1. The buffer is not a netranger buffer: do nothing 2. The buffer is a existing netranger buffer: refresh buffer content (e.g. directory content changed else where) and call any pending onuiquit functions 3. The buffer is a [No Name] temporary buffer and the buffer name is a directory. Then we either create a new netranger buffer or bring up an existing netranger buffer """ if bufnum in self.bufs: self.refresh_curbuf() if self.onuiquit is not None: # If not enough arguments are passed, ignore the pending onuituit, e.g. quit the bookmark go ui without pressing key to specify where to go. if len(VimVar('NETRRegister')) == self.onuiquitNumArgs: self.onuiquit(*VimVar('NETRRegister')) self.onuiquit = None self.vim.vars['NETRRegister'] = [] self.onuiquitNumArgs = 0 else: bufname = self.vim.current.buffer.name if len(bufname) > 0 and bufname[-1] == '~': bufname = os.path.expanduser('~') if not os.path.isdir(bufname): return bufname = os.path.abspath(bufname) if self.buf_existed(bufname): self.show_existing_buf(bufname) else: self.gen_new_buf(bufname)
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
def load_bookmarks(self): self.mark_dict = {} if os.path.isfile(VimVar('NETRBookmarkFile')): with open(VimVar('NETRBookmarkFile'), 'r') as f: for line in f: kp = line.split(':') if (len(kp) == 2): self.mark_dict[kp[0].strip()] = kp[1].strip()
def NETRemoteList(self): if self.rclone is None: Rclone.valid_or_install(self.vim) self.rclone = Rclone(VimVar('NETRemoteCacheDir'), VimVar('NETRemoteRoots')) if self.rclone.has_remote: self.vim.command('tabe ' + VimVar('NETRemoteCacheDir')) else: VimErrorMsg( "There's no remote now. Run 'rclone config' in a terminal to setup remotes" )
def NETRBufPanelOpen(self): if self.curNode.isDir: return if len(self.vim.current.tabpage.windows) == 1: self.NETROpen(VimVar('NETRSplitOrientation') + ' vsplit', use_rifle=False) newsize = VimCurWinWidth() * VimVar('NETRPanelSize') self.vim.command('vertical resize {}'.format(newsize)) else: fpath = self.curNode.fullpath self.vim.command('wincmd l') self.vim.command('edit {}'.format(fpath))
def initKeymaps(self): """ Add key mappings to NETR* functions for netranger buffers. Override or skip some default mappings on user demand. """ self.keymaps = {} self.keymap_doc = {} skip = [] for k in VimVar('NETRDefaultMapSkip'): skip.append(k.lower()) for fn, (keys, desc) in default.keymap.items(): user_keys = VimVar(fn, []) user_keys += [k for k in keys if k not in skip] self.keymaps[fn] = user_keys self.keymap_doc[fn] = (user_keys, desc)
def edit(self): self.vim.command('belowright split {}'.format( VimVar('NETRBookmarkFile'))) self.vim.command('setlocal bufhidden=wipe') self.del_buf('set') self.del_buf('go') self.netranger.pend_onuiquit(self.load_bookmarks)
def _set(self, mark): if mark == '': return if mark not in self.valid_mark: self.vim.command('echo "Only a-zA-Z are valid mark!!"') return set_buf = self.bufs['set'] set_buf.options['modifiable'] = True if mark in self.mark_dict: for i, line in enumerate(set_buf): if len(line) > 0 and line[0] == mark: set_buf[i] = '{}:{}'.format(mark, self.path_to_mark) break elif self.path_to_mark in self.mark_dict.values(): for i, line in enumerate(set_buf): if len(line) > 0 and line[2:] == self.path_to_mark: set_buf[i] = '{}:{}'.format(mark, self.path_to_mark) break else: set_buf.append('{}:{}'.format(mark, self.path_to_mark)) set_buf.options['modifiable'] = False self.mark_dict[mark] = self.path_to_mark self.del_buf('go') with open(VimVar('NETRBookmarkFile'), 'w') as f: for k, p in self.mark_dict.items(): f.write('{}:{}\n'.format(k, p))
def __init__(self, vim, netranger): UI.__init__(self, vim) self.valid_mark = string.ascii_lowercase + string.ascii_uppercase self.netranger = netranger self.mark_dict = {} self.path_to_mark = None # This is to avoid a bug that I can't solve. # If bookmark file is initially empty. The first time # 'm' (set) mapping is trigger, it won't quit the buffer # on user input.. if not os.path.isfile(VimVar('NETRBookmarkFile')): with open(VimVar('NETRBookmarkFile'), 'w') as f: f.write('/:/') self.load_bookmarks()
def reset_default_colors(self): for name, color in VimVar('NETRColors').items(): if name not in default.color: VimErrorMsg('netranger: {} is not a valid NETRColors key!') continue if type(color) is int and (color < 0 or color > 255): VimErrorMsg('netranger: Color value should be within 0~255') continue elif type(color) is str and color not in colortbl: VimErrorMsg('netranger: {} is not a valid color name!') continue default.color[name] = color
def gen_new_buf(self, bufname): bufnum = self.vim.current.buffer.number if (bufname.startswith(VimVar('NETRemoteCacheDir'))): self.bufs[bufnum] = NetRangerBuf(self.vim, os.path.abspath(bufname), self.rclone, self.rifle) else: self.bufs[bufnum] = NetRangerBuf(self.vim, os.path.abspath(bufname), self.fs, self.rifle) self.map_keys() self.wd2bufnum[bufname] = bufnum self.setBufOption()
def NETRToggleShowHidden(self): """ Change ignore pattern and mark all existing netranger buffers to be content_outdated so that their content will be updated when entered again. """ ignore_pat = VimVar('NETRIgnore') if '.*' in ignore_pat: ignore_pat.remove('.*') else: ignore_pat.append('.*') self.vim.vars['NETRIgnore'] = ignore_pat for buf in self.bufs.values(): buf.content_outdated = True self.curBuf.refresh_nodes(force_refreh=True)
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)
def shouldIgnore(self, basename): for ig in VimVar('NETRIgnore'): if fnmatch.fnmatch(basename, ig): return True return False
def NETRBufHSplitOpen(self): self.NETROpen(VimVar('NETRSplitOrientation') + ' split', use_rifle=False)
def position(self): return VimVar('NETRSplitOrientation')
def isRemotePath(self, path): return path.startswith(VimVar('NETRemoteCacheDir'))
def shouldIgnore(self, basename): # TODO this is not efficient for neovim for ig in VimVar('NETRIgnore'): if fnmatch.fnmatch(basename, ig): return True return False