Repository: qutebrowser/qutebrowser

Issue:
Show when in insert mode when using 'ui hide-statusbar true'
I have the statusbar hidden apart from when there's a message/download.  However, its sometimes difficult to remember whether i've left a window in insert mode, or also whether I've entered it, having a similar effect to leaving caps-lock on in vim where, before you realise, you've already clicked a load of things.
As such, it would be nice if the big green statusbar or even just a little icon would pop up when insert mode is active as an exception for hide-statusbar mode.



Discussion:
I'm interested in this as well. Rather than have a single option to show the status bar in insert mode, it would be better to allow options to be attached to specific modes, something which I think should be part of the config revolution: https://github.com/The-Compiler/qutebrowser/issues/499#issuecomment-237445402. This would also remove the need for a billion `statusbar.fg.mode` and `statusbar.bg.mode` color options.

The config revolution could take a long time to arrive, unfortunately.

Actually, can't `-- INSERT MODE --` be implemented as a "persistent message"? That would make the indicator always shown, regardless of the way colors are configured. There is already some message queue, which by the way has some strange priorities - when there is both `-- INSERT MODE --` indicator and a warning, the warning message wins, but is shown on green background.

Has any progress been made towards this?
@kontheocharis I don't think anyone has been working on this.

Resolving patch:
diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py
--- a/qutebrowser/config/configfiles.py
+++ b/qutebrowser/config/configfiles.py
@@ -332,6 +332,11 @@ def migrate(self) -> None:
             new_name='tabs.mode_on_change',
             true_value='persist',
             false_value='normal')
+        self._migrate_renamed_bool(
+            old_name='statusbar.hide',
+            new_name='statusbar.show',
+            true_value='never',
+            false_value='always')
 
         for setting in ['tabs.title.format',
                         'tabs.title.format_pinned',
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -68,6 +68,14 @@ class NotInModeError(Exception):
     """Exception raised when we want to leave a mode we're not in."""
 
 
+class UnavailableError(Exception):
+
+    """Exception raised when trying to access modeman before initialization.
+
+    Thrown by instance() if modeman has not been initialized yet.
+    """
+
+
 def init(win_id: int, parent: QObject) -> 'ModeManager':
     """Initialize the mode manager and the keyparsers for the given win_id."""
     modeman = ModeManager(win_id, parent)
@@ -169,8 +177,16 @@ def init(win_id: int, parent: QObject) -> 'ModeManager':
 
 
 def instance(win_id: Union[int, str]) -> 'ModeManager':
-    """Get a modemanager object."""
-    return objreg.get('mode-manager', scope='window', window=win_id)
+    """Get a modemanager object.
+
+    Raises UnavailableError if there is no instance available yet.
+    """
+    mode_manager = objreg.get('mode-manager', scope='window', window=win_id,
+                              default=None)
+    if mode_manager is not None:
+        return mode_manager
+    else:
+        raise UnavailableError("ModeManager is not initialized yet.")
 
 
 def enter(win_id: int,
diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py
--- a/qutebrowser/mainwindow/statusbar/bar.py
+++ b/qutebrowser/mainwindow/statusbar/bar.py
@@ -203,7 +203,7 @@ def __repr__(self):
 
     @pyqtSlot(str)
     def _on_config_changed(self, option):
-        if option == 'statusbar.hide':
+        if option == 'statusbar.show':
             self.maybe_hide()
         elif option == 'statusbar.padding':
             self._set_hbox_padding()
@@ -254,12 +254,26 @@ def _draw_widgets(self):
     @pyqtSlot()
     def maybe_hide(self):
         """Hide the statusbar if it's configured to do so."""
+        strategy = config.val.statusbar.show
         tab = self._current_tab()
-        hide = config.val.statusbar.hide
-        if hide or (tab is not None and tab.data.fullscreen):
+        if tab is not None and tab.data.fullscreen:
             self.hide()
-        else:
+        elif strategy == 'never':
+            self.hide()
+        elif strategy == 'in-mode':
+            try:
+                mode_manager = modeman.instance(self._win_id)
+            except modeman.UnavailableError:
+                self.hide()
+            else:
+                if mode_manager.mode == usertypes.KeyMode.normal:
+                    self.hide()
+                else:
+                    self.show()
+        elif strategy == 'always':
             self.show()
+        else:
+            raise utils.Unreachable
 
     def _set_hbox_padding(self):
         padding = config.val.statusbar.padding
@@ -336,6 +350,8 @@ def set_text(self, val):
     def on_mode_entered(self, mode):
         """Mark certain modes in the commandline."""
         mode_manager = modeman.instance(self._win_id)
+        if config.val.statusbar.show == 'in-mode':
+            self.show()
         if mode_manager.parsers[mode].passthrough:
             self._set_mode_text(mode.name)
         if mode in [usertypes.KeyMode.insert,
@@ -350,6 +366,8 @@ def on_mode_entered(self, mode):
     def on_mode_left(self, old_mode, new_mode):
         """Clear marked mode."""
         mode_manager = modeman.instance(self._win_id)
+        if config.val.statusbar.show == 'in-mode':
+            self.hide()
         if mode_manager.parsers[old_mode].passthrough:
             if mode_manager.parsers[new_mode].passthrough:
                 self._set_mode_text(new_mode.name)


Test patch: