Autocomplete randomly working / not working with yasnippet, why? - emacs

I have configured yasnippet and auto-complete bindings so it won't collide, auto complete uses <tab> and yasnippet uses <backtab>:
(add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet")
(require 'yasnippet)
(yas-global-mode 1)
;; Remove Yasnippet's default tab key binding
(define-key yas-minor-mode-map (kbd "<tab>") nil)
(define-key yas-minor-mode-map (kbd "TAB") nil)
;; Set Yasnippet's key binding to shift+tab
(define-key yas-minor-mode-map (kbd "<backtab>") 'yas-expand)
I also added yasnippet source like this to the ac-sources as recommended in this question.
(defun add-yasnippet-ac-sources ()
(add-to-list 'ac-sources 'ac-source-yasnippet))
(add-hook 'web-mode-hook 'add-yasnippet-ac-sources)
I created two yasnippets one with the key lorem_dummy and the other with the key lorem_image, one of the examples:
# -*- mode: snippet; require-final-newline: nil -*-
# name: lorem_image
# key: lorem_image
# binding: direct-keybinding
# --
<img src="http://lorempixel.com/${1:width}/${2:height}/${3:$$(yas-choose-value '("abstract" "city" "animals" "food" "people" "transport" "business" "sports" "technics"))}/${4:text}" alt="$3">
After following the solution in the "duplicated question" link, everything seemed to work perfectly, but then after a few hours it started to behave strange, randomdly, sometimes it works sometimes it doesn't. I made a video showing the problem, it works, then I restart Emacs and stops working again.
VIDEO 1
>UPDATE<
ok, I found out something, it's not that it works randomly, it's just that it simply doesn't works. In that video the auto complete works with the yasnippet keys because they're opened in other buffers, and it's using that. If I close those buffers, they simply stop working.
So, the problem is that with this init.el AC it simply doesn't works with yasnippet
VIDEO 2 UPDATE AND COMMENTS

Related

Is it possible to make autocomplete to complete a yasnippet in Emacs? [duplicate]

This question already has an answer here:
How to get completion for yasnippets using auto-complete
(1 answer)
Closed 7 years ago.
I have configured yasnippet and auto-complete bindings so it won't collide, auto complete uses <tab> and yasnippet uses <backtab>:
(add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet")
(require 'yasnippet)
(yas-global-mode 1)
;; Remove Yasnippet's default tab key binding
(define-key yas-minor-mode-map (kbd "<tab>") nil)
(define-key yas-minor-mode-map (kbd "TAB") nil)
;; Set Yasnippet's key binding to shift+tab
(define-key yas-minor-mode-map (kbd "<backtab>") 'yas-expand)
I created two yasnippets one with the key lorem_dummy and the other with the key lorem_image, one of the examples:
# -*- mode: snippet; require-final-newline: nil -*-
# name: lorem_image
# key: lorem_image
# binding: direct-keybinding
# --
<img src="http://lorempixel.com/${1:width}/${2:height}/${3:$$(yas-choose-value '("abstract" "city" "animals" "food" "people" "transport" "business" "sports" "technics"))}/${4:text}" alt="$3">
is it possible to make Emacs auto complete work if I just write lorem and press to show in a dropdown the two choices ( lorem_dummy and lorem_image )? Because right now it doesn't come up the yasnippets, but the regular autocomplete does work ( variables and the rest of the stuff ).
-- update --
Ok, this is strange, after following the solution in the "duplicated question" link, everything seemed to work perfectly, but then after a few hours it started to behave strange, randomdly, sometimes it works sometimes it doesn't. I made a video showing the problem, it works, then I restart Emacs and stops working again.
video
Add ac-source-yasnippet to your ac-sources, e.g.
(eval-after-load "auto-complete"
'(add-to-list 'ac-sources 'ac-source-yasnippet))

Emacs replacing require with autoload

After profiling my Emacs init file, I saw that many of my modes are taking a long time to load, explaining why I've been having slow start times.
I am trying to use after-load or autoload to decrease the load time but have been unsuccessful in many modes.
For example, I have a mode called multiple-cursors.el that I downloaded manually and placed in my .emacs.d directory. Here is the code I have now:
;; Multiple Cursors
(add-to-list 'load-path "~/.emacs.d/multiple-cursors.el/")
(require 'multiple-cursors)
(global-set-key (kbd "C-c c") 'mc/edit-lines)
(global-set-key (kbd "C-c .") 'mc/mark-next-like-this)
(global-set-key (kbd "C-c ,") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-c /") 'mc/mark-all-like-this)
I tried to replace the require line with (autoload 'multiple-cursors-mode "multiple-cursors.el" "Multiple cursors mode") but that did not work.
This format of the autoload seems to work well only with Melpa-installed packages. How can I do the equivalent for manually installed packages, such as the example above?
You need to write autoloads for the functions that you are actually calling through the key bindings (i.e. mc/edit-lines, mc/mark-next-like-this, mc/mark-previous-like-this and mc/mark-all-like-this), since that's how the loading of the file is triggered. The autoloads need to refer to the files where the respective functions are defined, which is mc-edit-lines for mc/edit-lines, and mc-mark-more for the others.
So after setting the load path and binding the keys, add something like this:
(autoload 'mc/edit-lines "mc-edit-lines" "" t)
(autoload 'mc/mark-next-like-this "mc-mark-more" "" t)
(autoload 'mc/mark-previous-like-this "mc-mark-more" "" t)
(autoload 'mc/mark-all-like-this "mc-mark-more" "" t)

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

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.

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[...]".

emacs, flyspell, deactivate "C-." key binding

I have this little problem, I have some key bindings like so C-. C-x or C-. C-m. After I activate the flyspell-mode, I cannot use these commands. In my .emacs file I have the next 2 lines before
(global-unset-key (kbd "C-."))
(define-key (current-global-map) (kbd "C-.") nil)
(global-set-key (kbd "C-. C-l") 'global-linum-mode)
Then, my C-. C-l works, but it does not when the flyspell-mode is activated. The command bound to C-. is flyspell-auto-correct-word. I tried to deactivate it as follows:
;; first try
(defun flyspell-auto-correct-word-disable() (define-key (current-local-map) (kbd "C-.") nil))
(add-hook 'flyspell-mode-hook 'flyspell-auto-correct-word-disable)
;; second try
(define-key (current-global-map) [remap flyspell-auto-correct-word] nil)
None of the tries work, what can I do? I tried in Emacs 23 and 24 and I have the same issue.
What about:
(eval-after-load "flyspell"
'(define-key flyspell-mode-map (kbd "C-.") nil))
Your first solution is almost correct, but you have to remember that the current local map is set up by the major mode, not minor modes. The best option you have it to directly access flyspell-mode-map and modify it (another option would be to find it in minor-mode-map-alist but I think it would be needlessly complicated).
Also, I prefer putting such mode-specific settings within eval-after-load (which means they will be evaluated once) rather than in a hook (in which case the settings are evaluated multiple times: each time one buffer activates flyspell-mode). But this is a matter of preference and either way is fine.