How to make auto-complete work with yasnippet and abbrev? - emacs

I want Emacs to work like this:
Let auto-complete auto-popup menu:
(setq ac-auto-show-menu 0.8)
(setq ac-delay 0.1)
Use C-n/p / M-n/p to select auto-complete popup menu candidates:
(define-key ac-menu-map (kbd "M-n") 'ac-next)
(define-key ac-menu-map (kbd "M-p") 'ac-previous)
When selecting a candiate
disable TAB / S-TAB in popup menu selection:
(define-key ac-menu-map (kbd "<tab>") nil)
(define-key ac-menu-map (kbd "<S-tab>") nil)
press Enter to select the candiate, without inserting newline:
;; ???
if the candidate is an abbrev, Enter should only select the candiate:
;; ???
... and pressing Space should cause Emacs to auto-expand the abbrev.
if the candidate is a dabbrev, pressing M-\ on candidate should trigger dabbrev-expand.
pressing TAB / C-i to expand the candidate for yasnippet:
(setq yas-trigger-key "TAB")
I set this, but the trigger does not expand when I press TAB.
pressing TAB to expand a snippet trigger while in a field:
(setq yas-triggers-in-field t)
pressing C-j to jump to next field:
(setq yas-next-field-key '("<tab>")) ;; or "C-j"
How can I expand a snippet within a snippet using yasnippet?
Some explanations
There are two TABs in Emacs:
(kbd "TAB") / (\t, [9])
(kbd "<tab>") / ([tab])
If modes like yasnippet and auto-complete want to bind to TAB, their trigger key must be the same as the original tab command. Since Emacs binds indent-for-tab-command to (kbd "TAB"), it's better to use that as the trigger key. yasnippet binds to it by default, and it is easy to set up auto-complete to trigger using TAB as well:
;; trigger using TAB and disable auto-start
(custom-set-variables
'(ac-trigger-key "TAB")
'(ac-auto-start nil)
'(ac-use-menu-map t))
But in some modes (ruby-mode, markdown-mode, org-mode, etc.), the command is bound to
(kbd "<tab>"). When the real tab key is typed, the function bound to (kbd "<tab>) has higher priority, so yasnippet and auto-complete are not invoked. This is easy to fix by moving the key binding:
(defun iy-tab-noconflict ()
(let ((command (key-binding [tab]))) ; remember command
(local-unset-key [tab]) ; unset from (kbd "<tab>")
(local-set-key (kbd "TAB") command))) ; re-bind to (kbd "TAB")
(add-hook 'ruby-mode-hook 'iy-ac-tab-noconflict)
(add-hook 'markdown-mode-hook 'iy-ac-tab-noconflict)
(add-hook 'org-mode-hook 'iy-ac-tab-noconflict)
My setup
I downloaded yasnippet, auto-complete via the el-get packager manager. I'm using Ubuntu 12.04 and Emacs 24.3.50.1.
Wrapping up
I know this problem is a little long, but it really makes it difficult for me to use auto-complete and yasnippet. If the basic key binding doesn't work smoothly, this slows down my workflow quite a bit. I think many people have similar problems because I found some similar questions on the internet (though none of them are exactly like mine).
As you can see above, some of the relevant settings I already know. (But if you think I made a mistake somewhere, please tell me.) There are also some things I still don't know how to set up (???). Maybe there isn't a way to make all of these settings work together? Let me know if that is the case, and otherwise please make sure none of these setting interfere with each other.
After I get the answer to this question, I hope to write an Emacs extension to initialize all of these settings automatically.
Thanks for your help!

I faced the problem you're describing a long time ago and resolved it like this:
bind auto-complete to TAB (also C-i which is the same)
and yasnippet to C-o.
Abbrevs are on C-o as well, but I don't use them a lot.
The advantages are:
No stateful behavior results in a much more relaxed and productive editing.
You no longer think "what will TAB do in this context?" before pressing,
you just press it.
You no longer check if you got the expected outcome, because there's only one.
You can use auto-complete while in the process of expanding yasnippet.
C-i and C-o are neighbors and very easy to press.
Yasnippets now expand reliably in any mode since no mode overrides C-o.
This may be not what you want right now but consider trying it:
you might like it after a while.

Bind RET or <return> to function ac-expand. This is for select candidate.

Related

completing-read-default auto-focus candidate window

How to automatically set focus to window with displayed candidates (after tab punch) in default emacs read with autocompletion?
I can not use IDO nor other autocompletion systems in my case because I need to browse through 80k+ candidates, and only autocompletion system which can handle this is the default one.
I will be glad for any useful pointers.
EDIT
After some research, I get to work following imperfect solution:
(define-key minibuffer-local-completion-map
(kbd "<tab>")
(lambda ()
(interactive)
(call-interactively 'minibuffer-complete)
(call-interactively 'switch-to-completions)))
(define-key completion-list-mode-map
(kbd "C-f")
'isearch-forward)
Only problem is, after I enter completing-read-default, I must first hit TAB to open window with candidates (with newly added autofocus). But I want it to open window with candidates immediately without need to hit TAB. How to do it? I tried to call minibuffer-complete after call to completing-read-default but it doesnt opened window with candidates, only standard minibuffer prompt.
After some pain, I finally found solution
(defun custom/default-completing-read (question candidates)
(run-at-time "0.5" nil
(lambda ()
(minibuffer-complete)
(switch-to-completions)
(isearch-forward)))
(completing-read-default question candidates))
After call, it invokes default (written in C) completion system which can handle tons and tons of candidates without problems with automatic jump into candidate selection with isearch-forward enabled.
Hope it will help someone in future ...

Disable completion pop-up in python-mode shadowing indentation

I updated recently my version of python-mode.el. Since then pressing at end of lines tries completion instead of indentation and pops up a buffer of suggestion.
I would rather have only indentation. I use something else for completion.
How can this be achieved?
By the way, auto indentation grew /less/ smart with the update. What possibly have I broken?
You didn't tell which python-mode. Also assume it's about TAB-key.
WRT python-mode.el comment out the present key-setting and write the desired one.
Like that:
;; (define-key map (kbd "TAB") 'py-indent-or-complete)
(define-key map (kbd "TAB") 'py-indent-line)
You shouldn't need to modify the mode file itself to make this happen. You should be able to do it via python-mode-hook. This works for me (in my ~/.emacs):
(add-hook 'python-mode-hook
(define-key python-mode-map (kbd "TAB") 'py-indent-line))

How to restore anything-like behavior for TAB autocomplete in helm?

A related question was asked here. But the answer is to get used to the new way autocomplete works in helm. I cannot get used to it, here's why.
Say, I want to open a file /home/user/work/f.txt. I do C-x C-f, it takes me to current dir, say /current/dir/. I hit Backspace and notice that autocomplete won't let me delete /. Ok, turn off autocomplete with C-Backspace. Then kill the line C-a C-k and start typing. Notice that autocomplete doesn't work, turn it back on C-Backspace. Normally I would type the part that I know is probably unique, e.g. /hom and hit Tab.
Not here. As soon as I type /ho, autocomplete resolves it to /home/, but since I type fast, I end up with /home/m, and continue typing now meaningless characters until I notice it. Chances are, by that time I got autocompleted into directories that I had no intent of going.
So I have to constantly watch what autocomplete is doing, rather than rely on what I type and only checking suggested completions when I hit Tab.
I also find myself descending into wrong directories due to occasional typo, and then having difficulty going up a level -- evil autocomplete won't let you fix the situation with a couple of Backspaces.
This interaction of autocomplete behavior and the removal of Tab functionality completely upsets my work, so much that I decided to ask this question. I am looking to either:
restore the old functionality
learn how to use autocomplete in a meaningful way, or
configure helm's C-x C-f to behave more like a linux command line
Please help.
Here are some ido tricks if you want to start using it.
Let me know if helm is better, perhaps I'll switch over.
I tried once shortly, but didn't like it.
Basic setup:
This will give you `ido-find-file on C-x C-f.
(ido-mode)
(setq ido-enable-flex-matching t)
Smex setup:
Install from https://github.com/nonsequitur/smex.
(require 'smex)
(global-set-key "\C-t" 'smex)
Switch buffers with ido:
(global-set-key
"η"
(lambda()(interactive)
(when (buffer-file-name)
(save-buffer))
(ido-switch-buffer)))
(global-set-key
(kbd "C-η")
(lambda()(interactive)
(let ((ido-default-buffer-method 'other-window))
(ido-switch-buffer))))
Tricks:
;; 1
(add-hook 'dired-mode-hook
(lambda()
(define-key dired-mode-map "j" 'ido-find-file)))
(add-hook
'ido-setup-hook
(lambda()
;; 2
(define-key ido-file-dir-completion-map "~"
(lambda ()(interactive)
(ido-set-current-directory "~/")
(setq ido-exit 'refresh)
(exit-minibuffer)))
;; 3
(define-key ido-buffer-completion-map "η" 'ido-next-match)
;; 4
(define-key ido-buffer-completion-map (kbd "C-p")
'ido-fallback-command)
;; 5
(define-key ido-completion-map (kbd "C-.") 'smex-find-function)
(define-key ido-completion-map (kbd "C-,") 'smex-describe-function)))
Quick open file from dired.
Move to home directory one key faster (i.e. ~ instead of ~/).
Cycle buffer candidates with the same key that shows the candidates (a la C-TAB in Firefox).
Useful to have a fall back when you want to create a file-less buffer (ido will try
select an existing buffer unless you fall back).
Useful to jump to function definition/documentation.
If you want TAB completion of directories and file names, map helm-execute-persistent-action to the TAB key:
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
See also the answer to "How can I change emacs helm-find-file default action[...]".

Setting shortcuts keys in specific modes in Emacs (e.g. ido)

I have two problems which are somewhat related I believe:
1) In IDO I'd like to change ido-restrict-to-matches to samething else than C-SPC or C-#. Unfortunately I do not know how to tell emacs that I want a different shortcut (say C-0).
2) I'd like to protect my C-; but whenever flyspell-mode is running it overtakes C-;. My definition is in .emacs as:
(global-set-key (kbd "C-;") 'mark-paragraph)
but apparently flyspell overwrites this... (although even then, if I look in the help M-h k C-; it does say mark-paragraph)
Could somebody please tell me how to bind/unbind keys in these conditions? It has to work without modifying ido.el and flyspell.el and re-building, right?
Thanks very much!
Flyspell provides a customization for the C-; binding, so you can either M-x customize RET flyspell-auto-correct-binding RET or put something like this in your ~/.emacs:
(setq flyspell-auto-correct-binding (kbd "C-~")) ; or a binding of your choice
As for ido, your question is slightly confusing, because it implies there are times when you're using ido outside the minibuffer...
The documentation in ido.el contains the following advice:
;; To modify the keybindings, use the ido-setup-hook. For example:
;;(add-hook 'ido-setup-hook 'ido-my-keys)
;;
;;(defun ido-my-keys ()
;; "Add my keybindings for ido."
;; (define-key ido-completion-map " " 'ido-next-match)
;; )
Using that knowledge, you can change the key bindings like this in your own "ido-my-keys" function:
(define-key ido-completion-map (kbd "C-SPC") nil)
(define-key ido-completion-map (kbd "C-#") nil)
(define-key ido-completion-map (kbd "C-0") 'ido-restrict-to-matches)
There's an additional ido hook specifically for the minibuffer, too, but it's not clear why you would need that: ido-minibuffer-setup-hook.

Assign multiple Emacs keybindings to a single command?

I'm giving ErgoEmacs mode a try to see if I can use Emacs more comfortably. Some of its keybindings are fairly intuitive, but in many cases I don't want to outright replace the defaults.
For example, in the context of ErgoEmacs' navigation shortcut structure, M-h makes sense as a replacement for C-a--but I want to be able to use both, not just M-h. I tried simply duplicating the commands:
;; Move to beginning/ending of line
(defconst ergoemacs-move-beginning-of-line-key (kbd "C-a")) ; original
(defconst ergoemacs-move-end-of-line-key (kbd "C-e")) ; original
(defconst ergoemacs-move-beginning-of-line-key (kbd "M-h")) ; ergoemacs
(defconst ergoemacs-move-end-of-line-key (kbd "M-H")) ; ergoemacs
But Emacs simply overwrites the first keybinding with the second. What's the best way to address this?
To re-post reply from ergo-emacs mailing list:
Xah Lee said:
that's very easy.
in the
ergoemacs-mode.el file, there's this
line (load "ergoemacs-unbind") just
comment it out. That should be all
you need to do. However, note that
ErgoEmacs keybinding defines those
common shortcuts such as Open, Close,
New, Save... with keys Ctrl+o,
Ctrl+w, Ctrl+n, Ctrl+s etc. About 7 of
them or so. So, i think some of these
will hit on emacs traditional
bindings with Ctrl. if you are new to
ErgoEmacs and trying to explore it,
you might just try starting with few
keys. this page might have some
useful info:
http://code.google.com/p/ergoemacs/wiki/adoption
thanks for checking out ErgoEmacs!
Xah ∑ http://xahlee.org/
As it turns out, ErgoEmacs uses two files to define the keybinding. One is the main ergoemacs-mode.el file, and the other is the specific keyboard layout you select (e.g. ergoemacs-layout-us.el). The latter document creates a constant, which the former uses to create the keybinding. So while I thought I was duplicating the keybinding, I was actually changing the constant which was subsequently used for that purpose.
Solution:
In ergomacs-mode.el:
;; Move to beginning/ending of line
(define-key ergoemacs-keymap ergoemacs-move-beginning-of-line-key 'move-beginning-of-line)
(define-key ergoemacs-keymap ergoemacs-move-end-of-line-key 'move-end-of-line)
(define-key ergoemacs-keymap ergoemacs-move-beginning-of-line-key2 'move-beginning-of-line) ; new
(define-key ergoemacs-keymap ergoemacs-move-end-of-line-key2 'move-end-of-line) ; new
In ergoemacs-layout-us.el:
;; Move to beginning/ending of line
(defconst ergoemacs-move-beginning-of-line-key (kbd "M-h"))
(defconst ergoemacs-move-end-of-line-key (kbd "M-H"))
(defconst ergoemacs-move-beginning-of-line-key2 (kbd "C-a")) ; new
(defconst ergoemacs-move-end-of-line-key2 (kbd "C-e")) ; new
Huh? Is having one and only one way for every function some golden principle of ErgoEmacs? Because normal keybinding works exactly the opposite way: you name one key at a time and specify what it should do. If a mode defines a global variable to mean "the key that end-of-line is bound to", then of course there can be only one value, but with the normal binding commands you can bind the same function to as many combinations as you like. In fact, every keybinding I have ever seen used looked either like this
(global-set-key [(meta space)] 'just-one-space)
or like this
(add-hook 'c-mode-hook 'my-c-mode-hook)
(defun my-c-mode-hook ()
(define-key c-mode-map [(control c) b] 'c-insert-block))
if it's only for a specific mode.