Check whether mode is on emacs - 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")))

Related

How to disable Emacs Evil selection auto-copies to clipboard

Related to this question: How to disable x paste in emacs
This works for the mouse
(setq mouse-drag-copy-region nil)
How do I do the same for Evil mode in emacs?
I'm on Mac OS, running Emacs 24.2.91.
Came across this while Googling for a solution to this problem. What I found to work is part of the Spacemacs FAQ:
(fset 'evil-visual-update-x-selection 'ignore)
After doing some digging into the same issue, I believe that the issue actually lies in the Emacs x-select-text function, which explicitly ignores the value of x-select-enable-clipboard on NextStep (and OS X is a NextStep).
I've "solved" this problem by replacing x-select-text with a no-op function, then explicitly using ns-{get,set}pasteboard for interprogram{cut,paste}-function:
; Override the default x-select-text function because it doesn't
; respect x-select-enable-clipboard on OS X.
(defun x-select-text (text))
(setq x-select-enable-clipboard nil)
(setq x-select-enable-primary nil)
(setq mouse-drag-copy-region nil)
(setq interprogram-cut-function 'ns-set-pasteboard)
(setq interprogram-paste-function 'ns-get-pasteboard)
Here is the original x-select-text code:
(defun x-select-text (text)
"Select TEXT, a string, according to the window system.
On X, if `x-select-enable-clipboard' is non-nil, copy TEXT to the
clipboard. If `x-select-enable-primary' is non-nil, put TEXT in
the primary selection.
On MS-Windows, make TEXT the current selection. If
`x-select-enable-clipboard' is non-nil, copy the text to the
clipboard as well.
On Nextstep, put TEXT in the pasteboard (`x-select-enable-clipboard'
is not used)."
(cond ((eq (framep (selected-frame)) 'w32)
(if x-select-enable-clipboard
(w32-set-clipboard-data text))
(setq x-last-selected-text text))
((featurep 'ns) ; This is OS X
;; Don't send the pasteboard too much text.
;; It becomes slow, and if really big it causes errors.
(ns-set-pasteboard text)
(setq ns-last-selected-text text))
(t
;; With multi-tty, this function may be called from a tty frame.
(when (eq (framep (selected-frame)) 'x)
(when x-select-enable-primary
(x-set-selection 'PRIMARY text)
(setq x-last-selected-text-primary text))
(when x-select-enable-clipboard
(x-set-selection 'CLIPBOARD text)
(setq x-last-selected-text-clipboard text))))))
I sent this to the evil-mode mailing list:
Problems with Clipboard History and selections
The current implementation of x-select-enable-clipboard calls x-select-text for all cursor movement with a selection. This is not the behavior when using non-evil mode. Basically, emacs takes over my clipboard history unless the below patch is done. I'm on a Mac and use Alfred clipboard history.
My change below in bold seems to fix this issue.
Is this the right thing to do?
Is there a contributions info page that explains how to contribute to this project. I'm familiar with github forks and pull requests.
Thanks,
Justin
(setq x-select-enable-clipboard nil)
(defun evil-visual-update-x-selection (&optional buffer)
"Update the X selection with the current visual region."
(let ((buf (or buffer (current-buffer))))
(when (buffer-live-p buf)
(with-current-buffer buf
(when (and (evil-visual-state-p)
(fboundp 'x-select-text)
(or (not (boundp 'ns-initialized))
(with-no-warnings ns-initialized))
(not (eq evil-visual-selection 'block)))
;; CHANGE
;; ONLY call x-select-text if x-select-enable-clipboard is true
(if x-select-enable-clipboard
(x-select-text (buffer-substring-no-properties
evil-visual-beginning
evil-visual-end))))))))

Emacs ESS key bindings

I am trying to set some key bindings for ESS. I read one way is:
(eval-after-load "ess-mode"
'(define-key ess-mode-map (kbd "<f5>") 'myfunc))
But this works only inside the code blocks delimited by <<>>, #.
Another problem is that I would like to use the same key both for plain LaTeX mode (a .tex file) and LaTeX as part of Noweb (a .rnw file) and so I can't just define the key twice for LaTeX mode and ESS mode.
While there is a LaTeX-mode-hook, I don't see something like `ess-noweb-mode-hook.
ess-noweb mode is just a wrapper and it loads latex-mode and R-mode in corresponding chunks. So if you define a shortcut in latex-mode-map it should be available in .rnw buffers as well.
After some trial and error, I found the answer.
If we are in a LaTeX only buffer this is true: (and (equal (symbol-name major-mode) "latex-mode") (not ess-noweb-mode))).
If we are outside chunks of an ESS buffer this is true: ess-noweb-mode.
You may be interested to the following convenience functions.
;Check ESS related modes
(defun is-pure-latex ()
"The buffer is in LaTeX mode, but not in ESS mode."
(and (equal (symbol-name major-mode) "latex-mode") (not ess-noweb-mode)))
(defun is-ess ()
"The buffer is in ESS mode."
ess-noweb-mode)
(defun is-ess-doc ()
"The buffer is in ESS mode and insertion point is outside a chunk."
(and ess-noweb-mode (equal (symbol-name major-mode) "latex-mode")))
(defun is-ess-chunk ()
"The buffer is in ESS mode an insertion point is inside a chunk."
(equal (symbol-name major-mode) "ess-mode"))
(defun is-ess-inf ()
"The buffer is in inferior ESS mode"
(equal (symbol-name major-mode) "inferior-ess-mode"))

Changing cursor color based on a minor mode

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)

Enable auto-complete in Emacs minibuffer

I'm trying to turn auto-complete in the minibuffer:
(add-hook 'minibuffer-setup-hook 'auto-complete-mode)
What I get is auto-complete working in the first instance of minibuffer, but no longer. That is the full minibuffer-setup-hook after loading:
(auto-complete-mode turn-on-visual-line-mode ido-minibuffer-setup rfn-eshadow-setup-minibuffer minibuffer-history-isearch-setup minibuffer-history-initialize)
How to turn auto-complete on persistently?
You rarely ever want to add a function symbol to a hook variable if that function acts as a toggle (which will be the case for most minor modes).
minibuffer-setup-hook runs "just after entry to minibuffer", which means that you would be enabling auto complete mode the first time you enter the minibuffer; disabling it the second time; enabling it the third time; etc...
Typically you would either look to see if there's a pre-defined turn-on-autocomplete-mode type of function, or define your own:
(defun my-turn-on-auto-complete-mode ()
(auto-complete-mode 1)) ;; an argument of 1 will enable most modes
(add-hook 'minibuffer-setup-hook 'my-turn-on-auto-complete-mode)
I can't test that, because you haven't linked to the autocomplete-mode you are using.
The creator of "auto-complete-mode" explicitly excludes the minibuffer for use with auto completion. The definition for the minor mode is:
(define-global-minor-mode global-auto-complete-mode
auto-complete-mode auto-complete-mode-maybe
:group 'auto-complete)
so the "turn mode on" function is "auto-complete-mode-maybe" - the definition of that function is:
(defun auto-complete-mode-maybe ()
"What buffer `auto-complete-mode' prefers."
(if (and (not (minibufferp (current-buffer)))
(memq major-mode ac-modes))
(auto-complete-mode 1)))
This function explicitly tests in the if statement if the current-buffer is the minibuffer and doesn't turn on the auto-complete-mode if it is.
If you want to use auto-complete-mode in the minibuffer, you should probably contact the maintainer of the mode and ask him why he excluded the minibuffer and what programming changes he feels are necessary to enable the mode in the minibuffer.
Zev called to my attention auto-complete-mode-maybe, and that is the required modifications (file auto-complete.el, all changes have comments):
;; Add this variable
(defcustom ac-in-minibuffer t
"Non-nil means expand in minibuffer."
:type 'boolean
:group 'auto-complete)
...
(defun ac-handle-post-command ()
(condition-case var
(when (and ac-triggered
(not (ido-active)) ;; Disable auto pop-up in ido mode
(or ac-auto-start
ac-completing)
(not isearch-mode))
(setq ac-last-point (point))
(ac-start :requires (unless ac-completing ac-auto-start))
(ac-inline-update))
(error (ac-error var))))
...
(defun auto-complete-mode-maybe ()
"What buffer `auto-complete-mode' prefers."
(if (or (and (minibufferp (current-buffer)) ac-in-minibuffer) ;; Changed
(memq major-mode ac-modes))
(auto-complete-mode 1)))
And .emacs:
(add-hook 'minibuffer-setup-hook 'auto-complete-mode)
Certainly, there are binding conflicts but it is possible to solve them.

Suppress emacs auto-fill in a selected region

I use emacs to edit everything. On some of my LateX documents I would like to automatically disable auto-fill mode when I am editing tables and code. Basically, I'd like to have two tags, like:
%%% BEGIN NO FILL
%%% END NO FILL
and nothing between them will be autofilled.
Can anybody think of a way to do this? I would need to figure out whether or not the cursor is inside the region and then have to toggle the mode, and would need to do that every time the cursor moved. Or is there a better way to do it?
If you are using AUCTeX (you should be) then you may want to check out LaTeX-indent-environment-list. Adding an environment to this variable will make it so that (among other things) M-q doesn't refill the paragraph. Unfortunately it doesn't seem work for auto-fill-mode. The following largely untested code added to LaTeX-mode-hook might do what you want.
(setq auto-fill-function
(lambda ()
(unless (> (save-excursion (or (search-backward "%%% BEGIN NO FILL" (point-min) t) 0))
(save-excursion (or (search-backward "%%% END NO FILL" (point-min) t) 0)))
(do-auto-fill))))
It's very stupid and inefficient, but seems to be fast enough on my machine. It doesn't allow nesting, and requires that you manually mark up all sections that you don't want filled. What I am thinking of adding to my .emacs (until I read your question I didn't realize how much this bugged me) is below which keys off of the current environment so there is no need for special markup (though it only looks at the innermost environment (I'm not sure how much of a problem that will cause in practice)). Combining the two is left as an exercise to the interested reader.
;; You can use the following to unset the variables and play around with them
;; (makunbound 'auto-fill-ignore-environments)
;; (makunbound 'auto-fill-ignore-environments-regexp)
(defcustom auto-fill-ignore-environments
(mapcar 'car LaTeX-indent-environment-list)
"List of environments for which `auto-fill-mode' should be
disabled. Used to generate `auto-fill-ignore-environments-regexp'."
:type '(sexp)
)
(defcustom auto-fill-ignore-environments-regexp
(regexp-opt auto-fill-ignore-environments)
"Regexp matching LaTeX environments for which `auto-fill-mode'
should be disabled. If not set, automatically generated from
`auto-fill-ignore-environments'"
:type '(string)
:set-after '(auto-fill-ignore-environments)
)
(add-hook 'LaTeX-mode-hook
(lambda ()
(setq auto-fill-function
(lambda ()
(unless (string-match auto-fill-ignore-environments-regexp
(LaTeX-current-environment))
(do-auto-fill))))))
I have never used defcustom before so I'm sure that part could be improved quite a bit.
Got it. Check this out:
(defun in-no-auto-fill-region ()
(> (save-excursion (or (search-backward "%%% BEGIN NO FILL" (point-min) t) 0))
(save-excursion (or (search-backward "%%% END NO FILL" (point-min) t) 0))
))
(defun previous-line-checking-auto-fill (arg)
(interactive "P")
(previous-line arg)
(if (in-no-auto-fill-region)
(turn-off-auto-fill)
(turn-on-auto-fill)))
(defun next-line-checking-auto-fill (arg)
(interactive "P")
(next-line arg)
(if (in-no-auto-fill-region)
(turn-off-auto-fill)
(turn-on-auto-fill)))
(add-hook 'LaTeX-mode-hook
'(lambda nil
(local-set-key "C-p" 'previous-line-checking-auto-fill)
(local-set-key "C-n" 'next-line-checking-auto-fill)
(auto-fill-mode 1)
))
Alternately, you can turn off auto-fill-mode and use M-q to format paragraphs. I don't love auto-fill's jumpiness so I use this in every mode.
If you want to go the route of advising/redefining all the movement functions, this should help:
(defmacro movement-advice (func)
`(defadvice ,func (after ; run this after the original function is done (and point has moved)
;; Give it a unique name
,(intern (concat (symbol-name func) "-auto-fill-auto-off"))
;; Hopefully this satisfies the arguments of any function we can throw at it
(&rest args)
;; turn it on
activate
)
"Turn auto-fill-mode on or off automatically."
(auto-fill-mode (not (in-no-auto-fill-region)))))
(dolist (func '(next-line
previous-line
forward-paragraph
backward-paragraph
mouse-drag-region
;; Whatever you use
))
(eval `(movement-advice ,func)))