Update linum and linum-relative background on color theme change in emacs/spacemacs - emacs

Trying to get the line numbering right aligned with a separator space and the same background color as the line highlighting in Spacemacs was quite complicated. Specialy when it came to do both at the same time in linum and linum-relative.
I don't know if this code is ok, but it manages so far:
(defun dotspacemacs/user-config ()
"Configuration function for user code.
This function is called at the very end of Spacemacs initialization after
layers configuration. You are free to put any user code."
(global-linum-mode t)
(unless window-system
(add-hook 'linum-before-numbering-hook
(lambda ()
(setq-local my-linum-format-fmt
(let ((w (length (number-to-string
(count-lines (point-min) (point-max))))))
(concat "%" (number-to-string w) "d"))))
(set-face-attribute 'linum nil
:background (face-background 'hl-line nil t))))
(defface my-linum-hl
`((t :inherit linum :background ,(face-background 'hl-line nil t)))
"Face for the current line number."
:group 'linum)
(defun my-linum-format-func (line)
(concat
(propertize (format my-linum-format-fmt line) 'face 'my-linum-hl)
(propertize " " 'face 'my-linum-hl)))
(unless window-system
(setq linum-format 'my-linum-format-func))
;; linum-relative
(linum-relative-toggle)
(unless window-system
(setq-local my-linum-relative-format-fmt
(let ((w (length (number-to-string
(count-lines (point-min) (point-max))))))
(concat "%" (number-to-string w) "s "))))
(unless window-system
(setq linum-relative-format my-linum-relative-format-fmt))
)
Problem is: The numbers background color don't change to the correct one when I change the theme while inside Emacs. The color remains the same. How do I make emacs update the linum and linum-relative background color after a color theme change?

Related

How to keep proper visual alignment of marker with window size changes?

I have the following elisp function and its hook...
(defun org-fontify-proof-blocks ()
(interactive)
(add-to-list 'font-lock-extra-managed-props 'display)
(let ((margin-format (format "%%%ds" left-margin-width)))
(font-lock-add-keywords nil
`(
("^#\\+begin_proof.*?\\(\n\\)"
1 '(face nil display " "))
("^\\(#\\+begin_proof.*$\\)"
1 '(face nil display ,(propertize "Proof." 'face '(:inherit bold))))
("\\(#\\+end_proof.*\\)$"
1 '(face nil display ,(propertize (concat (make-string (- (window-width) (string-width "⏹")) ?\ ) "⏹") 'face '(:inherit bold))))
)))
(font-lock-fontify-buffer))
(add-hook 'org-mode-hook #'org-fontify-proof-blocks)
This results in the proof variant of the org-special-block, given by...
#+begin_proof
<contents>
#+end_proof
getting fontified as
Proof. <contents>
⏹
The problem is that the alignment of the QED symbold (⏹) gets messed up when changing window size. How can I go about fixing this issue?
I have tried
(add-hook 'window-size-change-functions #'org-fontify-proof-blocks)
which did not really seem to do anything.
I also tried
(add-hook 'window-configuration-change-hook
(lambda ()
(with-current-buffer (current-buffer)
(org-fontify-proof-blocks))))
and
(add-hook 'window-configuration-change-hook #'org-fontify-proof-blocks)
which only seemed to keep the improper alignment after switching back to the original window size.

Emacs - No line numbering for empty lines

I'm trying to setup line numbering in Emacs.
Linum works well, but when I open two buffers, numbering for empty lines disappears.
I use Manjaro Linux. Emacs works in the terminal.
Here's screenshot.
Code from .emacs file:
(add-hook 'find-file-hook (lambda () (linum-mode 1)))
(unless window-system
(add-hook 'linum-before-numbering-hook
(lambda ()
(setq-local linum-format-fmt
(let ((w (length (number-to-string
(count-lines (point-min) (point-max))))))
(concat "%"(number-to-string w) "d"))))))
(defun linum-format-func (line)
(concat
(propertize (format linum-format-fmt line) 'face 'linum)
(propertize " " 'face 'mode-line)))
(unless window-system
(setq linum-format 'linum-format-func))
How can I fix it?
You might be able to fix this by replacing all of the above code with just
(global-linum-mode 1)
linum-mode should already do the variable-size-format thing for
you. Don't know why you're reinventing the wheel.
Maybe your problem is that you're trying to string concat two propertize-d objects. You can avoid this by making your formatting like "%3d " instead of "%3d" and concatting " " later:
(add-hook 'find-file-hook (lambda () (linum-mode 1)))
(unless window-system
(add-hook 'linum-before-numbering-hook
(lambda ()
(setq-local linum-format-fmt
(let ((w (length (number-to-string
(count-lines (point-min) (point-max))))))
(concat "%" (number-to-string w) "d "))))))
(defun linum-format-func (line)
(propertize (format linum-format-fmt line) 'face 'linum))
(unless window-system
(setq linum-format 'linum-format-func))

Configure Linum mode to not show whitespace symbols in whitespace mode?

Currently my buffer with linum mode and white space mode enabled looks like this:
How do I configure the linum region to not render the whitespace symbols?
Observation: There is no need for spaces to the right of the line numbers (as shown in the question), because the fringe width can be used to control separation between the line numbers and the body.
(setq-default left-fringe-width 10)
(setq-default right-fringe-width 0)
(set-face-attribute 'fringe nil :background "black")
Option # 1: However, this is not flush-right.
(setq linum-format "%d")
Option # 2: Use leading zeros -- is flush-right.
(eval-after-load 'linum
'(progn
(defface linum-leading-zero
`((t :inherit 'linum
:foreground ,(face-attribute 'linum :background nil t)))
"Face for displaying leading zeroes for line numbers in display margin."
:group 'linum)
(defun linum-format-func (line)
(let ((w (length
(number-to-string (count-lines (point-min) (point-max))))))
(concat
(propertize (make-string (- w (length (number-to-string line))) ?0)
'face 'linum-leading-zero)
(propertize (number-to-string line) 'face 'linum))))
(setq linum-format 'linum-format-func)))
You could improve #lawlists second solution, but instead of using 0s as a space replacement, you can use some exotic whitespace like the en-space which would be "\u2002". Since we aren't using proportional fonts that will look just like a space, but whitespace won't mess with it.
I'm actually using linum-relative-mode where you can conveniently just advice linum-relative:
(advice-add 'linum-relative :filter-return
(lambda (num)
(if (not (get-text-property 0 'invisible num))
(propertize (replace-regexp-in-string " " "\u2002" num)
'face (get-text-property 0 'face num)))))

Change the color of the mode-line depending on buffer state

Is there a way to dynamically change the color of the mode-line depending on specific conditions e.g. change color if I'm in narrowed view and to a different color if the buffer is read-only
Thank you very much!
You can use a post-command-hook and then just evaluate whatever you need and set the mode-line face color. I do this to change between 3 colors depending on which evil-mode state I'm in and if the buffer has any unsaved changes.
(lexical-let ((default-color (cons (face-background 'mode-line)
(face-foreground 'mode-line))))
(add-hook 'post-command-hook
(lambda ()
(let ((color (cond ((minibufferp) default-color)
((evil-insert-state-p) '("#e80000" . "#ffffff"))
((evil-emacs-state-p) '("#af00d7" . "#ffffff"))
((buffer-modified-p) '("#006fa0" . "#ffffff"))
(t default-color))))
(set-face-background 'mode-line (car color))
(set-face-foreground 'mode-line (cdr color))))))
I use this code. It colors the buffer-modified indicator on the left orange if it's read-only and red if it's modified. When you narrow a buffer it colors the line number indicator yellow. Obviously you might want to change the format yourself.
(defface my-narrow-face
'((t (:foreground "black" :background "yellow3")))
"todo/fixme highlighting."
:group 'faces)
(defface my-read-only-face
'((t (:foreground "black" :background "orange3")))
"Read-only buffer highlighting."
:group 'faces)
(defface my-modified-face
'((t (:foreground "gray80" :background "red4")))
"Modified buffer highlighting."
:group 'faces)
(setq-default
mode-line-format
'(" "
(:eval (let ((str (if buffer-read-only
(if (buffer-modified-p) "%%*" "%%%%")
(if (buffer-modified-p) "**" "--"))))
(if buffer-read-only
(propertize str 'face 'my-read-only-face)
(if (buffer-modified-p)
(propertize str 'face 'my-modified-face)
str))))
(list 'line-number-mode " ")
(:eval (when line-number-mode
(let ((str "L%l"))
(if (/= (buffer-size) (- (point-max) (point-min)))
(propertize str 'face 'my-narrow-face)
str))))
" %p"
(list 'column-number-mode " C%c")
" " mode-line-buffer-identification
" " mode-line-modes))

Highlight which of the file names in emacs buffer are missing

In GNU Emacs, I could use something like a hypothetical "flyexist.el" - I have a buffer with absolute (Unix) file names in it (plus some additional text around them). Most of those files exist, but some are missing. I would like to run a function that highlights me the missing files (maybe with a red overlay). This function would need to figure out which of the text in the buffer looks like a file name (some false positives are okay) and then work on it with file-exists-p.
For example, assume that my buffer contains
Some random text mentioning /file/that/does/exist.txt,
some more random text, and a /file/that/does/not-exist.txt
I want to have the second file highlighted.
Does something like this exist already?
I am new to emacs hacking... Here is my "minor-mode" version.
(defvar filehi-path-re "\\([/$][[:alnum:]$-_.]+\\)+"
"Regexp used for path matching.")
(defface filehi-file-existing
'((t (:foreground "White" :background "Green")))
"Face for existing files.")
(defface filehi-file-missing
'((t (:foreground "Yellow" :background "Red")))
"Face for missing files.")
(defun filehi-check-and-highlight (start end)
"Check if substring is existing file path and highlight it."
(remove-overlays start end 'name 'filehi-highlight)
(let ((overlay (make-overlay start end)))
(overlay-put overlay 'name 'filehi-highlight)
(overlay-put overlay 'face (if (file-exists-p (substitute-in-file-name
(buffer-substring start end)))
'filehi-file-existing
'filehi-file-missing))))
(defun filehi-highlight-file-paths (&optional start end _ignore)
"Run through the buffer and highliht file paths."
(save-excursion
(save-match-data ; fixes problem with dabbrev (and may be more...)
(remove-overlays (point-min) end 'name 'filehi-highlight)
(let ((prev-end (point-min)))
(goto-char (point-min)) ; FIXME use something like greedy
; search-backward
(while (and (<= (point) end)
(re-search-forward filehi-path-re nil t))
(filehi-check-and-highlight (match-beginning 0) (match-end 0)))))))
(define-minor-mode filehi-mode
"Minor mode for highlighting existing file paths.
May conflict with other modes..."
nil " Filehi" nil
(if filehi-mode
(progn ; enable mode
(make-local-hook 'after-change-functions)
(filehi-highlight-file-paths (point-min) (point-max))
(add-hook 'after-change-functions 'filehi-highlight-file-paths nil t))
; disable mode
(remove-hook 'after-change-functions 'filehi-highlight-file-paths t)
(remove-overlays (point-min) (point-max) 'name 'filehi-highlight)))
Try with this (you have to trigger it manually though, or incorporate it into some other periodical routine):
(defun x-mark-missing-files ()
(interactive)
(save-excursion
(while (search-forward-regexp "~?/[A-Za-z./-]+")
(when (not (file-exists-p (match-string 0)))
(overlay-put
(make-overlay (match-beginning 0) (match-end 0))
'face '(:background "red"))))))
Play a little with the filename regexp to get it right how you want it.