Emacs: How can I eliminate whitespace-mode in auto-complete pop-ups? - emacs

Here is a screenshot of what is going wrong:
As you can see, the whitespace characters are getting in the way of auto-complete's pop-up text and making things look really terrible.
When really, I'd like it to look like this:
Is there anyone out there who has been able to use whitespace-mode but eliminate it from popping up in the auto-complete stuff?

There is an issue about compatibility between auto-complete and whitespace-mode in the Prelude issue tracker which has the following workaround in its comments (improved a bit from the original):
(defvar my-prev-whitespace-mode nil)
(make-variable-buffer-local 'my-prev-whitespace-mode)
(defadvice popup-draw (before my-turn-off-whitespace activate compile)
"Turn off whitespace mode before showing autocomplete box"
(if whitespace-mode
(progn
(setq my-prev-whitespace-mode t)
(prelude-turn-off-whitespace))
(setq my-prev-whitespace-mode nil)))
(defadvice popup-delete (after my-restore-whitespace activate compile)
"Restore previous whitespace mode when deleting autocomplete box"
(if my-prev-whitespace-mode
(prelude-turn-on-whitespace)))
Essentially this disables whitespace mode for the whole buffer while a popup is shown.
The issue is also reported in the popup.el issue tracker.

Reworked example to make it work (partially).
There are following issues that prevent #lunaryorn's example from working
double activating the popup-draw advice would cause my-prev-whitespace-mode to lose stored information
activating the popup-delete advice before popup-draw would just switch-off whitespace mode because default value for my-prev-whitespace-mode is nil.
So I evolve the original workaround further to address the two difficulties.
(defun my:force-modes (rule-mode &rest modes)
"switch on/off several modes depending of state of
the controlling minor mode
"
(let ((rule-state (if rule-mode 1 -1)
))
(mapcar (lambda (k) (funcall k rule-state)) modes)
)
)
(require 'whitespace)
(defvar my:prev-whitespace-mode nil)
(make-variable-buffer-local 'my:prev-whitespace-mode)
(defvar my:prev-whitespace-pushed nil)
(make-variable-buffer-local 'my:prev-whitespace-pushed)
(defun my:push-whitespace (&rest skip)
(if my:prev-whitespace-pushed () (progn
(setq my:prev-whitespace-mode whitespace-mode)
(setq my:prev-whitespace-pushed t)
(my:force-modes nil 'whitespace-mode)
))
)
(defun my:pop-whitespace (&rest skip)
(if my:prev-whitespace-pushed (progn
(setq my:prev-whitespace-pushed nil)
(my:force-modes my:prev-whitespace-mode 'whitespace-mode)
))
)
(require 'popup)
(advice-add 'popup-draw :before #'my:push-whitespace)
(advice-add 'popup-delete :after #'my:pop-whitespace)
This solution still has drawbacks. Whitespace-mode is disabled only when a menu is shown. While there is only single candidate for substitution the whitespace mode continues to disrupt screen.
The issue is most likely with bad choice for functions to dirty hack with advices. There should be more appropriate that are called exactly when disabling whitespace-mode is desirable. But no-one except the developer can name them.

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))))))))

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)))

How to automatically save files on lose focus in Emacs

Is it possible to configure Emacs, so that it saves all files when the emacs window loses
focus?
I added focus hooks to Gnu Emacs 24.4.
They are called focus-in-hook and focus-out-hook.
You can add
(defun save-all ()
(interactive)
(save-some-buffers t))
(add-hook 'focus-out-hook 'save-all)
to your .emacs file and it should save all files on loss of focus.
I use this, it will only work if emacs is running under X (like it probably would in something like ubuntu).
(when
(and (featurep 'x) window-system)
(defvar on-blur--saved-window-id 0 "Last known focused window.")
(defvar on-blur--timer nil "Timer refreshing known focused window.")
(defun on-blur--refresh ()
"Runs on-blur-hook if emacs has lost focus."
(let* ((active-window (x-window-property
"_NET_ACTIVE_WINDOW" nil "WINDOW" 0 nil t))
(active-window-id (if (numberp active-window)
active-window
(string-to-number
(format "%x00%x"
(car active-window)
(cdr active-window)) 16)))
(emacs-window-id (string-to-number
(frame-parameter nil 'outer-window-id))))
(when (and
(= emacs-window-id on-blur--saved-window-id)
(not (= active-window-id on-blur--saved-window-id)))
(run-hooks 'on-blur-hook))
(setq on-blur--saved-window-id active-window-id)
(run-with-timer 1 nil 'on-blur--refresh)))
(add-hook 'on-blur-hook #'(lambda () (save-some-buffers t)))
(on-blur--refresh))
Not sure if this is what you want.
(defun dld-deselect-frame-hook ()
(save-some-buffers 1))
(add-hook 'deselect-frame-hook 'dld-deselect-frame-hook)
From: http://www.dribin.org/dave/blog/archives/2003/09/10/emacs/
EDIT: It only seems to work in XEmacs
[…] the feature I am talking about is from
Scribes. It is very convient when
editing html and the like, you don't
have to press C-x C-s anymore, you
just change the window and check your
browser.
In that case, instead of switching to the browser application, order Emacs to load the browser application (C-c C-v or M-x browse-url-of-buffer). With this method, you can write your own function that saves the buffer and then brings the browser up, like:
(defun my-browse-url-of-buffer ()
"Save current buffer and view its content in browser."
(interactive)
(save-buffer)
(browse-url-of-buffer))
And hook it to a convenient binding.
Or you can still use the html-autoview-mode that each time you saves the buffer, automatically loads the file into your favorite browser.
You can use `auto-save-interval' to save every n characters you type. Mine is set to 100. So about every 2-3 lines of code, maybe?
auto-save-interval is a variable
defined in `C source code'. Its value
is 100
Documentation:
*Number of input events between auto-saves. Zero means disable
autosaving due to number of characters
typed.
You can customize this variable.
This doesn't answer your original question; it's just a way to achieve something similar.

in Emacs, what's the best way for keyboard-escape-quit not destroy other windows?

EDIT: I understand there is keyboard-quit (which is normally bound to C-g); but I'm more interested to know about how one deals with editing functions that come with Emacs (like in this case). I run into this kind of situations from time to time when I want to change just a little bit of some build-in functions.
In emacs, when you hit M-ESC ESC (or ESC three times), you can get out of a lots of situations like transient-mark, etc. But I habitually hit the escape key (I actually remap this to a single hit of the escape key) more than I intended, and that ends up killing my windows configuration, which is quite annoying. The function keyboard-escape-quit is defined in simple.el:
(defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
(cond ((eq last-command 'mode-exited) nil)
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((and transient-mark-mode mark-active)
(deactivate-mark))
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
((not (one-window-p t))
(delete-other-windows))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
And I can see that I don't want the lines:
((not (one-window-p t))
(delete-other-windows))
But what is the best way to modify this function? I can see only two ways: 1) modify simple.el 2) copy this function to my .emacs file and do the modifications there. Both ways are not really good; ideally I would like to see something on the line of defadvice, but I can't see how I can do it in this case.
You could use around advice and redefine the offending function to do what you want (i.e. one-window-p should always return t):
(defadvice keyboard-escape-quit (around my-keyboard-escape-quit activate)
(let (orig-one-window-p)
(fset 'orig-one-window-p (symbol-function 'one-window-p))
(fset 'one-window-p (lambda (&optional nomini all-frames) t))
(unwind-protect
ad-do-it
(fset 'one-window-p (symbol-function 'orig-one-window-p)))))
This kind of acts like a (let ...) but has to be more complicated because you need to override a function for a limited scope instead of a variable.
I usually find that 'keyboard-quit (C-g) works to get out of all of those situations.
However, if you really want to have a variant of this function, I think that copying to your .emacs file (and renaming, I usually usa a prefix of bp) and making the edits there is probably the best option.
EDIT, in response to edit: In general, whenever I want an edited version of an emacs function, I either write it myself, or copy it to my .emacs, rename it bp-whotever and then do appropriate edits.
The downside of this is that my .emacs is HUGE, and probably extra-crufty with ancient functions that are nolonger used... the upside is that whenever I need to write something new, I've got tons of sample code to look at...
Here's another, simpler piece of advice that takes advantage of the fact that keyboard-escape-quit calls buffer-quit-function before closing windows:
(defadvice keyboard-escape-quit
(around keyboard-escape-quit-dont-close-windows activate)
(let ((buffer-quit-function (lambda () ())))
ad-do-it))
Works with Emacs 25.1. (I originally used #scottfrazer's advice, but it's unhappy in 25.1. Haven't bothered debugging yet.)
A single press of the Escape key, by default, acts as a Meta prefix key; that is, a keybinding which involves the Meta key.
Triple-pressing the Escape key will run keyboard-escape-quit, which is like keyboard-quit but with more of a "do what I mean" behaviour.
This code may help with your use case. You can use this in your Emacs init file:
;;; esc always quits
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)
(global-set-key [escape] 'keyboard-quit)
I'm more interested to know about how one deals with editing functions that come with Emacs (like in this case). I run into this kind of situations from time to time when I want to change just a little bit of some build-in functions.
This is exactly the purpose for which I created the library el-patch. You would put this in your init-file:
(el-patch-defun keyboard-escape-quit ()
"Exit the current \"mode\" (in a generalized sense of the word).
This command can exit an interactive command such as `query-replace',
can clear out a prefix argument or a region,
can get out of the minibuffer or other recursive edit,
cancel the use of the current buffer (for special-purpose buffers),
or go back to just one window (by deleting all but the selected window)."
(interactive)
(cond ((eq last-command 'mode-exited) nil)
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(current-prefix-arg
nil)
((and transient-mark-mode mark-active)
(deactivate-mark))
((> (recursion-depth) 0)
(exit-recursive-edit))
(buffer-quit-function
(funcall buffer-quit-function))
(el-patch-remove
((not (one-window-p t))
(delete-other-windows)))
((string-match "^ \\*" (buffer-name (current-buffer)))
(bury-buffer))))
Here's a new way using cl-lib instead of cl which is now deprecated:
;; Make it so keyboard-escape-quit doesn't delete-other-windows
(defadvice keyboard-escape-quit
(around keyboard-escape-quit-dont-delete-other-windows activate)
(cl-letf (((symbol-function 'delete-other-windows)
(lambda () nil)))
ad-do-it))
You'll need to make sure prior to it you have called:
(require 'cl-lib)