rougier / elegant-emacs

A very minimal but elegant emacs (I think)
GNU General Public License v3.0
1.36k stars 79 forks source link

Can't Tell Which Buffer is Active #6

Open NickDaly opened 4 years ago

NickDaly commented 4 years ago

Elegant is a quite pretty theme that suffered from some usability issues when I tried it out. Most notably, if the user has multiple buffers open on screen at once there's no way to tell which one is selected and active. I was trying to read through a PDF in one buffer while making notes on it in the other buffer and I kept getting lost, because I would forget which buffer had focus.

If this, and the ability to show a small modeline across the bottom for display-battery-mode or the current org-clock, could be added, this might easily replace my current theme.

rougier commented 4 years ago

The theme has been mostly designed for a single buffer use and I did not find yet an elegant way to indicate which buffer is active.

terlar commented 4 years ago

A few ideas:

rougier commented 4 years ago

Thanks for the suggestion, I'll look into that. Dimming the header line seems the way to go but the proposed solution is not fully working from what I've read.

NickDaly commented 4 years ago

The solution I chose was to underline the active buffer with a black line, which isn't the prettiest but quick and obvious:

(set-face-attribute 'mode-line nil :height 10 :underline '"black" :overline nil :box nil :foreground (face-background 'default) :background (face-background 'default)) (set-face-attribute 'mode-line-inactive nil :height 10 :underline (face-foreground 'default) :overline nil :box nil :foreground (face-background 'default) :background (face-background 'default))

rougier commented 4 years ago

underline in the header line ? Does it always work ? even for split frames/window ?

mathiasdahl commented 4 years ago

One idea is to use a block cursor with blinking enabled. That makes inactive buffers show a non-blinking hollow block cursor while you have a filled and blinking block cursor in the active buffer. I also experimented with the idea from @NickDaly above:

(set-face-attribute 'mode-line nil
                    :height 10
                    :underline '"black"
                    :overline nil
                    :box t
                    :foreground '"gray"
                    :background '"black")

(set-face-attribute 'mode-line-inactive nil
                    :height 10
                    :underline '"gray"
                    :overline nil
                    :box nil
                    :foreground (face-background 'default)
                    :background (face-background 'default))

This looked quite good with the light mode. I get a think line (really a very thin rectangle) in the active buffer. Change the background color of the mode-line-active face to something more colorful if it helps you.

rougier commented 4 years ago

I tried dimmer and it's pretty good actually. There's one problem with underline/overline but apart from that, it works like a charm and you can control the level of dimming for inactive buffers.

terlar commented 3 years ago

Another solution to the mix, which perhaps could be inspected if it could help with displaying in the header-line as well:

phuhl commented 3 years ago

Here is what I did:

(defvar ml-selected-window nil)

;; Important changes start here
(defun ml-record-selected-window ()
  (setq ml-selected-window (selected-window)))
(defun ml-update-all ()
  (force-mode-line-update t))
(add-hook 'post-command-hook 'ml-record-selected-window)
(add-hook 'buffer-list-update-hook 'ml-update-all)
;; Important changes end here

(defun mode-line-render (left middle right)
  "Function to render the modeline LEFT to RIGHT."
  (let* ((ww (- (window-total-width) 4))
         (available-width-left
          (- (/ ww 2) (length left) (/ (length middle) -2)))
         (available-width-right
          (- ww (length left) available-width-left)))
    (format (format "%%s %%%ds %%%ds"
                    available-width-left
                    available-width-right)
            left middle right)))

(setq-default mode-line-format
   '((:eval
      (mode-line-render
       (format-mode-line
        (propertize "%m" 'face `(:inherit face-faded)))
       (format-mode-line
        (list
         (if (and buffer-file-name (buffer-modified-p))
             (propertize " *" 'face `(:inherit face-faded))
           "")
;; Important changes start here
         (if (eq ml-selected-window (selected-window))
             (propertize " %b " 'face `(:inherit face-strong))
           (propertize " %b " 'face `(:inherit face-faded)))
;; Important changes end here
         (if (and buffer-file-name (buffer-modified-p))
             (propertize "* " 'face `(:inherit face-faded)))))
       (format-mode-line
        (propertize "%4l:%2c" 'face `(:inherit face-faded)))))))

;; In elegant-light.el:
;; Important changes start here
(set-face-attribute 'face-strong nil :foreground "#333333"
        :weight 'bold)
;; Important changes end here

(and some other tweaks to display three columns in the mode line instead of two). The additional code for the bold title of the selected buffer is marked by the ";; Important changes start/end here" comments

Result: grafik

Also, I disabled the change of the cursor and re-enabled the blinking by removing these two lines:

(set-default 'cursor-type  '(bar . 1))
(blink-cursor-mode 0)

But that is more down to preference.

rougier commented 3 years ago

Thanks. I tried something like this a few weeks ago but it did not work. I think I was missing the force-mode-line-update. By the way, do you know if there is some "official" way to have to active/inactive faces like for the modeline ?

phuhl commented 3 years ago

do you know if there is some "official" way to have to active/inactive faces like for the modeline ?

No idea, tbh. I just googled and found a stack overflow answer that described, that you had to force-update the mode-line. But it works well for me so far.

The only issues I had so far are, that I don't know how to add the org-mode clocked-in info to the mode line, yet

Also, the width varies strangely, so that I had to add an additional character of spacing to the mode line to not make the mode-line be cut off at the end in some buffers.

Ah, btw, maybe a good idea in general is to use (window-total-width) instead of (window-width) as e.g. linum-mode makes the modeline smaller when using window-width instead of total-width.

rougier commented 3 years ago

I think thee problems have been fixed in nano emacs modeline (see line 112 and line 115)

phuhl commented 3 years ago

Cool, thanks 👍