diff options
-rw-r--r-- | ranger/api/commands.py | 4 | ||||
-rw-r--r-- | ranger/config/commands.py | 58 | ||||
-rw-r--r-- | ranger/config/rc.conf | 4 | ||||
-rw-r--r-- | ranger/core/actions.py | 131 | ||||
-rw-r--r-- | ranger/core/environment.py | 198 | ||||
-rw-r--r-- | ranger/core/fm.py | 42 | ||||
-rw-r--r-- | ranger/core/main.py | 7 | ||||
-rw-r--r-- | ranger/core/tab.py | 140 | ||||
-rw-r--r-- | ranger/fsobject/directory.py | 4 | ||||
-rw-r--r-- | ranger/gui/displayable.py | 2 | ||||
-rw-r--r-- | ranger/gui/ui.py | 6 | ||||
-rw-r--r-- | ranger/gui/widgets/browsercolumn.py | 10 | ||||
-rw-r--r-- | ranger/gui/widgets/browserview.py | 11 | ||||
-rw-r--r-- | ranger/gui/widgets/statusbar.py | 29 | ||||
-rw-r--r-- | ranger/gui/widgets/titlebar.py | 14 |
15 files changed, 369 insertions, 291 deletions
diff --git a/ranger/api/commands.py b/ranger/api/commands.py index 97ef415c..aaadde5d 100644 --- a/ranger/api/commands.py +++ b/ranger/api/commands.py @@ -179,7 +179,7 @@ class Command(FileManagerAware): def _tab_only_directories(self): from os.path import dirname, basename, expanduser, join - cwd = self.fm.env.cwd.path + cwd = self.fm.thisdir.path rel_dest = self.rest(1) @@ -225,7 +225,7 @@ class Command(FileManagerAware): def _tab_directory_content(self): from os.path import dirname, basename, expanduser, join - cwd = self.fm.env.cwd.path + cwd = self.fm.thisdir.path rel_dest = self.rest(1) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 88b50860..8579b019 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -54,16 +54,16 @@ # self.fm.notify(string): Print the given string on the screen. # self.fm.notify(string, bad=True): Print the given string in RED. # self.fm.reload_cwd(): Reload the current working directory. -# self.fm.env.cwd: The current working directory. (A File object.) -# self.fm.env.cf: The current file. (A File object too.) -# self.fm.env.cwd.get_selection(): A list of all selected files. +# self.fm.thisdir: The current working directory. (A File object.) +# self.fm.thisfile: The current file. (A File object too.) +# self.fm.thistab.get_selection(): A list of all selected files. # self.fm.execute_console(string): Execute the string as a ranger command. # self.fm.open_console(string): Open the console with the given string # already typed in for you. # self.fm.move(direction): Moves the cursor in the given direction, which # can be something like down=3, up=5, right=1, left=1, to=6, ... # -# File objects (for example self.fm.env.cf) have these useful attributes and +# File objects (for example self.fm.thisfile) have these useful attributes and # methods: # # cf.path: The path to the file. @@ -126,7 +126,7 @@ class cd(Command): def tab(self): from os.path import dirname, basename, expanduser, join - cwd = self.fm.env.cwd.path + cwd = self.fm.thisdir.path rel_dest = self.rest(1) bookmarks = [v.path for v in self.fm.bookmarks.dct.values() @@ -222,7 +222,7 @@ class shell(Command): return (start + program + ' ' for program \ in get_executables() if program.startswith(command)) if position_of_last_space == len(command) - 1: - selection = self.fm.env.get_selection() + selection = self.fm.thistab.get_selection() if len(selection) == 1: return self.line + selection[0].shell_escaped_basename + ' ' else: @@ -230,14 +230,14 @@ class shell(Command): else: before_word, start_of_word = self.line.rsplit(' ', 1) return (before_word + ' ' + file.shell_escaped_basename \ - for file in self.fm.env.cwd.files \ + for file in self.fm.thisdir.files \ if file.shell_escaped_basename.startswith(start_of_word)) class open_with(Command): def execute(self): app, flags, mode = self._get_app_flags_mode(self.rest(1)) self.fm.execute_file( - files = [f for f in self.fm.env.cwd.get_selection()], + files = [f for f in self.fm.thistab.get_selection()], app = app, flags = flags, mode = mode) @@ -346,7 +346,7 @@ class find(Command): def quick(self): self.count = 0 - cwd = self.fm.env.cwd + cwd = self.fm.thisdir arg = self.rest(1) if not arg: return False @@ -369,7 +369,7 @@ class find(Command): self.count += 1 if self.count == 1: cwd.move(to=(cwd.pointer + i) % len(cwd.files)) - self.fm.env.cf = cwd.pointed_obj + self.fm.thisfile.cf = cwd.pointed_obj if self.count > 1: return False i += 1 @@ -490,8 +490,8 @@ class delete(Command): # user did not confirm deletion return - cwd = self.fm.env.cwd - cf = self.fm.env.cf + cwd = self.fm.thisdir + cf = self.fm.thisfile.cf if cwd.marked_items or (cf.is_directory and not cf.is_link \ and len(os.listdir(cf.path)) > 0): @@ -513,7 +513,7 @@ class mark(Command): def execute(self): import re - cwd = self.fm.env.cwd + cwd = self.fm.thisdir input = self.rest(1) searchflags = re.UNICODE if input.lower() == input: # "smartcase" @@ -604,7 +604,7 @@ class mkdir(Command): from os.path import join, expanduser, lexists from os import mkdir - dirname = join(self.fm.env.cwd.path, expanduser(self.rest(1))) + dirname = join(self.fm.thisdir.path, expanduser(self.rest(1))) if not lexists(dirname): mkdir(dirname) else: @@ -621,7 +621,7 @@ class touch(Command): def execute(self): from os.path import join, expanduser, lexists - fname = join(self.fm.env.cwd.path, expanduser(self.rest(1))) + fname = join(self.fm.thisdir.path, expanduser(self.rest(1))) if not lexists(fname): open(fname, 'a').close() else: @@ -637,7 +637,7 @@ class edit(Command): def execute(self): if not self.arg(1): - self.fm.edit_file(self.fm.env.cf.path) + self.fm.edit_file(self.fm.thisfile.path) else: self.fm.edit_file(self.rest(1)) @@ -655,7 +655,7 @@ class eval_(Command): Examples: :eval fm - :eval len(fm.env.directories) + :eval len(fm.directories) :eval p("Hello World!") """ name = 'eval' @@ -702,16 +702,16 @@ class rename(Command): if not new_name: return self.fm.notify('Syntax: rename <newname>', bad=True) - if new_name == self.fm.env.cf.basename: + if new_name == self.fm.thisfile.basename: return if access(new_name, os.F_OK): return self.fm.notify("Can't rename: file already exists!", bad=True) - self.fm.rename(self.fm.env.cf, new_name) + self.fm.rename(self.fm.thisfile, new_name) f = File(new_name) - self.fm.env.cwd.pointed_obj = f - self.fm.env.cf = f + self.fm.thisdir.pointed_obj = f + self.fm.thisfile = f def tab(self): return self._tab_directory_content() @@ -743,7 +743,7 @@ class chmod(Command): self.fm.notify("Need an octal number between 0 and 777!", bad=True) return - for file in self.fm.env.get_selection(): + for file in self.fm.thistab.get_selection(): try: os.chmod(file.path, mode) except Exception as ex: @@ -752,7 +752,7 @@ class chmod(Command): try: # reloading directory. maybe its better to reload the selected # files only. - self.fm.env.cwd.load_content() + self.fm.thisdir.load_content() except: pass @@ -776,7 +776,7 @@ class bulkrename(Command): py3 = sys.version > "3" # Create and edit the file list - filenames = [f.basename for f in self.fm.env.get_selection()] + filenames = [f.basename for f in self.fm.thistab.get_selection()] listfile = tempfile.NamedTemporaryFile() if py3: @@ -823,7 +823,7 @@ class relink(Command): from ranger.fsobject import File new_path = self.rest(1) - cf = self.fm.env.cf + cf = self.fm.thisfile if not new_path: return self.fm.notify('Syntax: relink <newpath>', bad=True) @@ -841,12 +841,12 @@ class relink(Command): self.fm.notify(err) self.fm.reset() - self.fm.env.cwd.pointed_obj = cf - self.fm.env.cf = cf + self.fm.thisdir.pointed_obj = cf + self.fm.thisfile = cf def tab(self): if not self.rest(1): - return self.line+os.readlink(self.fm.env.cf.path) + return self.line+os.readlink(self.fm.thisfile.path) else: return self._tab_directory_content() @@ -1009,5 +1009,5 @@ class grep(Command): if self.rest(1): action = ['grep', '--color=always', '--line-number'] action.extend(['-e', self.rest(1), '-r']) - action.extend(f.path for f in self.fm.env.get_selection()) + action.extend(f.path for f in self.fm.thistab.get_selection()) self.fm.execute_command(action, flags='p') diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index a347d116..1b802fd5 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -139,8 +139,8 @@ map yn shell -d echo -n %f | xsel -i map = chmod map cw console rename -map A eval fm.open_console('rename ' + fm.env.cf.basename) -map I eval fm.open_console('rename ' + fm.env.cf.basename, position=7) +map A eval fm.open_console('rename ' + fm.thisfile.basename) +map I eval fm.open_console('rename ' + fm.thisfile.basename, position=7) map pp paste map po paste overwrite=True diff --git a/ranger/core/actions.py b/ranger/core/actions.py index da4c480c..bf2e84dd 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -40,9 +40,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def reset(self): """Reset the filemanager, clearing the directory buffer""" - old_path = self.env.cwd.path + old_path = self.thisdir.path self.previews = {} - self.env.garbage_collect(-1, self.tabs) + self.garbage_collect(-1, self.tabs) self.enter_dir(old_path) self.change_mode('normal') @@ -50,9 +50,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): if mode == self.mode: return if mode == 'visual': - self._visual_start = self.env.cwd.pointed_obj - self._visual_start_pos = self.env.cwd.pointer - self._previous_selection = set(self.env.cwd.marked_items) + self._visual_start = self.thisdir.pointed_obj + self._visual_start_pos = self.thisdir.pointer + self._previous_selection = set(self.thisdir.marked_items) self.mark_files(val=not self._visual_reverse, movedown=False) elif mode == 'normal': if self.mode == 'visual': @@ -73,7 +73,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def reload_cwd(self): try: - cwd = self.env.cwd + cwd = self.thisdir except: pass cwd.unload() @@ -102,7 +102,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.loader.remove(index=0) def get_cumulative_size(self): - for f in self.env.get_selection() or (): + for f in self.thistab.get_selection() or (): f.look_up_cumulative_size() self.ui.status.request_redraw() self.ui.redraw_main_column() @@ -168,13 +168,13 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): macros['rangerdir'] = ranger.RANGERDIR - if self.fm.env.cf: - macros['f'] = self.fm.env.cf.basename + if self.fm.thisfile: + macros['f'] = self.fm.thisfile.basename else: macros['f'] = MACRO_FAIL - if self.fm.env.get_selection: - macros['s'] = [fl.basename for fl in self.fm.env.get_selection()] + if self.fm.thistab.get_selection: + macros['s'] = [fl.basename for fl in self.fm.thistab.get_selection()] else: macros['s'] = MACRO_FAIL @@ -183,14 +183,14 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): else: macros['c'] = MACRO_FAIL - if self.fm.env.cwd.files: - macros['t'] = [fl.basename for fl in self.fm.env.cwd.files + if self.fm.thisdir.files: + macros['t'] = [fl.basename for fl in self.fm.thisdir.files if fl.realpath in (self.fm.tags or [])] else: macros['t'] = MACRO_FAIL - if self.fm.env.cwd: - macros['d'] = self.fm.env.cwd.path + if self.fm.thisdir: + macros['d'] = self.fm.thisdir.path else: macros['d'] = '.' @@ -272,11 +272,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): # ranger can act as a file chooser when running with --choosefile=... if mode == 0 and 'label' not in kw: if ranger.arg.choosefile: - open(ranger.arg.choosefile, 'w').write(self.fm.env.cf.path) + open(ranger.arg.choosefile, 'w').write(self.fm.thisfile.path) if ranger.arg.choosefiles: open(ranger.arg.choosefiles, 'w').write("".join( - f.path + "\n" for f in self.fm.env.get_selection())) + f.path + "\n" for f in self.fm.thistab.get_selection())) if ranger.arg.choosefile or ranger.arg.choosefiles: raise SystemExit() @@ -288,7 +288,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): flags = kw.get('flags', '') if 'c' in squash_flags(flags): - files = [self.fm.env.cf] + files = [self.fm.thisfile] self.signal_emit('execute.before', keywords=kw) filenames = [f.path for f in files] @@ -318,7 +318,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.move(to=2, pages=True) # moves to page 2. self.move(to=1, percentage=True) # moves to 80% """ - cwd = self.env.cwd + cwd = self.thisdir direction = Direction(kw) if 'left' in direction or direction.left() > 0: steps = direction.left() @@ -328,16 +328,16 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): directory = os.path.join(*(['..'] * steps)) except: return - self.env.enter_dir(directory) + self.thistab.enter_dir(directory) self.change_mode('normal') if cwd and cwd.accessible and cwd.content_loaded: if 'right' in direction: mode = 0 if narg is not None: mode = narg - cf = self.env.cf - selection = self.env.get_selection() - if not self.env.enter_dir(cf) and selection: + cf = self.thisfile + selection = self.thistab.get_selection() + if not self.thistab.enter_dir(cf) and selection: if self.execute_file(selection, mode=mode) is False: self.open_console('open_with ') elif direction.vertical() and cwd.files: @@ -378,35 +378,36 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.change_mode('normal') if narg is not None: n *= narg - parent = self.env.at_level(-1) + parent = self.thistab.at_level(-1) if parent is not None: if parent.pointer + n < 0: n = 0 - parent.pointer try: - self.env.enter_dir(parent.files[parent.pointer+n]) + self.thistab.enter_dir(parent.files[parent.pointer+n]) except IndexError: pass def select_file(self, path): path = path.strip() if self.enter_dir(os.path.dirname(path)): - self.env.cwd.move_to_obj(path) + self.thisdir.move_to_obj(path) def history_go(self, relative): """Move back and forth in the history""" - self.env.history_go(int(relative)) + self.thistab.history_go(int(relative)) + # TODO: remove this method since it is not used? def scroll(self, relative): """Scroll down by <relative> lines""" if self.ui.browser and self.ui.browser.main_column: self.ui.browser.main_column.scroll(relative) - self.env.cf = self.env.cwd.pointed_obj + self.thisfile = self.thisdir.pointed_obj def enter_dir(self, path, remember=False, history=True): """Enter the directory at the given path""" - cwd = self.env.cwd - result = self.env.enter_dir(path, history=history) - if cwd != self.env.cwd: + cwd = self.thisdir + result = self.thistab.enter_dir(path, history=history) + if cwd != self.thisdir: if remember: self.bookmarks.remember(cwd) self.change_mode('normal') @@ -418,14 +419,14 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def traverse(self): self.change_mode('normal') - cf = self.env.cf - cwd = self.env.cwd + cf = self.thisfile + cwd = self.thisdir if cf is not None and cf.is_directory: self.enter_dir(cf.path) elif cwd.pointer >= len(cwd) - 1: while True: self.move(left=1) - cwd = self.env.cwd + cwd = self.thisdir if cwd.pointer < len(cwd) - 1: break if cwd.path == '/': @@ -467,7 +468,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def edit_file(self, file=None): """Calls execute_file with the current file and label='editor'""" if file is None: - file = self.env.cf + file = self.thisfile elif isinstance(file, str): file = File(os.path.expanduser(file)) if file is None: @@ -476,23 +477,23 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def toggle_option(self, string): """Toggle a boolean option named <string>""" - if isinstance(self.env.settings[string], bool): - self.env.settings[string] ^= True + if isinstance(self.settings[string], bool): + self.settings[string] ^= True def set_option(self, optname, value): """Set the value of an option named <optname>""" - self.env.settings[optname] = value + self.settings[optname] = value def sort(self, func=None, reverse=None): if reverse is not None: - self.env.settings['sort_reverse'] = bool(reverse) + self.settings['sort_reverse'] = bool(reverse) if func is not None: - self.env.settings['sort'] = str(func) + self.settings['sort'] = str(func) def set_filter(self, fltr): try: - self.env.cwd.filter = fltr + self.thisdir.filter = fltr except: pass @@ -506,10 +507,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): val - mark or unmark? """ - if self.env.cwd is None: + if self.thisdir is None: return - cwd = self.env.cwd + cwd = self.thisdir if not cwd.accessible: return @@ -543,7 +544,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.ui.status.need_redraw = True def mark_in_direction(self, val=True, dirarg=None): - cwd = self.env.cwd + cwd = self.thisdir direction = Direction(dirarg) pos, selected = direction.select(lst=cwd.files, current=cwd.pointer, pagesize=self.ui.termsize[0]) @@ -562,7 +563,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): text = re.compile(text, re.L | re.U | re.I) except: return False - self.env.last_search = text + self.thistab.last_search = text self.search_next(order='search', offset=offset) def search_next(self, order=None, offset=1, forward=True): @@ -575,7 +576,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): if order in ('search', 'tag'): if order == 'search': - arg = self.env.last_search + arg = self.thistab.last_search if arg is None: return False if hasattr(arg, 'search'): @@ -585,10 +586,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): elif order == 'tag': fnc = lambda x: x.realpath in self.tags - return self.env.cwd.search_fnc(fnc=fnc, offset=offset, forward=forward) + return self.thisdir.search_fnc(fnc=fnc, offset=offset, forward=forward) elif order in ('size', 'mimetype', 'ctime', 'mtime', 'atime'): - cwd = self.env.cwd + cwd = self.thisdir if original_order is not None or not cwd.cycle_list: lst = list(cwd.files) if order == 'size': @@ -621,7 +622,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): if not self.tags: return if paths is None: - tags = tuple(x.realpath for x in self.env.get_selection()) + tags = tuple(x.realpath for x in self.thistab.get_selection()) else: tags = [realpath(path) for path in paths] if value is True: @@ -654,7 +655,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): try: self.bookmarks.update_if_outdated() destination = self.bookmarks[str(key)] - cwd = self.env.cwd + cwd = self.thisdir if destination.path != cwd.path: self.bookmarks.enter(str(key)) self.bookmarks.remember(cwd) @@ -664,7 +665,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def set_bookmark(self, key): """Set the bookmark with the name <key> to the current directory""" self.bookmarks.update_if_outdated() - self.bookmarks[str(key)] = self.env.cwd + self.bookmarks[str(key)] = self.thisdir def unset_bookmark(self, key): """Delete the bookmark with the name <key>""" @@ -679,7 +680,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def draw_possible_programs(self): try: - target = self.env.get_selection()[0] + target = self.thistab.get_selection()[0] except: self.ui.browser.draw_info = [] return @@ -733,11 +734,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): pager.set_source(["Message Log:", "No messages!"]) def display_file(self): - if not self.env.cf or not self.env.cf.is_file: + if not self.thisfile or not self.thisfile.is_file: return pager = self.ui.open_embedded_pager() - pager.set_source(self.env.cf.get_preview_source(pager.wid, pager.hei)) + pager.set_source(self.thisfile.get_preview_source(pager.wid, pager.hei)) # -------------------------- # -- Previews @@ -801,12 +802,12 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): f.close() else: data[(-1, -1)] = None - if self.env.cf.realpath == path: + if self.thisfile.realpath == path: self.ui.browser.need_redraw = True data['loading'] = False pager = self.ui.browser.pager - if self.env.cf and self.env.cf.is_file: - pager.set_source(self.env.cf.get_preview_source( + if self.thisfile and self.thisfile.is_file: + pager.set_source(self.thisfile.get_preview_source( pager.wid, pager.hei)) def on_destroy(signal): try: @@ -830,6 +831,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): # -------------------------- # This implementation of tabs is very simple and keeps track of # directory paths only. + # TODO: Need to rewrite this to fit the new tab model def tab_open(self, name, path=None): tab_has_changed = name != self.current_tab @@ -872,9 +874,6 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): assert len(self.tabs) > 0, "There must be >=1 tabs at all times" return sorted(self.tabs) - def _update_current_tab(self): - self.tabs[self.current_tab] = self.env.cwd.path - # -------------------------- # -- Overview of internals # -------------------------- @@ -955,9 +954,9 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def copy(self, mode='set', narg=None, dirarg=None): """Copy the selected items. Modes are: 'set', 'add', 'remove'.""" assert mode in ('set', 'add', 'remove') - cwd = self.env.cwd + cwd = self.thisdir if not narg and not dirarg: - selected = (f for f in self.env.get_selection() if f in cwd.files) + selected = (f for f in self.thistab.get_selection() if f in cwd.files) else: if not dirarg and narg: direction = Direction(down=1) @@ -1038,7 +1037,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): cwd = self.get_directory(original_path) cwd.load_content() - cwd = self.env.cwd + cwd = self.thisdir original_path = cwd.path one_file = copied_files[0] if overwrite: @@ -1080,7 +1079,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): def delete(self): # XXX: warn when deleting mount points/unseen marked files? self.notify("Deleting!") - selected = self.env.get_selection() + selected = self.thistab.get_selection() self.copy_buffer -= set(selected) if selected: for f in selected: @@ -1094,11 +1093,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): os.remove(f.path) except OSError as err: self.notify(err) - self.env.ensure_correct_pointer() + self.thistab.ensure_correct_pointer() def mkdir(self, name): try: - os.mkdir(os.path.join(self.env.cwd.path, name)) + os.mkdir(os.path.join(self.thisdir.path, name)) except OSError as err: self.notify(err) diff --git a/ranger/core/environment.py b/ranger/core/environment.py index f04fc307..61bbb6b2 100644 --- a/ranger/core/environment.py +++ b/ranger/core/environment.py @@ -1,16 +1,17 @@ # Copyright (C) 2009, 2010, 2011 Roman Zimbelmann <romanz@lavabit.com> # This software is distributed under the terms of the GNU GPL version 3. -import os -from os.path import abspath, normpath, join, expanduser, isdir +# THIS WHOLE FILE IS OBSOLETE AND EXISTS FOR BACKWARDS COMPATIBILITIY -from ranger.fsobject import Directory -from ranger.container.history import History +import os from ranger.ext.signals import SignalDispatcher from ranger.core.shared import SettingsAware, FileManagerAware # COMPAT -class EnvironmentCompatibilityWrapper(object): +class Environment(SettingsAware, FileManagerAware, SignalDispatcher): + def __init__(self, path): + SignalDispatcher.__init__(self) + def _get_copy(self): return self.fm.copy_buffer def _set_copy(self, obj): self.fm.copy_buffer = obj copy = property(_get_copy, _set_copy) @@ -43,143 +44,68 @@ class EnvironmentCompatibilityWrapper(object): def _set_get_directory(self, obj): self.fm.get_directory = obj get_directory = property(_get_get_directory, _set_get_directory) - def _get_garbage_collect(self): return self.fm.thistab.garbage_collect - def _set_garbage_collect(self, obj): self.fm.thistab.garbage_collect = obj + def _get_garbage_collect(self): return self.fm.garbage_collect + def _set_garbage_collect(self, obj): self.fm.garbage_collect = obj garbage_collect = property(_get_garbage_collect, _set_garbage_collect) -class Environment(SettingsAware, FileManagerAware, SignalDispatcher, - EnvironmentCompatibilityWrapper): - """ - A collection of data which is relevant for more than one class. - """ - - def __init__(self, path): - SignalDispatcher.__init__(self) - self.cwd = None # Current Working Directory - self._cf = None # Current File - self.history = History(self.settings.max_history_size, unique=False) - self.last_search = None - self.path = abspath(expanduser(path)) - self.pathway = () - self.signal_bind('move', self._set_cf_from_signal, priority=0.1, - weak=True) - - def _set_cf_from_signal(self, signal): - self._cf = signal.new - - def _set_cf(self, value): - if value is not self._cf: - previous = self._cf - self.signal_emit('move', previous=previous, new=value) - - def _get_cf(self): - return self._cf + def _get_cwd(self): return self.fm.thisdir + def _set_cwd(self, obj): self.fm.thisdir = obj + cwd = property(_get_cwd, _set_cwd) + def _get_cf(self): return self.fm.thisfile + def _set_cf(self, obj): self.fm.thisfile = obj cf = property(_get_cf, _set_cf) - def at_level(self, level): - """ - Returns the FileSystemObject at the given level. - level >0 => previews - level 0 => current file/directory - level <0 => parent directories - """ - if level <= 0: - try: - return self.pathway[level - 1] - except IndexError: - return None - else: - directory = self.cf - for i in range(level - 1): - if directory is None: - return None - if directory.is_directory: - directory = directory.pointed_obj - else: - return None - try: - return self.fm.directories[directory.path] - except AttributeError: - return None - except KeyError: - return directory - - def get_selection(self): - if self.cwd: - return self.cwd.get_selection() - return set() + def _get_history(self): return self.fm.thistab.history + def _set_history(self, obj): self.fm.thistab.history = obj + history = property(_get_history, _set_history) + + def _get_last_search(self): return self.fm.thistab.last_search + def _set_last_search(self, obj): self.fm.thistab.last_search = obj + last_search = property(_get_last_search, _set_last_search) + + def _get_path(self): return self.fm.thistab.path + def _set_path(self, obj): self.fm.thistab.path = obj + path = property(_get_path, _set_path) + + def _get_pathway(self): return self.fm.thistab.pathway + def _set_pathway(self, obj): self.fm.thistab.pathway = obj + pathway = property(_get_pathway, _set_pathway) + + def _get_enter_dir(self): return self.fm.thistab.enter_dir + def _set_enter_dir(self, obj): self.fm.thistab.enter_dir = obj + enter_dir = property(_get_enter_dir, _set_enter_dir) + + def _get_at_level(self): return self.fm.thistab.at_level + def _set_at_level(self, obj): self.fm.thistab.at_level = obj + at_level = property(_get_at_level, _set_at_level) + + def _get_get_selection(self): return self.fm.thistab.get_selection + def _set_get_selection(self, obj): self.fm.thistab.get_selection = obj + get_selection = property(_get_get_selection, _set_get_selection) + + def _get_assign_cursor_positions_for_subdirs(self): + return self.fm.thistab.assign_cursor_positions_for_subdirs + def _set_assign_cursor_positions_for_subdirs(self, obj): + self.fm.thistab.assign_cursor_positions_for_subdirs = obj + assign_cursor_positions_for_subdirs = property( + _get_assign_cursor_positions_for_subdirs, + _set_assign_cursor_positions_for_subdirs) + + def _get_ensure_correct_pointer(self): + return self.fm.thistab.ensure_correct_pointer + def _set_ensure_correct_pointer(self, obj): + self.fm.thistab.ensure_correct_pointer = obj + ensure_correct_pointer = property(_get_ensure_correct_pointer, + _set_ensure_correct_pointer) + + def _get_history_go(self): return self.fm.thistab.history_go + def _set_history_go(self, obj): self.fm.thistab.history_go = obj + history_go = property(_get_history_go, _set_history_go) + + def _set_cf_from_signal(self, signal): + self.fm._cf = signal.new def get_free_space(self, path): stat = os.statvfs(path) return stat.f_bavail * stat.f_bsize - - def assign_cursor_positions_for_subdirs(self): - """Assign correct cursor positions for subdirectories""" - last_path = None - for path in reversed(self.pathway): - if last_path is None: - last_path = path - continue - - path.move_to_obj(last_path) - last_path = path - - def ensure_correct_pointer(self): - if self.cwd: - self.cwd.correct_pointer() - - def history_go(self, relative): - """Move relative in history""" - if self.history: - self.history.move(relative).go(history=False) - - def enter_dir(self, path, history = True): - """Enter given path""" - if path is None: return - path = str(path) - - previous = self.cwd - - # get the absolute path - path = normpath(join(self.path, expanduser(path))) - - if not isdir(path): - return False - new_cwd = self.fm.get_directory(path) - - try: - os.chdir(path) - except: - return True - self.path = path - self.cwd = new_cwd - - self.cwd.load_content_if_outdated() - - # build the pathway, a tuple of directory objects which lie - # on the path to the current directory. - if path == '/': - self.pathway = (self.fm.get_directory('/'), ) - else: - pathway = [] - currentpath = '/' - for dir in path.split('/'): - currentpath = join(currentpath, dir) - pathway.append(self.fm.get_directory(currentpath)) - self.pathway = tuple(pathway) - - self.assign_cursor_positions_for_subdirs() - - # set the current file. - self.cwd.sort_directories_first = self.settings.sort_directories_first - self.cwd.sort_reverse = self.settings.sort_reverse - self.cwd.sort_if_outdated() - self.cf = self.cwd.pointed_obj - - if history: - self.history.add(new_cwd) - - self.signal_emit('cd', previous=previous, new=self.cwd) - - return True diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 814d16ba..34e761bd 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -16,6 +16,7 @@ import sys import ranger from ranger.core.actions import Actions +from ranger.core.tab import Tab from ranger.container.tags import Tags from ranger.gui.ui import UI from ranger.container.bookmarks import Bookmarks @@ -49,11 +50,11 @@ class FM(Actions, SignalDispatcher): self.directories = dict() self.log = deque(maxlen=20) self.bookmarks = bookmarks - self.tags = tags + self.current_tab = 1 self.tabs = {} + self.tags = tags self.py3 = sys.version_info >= (3, ) self.previews = {} - self.current_tab = 1 self.loader = Loader() self.copy_buffer = set() self.do_cut = False @@ -76,6 +77,8 @@ class FM(Actions, SignalDispatcher): def initialize(self): """If ui/bookmarks are None, they will be initialized here.""" + self.thistab = Tab(".") + self.tabs[self.current_tab] = self.thistab if not ranger.arg.clean and os.path.isfile(self.confpath('rifle.conf')): rifleconf = self.confpath('rifle.conf') else: @@ -110,8 +113,6 @@ class FM(Actions, SignalDispatcher): self.notify(text, bad=True) self.run = Runner(ui=self.ui, logfunc=mylogfunc, fm=self) - self.env.signal_bind('cd', self._update_current_tab) - if self.settings.init_function: self.settings.init_function(self) @@ -130,6 +131,21 @@ class FM(Actions, SignalDispatcher): if debug: raise + def _get_thisfile(self): + return self.thistab.thisfile + + def _set_thisfile(self, obj): + self.thistab.thisfile = obj + + def _get_thisdir(self): + return self.thistab.thisdir + + def _set_thisdir(self, obj): + self.thistab.thisdir = obj + + thisfile = property(_get_thisfile, _set_thisfile) + thisdir = property(_get_thisdir, _set_thisdir) + def block_input(self, sec=0): self.input_blocked = sec != 0 self.input_blocked_until = time() + sec @@ -190,14 +206,13 @@ class FM(Actions, SignalDispatcher): self.directories[path] = obj return obj - def garbage_collect(self, age, tabs): + def garbage_collect(self, age, tabs=None): # tabs=None is for COMPATibility """Delete unused directory objects""" for key in tuple(self.directories): value = self.directories[key] if age != -1: - if not value.is_older_than(age) or value in self.pathway: - continue - if value in tabs.values(): + if not value.is_older_than(age) \ + or any(value in tab.pathway for tab in self.tabs.values()): continue del self.directories[key] if value.is_directory: @@ -215,7 +230,7 @@ class FM(Actions, SignalDispatcher): 5. after X loops: collecting unused directory objects """ - self.env.enter_dir(self.env.path) + self.enter_dir(self.thistab.path) gc_tick = 0 @@ -249,8 +264,7 @@ class FM(Actions, SignalDispatcher): gc_tick += 1 if gc_tick > ranger.TICKS_BEFORE_COLLECTING_GARBAGE: gc_tick = 0 - self.garbage_collect( - ranger.TIME_BEFORE_FILE_BECOMES_GARBAGE, self.tabs) + self.garbage_collect(ranger.TIME_BEFORE_FILE_BECOMES_GARBAGE) except KeyboardInterrupt: # this only happens in --debug mode. By default, interrupts @@ -258,9 +272,9 @@ class FM(Actions, SignalDispatcher): raise SystemExit finally: - if ranger.arg.choosedir and self.env.cwd and self.env.cwd.path: + if ranger.arg.choosedir and self.thisdir and self.thisdir.path: # XXX: UnicodeEncodeError: 'utf-8' codec can't encode character # '\udcf6' in position 42: surrogates not allowed - open(ranger.arg.choosedir, 'w').write(self.env.cwd.path) - self.bookmarks.remember(self.env.cwd) + open(ranger.arg.choosedir, 'w').write(self.thisdir.path) + self.bookmarks.remember(self.thisdir) self.bookmarks.save() diff --git a/ranger/core/main.py b/ranger/core/main.py index 1d25c54f..b0ddc4d1 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -12,8 +12,7 @@ def main(): import locale import ranger import sys - from ranger.core.shared import (EnvironmentAware, FileManagerAware, - SettingsAware) + from ranger.core.shared import FileManagerAware, SettingsAware from ranger.core.fm import FM if not sys.stdin.isatty(): @@ -86,10 +85,8 @@ def main(): crash_traceback = None try: # Initialize objects - from ranger.core.environment import Environment fm = FM() FileManagerAware.fm = fm - EnvironmentAware.env = Environment(target) fm.tabs = dict((n+1, os.path.abspath(path)) for n, path \ in enumerate(targets[:9])) load_settings(fm, arg.clean) @@ -141,7 +138,7 @@ def main(): finally: if crash_traceback: try: - filepath = fm.env.cf.path if fm.env.cf else "None" + filepath = fm.thisfile.path if fm.thisfile else "None" except: filepath = "None" try: diff --git a/ranger/core/tab.py b/ranger/core/tab.py new file mode 100644 index 00000000..8157ac37 --- /dev/null +++ b/ranger/core/tab.py @@ -0,0 +1,140 @@ +# Copyright (C) 2009, 2010, 2011 Roman Zimbelmann <romanz@lavabit.com> +# This software is distributed under the terms of the GNU GPL version 3. + +import os +from os.path import abspath, normpath, join, expanduser, isdir + +from ranger.container.history import History +from ranger.core.shared import FileManagerAware, SettingsAware +from ranger.ext.signals import SignalDispatcher + +class Tab(FileManagerAware, SettingsAware): + def __init__(self, path): + self.thisdir = None # Current Working Directory + self._thisfile = None # Current File + self.history = History(self.settings.max_history_size, unique=False) + self.last_search = None + self.path = abspath(expanduser(path)) + self.pathway = () + self.fm.signal_bind('move', self._set_thisfile_from_signal, priority=0.1, + weak=True) + + def _set_thisfile_from_signal(self, signal): + if self == self.fm.thistab: + self._thisfile = signal.new + + def _set_thisfile(self, value): + if value is not self._thisfile: + previous = self._thisfile + self.fm.signal_emit('move', previous=previous, new=value) + + def _get_thisfile(self): + return self._thisfile + + thisfile = property(_get_thisfile, _set_thisfile) + + def at_level(self, level): + """ + Returns the FileSystemObject at the given level. + level >0 => previews + level 0 => current file/directory + level <0 => parent directories + """ + if level <= 0: + try: + return self.pathway[level - 1] + except IndexError: + return None + else: + directory = self.thisfile + for i in range(level - 1): + if directory is None: + return None + if directory.is_directory: + directory = directory.pointed_obj + else: + return None + try: + return self.fm.directories[directory.path] + except AttributeError: + return None + except KeyError: + return directory + + def get_selection(self): + if self.thisdir: + return self.thisdir.get_selection() + return set() + + def assign_cursor_positions_for_subdirs(self): + """Assign correct cursor positions for subdirectories""" + last_path = None + for path in reversed(self.pathway): + if last_path is None: + last_path = path + continue + + path.move_to_obj(last_path) + last_path = path + + def ensure_correct_pointer(self): + if self.thisdir: + self.thisdir.correct_pointer() + + def history_go(self, relative): + """Move relative in history""" + if self.history: + self.history.move(relative).go(history=False) + + def enter_dir(self, path, history = True): + """Enter given path""" + if path is None: return + path = str(path) + + previous = self.thisdir + + # get the absolute path + path = normpath(join(self.path, expanduser(path))) + + if not isdir(path): + return False + new_thisdir = self.fm.get_directory(path) + + try: + os.chdir(path) + except: + return True + self.path = path + self.thisdir = new_thisdir + + self.thisdir.load_content_if_outdated() + + # build the pathway, a tuple of directory objects which lie + # on the path to the current directory. + if path == '/': + self.pathway = (self.fm.get_directory('/'), ) + else: + pathway = [] + currentpath = '/' + for dir in path.split('/'): + currentpath = join(currentpath, dir) + pathway.append(self.fm.get_directory(currentpath)) + self.pathway = tuple(pathway) + + self.assign_cursor_positions_for_subdirs() + + # set the current file. + self.thisdir.sort_directories_first = self.fm.settings.sort_directories_first + self.thisdir.sort_reverse = self.fm.settings.sort_reverse + self.thisdir.sort_if_outdated() + self.thisfile = self.thisdir.pointed_obj + + if history: + self.history.add(new_thisdir) + + self.fm.signal_emit('cd', previous=previous, new=self.thisdir) + + return True + + def __repr__(self): + return "<Tab '%s'>" % self.thisdir diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py index 70543351..a8088cb2 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -454,8 +454,8 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): Accumulator.correct_pointer(self) try: - if self == self.fm.env.cwd: - self.fm.env.cf = self.pointed_obj + if self == self.fm.thisdir: + self.fm.thisfile = self.pointed_obj except: pass diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py index a70dd2ff..cbd77fe4 100644 --- a/ranger/gui/displayable.py +++ b/ranger/gui/displayable.py @@ -37,7 +37,7 @@ class Displayable(EnvironmentAware, FileManagerAware, CursesShortcuts): win -- the own curses window object parent -- the parent (DisplayableContainer) object or None x, y, wid, hei -- absolute coordinates and boundaries - settings, fm, env -- inherited shared variables + settings, fm -- inherited shared variables """ def __init__(self, win, env=None, fm=None, settings=None): diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index 835c4cc0..cc7e985e 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -47,10 +47,7 @@ class UI(DisplayableContainer): self._draw_title = os.environ["TERM"] in TERMINALS_WITH_TITLE self.keybuffer = KeyBuffer() self.keymaps = KeyMaps(self.keybuffer) - self.keymaps.use_keymap('browser') - if env is not None: - self.env = env if fm is not None: self.fm = fm @@ -63,6 +60,7 @@ class UI(DisplayableContainer): os.environ['TERM'] = 'linux' self.win = curses.initscr() self.termsize = self.win.getmaxyx() + self.keymaps.use_keymap('browser') DisplayableContainer.__init__(self, None) def initialize(self): @@ -279,7 +277,7 @@ class UI(DisplayableContainer): self.win.touchwin() DisplayableContainer.draw(self) if self._draw_title and self.settings.update_title: - cwd = self.fm.env.cwd.path + cwd = self.fm.thisdir.path if cwd.startswith(self.fm.home_path): cwd = '~' + cwd[len(self.fm.home_path):] if self.settings.shorten_title: diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index b94fd7e5..adf79e92 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -21,7 +21,7 @@ class BrowserColumn(Pager): ellipsis = { False: '~', True: '…' } old_dir = None - old_cf = None + old_thisfile = None def __init__(self, win, level): """ @@ -75,7 +75,7 @@ class BrowserColumn(Pager): if clicked_file.is_directory: self.fm.enter_dir(clicked_file.path) elif self.level == 0: - self.fm.env.cwd.move_to_obj(clicked_file) + self.fm.thisdir.move_to_obj(clicked_file) self.fm.execute_file(clicked_file) except: pass @@ -118,7 +118,7 @@ class BrowserColumn(Pager): def poke(self): Widget.poke(self) - self.target = self.env.at_level(self.level) + self.target = self.fm.thistab.at_level(self.level) def draw(self): """Call either _draw_file() or _draw_directory()""" @@ -131,9 +131,9 @@ class BrowserColumn(Pager): if self.target and self.target.is_directory \ and (self.level <= 0 or self.settings.preview_directories): - if self.target.pointed_obj != self.old_cf: + if self.target.pointed_obj != self.old_thisfile: self.need_redraw = True - self.old_cf = self.target.pointed_obj + self.old_thisfile = self.target.pointed_obj if self.target.load_content_if_outdated() \ or self.target.sort_if_outdated() \ diff --git a/ranger/gui/widgets/browserview.py b/ranger/gui/widgets/browserview.py index b539ad4b..3c45b7ca 100644 --- a/ranger/gui/widgets/browserview.py +++ b/ranger/gui/widgets/browserview.py @@ -36,7 +36,7 @@ class BrowserView(Widget, DisplayableContainer): self.settings.signal_bind('setopt.' + option, self._request_clear_if_has_borders, weak=True) - self.fm.env.signal_bind('move', self.request_clear) + self.fm.signal_bind('move', self.request_clear) self.settings.signal_bind('setopt.column_ratios', self.request_clear) def change_ratios(self, ratios): @@ -87,11 +87,10 @@ class BrowserView(Widget, DisplayableContainer): self.win.erase() self.need_redraw = True self.need_clear = False - for path in self.fm.tabs.values(): - if path is not None: - directory = self.fm.get_directory(path) - directory.load_content_if_outdated() - directory.use() + for tab in self.fm.tabs.values(): + directory = tab.thisdir + directory.load_content_if_outdated() + directory.use() DisplayableContainer.draw(self) if self.settings.draw_borders: self._draw_borders() diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index 20bc7c60..bf5ee641 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -9,6 +9,7 @@ print for the current file. The right side shows directory information such as the space used by all the files in this directory. """ +import os from pwd import getpwuid from grp import getgrgid from os import getuid, readlink @@ -26,7 +27,7 @@ class StatusBar(Widget): hint = None msg = None - old_cf = None + old_thisfile = None old_ctime = None old_du = None old_hint = None @@ -69,10 +70,10 @@ class StatusBar(Widget): self.msg = None self.need_redraw = True - if self.env.cf: - self.env.cf.load_if_outdated() + if self.fm.thisfile: + self.fm.thisfile.load_if_outdated() try: - ctime = self.env.cf.stat.st_ctime + ctime = self.fm.thisfile.stat.st_ctime except: ctime = -1 else: @@ -81,12 +82,12 @@ class StatusBar(Widget): if not self.result: self.need_redraw = True - if self.old_du and not self.env.cwd.disk_usage: - self.old_du = self.env.cwd.disk_usage + if self.old_du and not self.fm.thisdir.disk_usage: + self.old_du = self.fm.thisdir.disk_usage self.need_redraw = True - if self.old_cf != self.env.cf: - self.old_cf = self.env.cf + if self.old_thisfile != self.fm.thisfile: + self.old_thisfile = self.fm.thisfile self.need_redraw = True if self.old_ctime != ctime: @@ -139,7 +140,7 @@ class StatusBar(Widget): and self.column.target.is_directory: target = self.column.target.pointed_obj else: - target = self.env.at_level(0).pointed_obj + target = self.fm.thistab.at_level(0).pointed_obj try: stat = target.stat except: @@ -215,9 +216,9 @@ class StatusBar(Widget): max_pos = len(target) - self.column.hei base = 'scroll' - if self.env.cwd.filter: + if self.fm.thisdir.filter: right.add(" f=", base, 'filter') - right.add(repr(self.env.cwd.filter), base, 'filter') + right.add(repr(self.fm.thisdir.filter), base, 'filter') right.add(", ", "space") if target.marked_items: @@ -231,7 +232,7 @@ class StatusBar(Widget): else: right.add(human_readable(target.disk_usage, separator='') + " sum") try: - free = self.env.get_free_space(target.mount_path) + free = get_free_space(target.mount_path) except OSError: pass else: @@ -265,6 +266,10 @@ class StatusBar(Widget): self.addstr(str(part)) self.color_reset() +def get_free_space(path): + stat = os.statvfs(path) + return stat.f_bavail * stat.f_bsize + class Message(object): elapse = None text = None diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py index fddf2e64..04fdb7b6 100644 --- a/ranger/gui/widgets/titlebar.py +++ b/ranger/gui/widgets/titlebar.py @@ -13,7 +13,7 @@ from . import Widget from ranger.gui.bar import Bar class TitleBar(Widget): - old_cf = None + old_thisfile = None old_keybuffer = None old_wid = None result = None @@ -30,12 +30,12 @@ class TitleBar(Widget): def draw(self): if self.need_redraw or \ - self.env.cf != self.old_cf or\ + self.fm.thisfile != self.old_thisfile or\ str(self.fm.ui.keybuffer) != str(self.old_keybuffer) or\ self.wid != self.old_wid: self.need_redraw = False self.old_wid = self.wid - self.old_cf = self.env.cf + self.old_thisfile = self.fm.thisfile self._calc_bar() self._print_result(self.result) if self.wid > 2: @@ -101,9 +101,9 @@ class TitleBar(Widget): bar.add(self.fm.hostname, 'hostname', clr, fixed=True) bar.add(':', 'hostname', clr, fixed=True) - pathway = self.env.pathway + pathway = self.fm.thistab.pathway if self.settings.tilde_in_titlebar and \ - self.fm.env.cwd.path.startswith(self.fm.home_path): + self.fm.thisdir.path.startswith(self.fm.home_path): pathway = pathway[self.fm.home_path.count('/')+1:] bar.add('~/', 'directory', fixed=True) @@ -116,8 +116,8 @@ class TitleBar(Widget): bar.add(path.basename, clr, directory=path) bar.add('/', clr, fixed=True, directory=path) - if self.env.cf is not None: - bar.add(self.env.cf.basename, 'file') + if self.fm.thisfile is not None: + bar.add(self.fm.thisfile.basename, 'file') def _get_right_part(self, bar): # TODO: fix that pressed keys are cut off when chaining CTRL keys |