summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/container/directory.py71
-rw-r--r--ranger/container/fsobject.py16
-rw-r--r--ranger/core/fm.py10
-rw-r--r--ranger/gui/widgets/browsercolumn.py2
-rw-r--r--ranger/gui/widgets/titlebar.py2
5 files changed, 57 insertions, 44 deletions
diff --git a/ranger/container/directory.py b/ranger/container/directory.py
index c6987a76..506d1052 100644
--- a/ranger/container/directory.py
+++ b/ranger/container/directory.py
@@ -20,7 +20,7 @@ from ranger.container.settings import LocalSettings
 
 def sort_by_basename(path):
     """returns path.basename (for sorting)"""
-    return path.basename
+    return path.drawn_basename
 
 def sort_by_basename_icase(path):
     """returns case-insensitive path.basename (for sorting)"""
@@ -45,6 +45,24 @@ def accept_file(fname, directory, hidden_filter, name_filter):
         return False
     return True
 
+def walklevel(some_dir, level):
+    some_dir = some_dir.rstrip(os.path.sep)
+    assert os.path.isdir(some_dir)
+    num_sep = some_dir.count(os.path.sep)
+    for root, dirs, files in os.walk(some_dir):
+        yield root, dirs, files
+        num_sep_this = root.count(os.path.sep)
+        if level != -1 and num_sep + level <= num_sep_this:
+            del dirs[:]
+
+def mtimelevel(path, level):
+    mtime = os.stat(path).st_mtime
+    for dirpath, dirnames, filenames in walklevel(path, level):
+        dirlist = [os.path.join("/", dirpath, d) for d in dirnames
+                if level == -1 or dirpath.count(os.path.sep) - path.count(os.path.sep) <= level]
+        mtime = max(mtime, max([-1] + [os.stat(d).st_mtime for d in dirlist]))
+    return mtime
+
 class Directory(FileSystemObject, Accumulator, Loadable):
     is_directory = True
     enterable = False
@@ -183,7 +201,7 @@ class Directory(FileSystemObject, Accumulator, Loadable):
         self.move_to_obj(self.pointed_obj)
 
     # XXX: Check for possible race conditions
-    def load_bit_by_bit(self, flat=0):
+    def load_bit_by_bit(self):
         """An iterator that loads a part on every next() call
 
         Returns a generator which load a part of the directory
@@ -194,17 +212,7 @@ class Directory(FileSystemObject, Accumulator, Loadable):
         self.percent = 0
         self.load_if_outdated()
 
-        basename_is_rel = True if flat else False
-
-        def walklevel(some_dir, level):
-            some_dir = some_dir.rstrip(os.path.sep)
-            assert os.path.isdir(some_dir)
-            num_sep = some_dir.count(os.path.sep)
-            for root, dirs, files in os.walk(some_dir):
-                yield root, dirs, files
-                num_sep_this = root.count(os.path.sep)
-                if level != -1 and num_sep + level <= num_sep_this:
-                    del dirs[:]
+        basename_is_rel_to = self.path if self.flat else None
 
         try:
             if self.runnable:
@@ -213,17 +221,20 @@ class Directory(FileSystemObject, Accumulator, Loadable):
 
                 self.mount_path = mount_path(mypath)
 
-                if flat:
+                if self.flat:
                     filelist = []
-                    for dirpath, dirnames, filenames in walklevel(mypath, flat):
-                        filelist += [os.path.join("/", dirpath, d) for d in dirnames
-                                if dirpath.count(os.path.sep) - mypath.count(os.path.sep) == flat]
+                    for dirpath, dirnames, filenames in walklevel(mypath, self.flat):
+                        dirlist = [os.path.join("/", dirpath, d) for d in dirnames
+                                if self.flat == -1 or dirpath.count(os.path.sep) - mypath.count(os.path.sep) <= self.flat]
+                        filelist += dirlist
                         filelist += [os.path.join("/", dirpath, f) for f in filenames]
-                    filenames = [os.path.relpath(name, mypath) for name in filelist]
+                    filenames = filelist
+                    self.load_content_mtime = mtimelevel(mypath, self.flat)
                 else:
                     filelist = os.listdir(mypath)
                     filenames = [mypath + (mypath == '/' and fname or '/' + fname)
                             for fname in filelist]
+                    self.load_content_mtime = os.stat(mypath).st_mtime
 
                 if self._cumulative_size_calculated:
                     # If self.content_loaded is true, this is not the first
@@ -245,8 +256,6 @@ class Directory(FileSystemObject, Accumulator, Loadable):
 
                 yield
 
-                self.load_content_mtime = os.stat(mypath).st_mtime
-
                 marked_paths = [obj.path for obj in self.marked_items]
 
                 files = []
@@ -270,16 +279,19 @@ class Directory(FileSystemObject, Accumulator, Loadable):
                         is_a_dir = False
                     if is_a_dir:
                         try:
-                            item = self.fm.get_directory(name,
-                                    basename_is_rel=basename_is_rel)
-                            item.load_if_outdated()
+                            if self.flat:
+                                item = Directory(name, preload=stats, path_is_abs=True,
+                                        basename_is_rel_to=basename_is_rel_to)
+                                item.load()
+                            else:
+                                item = self.fm.get_directory(name)
+                                item.load_if_outdated()
                         except:
-                            item = Directory(name, preload=stats, path_is_abs=True,
-                                    basename_is_rel=basename_is_rel)
+                            item = Directory(name, preload=stats, path_is_abs=True)
                             item.load()
                     else:
                         item = File(name, preload=stats, path_is_abs=True,
-                                    basename_is_rel=basename_is_rel)
+                                    basename_is_rel_to=basename_is_rel_to)
                         item.load()
                         disk_usage += item.size
 
@@ -350,7 +362,7 @@ class Directory(FileSystemObject, Accumulator, Loadable):
                 schedule = True   # was: self.size > 30
 
             if self.load_generator is None:
-                self.load_generator = self.load_bit_by_bit(flat=self.flat)
+                self.load_generator = self.load_bit_by_bit()
 
                 if schedule and self.fm:
                     self.fm.loader.add(self)
@@ -530,7 +542,10 @@ class Directory(FileSystemObject, Accumulator, Loadable):
             return True
 
         try:
-            real_mtime = os.stat(self.path).st_mtime
+            if self.flat:
+                real_mtime = mtimelevel(self.path, self.flat)
+            else:
+                real_mtime = os.stat(self.path).st_mtime
         except OSError:
             real_mtime = None
             return False
diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py
index 6f206d0d..ef1938ff 100644
--- a/ranger/container/fsobject.py
+++ b/ranger/container/fsobject.py
@@ -78,18 +78,20 @@ class FileSystemObject(FileManagerAware, SettingsAware):
     vcs_outdated = False
     vcs_enabled = False
 
-    basename_is_rel = False
+    basename_is_rel_to = None
 
-    def __init__(self, path, preload=None, path_is_abs=False, basename_is_rel=False):
+    def __init__(self, path, preload=None, path_is_abs=False, basename_is_rel_to=None):
         if not path_is_abs:
             path = abspath(path)
         self.path = path
-        self.basename_is_rel = basename_is_rel
-        if not basename_is_rel:
+        self.basename_is_rel_to = basename_is_rel_to
+        if basename_is_rel_to == None:
             self.basename = basename(path)
+            self.drawn_basename = self.basename
         else:
-            self.basename = relpath(path, getcwd())
-        self.basename_lower = self.basename.lower()
+            self.basename = basename(path)
+            self.drawn_basename = relpath(path, basename_is_rel_to)
+        self.basename_lower = self.drawn_basename.lower()
         self.extension = splitext(self.basename)[1].lstrip(extsep) or None
         self.dirname = dirname(path)
         self.preload = preload
@@ -118,7 +120,7 @@ class FileSystemObject(FileManagerAware, SettingsAware):
     @lazy_property
     def basename_natural(self):
         return [c if i % 3 == 1 else (int(c) if c else 0) for i, c in \
-            enumerate(_extract_number_re.split(self.basename))]
+            enumerate(_extract_number_re.split(self.drawn_basename))]
 
     @lazy_property
     def basename_natural_lower(self):
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index d567bf24..2a9ce315 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -252,17 +252,13 @@ class FM(Actions, SignalDispatcher):
         """returns the path relative to rangers library directory"""
         return os.path.join(ranger.RANGERDIR, *paths)
 
-    def get_directory(self, path, basename_is_rel = False):
+    def get_directory(self, path):
         """Get the directory object at the given path"""
         path = os.path.abspath(path)
         try:
-            directory = self.directories[path]
-            if directory.basename_is_rel != basename_is_rel:
-                del self.directories[path]
-                raise KeyError
-            return directory
+            return self.directories[path]
         except KeyError:
-            obj = Directory(path, basename_is_rel = basename_is_rel)
+            obj = Directory(path)
             self.directories[path] = obj
             return obj
 
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py
index 0edb9c8d..55601130 100644
--- a/ranger/gui/widgets/browsercolumn.py
+++ b/ranger/gui/widgets/browsercolumn.py
@@ -257,7 +257,7 @@ class BrowserColumn(Pager):
                 self.color_reset()
                 continue
 
-            text = drawn.basename
+            text = drawn.drawn_basename
             if drawn.marked and (self.main_column or \
                     self.settings.display_tags_in_all_columns):
                 text = " " + text
diff --git a/ranger/gui/widgets/titlebar.py b/ranger/gui/widgets/titlebar.py
index fa10a744..25edd5e4 100644
--- a/ranger/gui/widgets/titlebar.py
+++ b/ranger/gui/widgets/titlebar.py
@@ -117,7 +117,7 @@ class TitleBar(Widget):
 
         if self.fm.thisfile is not None and \
                 self.settings.show_selection_in_titlebar:
-            bar.add(self.fm.thisfile.basename, 'file')
+            bar.add(self.fm.thisfile.drawn_basename, 'file')
 
     def _get_right_part(self, bar):
         # TODO: fix that pressed keys are cut off when chaining CTRL keys