summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/config/rc.conf2
-rw-r--r--ranger/core/actions.py47
2 files changed, 49 insertions, 0 deletions
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index 2f6aa2d9..4da1ffc0 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -520,6 +520,8 @@ map <a-6>     tab_open 6
 map <a-7>     tab_open 7
 map <a-8>     tab_open 8
 map <a-9>     tab_open 9
+map <a-r>     tab_shift 1
+map <a-l>     tab_shift -1
 
 # Sorting
 map or set sort_reverse!
diff --git a/ranger/core/actions.py b/ranger/core/actions.py
index 1c5459d0..40fd52a3 100644
--- a/ranger/core/actions.py
+++ b/ranger/core/actions.py
@@ -1262,6 +1262,53 @@ class Actions(  # pylint: disable=too-many-instance-attributes,too-many-public-m
             i += 1
         return self.tab_open(i, path)
 
+    def tab_shift(self, offset=0, to=None):  # pylint: disable=invalid-name
+        """Shift the tab left/right
+
+        Shift the current tab to the left or right by either:
+        offset - changes the tab number by offset
+        to - shifts the tab to the specified tab number
+        """
+
+        oldtab_index = self.current_tab
+        if to is None:
+            assert isinstance(offset, int)
+            # enumerated index (1 to 9)
+            newtab_index = oldtab_index + offset
+        else:
+            assert isinstance(to, int)
+            newtab_index = to
+        # shift tabs without enumerating, preserve tab numbers when can
+        if newtab_index != oldtab_index:
+            # the other tabs shift in the opposite direction
+            if (newtab_index - oldtab_index) > 0:
+                direction = -1
+            else:
+                direction = 1
+
+            def tabshiftreorder(source_index):
+                # shift the tabs to make source_index empty
+                if source_index in self.tabs:
+                    target_index = source_index + direction
+                    # make the target_index empty recursively
+                    tabshiftreorder(target_index)
+                    # shift the source to target
+                    source_tab = self.tabs[source_index]
+                    self.tabs[target_index] = source_tab
+                    del self.tabs[source_index]
+
+            # first remove the current tab from the dict
+            oldtab = self.tabs[oldtab_index]
+            del self.tabs[oldtab_index]
+            # make newtab_index empty by shifting
+            tabshiftreorder(newtab_index)
+            self.tabs[newtab_index] = oldtab
+            self.current_tab = newtab_index
+            self.thistab = oldtab
+            self.ui.titlebar.request_redraw()
+            self.signal_emit('tab.layoutchange')
+        return None
+
     def tab_switch(self, path, create_directory=False):
         """Switches to tab of given path, opening a new tab as necessary.
 
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239