Repository: qutebrowser/qutebrowser

Issue:
Undo after tab-detach reopens the detached tab
As `:tab-detach` currently closes the tab normally and then reopens it elsewhere, `:undo` will reopen the tab that was detached.



Discussion:
If this is implement then `:undo` should take a parameter, like `:undo close` or `:undo tab-dedetach` (the parameter being the command you would like to undo, or `:undo any` (default) for all).

Reason is because personally I don't think of ‘undo’ as ‘undo my last action’, I think of it as ‘undo close tab’.

@haasn This is a bug report saying that `:undo` _does_ kind-of-undo `:tab-detach` and it shouldn't.

Oh, I see :)


Resolving patch:
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -427,7 +427,7 @@ def tab_detach(self):
         url = self._current_url()
         self._open(url, window=True)
         cur_widget = self._current_widget()
-        self._tabbed_browser.close_tab(cur_widget)
+        self._tabbed_browser.close_tab(cur_widget, add_undo=False)
 
     def _back_forward(self, tab, bg, window, count, forward):
         """Helper function for :back/:forward."""
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -217,11 +217,12 @@ def shutdown(self):
         for tab in self.widgets():
             self._remove_tab(tab)
 
-    def close_tab(self, tab):
+    def close_tab(self, tab, *, add_undo=True):
         """Close a tab.
 
         Args:
             tab: The QWebView to be closed.
+            add_undo: Whether the tab close can be undone.
         """
         last_close = config.get('tabs', 'last-close')
         count = self.count()
@@ -229,7 +230,7 @@ def close_tab(self, tab):
         if last_close == 'ignore' and count == 1:
             return
 
-        self._remove_tab(tab)
+        self._remove_tab(tab, add_undo=add_undo)
 
         if count == 1:  # We just closed the last tab above.
             if last_close == 'close':
@@ -243,11 +244,12 @@ def close_tab(self, tab):
                 url = config.get('general', 'default-page')
                 self.openurl(url, newtab=True)
 
-    def _remove_tab(self, tab):
+    def _remove_tab(self, tab, *, add_undo=True):
         """Remove a tab from the tab list and delete it properly.
 
         Args:
             tab: The QWebView to be closed.
+            add_undo: Whether the tab close can be undone.
         """
         idx = self.indexOf(tab)
         if idx == -1:
@@ -261,8 +263,9 @@ def _remove_tab(self, tab):
                           window=self._win_id)
         if tab.url().isValid():
             history_data = tab.history.serialize()
-            entry = UndoEntry(tab.url(), history_data, idx)
-            self._undo_stack.append(entry)
+            if add_undo:
+                entry = UndoEntry(tab.url(), history_data, idx)
+                self._undo_stack.append(entry)
         elif tab.url().isEmpty():
             # There are some good reasons why a URL could be empty
             # (target="_blank" with a download, see [1]), so we silently ignore


Test patch: