Revert display mapping in whitespace-mode? - emacs

I would like to make the display mappings and face attributes to be updated if i were to change them after invoking M-x whitespace-mode. I would like to do so to make the code below work. If I don't include the add-hook and try setting the faces before I enter whitespace-mode it tells me that the face is invalid.
;; configure custom whitespace faces
(add-hook 'whitespace-mode-hook (lambda ()
(set-face-attribute 'whitespace-space nil :background nil :foreground color)
(set-face-attribute 'whitespace-tab nil :background nil :foreground color)
(set-face-attribute 'whitespace-newline nil :background nil :foreground color)
(whitespace-reload) ;; what i want to do
)))
Any help appreciated. Thanks.

Just using whitespace-mode in .emacs worked.
;; ... add-hook 'n all
(whitespace-mode 1)(whitespace-mode 0)

Related

Evil mode has unpredictable behavior when using compile

I have this issue, where whenever I run the compile command evil mode creates a new window instead of using the windows on the screen which the normal compile command would or it would compile on the current window I am on.
Take the following images as examples:
Without evil mode, if I have 2 windows open in a split and I am on a window on the left and I run M-x compile and specify an argument (assume it will be a batch script called build.bat) emacs will use the screen on the right as shown in this image:
https://i.stack.imgur.com/LeoMm.png
The .emacs is:
(require 'ido)
(require 'compile)
(ido-mode t)
; Compilation
(defun make-without-asking ()
(interactive)
(switch-to-buffer-other-window "*compilation*")
(compile "build.bat")
(other-window 1))
(define-key global-map "\em" 'make-without-asking)
(add-to-list 'default-frame-alist '(font . "Liberation Mono-11.5"))
(set-face-attribute 'default t :font "Liberation Mono-11.5")
(set-face-attribute 'font-lock-builtin-face nil :foreground "#DAB98F")
(set-face-attribute 'font-lock-comment-face nil :foreground "gray50")
(set-face-attribute 'font-lock-constant-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-doc-face nil :foreground "gray50")
(set-face-attribute 'font-lock-function-name-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-keyword-face nil :foreground "DarkGoldenrod3")
(set-face-attribute 'font-lock-string-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-type-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-variable-name-face nil :foreground "burlywood3")
(menu-bar-mode -1)
(set-foreground-color "burlywood3")
(set-background-color "#161616")
(set-cursor-color "#40FF40")
However, as soon as I add evil mode the behavior becomes unpredictable as it would sometimes create a new window or it will compile on the window I am on.
In the following example I am on the window on the right with evil mode enabled and when I run M-x compile with build.bat as the argument (like before), evil mode compiles the code and shows the *compilation* buffer on the same window instead of using the window on the left:
https://i.stack.imgur.com/MdNpg.png
The .emacs with evil mode enabled is:
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(require 'package)
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(setq package-selected-packages '(evil))
(package-install-selected-packages)
(require 'ido)
(require 'compile)
(require 'evil)
(evil-mode 1)
(ido-mode t)
; Compilation
(defun make-without-asking ()
(interactive)
(switch-to-buffer-other-window "*compilation*")
(compile "build.bat")
(other-window 1))
(define-key global-map "\em" 'make-without-asking)
(add-to-list 'default-frame-alist '(font . "Liberation Mono-11.5"))
(set-face-attribute 'default t :font "Liberation Mono-11.5")
(set-face-attribute 'font-lock-builtin-face nil :foreground "#DAB98F")
(set-face-attribute 'font-lock-comment-face nil :foreground "gray50")
(set-face-attribute 'font-lock-constant-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-doc-face nil :foreground "gray50")
(set-face-attribute 'font-lock-function-name-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-keyword-face nil :foreground "DarkGoldenrod3")
(set-face-attribute 'font-lock-string-face nil :foreground "olive drab")
(set-face-attribute 'font-lock-type-face nil :foreground "burlywood3")
(set-face-attribute 'font-lock-variable-name-face nil :foreground "burlywood3")
(menu-bar-mode -1)
(set-foreground-color "burlywood3")
(set-background-color "#161616")
(set-cursor-color "#40FF40")
I just switched over to neovim and setup this functionlity using vimscript, it was much easier.

How to make line numbers not touch the text of text in emacs

Here is a picture of the problem:
And I changed the background colour of the line numbers using:
(set-face-attribute 'linum nil :background "gray20")
(setq linum-format "%3d ")
(by the way I had to use gray20, #272822 made everything green...)
Notice how the line numbers touch the text. Is there a way to stop this?
(global-linum-mode 1)
(setq-default left-fringe-width 30)
(setq-default right-fringe-width 0)
(set-face-attribute 'fringe nil :background "black")
(set-face-attribute 'default nil :background "black"
:foreground "white" :font "Courier" :height 180)

How to change modeline color with active minibuffer and switch to other-window

Within the same frame and with an active minibuffer, can anyone think of a way to have switch to other-window behave similar to a minibuffer-exit-hook (without completely exiting the minibuffer)?
Essentially, I'd like to have the main windows show an inactive modeline color when focus is in the minibuffer, and then update the modline to active (for a window that has focus) when I move from the semi-active minibuffer to another window using other-window.
For example, there are two windows open in the same frame (side by side) -- Window # 1 are my notes -- Window # 2 is a Big Brother Database display of a record that I want to modify. So I open the minibuffer to input my record modification and then switch back and forth between my notes in Window # 1 and the minibuffer to copy and paste the relevant portions. When using other-window to jump between the three areas, it is still difficult to know whether focus is in the minibuffer or another window.
Window # 1 (notes)         | Window # 2 (bbdb record display)
                           |
___________________________|_____________________________________
Name: lawlist . . .
(defun enter-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black")
(set (make-local-variable 'face-remapping-alist)
'((default :background "gray10" :foreground "yellow"))))
(defun exit-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70"))
(add-hook 'minibuffer-setup-hook 'enter-minibuffer-setup)
(add-hook 'minibuffer-exit-hook 'exit-minibuffer-setup)
One option would be to "advise" the other-window function to execute some form when switching to the minibuffer.
For example, the following code will turn the minibuffer prompt green when you cycle back to it using other-window, and if you land on a non minibuffer window it turns the prompt grey:
(defadvice other-window (after adv-other-window-minibuffer
(COUNT &optional ALL-FRAMES))
"Make minibuffer prompt green when switched to"
(if (minibufferp)
(set-face-attribute 'minibuffer-prompt nil
:foreground "green" :background "black")
(set-face-attribute 'minibuffer-prompt nil
:foreground "dark grey" :background "black")))
(ad-activate 'other-window)
Of course you are not limited to just setting the minibuffer prompt, but it's not clear to me exactly what effect your are trying to achieve.
Updated draft -- borrowing (minibufferp) from #Carl Groner
(defun enter-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black")
(set (make-local-variable 'face-remapping-alist)
'((default :background "black" :foreground "yellow")))
(set-face-attribute 'minibuffer-prompt nil
:background "black" :foreground "cyan"))
(defun exit-minibuffer-setup ()
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70")
(set-face-attribute 'minibuffer-prompt nil
:background "black" :foreground "cyan"))
(add-hook 'minibuffer-setup-hook 'enter-minibuffer-setup)
(add-hook 'minibuffer-exit-hook 'exit-minibuffer-setup)
(defun lawlist-minibuffer-conditions ()
(cond
((minibufferp)
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black")
(set-face-attribute 'minibuffer-prompt nil
:background "black" :foreground "cyan"))
(t
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70")
(set-face-attribute 'minibuffer-prompt nil
:background "black" :foreground "gray70")) ))
(defun lawlist-forward-window ()
(interactive)
(other-window 1)
(lawlist-minibuffer-conditions))
(defun lawlist-backward-window ()
(interactive)
(other-window -1)
(lawlist-minibuffer-conditions))

Change Emacs Mode-Line color based on major-mode

I like to see if there is a way to change the mode-link foreground and background color base on the major-mode,
I was thinking to add the logic in the
(add-hook 'after-change-major-mode-hook
But, I do not have all the emacs lisp experience to make such change. Here is the logic:
switch major-mode:
case "emacs-lisp-mode":
(set-face-foreground 'mode-line "ivory")
(set-face-background 'mode-line "DarkOrange2")
case "ruby-mode":
(set-face-foreground 'mode-line "white")
(set-face-background 'mode-line "red")
...
default:
(set-face-foreground 'mode-line "black")
(set-face-background 'mode-line "white")
end switch
Many thanks in advance!.
You probably want something like:
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(face-remap-add-relative
'mode-line '((:foreground "ivory" :background "DarkOrange2") mode-line))))
You might want to use face-remap for the mode-line-inactive face as well.
"The logic" you are talking about is something like this:
(add-hook 'after-change-major-mode-hook 'my-set-mode-line-colors)
(defvar my-mode-line-colors
'((emacs-lisp-mode :foreground "ivory" :background "DarkOrange2")
(ruby-mode :foreground "white" :background "red")))
(defun my-set-mode-line-colors ()
(face-remap-add-relative
'mode-line (list (or (cdr (assq major-mode my-mode-line-colors))
'(:foreground "black" :background "white"))
'mode-line)))
Alternatively, you can do that from mode-specific hooks, as suggested by Stefan.

Custom background for active window

How can I configure a different background color for the active window in Emacs?
Try Yoshida's hiwin-mode (visible active window mode): https://github.com/yoshida-mediba/hiwin-mode
If by "window" you mean Emacs' definition of windows, i.e., panes, not really.
If by "window" you mean everyone else's conception of windows, which Emacs calls frames, then yes. Here's an example:
(defadvice handle-switch-frame (around switch-frame-set-background)
(set-background-color "white")
ad-do-it
(set-background-color "yellow"))
(ad-activate 'handle-switch-frame)
(defadvice delete-frame (after delete-frame-set-background)
(set-background-color "yellow"))
(ad-activate 'delete-frame)
Here is an alternative using the modeline inactive color matching the background so the only modeline with color is the active window. I have a hooks for the minibuffer enter and exit, and also when switching windows. I use bold for certain modeline things like read only and the file name, so that the a different color doesn't stand out when switching windows. When I enter the minibuffer, the active window modeline turns to inactive until I exit the minibuffer, or when I switch from an active minibuffer (leaving it open) to another window. I had to set the modeline background box to match also.
(set-face-attribute 'default nil :background "black" :foreground "white"
:font "Courier" :height 180)
(set-face-attribute 'mode-line nil
:height 160 ;; affects everything
:foreground "black" :background "gray70")
(set-face-attribute 'mode-line-inactive nil
:foreground "gray70" :background "black" :box '(:line-width 1 :color "black"))
(defun enter-minibuffer-setup ()
(whitespace-mode t)
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black" :box '(:line-width 1 :color "black"))
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "cyan")
(set (make-local-variable 'face-remapping-alist)
'((default :background "black" :foreground "yellow"))) )
(defun exit-minibuffer-setup ()
(cond
((or save-as-variable multi-extract-variable multi-attach-variable)
(set-face-attribute 'mode-line nil :height 160 :foreground "black" :background "#eab700"))
(t (set-face-attribute 'mode-line nil :height 160 :foreground "black" :background "gray70" :box nil)))
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "cyan"))
(add-hook 'minibuffer-setup-hook 'enter-minibuffer-setup)
(add-hook 'minibuffer-exit-hook 'exit-minibuffer-setup)
(defun lawlist-minibuffer-conditions ()
(cond
((minibufferp)
(set-face-attribute 'mode-line nil
:height 160 :foreground "gray70" :background "black" :box '(:line-width 1 :color "black"))
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "cyan"))
(t
(set-face-attribute 'mode-line nil
:height 160 :foreground "black" :background "gray70")
(set-face-attribute 'minibuffer-prompt nil :background "black" :foreground "gray70")) ))
(defun lawlist-forward-window ()
(interactive)
(other-window 1)
(lawlist-minibuffer-conditions))
(defun lawlist-backward-window ()
(interactive)
(other-window -1)
(lawlist-minibuffer-conditions))
ALTERNATIVE ANSWER (similar concept):  set-face-attribute is too slow for changing faces during redisplay. The preferred method for adjusting faces in that context is with the function face-remap-add-relative; however, that function is a little complicated to use because faces stack up one behind the other and get shadowed. So, I'll need to revise the following draft alternative answer (in the future) to incorporate face-remap-add-relative -- in the meantime, I'm setting the face-remapping-alist manually (which admittedly is not the preferred method according to the manual / doc-string).
(defvar modeline-selected-window nil)
(let ((default-background (face-background 'default nil 'default)))
(set-face-attribute 'mode-line-inactive nil :background default-background :box nil))
(defun modeline-record-selected-window ()
(setq modeline-selected-window (selected-window)))
(defun modeline-update-function ()
(cond
((minibufferp)
(let ((default-background (face-background 'default nil 'default)))
(with-selected-window (minibuffer-window)
(setq-local face-remapping-alist '(
(default :foreground "blue")
(minibuffer-prompt :foreground "red"))))
(setq-default face-remapping-alist `((mode-line ,'mode-line-inactive)))))
(t
(with-selected-window (minibuffer-window)
(when (local-variable-p 'face-remapping-alist)
(kill-local-variable 'face-remapping-alist)))
(setq-default face-remapping-alist nil))))
(defun modeline-set-format ()
(setq mode-line-format '(
(:eval
(if (eq modeline-selected-window (selected-window))
(propertize "SELECTED WINDOW" 'face 'font-lock-warning-face)
(propertize "NOT-SELECTED WINDOW" 'face 'font-lock-keyword-face)))))
;; next two lines make the affect immediately apparent
(setq modeline-selected-window (selected-window))
(force-mode-line-update))
(define-minor-mode modeline-mode
"This is a minor-mode for `modeline-mode`."
:init-value nil
:lighter " ML"
:keymap nil
:global t
:group nil
(cond
(modeline-mode
(add-hook 'post-command-hook 'modeline-record-selected-window)
(add-hook 'buffer-list-update-hook 'modeline-update-function)
(add-hook 'text-mode-hook 'modeline-set-format)
(when (called-interactively-p 'any)
(message "Globally turned ON `modeline-mode`.")))
(t
(remove-hook 'post-command-hook 'modeline-record-selected-window)
(remove-hook 'buffer-list-update-hook 'modeline-update-function)
(remove-hook 'text-mode-hook 'modeline-set-format)
(when (called-interactively-p 'any)
(message "Globally turned OFF `modeline-mode`.") ))))
(modeline-mode 1) ;; globally turn on minor-mode
If what you are trying to achieve is to highlight the current buffer/frame, the way I do that is through Highlight-Current-Line. It shows you the line where the cursor is, but a side effect of that is that it also shows you which buffer/frame you are in. You could configure it to highlight the entire buffer, or look into the code to see how they do it.
Crosshairs mode is your best bet, I think. It not only draws attention to the active window, but it also shows you immediately where the cursor is in an obvious way. You can easily toggle it on/off (I bind it to C-+.)
You can also use crosshairs-toggle-when-idle as an alternative. It does not show the crosshairs until a delay has past. It too is a toggle.
You can of course use crosshairs together with an in-your-face mode-line face.
I was using hiwin-mode as suggested in this topic but there is an open issue with shell buffers (when inactive, the text becomes invisible).
Therefore, another option which I'm enjoying so far is auto-dim-other-buffers mode.