summary refs log tree commit diff stats
path: root/ranger
diff options
context:
space:
mode:
authornfnty <git@nfnty.se>2016-02-09 14:51:05 +0100
committernfnty <git@nfnty.se>2016-02-09 16:13:05 +0100
commitde592fa35bb7fed0de47f3294566b31c470dbb6a (patch)
treed46b9b0849499fba9649108a40b5b401ac186c92 /ranger
parent6edb035a4d176c4df852b7e7ad9be89a3de24a72 (diff)
downloadranger-de592fa35bb7fed0de47f3294566b31c470dbb6a.tar.gz
VCS: Process queue more efficiently
Diffstat (limited to 'ranger')
-rw-r--r--ranger/container/directory.py3
-rw-r--r--ranger/ext/vcs/vcs.py91
2 files changed, 62 insertions, 32 deletions
diff --git a/ranger/container/directory.py b/ranger/container/directory.py
index cd814cb1..2ee250ea 100644
--- a/ranger/container/directory.py
+++ b/ranger/container/directory.py
@@ -333,7 +333,8 @@ class Directory(FileSystemObject, Accumulator, Loadable):
                                 item.relative_path = item.basename
                             item.relative_path_lower = item.relative_path.lower()
                         if item.vcs and item.vcs.track and not item.vcs.is_root:
-                            item.vcsstatus = item.vcs.rootvcs.status_subpath(item.path)
+                            item.vcsstatus = item.vcs.rootvcs.status_subpath(
+                                item.path, is_directory=True)
                     else:
                         item = File(name, preload=stats, path_is_abs=True,
                                     basename_is_rel_to=basename_is_rel_to)
diff --git a/ranger/ext/vcs/vcs.py b/ranger/ext/vcs/vcs.py
index 5c456120..4710feb6 100644
--- a/ranger/ext/vcs/vcs.py
+++ b/ranger/ext/vcs/vcs.py
@@ -371,6 +371,7 @@ class VcsThread(threading.Thread):  # pylint: disable=too-many-instance-attribut
         self.awoken = threading.Event()
         self.timestamp = time.time()
         self.redraw = False
+        self.roots = set()
 
     def _hindered(self):
         """Check for hinders"""
@@ -379,50 +380,78 @@ class VcsThread(threading.Thread):  # pylint: disable=too-many-instance-attribut
                 return True
         return False
 
+    def _is_targeted(self, dirobj):
+        ''' Check if dirobj is targeted '''
+        if not self.ui.browser.main_column:
+            return False
+        target = self.ui.browser.main_column.target
+        if target and target.is_directory and target.path == dirobj.path:
+            return True
+        return False
+
+    def _update_files(self, fileobjs):
+        ''' Update files '''
+        if not fileobjs:
+            return False
+
+        has_vcschild = False
+        for fileobj in fileobjs:
+            if not fileobj.is_directory or not fileobj.vcs or not fileobj.vcs.track:
+                continue
+
+            if fileobj.vcs.is_root:
+                has_vcschild = True
+                if not fileobj.vcs.rootinit and not self._is_targeted(fileobj):
+                    fileobj.vcs.init_root()
+                    self.roots.add(fileobj.vcs.path)
+                    self.redraw = True
+
+            elif fileobj.is_link:
+                rootvcs = fileobj.vcs.rootvcs
+                realpath = os.path.realpath(fileobj.path)
+                if realpath == fileobj.vcs.root:
+                    has_vcschild = True
+                    if not rootvcs.rootinit and not self._is_targeted(rootvcs.obj):
+                        rootvcs.init_root()
+                        self.roots.add(rootvcs.path)
+                    fileobj.vcsstatus = rootvcs.obj.vcsstatus
+                    fileobj.vcsremotestatus = rootvcs.obj.vcsremotestatus
+                else:
+                    fileobj.vcsstatus = rootvcs.status_subpath(realpath)
+                self.redraw = True
+
+        return has_vcschild
+
     def _queue_process(self):  # pylint: disable=too-many-branches
         """Process queue: Initialize roots under dirobj"""
-        roots = set()
+        dirobjs = []
+        paths = set()
+        self.roots.clear()
+
         while True:
             try:
-                dirobj = self.queue.get(block=False)
+                dirobjs.append(self.queue.get(block=False))
             except queue.Empty:
                 break
 
-            if dirobj.vcs.track:
-                if dirobj.vcs.rootvcs.path not in roots \
-                        and dirobj.vcs.rootvcs.check_outdated() \
-                        and dirobj.vcs.rootvcs.update_root():
-                    roots.add(dirobj.vcs.rootvcs.path)
-                    dirobj.vcs.rootvcs.update_tree()
-                    self.redraw = True
-
-            if dirobj.files_all is None:
+        for dirobj in dirobjs:
+            if dirobj.path in paths:
                 continue
+            paths.add(dirobj.path)
 
-            has_vcschild = False
-            for fileobj in dirobj.files_all:
-                if not fileobj.is_directory or not fileobj.vcs or not fileobj.vcs.track:
-                    continue
-                if fileobj.vcs.is_root:
-                    has_vcschild = True
-                    if not fileobj.vcs.rootinit:
-                        fileobj.vcs.init_root()
-                        self.redraw = True
-                elif fileobj.is_link:
-                    if os.path.realpath(fileobj.path) == fileobj.vcs.root:
-                        has_vcschild = True
-                        if not fileobj.vcs.rootvcs.rootinit:
-                            fileobj.vcs.rootvcs.init_root()
-                        fileobj.vcsstatus = fileobj.vcs.rootvcs.obj.vcsstatus
-                        fileobj.vcsremotestatus = fileobj.vcs.rootvcs.obj.vcsremotestatus
-                    else:
-                        fileobj.vcsstatus = fileobj.vcs.rootvcs.status_subpath(
-                            os.path.realpath(fileobj.path))
+            if dirobj.vcs.track:
+                rootvcs = dirobj.vcs.rootvcs
+                if rootvcs.path not in self.roots \
+                        and rootvcs.check_outdated() and rootvcs.update_root():
+                    rootvcs.update_tree()
+                    self.roots.add(rootvcs.path)
                     self.redraw = True
 
+            has_vcschild = self._update_files(dirobj.files_all)
+
             if dirobj.has_vcschild != has_vcschild:
-                self.redraw = True
                 dirobj.has_vcschild = has_vcschild
+                self.redraw = True
 
     def run(self):
         while True: