Changing cursor color based on a minor mode - emacs

I have written a minor-mode, it defines some key bindings and does some initialization. The mode properly sets up Navi-mode and Navi-mode-map.
How do I enhance this minor-mode to change the color of the cursor when Navi-mode is enabled, and change it back whenever the mode is disabled? Can I use the hook Navi-mode-hook?

Try this:
(define-minor-mode foo-mode "doodad" :lighter ""
(if foo-mode
(setq cursor-type 'bar)
(setq cursor-type (default-value 'cursor-type))))
Or, if you anticipate cursor-type to already have a non-default value, you can save it when the mode is enabled and restore the saved value when it's disabled.

Either you have total control of the minor mode (because you wrote it), and you can embed this behaviour directly in your minor-mode function as explained in Dmitry's answer:
(define-minor-mode navi-mode
"Navi mode does wonderful things"
:lighter " Navi"
:global t
:init-value 0
(if navi-mode
(progn
(setq old-cursor-color (cdr (assoc 'cursor-color (frame-parameters))))
(set-cursor-color "red"))
(set-cursor-color old-cursor-color)))
Or you don't control the minor mode definition and you'll have to use a hook:
(defun navi-change-cursor-color ()
(if navi-mode
(progn
(setq old-cursor-color (cdr (assoc 'cursor-color (frame-parameters))))
(set-cursor-color "red"))
(set-cursor-color old-cursor-color)))
(add-hook 'navi-mode-hook 'navi-change-cursor-color)

Related

Emacs: How to enable a mode globally?

I just have a mode from an addon which I want to enable globally. In order to turn on it by hand I need to enter M-x highlight-indentation-mode. So, below is a list of what I have tried yet: (highlight-indentation-mode t), (highlight-indentation-mode 1), (setq highlight-indentation-mode t). Nothing worked. Next I figure out that may be I need to enable a mode globally, and I started google about it. What I have tried next:
(define-globalized-minor-mode global-highlight-indentation-mode highlight-indentation-mode
(lambda () (setq highlight-indentation-mode t)))
No, this surely aren't the droids I am looking for, it turns on the variable, but a mode still doesn't work.
(define-globalized-minor-mode global-highlight-indentation-mode highlight-indentation-mode
(lambda () highlight-indentation-mode t))
(define-globalized-minor-mode global-highlight-indentation-mode highlight-indentation-mode
(highlight-indentation-mode t))
These two just broke my Emacs: when I tried open file with this two commands in config, Emacs wrote an error, and refused to open a files.
UPD: Based on comments I also tried
(defun enable-highlight-indentation-mode ()
(interactive)
(highlight-indentation-mode t))
(define-globalized-minor-mode global-highlight-indentation-mode highlight-indentation-mode
enable-highlight-indentation-mode)
(global-highlight-indentation-mode t)
And the same without (interactive). When I am try to open a file with this, Emacs refuse to open, and write an error:
File mode specification error: (void-function nil)
c-font-lock-fontify-region: Symbol's function definition is void: nil
;;; highlight-indentation.el --- Minor modes for highlighting indentation
;; Author: Anton Johansson <anton.johansson#gmail.com> - http://antonj.se
;; Created: Dec 15 23:42:04 2010
;; Version: 0.6.0
;; URL: https://github.com/antonj/Highlight-Indentation-for-Emacs
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be
;; useful, but WITHOUT ANY WARRANTY; without even the implied
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE. See the GNU General Public License for more details.
;;
;;; Commentary:
;; Customize `highlight-indentation-face', and
;; `highlight-indentation-current-column-face' to suit your theme.
;;; Code:
(defgroup highlight-indentation nil
"Highlight Indentation"
:prefix "highlight-indentation-"
:group 'basic-faces)
(defface highlight-indentation-face
;; Fringe has non intrusive color in most color-themes
'((t :inherit fringe))
"Basic face for highlighting indentation guides."
:group 'highlight-indentation)
(defcustom highlight-indentation-offset 4
"Default indentation offset, used if no other can be found from
major mode. This value is always used by
`highlight-indentation-mode' if set buffer local. Set buffer
local with `highlight-indentation-set-offset'"
:group 'highlight-indentation)
(defvar highlight-indentation-current-regex nil)
;;;###autoload
(define-minor-mode highlight-indentation-mode
"Highlight indentation minor mode highlights indentation based
on spaces"
:lighter " ||"
(when highlight-indentation-current-regex ;; OFF
(font-lock-remove-keywords nil `((,highlight-indentation-current-regex
(1 'highlight-indentation-face)))))
(set (make-local-variable 'highlight-indentation-current-regex) nil)
(when highlight-indentation-mode ;; ON
(when (not (local-variable-p 'highlight-indentation-offset))
(set (make-local-variable 'highlight-indentation-offset)
;; Set indentation offset from highlight-indentation-offset if set, otherwise
;; according to major mode
(cond ((and (eq major-mode 'python-mode) (boundp 'python-indent))
python-indent)
((and (eq major-mode 'python-mode) (boundp 'py-indent-offset))
py-indent-offset)
((and (eq major-mode 'python-mode) (boundp 'python-indent-offset))
python-indent-offset)
((eq major-mode 'ruby-mode)
ruby-indent-level)
((and (eq major-mode 'scala-mode) (boundp 'scala-indent:step))
scala-indent:step)
((and (eq major-mode 'scala-mode) (boundp 'scala-mode-indent:step))
scala-mode-indent:step)
((or (eq major-mode 'scss-mode) (eq major-mode 'css-mode))
css-indent-offset)
((eq major-mode 'nxml-mode)
nxml-child-indent)
((eq major-mode 'coffee-mode)
coffee-tab-width)
((eq major-mode 'js-mode)
js-indent-level)
((eq major-mode 'js2-mode)
js2-basic-offset)
((local-variable-p 'c-basic-offset)
c-basic-offset)
(t
(default-value 'highlight-indentation-offset)))))
(set (make-local-variable 'highlight-indentation-current-regex)
(format "\\( \\) \\{%s\\}" (- highlight-indentation-offset 1)))
(font-lock-add-keywords nil `((,highlight-indentation-current-regex
(1 'highlight-indentation-face)))))
(font-lock-fontify-buffer))
;;;###autoload
(defun highlight-indentation-set-offset (offset)
"Set indentation offset localy in buffer, will prevent
highlight-indentation from trying to guess indentation offset
from major mode"
(interactive
(if (and current-prefix-arg (not (consp current-prefix-arg)))
(list (prefix-numeric-value current-prefix-arg))
(list (read-number "Indentation offset: "))))
(set (make-local-variable 'highlight-indentation-offset) offset)
(when highlight-indentation-mode
(highlight-indentation-mode)))
;;;
;;; Copyright (C) Kresten Krab Thorup
;;; Available under Apache License, Version 2.
;;;
;;; This minor mode will highlight the indentation of the current line
;;; as a vertical bar (grey background color) aligned with the column of the
;;; first character of the current line.
;;;
(defface highlight-indentation-current-column-face
;; Fringe has non intrusive color in most color-themes
'((t :inherit fringe))
"Basic face for highlighting indentation guides."
:group 'highlight-indentation)
;; used to hold the last regex we installed
(defvar highlight-indentation-current-column-regex nil)
;;;###autoload
(define-minor-mode
highlight-indentation-current-column-mode
"Hilight Indentation minor mode displays
a vertical bar corresponding to the indentation of the current line"
:lighter " |"
(when highlight-indentation-current-column-regex
(font-lock-remove-keywords nil highlight-indentation-current-column-regex))
(set (make-local-variable 'highlight-indentation-current-column-regex) nil)
(cond (highlight-indentation-current-column-mode
(add-hook 'post-command-hook 'highlight-indentation-current-column-post-command-hook nil t))
(t
(remove-hook 'post-command-hook 'highlight-indentation-current-column-post-command-hook t)
(font-lock-fontify-buffer))))
(defun highlight-indentation-current-column-post-command-hook ()
"This hook runs after every keystroke"
(when highlight-indentation-current-column-regex
(font-lock-remove-keywords nil highlight-indentation-current-column-regex))
(let ((indent (save-excursion (back-to-indentation) (current-column))))
(when (and highlight-indentation-current-column-mode
(> indent 1))
(let* ((re (format "^ \\{%d\\}\\( \\)" indent))
(arg `((,re (1 'highlight-indentation-current-column-face prepend)))))
(set (make-local-variable 'highlight-indentation-current-column-regex) arg)
(font-lock-add-keywords nil arg))))
(font-lock-fontify-buffer))
(defun turn-on-highlight-indentation-mode ()
(interactive)
(highlight-indentation-mode 1))
(define-globalized-minor-mode global-highlight-indentation-mode
highlight-indentation-mode turn-on-highlight-indentation-mode)
(global-highlight-indentation-mode 1)
(provide 'highlight-indentation)

Making Document View in Emacs fit to width of page

I'm trying to use Document View in Emacs to read PDFs, but I can't figure out how to make it behave similarly to the 'fit to width' command many PDF readers have. Is there an internal way to do this?
The following snippet defines a new minor-mode doc-view-autofit-mode, which I have activated below using doc-view-mode-hook. It works for me on Emacs 24.3 on Ubuntu 14.04, even to the point of resizing the zoom when I resize the window!
(There is usually a short resize delay thanks to doc-view-autofit-timer-start, but I'm happy to live with this.)
I take no credit for the solution; I found this code on the emacs-devel mailing list.
(require 'cl)
;;;; Automatic fitting minor mode
(defcustom doc-view-autofit-timer-start 1.0
"Initial value (seconds) for the timer that delays the fitting when
`doc-view-autofit-fit' is called (Which is when a window
configuration change occurs and a document needs to be fitted)."
:type 'number
:group 'doc-view)
(defcustom doc-view-autofit-timer-inc 0.02
"Value to increase (seconds) the timer (see `doc-view-autofit-timer-start')
by, if there is another window configuration change occuring, before
it runs out."
:type 'number
:group 'doc-view)
(defcustom doc-view-autofit-default-fit 'width
"The fitting type initially used when mode is enabled.
Valid values are: width, height, page."
:type 'symbol
:group 'doc-view)
(defvar doc-view-autofit-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c W") 'doc-view-autofit-width)
(define-key map (kbd "C-c H") 'doc-view-autofit-height)
(define-key map (kbd "C-c P") 'doc-view-autofit-page)
map)
"Keymap used by `doc-view-autofit-mode'.")
(defun doc-view-autofit-set (type)
"Set autofitting to TYPE for current buffer."
(when doc-view-autofit-mode
(setq doc-view-autofit-type type)
(doc-view-autofit-fit)))
(defun doc-view-autofit-width ()
"Set autofitting to width for current buffer."
(interactive) (doc-view-autofit-set 'width))
(defun doc-view-autofit-height ()
"Set autofitting to height for current buffer."
(interactive) (doc-view-autofit-set 'height))
(defun doc-view-autofit-page ()
"Set autofitting to page for current buffer."
(interactive) (doc-view-autofit-set 'page))
(defun doc-view-autofit-fit ()
"Fits the document in the selected window's buffer
delayed with a timer, so multiple calls in succession
don't cause as much overhead."
(lexical-let
((window (selected-window)))
(if (equal doc-view-autofit-timer nil)
(setq doc-view-autofit-timer
(run-with-timer
doc-view-autofit-timer-start nil
(lambda ()
(if (window-live-p window)
(save-selected-window
(select-window window)
(cancel-timer doc-view-autofit-timer)
(setq doc-view-autofit-timer nil)
(cond
((equal 'width doc-view-autofit-type)
(doc-view-fit-width-to-window))
((equal 'height doc-view-autofit-type)
(doc-view-fit-height-to-window))
((equal 'page doc-view-autofit-type)
(doc-view-fit-page-to-window))))))))
(timer-inc-time doc-view-autofit-timer doc-view-autofit-timer-inc))))
(define-minor-mode doc-view-autofit-mode
"Minor mode for automatic (timer based) fitting in DocView."
:lighter " AFit" :keymap doc-view-autofit-mode-map :group 'doc-view
(when doc-view-autofit-mode
(set (make-local-variable 'doc-view-autofit-type)
doc-view-autofit-default-fit)
(set (make-local-variable 'doc-view-autofit-timer) nil)
(add-hook 'window-configuration-change-hook
'doc-view-autofit-fit nil t)
(doc-view-autofit-fit))
(when (not doc-view-autofit-mode)
(remove-hook 'window-configuration-change-hook
'doc-view-autofit-fit t)
(when doc-view-autofit-timer
(cancel-timer doc-view-autofit-timer)
(setq doc-view-autofit-timer nil))
(setq doc-view-autofit-type nil)))
(add-hook 'doc-view-mode-hook 'doc-view-autofit-mode)
It works for me:
(add-hook 'doc-view-mode-hook 'doc-view-fit-width-to-window)
Update: It doesn't work correctly if a conversion (to png or something else) is still ongoing (First opening the document). There is alternative, more reliable way, which handles this special case (it doesn't use hook at all but uses advice):
(defadvice doc-view-display (after fit-width activate)
(doc-view-fit-width-to-window))
The following is a slight modification of the answer by Chris -- it provides compatibility with functions like find-file-other-window -- e.g., when the selected-window is different than the one displaying the *.pdf file.
(defvar last-displayed-doc-view-buffer nil)
(defun get-last-displayed-doc-view-buffer ()
(setq last-displayed-doc-view-buffer (current-buffer)))
(add-hook 'doc-view-mode-hook 'get-last-displayed-doc-view-buffer)
(defun doc-view-autofit-fit ()
"Fits the document in the selected window's buffer
delayed with a timer, so multiple calls in succession
don't cause as much overhead."
(if (null doc-view-autofit-timer)
(setq doc-view-autofit-timer
(run-with-timer doc-view-autofit-timer-start nil (lambda ()
(let* (
(selected-window
(cond
((eq major-mode 'doc-view-mode)
(selected-window))
(t
(get-buffer-window last-displayed-doc-view-buffer))))
(current-buffer
(cond
((eq major-mode 'doc-view-mode)
(current-buffer))
(t
(get-buffer last-displayed-doc-view-buffer))))
(selected-fit
(when (buffer-live-p (get-buffer current-buffer))
(with-current-buffer (get-buffer current-buffer)
doc-view-autofit-type))) )
(when (window-live-p selected-window)
(with-selected-window selected-window
(when doc-view-autofit-timer (cancel-timer doc-view-autofit-timer))
(setq doc-view-autofit-timer nil)
(cond
((eq 'width selected-fit)
(doc-view-fit-width-to-window))
((eq 'height selected-fit)
(doc-view-fit-height-to-window))
((eq 'page selected-fit)
(doc-view-fit-page-to-window)))))))))
(timer-inc-time doc-view-autofit-timer doc-view-autofit-timer-inc)))
And, as noted in my earlier comment to Chris' answer, the following variables need definitions:
(defvar doc-view-autofit-timer nil)
(defvar doc-view-autofit-type nil)
Because the modification above adds a new function to the doc-view-mode-hook to obtain the current-buffer, which is needed for the function doc-view-autofit-fit, it is necessary to ensure that the latter function is appended to the end of the doc-view-mode-hook. So the change looks like this -- i.e., we add a t for the append argument:
(add-hook 'doc-view-mode-hook 'doc-view-autofit-mode t)
Everything else from Chris's answer that has not been superseded by the above modifications remain in effect.
TO DO:
Create a test to examine each page while scrolling to make certain that the view coincides with the autofit-type. Presently, errors occur in page size when dealing with a long *.pdf file.
Just a note: (require 'cl) is out of date. Since emacs-24.3 it should be
(require ‘cl-lib)
See http://www.emacswiki.org/emacs/CommonLispForEmacs

emacs custom php tags highlight syntax

I want to set custom color background in tags, but other do not touch
(define-derived-mode php-mode fundamental-mode
"php-mode"
:syntax-table php-syntax-table
(setq font-lock-defaults '(php-keywords)))
(defvar php-syntax-table (make-syntax-table) "Syntax table for php-mode")
(make-face 'php-region-face)
(set-face-background 'php-region-face "red")
(setq php-keywords '(("<\\?php[[:ascii:]]*?\\?>" 0 'php-region-face t)))
But highlight background tags is not correctly, see below:
You'll want to setup multiline font-lock and define the boundaries of the font-lock search (so it doesn't take too much time). My information (and this code) comes from this SO question.
Here, I define multiline font-locking to take place within tags (< ... >). If this is added to your define-derived mode, it works as you describe.
(set (make-local-variable 'font-lock-multiline) t)
(add-hook 'font-lock-extend-region-functions
'test-font-lock-extend-region)
(defun test-font-lock-extend-region ()
"Extend the search region to include an entire SGML tag."
;; Avoid compiler warnings about these global variables from font-lock.el.
;; See the documentation for variable `font-lock-extend-region-functions'.
(eval-when-compile (defvar font-lock-beg) (defvar font-lock-end))
(save-excursion
(goto-char font-lock-beg)
(let ((found (or (re-search-backward "<" nil t) (point-min))))
(goto-char font-lock-end)
(when (re-search-forward ">" nil t)
(beginning-of-line)
(setq font-lock-end (point)))
(setq font-lock-beg found))))
EDIT: for some reason, SO doesn't like my code formatting.

Check whether mode is on emacs

How to check whether in the current buffer a mode is on?
I tried this for LaTeX, for which I wanted to have an align function align on &, but only if I am in a LaTeX buffer, not in an ESS mode buffer.
How to do a check for this? I tried:
(if (equal reftex-mode t) (message "TRUE"))
and
(if (equal LaTeX-mode t) (message "TRUE"))
but reftex is set globally and LaTeX stuff does not work at all. Ideas?
Also, how to prevent the error "void variable" in the case these variables are not initiated?
Test against the "major-mode" variable:
(defun a-function()
(if (eq major-mode 'latex-mode)
(message "LaTeX mode is ON")
(message "LaTeX mode is OFF")))

Emacs key-bindings: (dired) mode overwrites minor-mode key map?

Even after following all that was given in
Globally override key binding in Emacs
I still couldn't get it to work.
I bound M-o to other-window in my global key map like this:
(defvar my-keys-minor-mode-map (make-keymap) "my-keys-minor-mode keymap.")
(define-key my-keys-minor-mode-map "\M-o" 'other-window)
(define-minor-mode my-keys-minor-mode
"A minor mode so that my key settings override annoying major modes."
t " my-keys" 'my-keys-minor-mode-map)
(my-keys-minor-mode 1)
(defun my-minibuffer-setup-hook ()
(my-keys-minor-mode 0))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
;; Maintain the above keymap even after loading a new library
(defadvice load (after give-my-keybindings-priority)
"Try to ensure that my keybindings always have priority."
(if (not (eq (car (car minor-mode-map-alist)) 'my-keys-minor-mode))
(let ((mykeys (assq 'my-keys-minor-mode minor-mode-map-alist)))
(assq-delete-all 'my-keys-minor-mode minor-mode-map-alist)
(add-to-list 'minor-mode-map-alist mykeys))))
(ad-activate 'load)
but dired mode overrides this and remaps it to dired-omit-mode.
What am I missing ?
Your minor mode is defined to be buffer-local. You can Define it to be global, like this:
(define-minor-mode my-keys-minor-mode
"A minor mode so that my key settings override annoying major modes."
:global t
:lighter " my-keys")
But then your my-minibuffer-setup-hook will turn it off globally as well. Also if it's global and you basically always have it ON, you might prefer to not provide the :lighter " my-keys", so your mode-line isn't filled unnecessarily.