Enable auto-complete in Emacs minibuffer - emacs

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.

Related

Change cursor to insert state while in minubuffer

I change my cursor based on state in evil. However I notice that when I type in the minibuffer I'm in normal mode.
I'm trying to make code that change the state from whatever it's in to insert state while I type in the minibuffer and switch back when I exit the minibuffer. Note, I use ivy for minibuffer completion (though I don't think it makes a difference).
(setq evil-insert-state-cursor '((bar . 3) "chartreuse3"))
(defun void-ivy-insert-state (orig-func &rest args)
"Wrapper around ivy, so it goes into insert state."
;; minibuffer is different so I have to manually change the state
(let ((saved-evil-state evil-state))
(evil-insert-state)
(setq cursor-type (elt evil-insert-state-cursor 0))
(set-cursor-color (elt evil-insert-state-cursor 1))
(apply orig-func args)
(evil-change-state saved-evil-state)))
(advice-add 'ivy-read :around #'void-ivy-insert-state)
I expect the cursor to be the right color and the write shape while typing something into the minibuffer. And to return to the appropriate shape of the state I was in before entering the minibuffer.
What actually happens is that the cursor is the right color, but it's the wrong shape. And if I exit the minibuffer with C-g insert state persists. It never returns to the original state. I think C-g aborts the execution of my advice.
I achieved the desired behavior with this code.
(add-hook 'minibuffer-setup-hook (lambda () (evil-insert-state)))
(add-hook 'minibuffer-exit-hook (lambda () (evil-normal-state)))
(define-key evil-insert-state-map [escape] (lambda () (interactive)
(evil-normal-state)
(minibuffer-keyboard-quit)))
The only annoying side effect is that whenever ESC is pressed No recursive edit is in progress is printed to the output.
The version below is the one I use in my code. Instead of returning to normal state, it uses a variable to return to the previous evil-state before the minibuffer was opened. Also it only uses minibuffer-keyboard-quit if the minibuffer is active.
(defvar evil-state-before-minibuffer-setup 'normal)
(add-hook 'minibuffer-setup-hook
(lambda () (setq evil-state-before-minibuffer-setup evil-state)
(evil-insert-state)))
(add-hook 'minibuffer-exit-hook (lambda ()
(evil-change-state evil-state-before-minibuffer-setup)))
(define-key evil-insert-state-map [escape]
(lambda () (interactive) (evil-normal-state)
(when (eq (active-minibuffer-window))
(selected-window))
(minibuffer-keyboard-quit))))
I make sure I only quit when the minibuffer is the selected window. Otherwise, the minibuffer would quit if we were to, say, edit a buffer while viewing the contents of the minibuffer.

new comint mod in emacs for plink (putty): Symbol's function definition is void

i want to use a new comint mode for plink(putty), i put the code in init.el, but if M-x run-plink, i got below error:
let*: Symbol's function definition is void: comint-check-proc
;; path
(defvar plink-file-path "C:/Programme/Putty/plink.exe"
"Path to the program used by `run-plink'")
;; arguments
(defvar plink-arguments '()
"Commandline arguments to pass to `plink'")
;; prompt
(defvar plink-prompt-regexp "^>\s"
"Prompt for `run-plink'.")
;; Run-plink
(defun run-plink ()
"Run an inferior instance of `plink.js' inside Emacs."
(interactive)
(setq plink-buffer "*Plink*")
(let* ((plink-program plink-file-path) (buffer (comint-check-proc "Plink")))
;; pop to the "*plink*" buffer if the process is dead, the
;; buffer is missing or it's got the wrong mode.
(pop-to-buffer-same-window
(if (or buffer (not (derived-mode-p 'plink-mode))
(comint-check-proc (current-buffer)))
(get-buffer-create (or buffer "*Plink*"))
(current-buffer)))
;; create the comint process if there is no buffer.
(unless buffer
(apply 'make-comint-in-buffer "Plink" buffer plink-program plink-arguments)
(plink-mode))))
;; plink-mode
(define-derived-mode plink-mode comint-mode "plink" nil "plink"
(setq comint-process-echoes t)
(setq comint-use-prompt-regexp t)
(setq comint-prompt-regexp plink-prompt-regexp)
; ">" read-only
(setq comint-prompt-read-only t)
(set (make-local-variable 'paragraph-separate) "..'")
(set (make-local-variable 'paragraph-start) plink-prompt-regexp))
You have not loaded library comint. You need to do that before Emacs can know about comint-check-proc.
Add a (require 'comint), either in your init file or near the beginning of run-plink - somewhere before it tries to use comint-check-proc.
To give this question an answer, which is also meaningful for other questions marked as duplicates of this one, but actually are about other packages not being loaded, I will give a more general answer, which should be applicable to the other questions as well.
Generally an error Symbol's function definition is void often indicates, that a package was not loaded, but then someone/something tried to use it.
So the general answer, that you probably need to (require '<package name>) in your init.el, where the package name is the name of the package which provides what is currently void.

How to make a buffer-local key binding in Emacs?

I've been working on an Emacs minor mode lately and part of its functionality was displaying images in separate buffers. So far I've been using a function like this:
(defun create-buffer-with-image (name)
(let ((buffer (generate-new-buffer name))
(image (get-svg-for-kanji-code name)))
(switch-to-buffer buffer)
(turn-on-iimage-mode)
(iimage-mode-buffer t)
(insert-image image)))
and it produces a buffer with the image passed as argument, but closing the buffer requires hitting C-x k and Return, which started to get cumbersome after a while. The way to simplify closing of such transient buffers would be to have a key binding for the kill-this-buffer function, but it would need to be buffer-specific, so as not to mess up anything else. The question is how to make such a binding with the creation of a buffer.
From EmacsWiki: https://www.emacswiki.org/emacs/BufferLocalKeys
For buffer-local keys, you cannot use local-set-key, unless you want to modify the keymap of the entire major-mode in question: local-set-key is local to a major-mode, not to a buffer.
For buffer-local modifications, use this instead:
(use-local-map (copy-keymap foo-mode-map))
(local-set-key "d" 'some-function)
Written by:  TiagoSaboga
To inspect the change, type C-h b aka M-x describe-bindings
I'd suggest you add a call to special-mode after the call to switch-to-buffer.
In the longer run, you'll want to use your own major mode, so you'd do:
(define-derived-mode my-image-mode special-mode "MyImage"
"My own major mode to display images."
;; We could add more things here
)
(defun create-buffer-with-image (name)
(with-current-buffer (generate-new-buffer name)
(my-image-mode)
(let ((image (get-svg-for-kanji-code name)))
(turn-on-iimage-mode)
(iimage-mode-buffer t)
(insert-image image)
(pop-to-bffer (current-buffer)))))
I was a bit mislead by some posts on the web suggesting the use of local-key-binding, but somehow it did not work for me - when the image was displayed and I examined the key bindings, my choice of q was not in effect. After some experimentation and digging through elisp references I found that I needed to use local-set-key. So now my function looks like this:
(defun create-buffer-with-image (name)
(let ((buffer (generate-new-buffer name))
(image (get-svg-for-kanji-code name)))
(switch-to-buffer buffer)
(local-set-key (kbd "q") 'kill-this-buffer)
(turn-on-iimage-mode)
(iimage-mode-buffer t)
(insert-image image)))
and the newly created image buffer can easily be closed by pressing q.
Create a minor mode:
(define-minor-mode my-mode "my doc" nil nil (make-sparse-keymap))
Then you can use this mode's my-mode-map to define your keybindings. Activate the mode with (my-mode).

Preserving buffer-face-mode when switching major-modes

Once in a while I manually set the font-family and size different from the default, and I use buffer-face-mode to do it. (To be exact I use the mouse & pick one from the dialog box.) Once I set it, I'd like it to stay set for that buffer, even if I change modes, so I tried a customization. The idea was to add a change-major-mode-hook (which runs just before buffer-locals get killed) that would save the buffer face, if it is set, in a function to be called later- that much seems to work. But then that function seems to be called too soon, and when the mode change is over, buffer-face-mode is not active.
Here's the customization I cam up with so far
(defun my-preserve-bufface-cmmh ()
"Keep the state of buffer-face-mode between major-mode changes"
(if (and (local-variable-p 'buffer-face-mode) buffer-face-mode)
(delay-mode-hooks
(message "face is %s" buffer-face-mode-face) ; Just to show me it has the right face
(let ((my-inner-face buffer-face-mode-face))
(run-mode-hooks
(message "inner %s" my-inner-face) ; it still has the right face here
(setq buffer-face-mode-face my-inner-face)
(buffer-face-mode))))))
(add-hook 'change-major-mode-hook
'my-preserve-bufface-cmmh)
The messages both run and show a custom face, as they should, when I'm changing major-mode in a buffer with the minor-mode buffer-face-mode set. I had thought the combination of delay-mode-hooks ... run-mode-hooks would make setq buffer-face-mode-face ... (buffer-face-mode) run after the new mode was set up, but apparently not.
Is this customization "close"/salvageable for my wants? Is there a cleaner way?
The first thing is that delayed-mode-hooks is itself a local variable.
That means, if you set it by (delay-mode-hooks (run-mode-hooks ...)) in change-major-mode-hook
this will have no effect since it is killed instantaneously.
The second thing is that the stuff within your run-mode-hooks is
evaluated within my-preserve-bufface-cmmh. It should be defined as a back-quoted hook function
`(lambda () ...) where you splice in the values you want to keep.
The alternative would be to use lexical binding (which google).
The 2nd thing is demonstrated in the following example (to be evaluated step-by-step):
(defun test (str)
(let ((mytest (concat "hello " str)))
(add-hook 'my-own-hook `(lambda () (message "mytest:%S" ,mytest)))))
(test "you")
(run-hooks 'my-own-hook)
(test "world")
(run-hooks 'my-own-hook)
(put :myface 'test)
If you want to keep the font buffer-local you have to use a local variable that survives kill-all-local-variables such as buffer-file-name. You can hook a property there:
Edit: Even if the symbol has a buffer local value its properties are not buffer local. Thus, the previous approach did not work. Better: Create your own permanent buffer-local variable:
(defvar-local my-preserve-bufface nil
"Keep the state of buffer-face-mode between major-mode changes")
(put 'my-preserve-bufface 'permanent-local t)
(defun my-preserve-bufface-put ()
"Keep the state of buffer-face-mode between major-mode changes"
(and (local-variable-p 'buffer-face-mode)
buffer-face-mode
(setq my-preserve-bufface buffer-face-mode-face)))
(defun my-preserve-bufface-get ()
"Keep the state of buffer-face-mode between major-mode changes"
(and my-preserve-bufface
(setq buffer-face-mode-face my-preserve-bufface)
(buffer-face-mode)))
(add-hook 'change-major-mode-hook 'my-preserve-bufface-put)
(add-hook 'after-change-major-mode-hook 'my-preserve-bufface-get)
Thanks for the educational comments and especially the answer/example from #user2708138, which I am going to accept because it does answer the question.
Yet I am also going to answer my own question, since I did come up with working code that is a more general solution. I went down this path after finding I also wanted my font-size changes maintained and that they were from text-scale-mode, one more minor-mode to keep. This code reads a list of minor-modes to preserve, without my having to figure out which variables they use. (It isn't too hard for a human to figure them out, but I wanted to try having emacs do it).
Alas there is no function I know of to retrieve the variables used by a minor-mode, but the modes I'm interested in use the convention minor-mode-var-name, so this code just filters buffer-local variables for that pattern.
; Save & restore minor modes I wish to be "permanent" if set
(setq my-preserve-minor-modes '(buffer-face-mode text-scale-mode))
(defun my-preserve-minor-modes-cmmh ()
"Keep the state of desired-permanent minor modes between major-mode changes. Assumes that associated buffer-local minor-mode variables to save begin with `minor-mode-'"
(setq my-restore-minor-modes-acmmh nil)
(dolist (mm my-preserve-minor-modes)
(when (and (local-variable-p mm) (symbol-value mm))
(push mm my-restore-minor-modes-acmmh)))
(when my-restore-minor-modes-acmmh
(add-hook 'after-change-major-mode-hook 'my-restore-minor-modes-acmmh)
; Predicate-list showing if symbol starts with a preserved mode
(let ((mm-p-l `(lambda (locvar-nm)
(or ,#(mapcar (lambda (mm)
`(and (< ,(length (symbol-name mm))
(length locvar-nm))
(string-prefix-p ,(symbol-name mm)
locvar-nm)))
my-restore-minor-modes-acmmh)))))
; For each found minor mode, create fn to restore its buf-local variables
(dolist (locvar (buffer-local-variables))
(if (and (listp locvar) (funcall mm-p-l (symbol-name (car locvar))))
(push `(lambda()(setq ,(car locvar) ',(cdr locvar)))
my-restore-minor-modes-acmmh))))))
(defun my-restore-minor-modes-acmmh ()
"After major-mode change, restore minor-mode state, and remove self from hook. It restores state by calling the function stored in the variable my-restore-minor-modes-acmmh."
(remove-hook 'after-change-major-mode-hook 'my-restore-minor-modes-acmmh)
(dolist (restore-f my-restore-minor-modes-acmmh) (funcall restore-f)))
(add-hook 'change-major-mode-hook 'my-preserve-minor-modes-cmmh)
I did know about the permanent-local property but I wasn't sure about any unwanted side-effects... probably unwarranted paranoia on my part!
My answer could be improved if there is ever a way to get a list of variables for a minor mode, or by having the user specify an alist of variables per minor mode- in either case we wouldn't have to loop over buffer-local-variables anymore, and maybe simply making those all permanent-local would be all we need, simplifying the code quite a bit. Anyway, figuring all this out (with your help & looking at the fine manual) was quite educational.

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