The right place to use yas-activate-extra-mode
is web-mode-on-engine-setted
since that function also sets the engine specific snippets of web-mode
.
Pityingly there is no hook so we have to add an advice.
You can put the following into your init file.
After loading that init file (e.g., at emacs-restart) your engine-dependent yas-directory structure works.
(require 'web-mode)
(defcustom my-web-yas-mode-alist
'(("erb" . erb)
("django" . django))
""
:group 'web-mode
:type '(repeat (cons
:tag "Map engine name to mode"
(string :tag "Engine Name")
(symbol :tag "Mode"))))
(defun my-web-setup-yas ()
"Setup yas according to `web-mode-engine`."
(require 'yasnippet)
(let ((extra-mode (cdr (assoc-string web-mode-engine my-web-yas-mode-alist))))
(when extra-mode
(yas-activate-extra-mode extra-mode))))
(advice-add 'web-mode-on-engine-setted :after #'my-web-setup-yas)
Note that you should use the web-mode as yas-parent in each of your derived yasnippet modes (also those that do not exist as real major modes).
Correction: The snippets for web-mode
are activated anyway since that is the major-mode of the buffer.
Note: If you want to keep your directory structure you must consider following items:
Use ~/.emacs.d/snippets/web-mode
as one of the root-directories.
- You can do that with the following code:
(eval-after-load 'yasnippet
'(let ((dir "~/.emacs.d/snippets/web-mode"))
(add-to-list 'yas-snippet-dirs dir)
(yas-load-directory dir)))
You cannot load snippets directly from the directory ~/.emacs.d/snippets/web-mode
.
- Otherwise the snippets in all sub-directories are also interpreted as snippets of
web-mode
.
- You can avoid loading snippets from
~/.emacs.d/snippets/web-mode
by putting a file .yas-skip
in there.
- If you have snippets for web-mode in
~/.emacs.d/snippets/web-mode
you could use another directory, e.g., ~/.emacs.d/snippets/web-mode-engines
for collecting the extra modes erb
and django
in that case you must adapt the Elisp code here and the location for .yas-skip
to that new directory. Actually, you do not even need .yas-skip
anymore since there is no mode named web-mode-engines
that could be loaded.
If you do not like that hassle of the previous steps you need to move ~/.emacs.d/snippets/web-mode/erb
and ~/.emacs.d/snippets/web-mode/django
to ~/.emacs.d/snippets/
and afterwards reload the snippet directory ~/.emacs.d/snippets/
.
Test conditions:
Running emacs -Q
, version GNU Emacs 26.1 (build 2, i686-pc-linux-gnu, GTK+ Version 3.22.30) of 2018-05-29
Via package
library installed relevant packages:
Reconstruction:
- Start Emacs with
emacs -Q
- Run M-x
package-initialize
- Put the following snippets into their places:
File ~/.emacs.d/snippets/web-mode/erb/if
:
# -*- mode: snippet -*-
# name: if statement
# key: if
# --
<% if $1 %>
$2
<% end %>
File ~/.emacs.d/snippets/web-mode/erb/unless
:
# -*- mode: snippet -*-
# name: unless statement
# key: unless
# --
<% unless $1 %>
$2
<% end %>
File ~/.emacs.d/snippets/web-mode/django/if
:
# -*- mode: snippet -*-
# name: if statement
# key: if
# --
{% if $1 %}
$2
{% endif %}
File ~/.emacs.d/snippets/web-mode/django/with
:
# -*- mode: snippet -*-
# name: with statement
# key: with
# --
{% with $1 %}
$2
{% endwith %}
- Put the above two Elisp source blocks into the
*scratch*
buffer and run M-x eval-buffer
there.
- Run M-x
yas-global-mode
.
- Open the erb test file with the following content:
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<ul>
<% @products.each do |p| %>
<li><%= @p.name %></li>
</ul>
</body>
</html>
<!--
Local Variables:
mode: web
eval: (web-mode-set-engine "erb")
End:
-->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>About {{ title }}</h1>
<p>This Website was developed by {{ author }}.</p>
<p>Now using the Django's Template Engine.</p>
<p><a href="{% url 'homepage' %}">Return to the homepage</a>.</p>
</body>
</html>
<!--
Local Variables:
mode: web
eval: (web-mode-set-engine "django")
End:
-->
Test result:
- The
YASnippet
menu now contains the submenus django,prog-mode,nxml-mode,html-mode
.
- The
django
submenu contains the items
- Inserting
if
and pressing TAB results into the expansion of the django-if-statement.
- The
erb
submenu contains the items if statement
and with statement
.
.djhtml
or.rhtml
?.erb.html
but Django uses plain.html
files.M-x emacs-version
), your web-mode version and your yas-version. You find your web-mode version and your yas-version inM-x package-list-packages
.