4

I'm trying to hide the modeline whenever helm pops up. I have configure helm to always show up at the bottom. It should look like this (two windows above the helm completion window):

enter image description here

Opposed of the regular way, where modelines from *scratch* and test.el buffer are shown like this:

enter image description here

I want to hide the modeline only in the bottom windows so if there are other windows above, their modeline should still be visible like this (three windows above the helm completion window):

enter image description here

I have written the following code to achieve this:

(defun toggle-mode-line ()
  "toggles the visibility of modeline in bottom windows"
  (interactive)
  (dolist (current-window (window-list))
    (with-current-buffer (window-buffer current-window)
      (unless (window-in-direction 'below current-window)
        (setq mode-line-format 
              (unless mode-line-format
                (default-value 'mode-line-format)))))))

Now this has to be called before helm is activated to make the modeline invisible and after helm was activated it has to be called again to make it visible again. So far the following code works for hiding it:

(add-hook 'helm-before-initialize-hook 'helm-toggle-mode-line) 

But I couldn't find a way to make it visible again when the completion buffer is gone. This does not work:

(add-hook 'helm-exit-minibuffer-hook 'toggle-mode-line)

And this does not work, too:

(add-hook 'helm-cleanup-hook 'toggle-mode-line) 

What's the proper way to achieve this?

EDIT:

The following works if I select a command in the helm completion buffer:

(add-hook 'helm-before-action-hook 'toggle-mode-line)

But I still don't know how to make it visible again when I quit with C-g or calling helm-keyboard-quit. I tried this but it dosen't work:

(define-key helm-map (kbd "C-q") 'my-helm-keyboard-quit)

(defun my-helm-keyboard-quit ()
  (interactive)
  (helm-keyboard-quit)
  (message "this and the line below is not called for some reason")
  (toggle-mode-line))
  • Do you mean helm-buffer (that is, the completing buffer) by saying "all bottom windows"? I ask this because the helm-buffer can be placed in anywhere by using different user configs, not just the bottom. – xuchunyang Sep 1 '15 at 17:07
  • @xuchunyang I have added a picture to clarify. – clemera Sep 1 '15 at 19:05
  • @xuchunyang And another one. Hope it is clearer now. – clemera Sep 1 '15 at 19:14
  • It's clear enough to me now. How do you make the helm completion window always in the bottom? it isn't the default behavior of helm, for all I know, there is no user option for it. In your my-helm-keyboard-quit, code after helm-keyboard-quit didn't work because it had been terminated in helm-keyboard-quit, it is like: you are unable to cleanup after you have killed your app. – xuchunyang Sep 1 '15 at 21:12
  • @xuchunyang Thanks, I understand any idea how I could do it then? I tried advicing helm-keyboard-quit but it's the same problem. I use shackle for showing helm always at the bottom. This the shackle-rule I use: ("\`\\*helm.*?\\*\\'" :regexp t :align below :ratio 0.4) – clemera Sep 1 '15 at 21:25
4
;; 1. Collect bottom buffers
(defvar bottom-buffers nil
  "List of bottom buffers before helm session.
    Its element is a pair of `buffer-name' and `mode-line-format'.")

(defun bottom-buffers-init ()
  (when bottom-buffers
    (bottom-buffers-show-mode-line))
  (setq bottom-buffers
        (cl-loop for w in (window-list)
                 when (window-at-side-p w 'bottom)
                 collect (with-current-buffer (window-buffer w)
                           (cons (buffer-name) mode-line-format)))))

(add-hook 'helm-before-initialize-hook #'bottom-buffers-init)

;; 2. Hide mode line
(defun bottom-buffers-hide-mode-line ()
  (mapc (lambda (elt)
          (with-current-buffer (car elt)
            (setq-local mode-line-format nil)))
        bottom-buffers))

(add-hook 'helm-after-initialize-hook #'bottom-buffers-hide-mode-line)

;; 3. Restore mode line
(defun bottom-buffers-show-mode-line ()
  (when bottom-buffers
    (mapc (lambda (elt)
            (with-current-buffer (car elt)
              (setq-local mode-line-format (cdr elt))))
          bottom-buffers)
    (setq bottom-buffers nil)))

(add-hook 'helm-exit-minibuffer-hook #'bottom-buffers-show-mode-line)

(defun helm-keyboard-quit-advice (orig-func &rest args)
  (bottom-buffers-show-mode-line)
  (apply orig-func args))

(advice-add 'helm-keyboard-quit :around #'helm-keyboard-quit-advice)

enter image description here

1

The display has to be updated after the mode-line modification with (redraw-display):

(defun toggle-mode-line ()
      "toggles the visibility of modeline in bottom windows"
      (interactive)
      (dolist (current-window (window-list))
        (with-current-buffer (window-buffer current-window)
          (unless (window-in-direction 'below current-window)
            (setq mode-line-format
                  (unless mode-line-format
                    (default-value 'mode-line-format))))))
      (redraw-display))

As @xuchunyang has noted my-helm-keyboard-quit does not work because everything is stopped before toggle-mode-line is executed. To make it work after quitting helm I used the following:

(defun helm-keyboard-quit-advice (orig-func &rest args)
  (interactive)
  (run-with-timer .03 nil 'toggle-mode-line)
  (apply orig-func args))


(advice-add 'helm-keyboard-quit :around #'helm-keyboard-quit-advice)
0

If you really want to hide helm's informative mode line, try this:

;;; Don't use helm's own displaying mode line function
(fset 'helm-display-mode-line #'ignore)

(add-hook 'helm-after-initialize-hook
          (defun hide-mode-line-in-helm-buffer ()
            "Hide mode line in `helm-buffer'."
            (with-helm-buffer
              (setq-local mode-line-format nil))))

BTW, you might also want to hide minibuffer content when turning on helm-echo-input-in-header-line:

(setq helm-echo-input-in-header-line t)
;;; Hide minibuffer contents when the above option is on.
(add-hook 'helm-minibuffer-set-up-hook
          #'helm-hide-minibuffer-maybe)
  • Thanks for your help but you have misunderstood my question. I want to hide the modeline of the buffers above the helm completion buffer (like shown in the picture). I already have achieved this with my code but have still dificulties showing them again when the helm completion buffer is gone. – clemera Sep 1 '15 at 18:49
  • I already have the helm-echo-input-in-header-line set to true. Please take a look at the new pictures, I have added to the question. – clemera Sep 1 '15 at 19:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.