Merge in branch 'master' into snippet-engine

This commit is contained in:
João Távora 2015-04-02 17:51:27 +01:00
commit d1930d2ff2
20 changed files with 899 additions and 628 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
authors.txt authors.txt
doc/gh-pages doc/gh-pages
doc/*.html doc/*.html
doc/html-revision
pkg/ pkg/
extras/imported/** extras/imported/**
!extras/imported/*/.yas-setup.el !extras/imported/*/.yas-setup.el

9
.gitmodules vendored
View File

@ -1,6 +1,7 @@
[submodule "snippets"] [submodule "snippets"]
path = snippets path = snippets
url = git@github.com:AndreaCrotti/yasnippet-snippets.git url = https://github.com/AndreaCrotti/yasnippet-snippets.git
branch = master
[submodule "yasmate"] [submodule "yasmate"]
path = yasmate path = yasmate
url = git@github.com:capitaomorte/yasmate.git url = https://github.com/capitaomorte/yasmate.git

24
.travis.yml Normal file
View File

@ -0,0 +1,24 @@
language: emacs
env:
- "EMACS=emacs23"
- "EMACS=emacs24"
install:
- if [ "$EMACS" = "emacs23" ]; then
sudo apt-get -qq update &&
sudo apt-get -qq -f install &&
sudo apt-get -qq install emacs23-nox &&
curl -LO https://raw.githubusercontent.com/ohler/ert/c619b56c5bc6a866e33787489545b87d79973205/lisp/emacs-lisp/ert.el &&
curl -LO https://raw.githubusercontent.com/ohler/ert/c619b56c5bc6a866e33787489545b87d79973205/lisp/emacs-lisp/ert-x.el &&
curl -Lo cl-lib.el http://elpa.gnu.org/packages/cl-lib-0.5.el;
fi
- if [ "$EMACS" = "emacs24" ]; then
sudo add-apt-repository -y ppa:cassou/emacs &&
sudo apt-get -qq update &&
sudo apt-get -qq -f install &&
sudo apt-get -qq install emacs24-nox;
fi
script:
- rake compile; rake tests

27
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,27 @@
# Submitting Bug Reports
Please read [Important note regarding bug reporting][bugnote].
# Contributing to Yasnippet
## Copyright Assignment
Yasnippet is part of GNU ELPA, so it falls under the same copyright
assignment policy as the rest of Emacs (see "Copyright Assignment" in
https://www.gnu.org/software/emacs/CONTRIBUTE). A copyright assignment
for Emacs also covers Yasnippet.
## Commit message format
The commit message format roughly follows Emacs conventions, although
there is no separate Changelog file.
The commit message's first sentence should be capitalized, no period
It may be followed by a paragraph with a longer explanation. The
changelog style entry goes at the end of the message.
* foo.el (a-function): Terse summary of per-function changes.
[bugnote]: https://github.com/capitaomorte/yasnippet#important-note-regarding-bug-reporting

View File

@ -1,3 +1,5 @@
[![Build Status](https://travis-ci.org/capitaomorte/yasnippet.png)](https://travis-ci.org/capitaomorte/yasnippet)
# Intro # Intro
**YASnippet** is a template system for Emacs. It allows you to **YASnippet** is a template system for Emacs. It allows you to
@ -107,44 +109,63 @@ should be added like this to `yas-snippet-dirs`:
(yas-global-mode 1) ;; or M-x yas-reload-all if you've started YASnippet already. (yas-global-mode 1) ;; or M-x yas-reload-all if you've started YASnippet already.
# Documentation, issues, etc # Manual, issues etc
Please refer to the comprehensive (albeit slightly outdated) Please refer to the comprehensive [documentation][docs] for full
[documentation][docs] for full customization customisation and support. If you find a bug in the code or in the
and support. If you find a bug, please report it on documentation, please report it on [the GitHub issue tracker][issues].
[the GitHub issue tracker][issues]. (please **do not** submit new issues to the old
[googlecode tracker][googlecode tracker])
## Important note regarding bug reporting ## Important note regarding bug reporting
If you think have found a bug, please report it clearly. Yasnippet
does have (lots of) bugs and your reports are very valuable. Here's
a [great example](https://github.com/capitaomorte/yasnippet/issues/318)
of a bug report. It has everything needed for a sucessfull analysis and
speedy resolution:
*Before* reporting try to reproduce the bug **without** your usual Your bug reports are very valuable.
`.emacs` (or whatever startup file you use). Do so either by starting
emacs from the command line with the `-Q` switch, or by temporarily
moving away your `.emacs` and creating a new smaller one just for
reproducing the bug. Paste that file in your bug report. Paste any sequence
of relevant shell commands before you launch Emacs.
*Then*, describe steps taken to reproduce from an The most important thing when reporting bugs is making sure that we have
end-user perspective. Try to be as unambiguous as possible. a way to reproduce the problem exactly like it happened to you.
To do this, we need to rule out interference from external factors
like other Emacs extensions or your own customisations.
Here's an example report that "sandboxes" an Emacs session just for
reproducing a bug.
```
$ emacs --version
Emacs 24.3
$ cd /tmp/
$ git clone https://github.com/capitaomorte/yasnippet.git yasnippet-bug
$ cd yasnippet-bug
$ git log -1 --oneline
6053db0 Closes #527: Unbreak case where yas-fallback-behaviour is a list
$ HOME=$PWD emacs -L # This "sandboxes" your emacs, melpa configuration, etc
(require 'yasnippet)
(yas-global-mode 1)
When I open a foo-mode file I can't expand foo-mode snippets!
OR
I can't get yasnippet to load because frankinbogen!
```
Using `emacs -Q` or temporarily moving your `.emacs` init file to the side
is another way to achieve good reproducibility.
Here's a
[another example](https://github.com/capitaomorte/yasnippet/issues/318)
of a bug report. It has everything needed for a successful analysis
and speedy resolution.
Also, don't forget to state the Emacs version (use `M-x emacs-version`) and Also, don't forget to state the Emacs version (use `M-x emacs-version`) and
the yasnippet version you are using (if using the latest from github, the yasnippet version you are using (if using the latest from github,
do `git log -1` in the dir). do `git log -1` in the dir).
Any more info is welcome, but don't just paste a backtrace or an error Any more info is welcome, but don't just paste a backtrace or an error
message string you got. I'm not saying your analysis might not be message string you got, unless we ask for it.
useful but following the instructions above immediately gives me a
clear picture of what is happening.
There is also a [YASnippet google group][forum]. I will keep the group There is also a [YASnippet google group][forum]. I will keep the group
open for reference and for discussion among users, unfortunately I open for reference and for discussion among users. Unfortunately I
can't guarantee a timely response, so maybe creating a github issue can't guarantee a timely response, so maybe it's better to create a
clearly marking your intent (user support/bug/feature request). github issue clearly marking your intent (user support/bug/feature
request).
Finally, thank you very much for using YASnippet! Finally, thank you very much for using YASnippet!

View File

@ -2,7 +2,10 @@
require 'fileutils' require 'fileutils'
$EMACS=ENV["EMACS"] || "emacs" $EMACS = ENV["EMACS"]
if not $EMACS or $EMACS == 't'
$EMACS = "emacs"
end
def find_version def find_version
File.read("yasnippet.el", :encoding => "UTF-8") =~ /;; Package-version: *([0-9.]+?) *$/ File.read("yasnippet.el", :encoding => "UTF-8") =~ /;; Package-version: *([0-9.]+?) *$/
@ -13,9 +16,8 @@ FileUtils.mkdir_p('pkg')
desc "run tests in batch mode" desc "run tests in batch mode"
task :tests do task :tests do
batch_run_line = "(yas-batch-run-tests t)" sh "#{$EMACS} -Q -L . -l yasnippet-tests.el" +
sh "#{$EMACS} -Q -L . -l yasnippet-tests.el -nw" + " --batch -f ert-run-tests-batch-and-exit"
" --batch --eval '#{batch_run_line}'"
end end
desc "create a release package" desc "create a release package"
@ -67,10 +69,22 @@ namespace :doc do
Dir.glob("doc/images/*").each do |file| Dir.glob("doc/images/*").each do |file|
FileUtils.cp file, 'doc/gh-pages/images' FileUtils.cp file, 'doc/gh-pages/images'
end end
rev = `git rev-parse --verify HEAD` Dir.glob("doc/stylesheets/*.css").each do |file|
FileUtils.cp file, 'doc/gh-pages/stylesheets'
end
curRev = `git rev-parse --verify HEAD`.chomp()
expRev = IO.read('doc/html-revision').chomp()
if curRev != expRev
raise ("The HTML rev: #{expRev},\n" +
"current rev: #{curRev}!\n")
end
if !system "git diff-index --quiet HEAD"
system "git status --untracked-files=no"
raise "You have uncommitted changes!"
end
Dir.chdir 'doc/gh-pages' do Dir.chdir 'doc/gh-pages' do
sh "git commit -a -m 'Automatic documentation update.\n\n" + sh "git commit -a -m 'Automatic documentation update.\n\n" +
"From #{rev.chomp()}'" "From #{curRev.chomp()}'"
sh "git push" sh "git push"
end end
end end

0
doc/.nosearch Normal file
View File

View File

@ -134,8 +134,7 @@ This is also the default value starting for that version. It skips the
minor mode in buffers where it is not applicable (no snippet tables), minor mode in buffers where it is not applicable (no snippet tables),
but only once you have setup your yas-root-directory. but only once you have setup your yas-root-directory.
* How do I define an abbrev key containing characters not supported by * How do I define an abbrev key containing characters not supported by the filesystem?
the filesystem?
- *Note*: This question applies if you're still defining snippets - *Note*: This question applies if you're still defining snippets
whose key /is/ the filename. This is behavior still provided by whose key /is/ the filename. This is behavior still provided by

16
doc/nav-menu.html.inc Normal file
View File

@ -0,0 +1,16 @@
<nav>
<ul class="center">
<li> <a href="index.html">Overview</a>
<li> <a href="https://github.com/capitaomorte/yasnippet/blob/master/README.mdown">
Intro and Tutorial</a>
<li class="center">Snippet
<ul>
<li> <a href="snippet-organization.html">Organization</a>
<li> <a href="snippet-expansion.html">Expansion</a>
<li> <a href="snippet-development.html">Development</a>
<li> <a href="snippet-menu.html">Menu</a>
</ul>
<li> <a href="faq.html">FAQ</a>
<li> <a href="snippet-reference.html">Reference</a>
</ul>
</nav>

View File

@ -4,6 +4,8 @@
#+LINK: sym file:snippet-reference.org::#%s #+LINK: sym file:snippet-reference.org::#%s
#+LINK_HOME: ./index.html
#+OPTIONS: author:nil num:nil #+OPTIONS: author:nil num:nil
#+AUTHOR: #+AUTHOR:
# org < 8.0 use +STYLE, after use +HTML_HEAD
#+STYLE: <link rel="stylesheet" type="text/css" href="stylesheets/manual.css" />
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="stylesheets/manual.css" />

View File

@ -6,14 +6,18 @@
** Quickly finding snippets ** Quickly finding snippets
There are some ways you can quickly find a snippet file: There are some ways you can quickly find a snippet file or create a new one:
- =M-x yas-new-snippet= - =M-x yas-new-snippet=
Prompts you for a snippet name, then tries to guess a suitable Creates a new buffer with a template for making a new snippet.
directory to store it, prompting you for creation if it does not The buffer is in =snippet-mode= (see below). When you are done
exist. Finally, places you in a new buffer set to =snippet-mode= so editing the new snippet, use =C-c C-c= to save it. This will
you can write your snippet. prompt for a directory two steps: first, the snippet table
(with a default based on the major mode you started in), and then
then snippet collection directory (defaults to the first directory
in =yas-snippet-dirs=. (See [[file:snippet-organization.org][Organizing Snippets]]
for more detail on how snippets are organized.)
- =M-x yas-find-snippets= - =M-x yas-find-snippets=
@ -169,12 +173,28 @@ This binding will be recorded in the keymap =html-mode-map=. To expand a
paragraph tag newlines, just press =C-u C-c C-c C-m=. Omitting the =C-u= paragraph tag newlines, just press =C-u C-c C-c C-m=. Omitting the =C-u=
will expand the paragraph tag without newlines. will expand the paragraph tag without newlines.
** =# type:= =snippet= or =command=
If the =type= directive is set to =command=, the body of the snippet
is interpreted as lisp code to be evaluated when the snippet is
triggered.
If it's =snippet= (the default when there is no =type= directive), the
snippet body will be parsed according to the [[Template Syntax]],
described below.
** =# uuid:= unique identifier
This provides to a way to identify a snippet, independent of its name.
Loading a second snippet file with the same uuid would replace the
previous snippet.
** =# contributor:= snippet author ** =# contributor:= snippet author
This is optional and has no effect whatsoever on snippet functionality, This is optional and has no effect whatsoever on snippet functionality,
but it looks nice. but it looks nice.
* Template syntax * <<Template syntax>>
The syntax of the snippet template is simple but powerful, very similar The syntax of the snippet template is simple but powerful, very similar
to TextMate's. to TextMate's.
@ -182,14 +202,14 @@ to TextMate's.
** Plain Text ** Plain Text
Arbitrary text can be included as the content of a template. They are Arbitrary text can be included as the content of a template. They are
usually interpreted as plain text, except =$= and ==. You need to usually interpreted as plain text, except =$= and =`=. You need to
use \` to escape them: =\$= and =\=. The \` itself may also needed to be use =\= to escape them: =\$= and =\`=. The =\= itself may also needed to be
escaped as =\\= sometimes. escaped as =\\= sometimes.
** Embedded Emacs-lisp code ** Embedded Emacs-lisp code
Emacs-Lisp code can be embedded inside the template, written inside Emacs-Lisp code can be embedded inside the template, written inside
back-quotes (==). The lisp forms are evaluated when the snippet is back-quotes (=`=). The lisp forms are evaluated when the snippet is
being expanded. The evaluation is done in the same buffer as the being expanded. The evaluation is done in the same buffer as the
snippet being expanded. snippet being expanded.
@ -267,12 +287,13 @@ the field and others mirrors.
** Mirrors with <<transformations>> ** Mirrors with <<transformations>>
If the value of an =${n:=-construct starts with and contains =$(=, then If the value of an =${n:=-construct starts with and contains =$(=,
it is interpreted as a mirror for field =n= with a transformation. The then it is interpreted as a mirror for field =n= with a
mirror's text content is calculated according to this transformation, transformation. The mirror's text content is calculated according to
which is Emacs-lisp code that gets evaluated in an environment where the this transformation, which is Emacs-lisp code that gets evaluated in
variable =text= (or [[sym:yas-text][=yas-text=]]) is bound to the text content (string) an environment where the variable [[sym:yas-text][=yas-text=]] is bound to the text
contained in the field =n=.Here's an example for Objective-C: content (string) contained in the field =n=. Here's an example for
Objective-C:
#+BEGIN_SRC snippet #+BEGIN_SRC snippet
- (${1:id})${2:foo} - (${1:id})${2:foo}
@ -280,7 +301,7 @@ contained in the field =n=.Here's an example for Objective-C:
return $2; return $2;
} }
- (void)set${2:$(capitalize text)}:($1)aValue - (void)set${2:$(capitalize yas-text)}:($1)aValue
{ {
[$2 autorelease]; [$2 autorelease];
$2 = [aValue retain]; $2 = [aValue retain];
@ -288,12 +309,13 @@ contained in the field =n=.Here's an example for Objective-C:
$0 $0
#+END_SRC #+END_SRC
Look at =${2:$(capitalize text)}=, it is a mirror with transformation Look at =${2:$(capitalize yas-text)}=, it is a mirror with
instead of a field. The actual field is at the first line: =${2:foo}=. transformation instead of a field. The actual field is at the first
When you type text in =${2:foo}=, the transformation will be evaluated line: =${2:foo}=. When you type text in =${2:foo}=, the transformation
and the result will be placed there as the transformed text. So in this will be evaluated and the result will be placed there as the
example, if you type "baz" in the field, the transformed text will be transformed text. So in this example, if you type "baz" in the field,
"Baz". This example is also available in the screencast. the transformed text will be "Baz". This example is also available in
the screencast.
Another example is for =rst-mode=. In reStructuredText, the document Another example is for =rst-mode=. In reStructuredText, the document
title can be some text surrounded by "===" below and above. The "===" title can be some text surrounded by "===" below and above. The "==="
@ -316,9 +338,9 @@ is a valid title but
is not. Here's an snippet for rst title: is not. Here's an snippet for rst title:
#+BEGIN_SRC snippet #+BEGIN_SRC snippet
${1:$(make-string (string-width text) ?\=)} ${1:$(make-string (string-width yas-text) ?\=)}
${1:Title} ${1:Title}
${1:$(make-string (string-width text) ?\=)} ${1:$(make-string (string-width yas-text) ?\=)}
$0 $0
#+END_SRC #+END_SRC

View File

@ -53,7 +53,7 @@ When you use [[sym:yas-global-mode][=yas-global-mode=]] you can also selectively
YASnippet in some buffers by setting the buffer-local variable YASnippet in some buffers by setting the buffer-local variable
[[sym:yas-dont-active][=yas-dont-active=]] in the buffer's mode hook. [[sym:yas-dont-active][=yas-dont-active=]] in the buffer's mode hook.
*** Fallback bahaviour *** Fallback behaviour
[[sym:yas-fallback-behaviour][=yas-fallback-behaviour=]] is a customization variable bound to [[sym:yas-fallback-behaviour][=yas-fallback-behaviour=]] is a customization variable bound to
'=call-other-command= by default. If [[sym:yas-expand][=yas-expand=]] failed to find any '=call-other-command= by default. If [[sym:yas-expand][=yas-expand=]] failed to find any

View File

@ -2,14 +2,11 @@
#+TITLE: Reference #+TITLE: Reference
* Reference
#+BEGIN_SRC emacs-lisp :exports results :results value raw #+BEGIN_SRC emacs-lisp :exports results :results value raw
(yas--document-symbols 2 `("Interactive functions" . ,#'interactive-form) (yas--document-symbols 1 `("Interactive functions" . ,#'interactive-form)
`("Customization variables" . ,#'(lambda (sym) `("Customization variables" . ,#'(lambda (sym)
(and (boundp sym) (and (boundp sym)
(get sym 'standard-value)))) (get sym 'standard-value))))
`("Useful functions" . ,#'fboundp) `("Useful functions" . ,#'fboundp)
`("Useful variables" . ,#'boundp)) `("Useful variables" . ,#'boundp))
#+END_SRC #+END_SRC

View File

@ -0,0 +1,26 @@
nav > ul > li.center > ul {
padding: 0;
}
nav li {
vertical-align: top;
display: inline;
list-style-type: none;
padding: 0.5em;
}
nav > ul > li {
display: inline-block;
}
/* match org's css for <pre> */
code {
background-color: #F3F5F7;
font-family: courier, monospace;
}
#content {
margin-left: 5%;
margin-right: 10%;
}

View File

@ -27,9 +27,18 @@
(eval-when-compile (eval-when-compile
(require 'cl)) (require 'cl))
(require 'org) (require 'org)
(require 'org-publish) (or (require 'org-publish nil t)
(require 'ox-publish))
(require 'yasnippet) ; docstrings must be loaded (require 'yasnippet) ; docstrings must be loaded
(defun yas--org-raw-html (tag content)
;; in version 8.0 org-mode changed the export syntax, see
;; http://orgmode.org/worg/org-8.0.html#sec-8-1
(format (if (version< org-version "8.0.0")
"@<%s>%s@</%s>" ; old: @<tag>
"@@html:<%s>@@%s@@html:</%s>@@") ; new: @@html:<tag>@@
tag content tag))
(defun yas--document-symbol (symbol level) (defun yas--document-symbol (symbol level)
(flet ((concat-lines (&rest lines) (flet ((concat-lines (&rest lines)
(mapconcat #'identity lines "\n"))) (mapconcat #'identity lines "\n")))
@ -67,13 +76,15 @@
(setq body (replace-regexp-in-string (setq body (replace-regexp-in-string
"\\<\\([A-Z][-A-Z0-9]+\\)\\(\\sw+\\)?\\>" "\\<\\([A-Z][-A-Z0-9]+\\)\\(\\sw+\\)?\\>"
#'(lambda (match) #'(lambda (match)
(let* ((match1 (downcase (match-string 1 match))) (let* ((match1 (match-string 1 match))
(prefix (downcase match1))
(suffix (match-string 2 match)) (suffix (match-string 2 match))
(fmt (cond (fmt (cond
((member match1 args) "@<code>%s@</code>") ((member prefix args)
(yas--org-raw-html "code" "%s"))
((null suffix) "/%s/")))) ((null suffix) "/%s/"))))
(if fmt (format fmt match1) (if fmt (format fmt prefix)
match))) match1)))
body t t 1) body t t 1)
body (replace-regexp-in-string body (replace-regexp-in-string
"`\\([a-z-]+\\)'" "`\\([a-z-]+\\)'"
@ -91,7 +102,8 @@
body)))) body))))
(defun yas--document-symbols (level &rest names-and-predicates) (defun yas--document-symbols (level &rest names-and-predicates)
(let ((sym-lists (make-vector (length names-and-predicates) nil))) (let ((sym-lists (make-vector (length names-and-predicates) nil))
(stars (make-string level ?*)))
(loop for sym in yas--exported-syms (loop for sym in yas--exported-syms
do (loop for test in (mapcar #'cdr names-and-predicates) do (loop for test in (mapcar #'cdr names-and-predicates)
for i from 0 for i from 0
@ -100,7 +112,7 @@
(return)))) (return))))
(loop for slist across sym-lists (loop for slist across sym-lists
for name in (mapcar #'car names-and-predicates) for name in (mapcar #'car names-and-predicates)
concat (format "\n** %s\n" name) concat (format "\n%s %s\n" stars name)
concat (mapconcat (lambda (sym) concat (mapconcat (lambda (sym)
(yas--document-symbol sym (1+ level))) (yas--document-symbol sym (1+ level)))
slist "\n\n")))) slist "\n\n"))))
@ -114,20 +126,25 @@
;; This lets all the org files be exported to HTML with ;; This lets all the org files be exported to HTML with
;; `org-publish-current-project' (C-c C-e P). ;; `org-publish-current-project' (C-c C-e P).
(let* ((rev (or (with-temp-buffer (let* ((dir (if load-file-name (file-name-directory load-file-name)
(when (eq (call-process "git" nil t nil
"rev-parse" "--verify" "HEAD") 0)
(buffer-string)))
yas--version))
(dir (if load-file-name (file-name-directory load-file-name)
default-directory)) default-directory))
(rev (with-temp-file (expand-file-name "html-revision" dir)
(or (when (eq (call-process "git" nil t nil
"rev-parse" "--verify" "HEAD") 0)
(buffer-string))
(princ yas--version (current-buffer)))))
(proj-plist (proj-plist
(list `(,@(when (fboundp 'org-html-publish-to-html)
:base-directory dir :publishing-directory dir '(:publishing-function 'org-html-publish-to-html))
:html-postamble :base-directory ,dir :publishing-directory ,dir
(concat "<hr><p class='creator'>Generated by %c on %d from " :html-preamble
rev "</p>\n" ,(with-temp-buffer
"<p class='xhtml-validation'>%v</p>\n"))) (insert-file-contents (expand-file-name "nav-menu.html.inc" dir))
(buffer-string))
:html-postamble
,(concat "<hr><p class='creator'>Generated by %c on %d from "
rev "</p>\n"
"<p class='xhtml-validation'>%v</p>\n")))
(project (assoc "yasnippet" org-publish-project-alist))) (project (assoc "yasnippet" org-publish-project-alist)))
(if project (if project
(setcdr project proj-plist) (setcdr project proj-plist)
@ -144,7 +161,8 @@
(provide 'yas-doc-helper) (provide 'yas-doc-helper)
;;; yas-doc-helper.el ends here
;; Local Variables: ;; Local Variables:
;; indent-tabs-mode: nil
;; coding: utf-8 ;; coding: utf-8
;; End: ;; End:
;;; yas-doc-helper.el ends here

@ -1 +1 @@
Subproject commit 7638321285cf78a9d075fa63d5ada105aa44752e Subproject commit 32bbd36d9a774b9cab6207523ffb5b24179b6505

@ -1 +1 @@
Subproject commit 78ef957e6bbc2891fb644e060f504c68ac1d8c6b Subproject commit 0543618bd34a6715918992f01161c118f136bb37

View File

@ -124,4 +124,8 @@
(add-hook 'post-command-hook 'yas-debug-snippet-vars 't 'local))) (add-hook 'post-command-hook 'yas-debug-snippet-vars 't 'local)))
(provide 'yasnippet-debug) (provide 'yasnippet-debug)
;; Local Variables:
;; indent-tabs-mode: nil
;; byte-compile-warnings: (not cl-functions)
;; End:
;;; yasnippet-debug.el ends here ;;; yasnippet-debug.el ends here

View File

@ -112,6 +112,17 @@
(ert-simulate-command `(yas-mock-insert "abc")) (ert-simulate-command `(yas-mock-insert "abc"))
(should (string= (yas--buffer-contents) "abcabcabcabc")))) (should (string= (yas--buffer-contents) "abcabcabcabc"))))
(ert-deftest delete-numberless-inner-snippet-issue-562 ()
(with-temp-buffer
(yas-minor-mode 1)
(yas-expand-snippet "${3:${test}bla}$0${2:ble}")
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(should (looking-at "testblable"))
(ert-simulate-command '(yas-next-field-or-maybe-expand))
(ert-simulate-command '(yas-skip-and-clear-or-delete-char))
(should (looking-at "ble"))
(should (null (yas--snippets-at-point)))))
;; (ert-deftest in-snippet-undo () ;; (ert-deftest in-snippet-undo ()
;; (with-temp-buffer ;; (with-temp-buffer
;; (yas-minor-mode 1) ;; (yas-minor-mode 1)
@ -190,6 +201,7 @@
(ert-deftest be-careful-when-escaping-in-yas-selected-text-2 () (ert-deftest be-careful-when-escaping-in-yas-selected-text-2 ()
(with-temp-buffer (with-temp-buffer
(yas-minor-mode 1)
(let ((yas-selected-text "He)}o world!")) (let ((yas-selected-text "He)}o world!"))
(yas-expand-snippet "Look ma! ${1:`(yas-selected-text)`} OK?") (yas-expand-snippet "Look ma! ${1:`(yas-selected-text)`} OK?")
(should (string= (yas--buffer-contents) "Look ma! He)}o world! OK?"))))) (should (string= (yas--buffer-contents) "Look ma! He)}o world! OK?")))))
@ -204,54 +216,56 @@
(ert-simulate-command `(yas-mock-insert "bbb")) (ert-simulate-command `(yas-mock-insert "bbb"))
(should (string= (yas--buffer-contents) "if condition\naaa\nelse\nbbb\nend"))))) (should (string= (yas--buffer-contents) "if condition\naaa\nelse\nbbb\nend")))))
(ert-deftest example-for-issue-404 () (defmacro yas--with-font-locked-temp-buffer (&rest body)
(with-temp-buffer "Like `with-temp-buffer', but ensure `font-lock-mode'."
(c++-mode) (declare (indent 0) (debug t))
(yas-minor-mode 1) (let ((temp-buffer (make-symbol "temp-buffer")))
(insert "#include <foo>\n") ;; NOTE: buffer name must not start with a space, otherwise
(let ((snippet "main")) ;; `font-lock-mode' doesn't turn on.
(let ((yas-good-grace nil)) (yas-expand-snippet snippet)) `(let ((,temp-buffer (generate-new-buffer "*yas-temp*")))
(should (string= (yas--buffer-contents) "#include <foo>\nmain"))))) (with-current-buffer ,temp-buffer
;; pretend we're interactive so `font-lock-mode' turns on
(let ((noninteractive nil)
;; turn on font locking after major mode change
(change-major-mode-after-body-hook #'font-lock-mode))
(unwind-protect
(progn (require 'font-lock)
;; turn on font locking before major mode change
(font-lock-mode +1)
,@body)
(and (buffer-name ,temp-buffer)
(kill-buffer ,temp-buffer))))))))
(ert-deftest example-for-issue-404-c-mode () (ert-deftest example-for-issue-474 ()
(with-temp-buffer (yas--with-font-locked-temp-buffer
(c-mode) (c-mode)
(yas-minor-mode 1) (yas-minor-mode 1)
(insert "#include <foo>\n") (insert "#include <foo>\n")
(let ((snippet "main")) (let ((yas-good-grace nil)) (yas-expand-snippet "`\"TODO: \"`"))
(let ((yas-good-grace nil)) (yas-expand-snippet snippet)) (should (string= (yas--buffer-contents) "#include <foo>\nTODO: "))))
(should (string= (yas--buffer-contents) "#include <foo>\nmain")))))
(ert-deftest example-for-issue-404-external-emacs () (ert-deftest example-for-issue-404 ()
:tags '(:external) (yas--with-font-locked-temp-buffer
(let ((fixture-el-file (make-temp-file "yas-404-fixture" nil ".el"))) (c++-mode)
(with-temp-buffer (yas-minor-mode 1)
(insert (pp-to-string (insert "#include <foo>\n")
`(condition-case _ (let ((yas-good-grace nil)) (yas-expand-snippet "main"))
(progn (should (string= (yas--buffer-contents) "#include <foo>\nmain"))))
(require 'yasnippet)
(yas-global-mode) (ert-deftest example-for-issue-404-c-mode ()
(switch-to-buffer "foo.c") (yas--with-font-locked-temp-buffer
(c-mode) (c-mode)
(insert "#include <iostream>\nmain") (yas-minor-mode 1)
(setq yas-good-grace nil) (insert "#include <foo>\n")
(yas-expand) (let ((yas-good-grace nil)) (yas-expand-snippet "main"))
(kill-emacs 0)) (should (string= (yas--buffer-contents) "#include <foo>\nmain"))))
(error (kill-emacs -1)))))
(write-file fixture-el-file))
(should (= 0
(call-process (concat invocation-directory invocation-name)
nil nil nil
"-Q" ;; "--batch"
"-L" "." "-l" fixture-el-file)))))
(ert-deftest middle-of-buffer-snippet-insertion () (ert-deftest middle-of-buffer-snippet-insertion ()
(with-temp-buffer (with-temp-buffer
(yas-minor-mode 1) (yas-minor-mode 1)
(insert "beginning") (insert "beginning")
(save-excursion (insert "end")) (save-excursion (insert "end"))
(let ((snippet "-middle-")) (yas-expand-snippet "-middle-")
(yas-expand-snippet snippet))
(should (string= (yas--buffer-contents) "beginning-middle-end")))) (should (string= (yas--buffer-contents) "beginning-middle-end"))))
(ert-deftest another-example-for-issue-271 () (ert-deftest another-example-for-issue-271 ()
@ -311,6 +325,47 @@ TODO: correct this bug!"
(should (string= (yas--buffer-contents) (should (string= (yas--buffer-contents)
"brother from another mother") ;; no newline should be here! "brother from another mother") ;; no newline should be here!
))) )))
;; See issue #497. To understand this test, follow the example of the
;; `yas-key-syntaxes' docstring.
;;
(ert-deftest complicated-yas-key-syntaxes ()
(with-temp-buffer
(yas-saving-variables
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("emacs-lisp-mode"
("foo-barbaz" . "# condition: yas--foobarbaz\n# --\nOKfoo-barbazOK")
("barbaz" . "# condition: yas--barbaz\n# --\nOKbarbazOK")
("baz" . "OKbazOK")
("'quote" . "OKquoteOK"))))
(yas-reload-all)
(emacs-lisp-mode)
(yas-minor-mode-on)
(let ((yas-key-syntaxes '("w" "w_")))
(let ((yas--barbaz t))
(yas-should-expand '(("foo-barbaz" . "foo-OKbarbazOK")
("barbaz" . "OKbarbazOK"))))
(let ((yas--foobarbaz t))
(yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK"))))
(let ((yas-key-syntaxes
(cons #'(lambda (_start-point)
(unless (looking-back "-")
(backward-char)
'again))
yas-key-syntaxes))
(yas--foobarbaz t))
(yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK")))))
(let ((yas-key-syntaxes '(yas-try-key-from-whitespace)))
(yas-should-expand '(("xxx\n'quote" . "xxx\nOKquoteOK")
("xxx 'quote" . "xxx OKquoteOK"))))
(let ((yas-key-syntaxes '(yas-shortest-key-until-whitespace))
(yas--foobarbaz t) (yas--barbaz t))
(yas-should-expand '(("foo-barbaz" . "foo-barOKbazOK")))
(setq yas-key-syntaxes '(yas-longest-key-from-whitespace))
(yas-should-expand '(("foo-barbaz" . "OKfoo-barbazOK")
("foo " . "foo "))))))))
;;; Loading ;;; Loading
;;; ;;;
@ -325,10 +380,10 @@ TODO: correct this bug!"
;; saving all definitions before overriding anything ensures FDEFINITION ;; saving all definitions before overriding anything ensures FDEFINITION
;; errors don't cause accidental permanent redefinitions. ;; errors don't cause accidental permanent redefinitions.
;; ;;
(cl-flet ((set-fdefinitions (names functions) (cl-labels ((set-fdefinitions (names functions)
(loop for name in names (loop for name in names
for fn in functions for fn in functions
do (fset name fn)))) do (fset name fn))))
(set-fdefinitions definition-names overriding-functions) (set-fdefinitions definition-names overriding-functions)
(unwind-protect (funcall function) (unwind-protect (funcall function)
(set-fdefinitions definition-names saved-functions))))) (set-fdefinitions definition-names saved-functions)))))
@ -409,12 +464,14 @@ TODO: correct this bug!"
(yas-reload-all) (yas-reload-all)
(with-temp-buffer (with-temp-buffer
(let* ((major-mode 'c-mode) (let* ((major-mode 'c-mode)
(expected '(c-mode (expected `(c-mode
cc-mode cc-mode
yet-another-c-mode yet-another-c-mode
and-also-this-one and-also-this-one
and-that-one and-that-one
prog-mode ;; prog-mode doesn't exit in emacs 24.3
,@(if (fboundp 'prog-mode)
'(prog-mode))
emacs-lisp-mode emacs-lisp-mode
lisp-interaction-mode)) lisp-interaction-mode))
(observed (yas--modes-to-activate))) (observed (yas--modes-to-activate)))
@ -422,6 +479,41 @@ TODO: correct this bug!"
(should (= (length expected) (should (= (length expected)
(length observed)))))))) (length observed))))))))
(ert-deftest issue-492-and-494 ()
(defalias 'yas--phony-c-mode 'c-mode)
(define-derived-mode yas--test-mode yas--phony-c-mode "Just a test mode")
(yas-with-snippet-dirs '((".emacs.d/snippets"
("yas--test-mode")))
(yas-reload-all)
(with-temp-buffer
(let* ((major-mode 'yas--test-mode)
(expected `(c-mode
,@(if (fboundp 'prog-mode)
'(prog-mode))
yas--phony-c-mode
yas--test-mode))
(observed (yas--modes-to-activate)))
(should (null (cl-set-exclusive-or expected observed)))
(should (= (length expected)
(length observed)))))))
(ert-deftest issue-504-tricky-jit ()
(define-derived-mode yas--test-mode c-mode "Just a test mode")
(define-derived-mode yas--another-test-mode c-mode "Another test mode")
(yas-with-snippet-dirs
'((".emacs.d/snippets"
("yas--another-test-mode"
(".yas-parents" . "yas--test-mode"))
("yas--test-mode")))
(let ((b (with-current-buffer (generate-new-buffer "*yas-test*")
(yas--another-test-mode)
(current-buffer))))
(unwind-protect
(progn
(yas-reload-all)
(should (= 0 (hash-table-count yas--scheduled-jit-loads))))
(kill-buffer b)))))
(defun yas--basic-jit-loading-1 () (defun yas--basic-jit-loading-1 ()
(with-temp-buffer (with-temp-buffer
(should (= 4 (hash-table-count yas--scheduled-jit-loads))) (should (= 4 (hash-table-count yas--scheduled-jit-loads)))
@ -592,7 +684,11 @@ TODO: be meaner"
(yas-reload-all) (yas-reload-all)
(should (not (eq (key-binding (yas--read-keybinding "TAB")) 'yas-expand))) (should (not (eq (key-binding (yas--read-keybinding "TAB")) 'yas-expand)))
(should (eq (key-binding (yas--read-keybinding "SPC")) 'yas-expand)))) (should (eq (key-binding (yas--read-keybinding "SPC")) 'yas-expand))))
(setcdr yas-minor-mode-map (cdr (yas--init-minor-keymap))))) ;; FIXME: actually should restore to whatever saved values where there.
;;
(define-key yas-minor-mode-map [tab] 'yas-expand)
(define-key yas-minor-mode-map (kbd "TAB") 'yas-expand)
(define-key yas-minor-mode-map (kbd "SPC") nil)))
(ert-deftest test-yas-in-org () (ert-deftest test-yas-in-org ()
(with-temp-buffer (with-temp-buffer
@ -627,33 +723,31 @@ add the snippets associated with the given mode."
;;; Helpers ;;; Helpers
;;; ;;;
(defun yas-batch-run-tests (&optional also-external)
(interactive)
(with-temp-buffer
(yas--with-temporary-redefinitions
((message (&rest _args) nil))
(ert (or (and also-external t)
'(not (tag :external))) (buffer-name (current-buffer)))
(princ (buffer-string)))))
(defun yas-should-expand (keys-and-expansions) (defun yas-should-expand (keys-and-expansions)
(dolist (key-and-expansion keys-and-expansions) (dolist (key-and-expansion keys-and-expansions)
(yas-exit-all-snippets) (yas-exit-all-snippets)
(erase-buffer) (narrow-to-region (point) (point))
(insert (car key-and-expansion)) (insert (car key-and-expansion))
(let ((yas-fallback-behavior nil)) (let ((yas-fallback-behavior nil))
(ert-simulate-command '(yas-expand))) (ert-simulate-command '(yas-expand)))
(should (string= (yas--buffer-contents) (cdr key-and-expansion)))) (unless (string= (yas--buffer-contents) (cdr key-and-expansion))
(ert-fail (format "\"%s\" should have expanded to \"%s\" but got \"%s\""
(car key-and-expansion)
(cdr key-and-expansion)
(yas--buffer-contents)))))
(yas-exit-all-snippets)) (yas-exit-all-snippets))
(defun yas-should-not-expand (keys) (defun yas-should-not-expand (keys)
(dolist (key keys) (dolist (key keys)
(yas-exit-all-snippets) (yas-exit-all-snippets)
(erase-buffer) (narrow-to-region (point) (point))
(insert key) (insert key)
(let ((yas-fallback-behavior nil)) (let ((yas-fallback-behavior nil))
(ert-simulate-command '(yas-expand))) (ert-simulate-command '(yas-expand)))
(should (string= (yas--buffer-contents) key)))) (unless (string= (yas--buffer-contents) key)
(ert-fail (format "\"%s\" should have stayed put, but instead expanded to \"%s\""
key
(yas--buffer-contents))))))
(defun yas-mock-insert (string) (defun yas-mock-insert (string)
(interactive) (interactive)
@ -739,8 +833,9 @@ add the snippets associated with the given mode."
(provide 'yasnippet-tests) (provide 'yasnippet-tests)
;;; yasnippet-tests.el ends here
;; Local Variables: ;; Local Variables:
;; indent-tabs-mode: nil
;; lexical-binding: t ;; lexical-binding: t
;; byte-compile-warnings: (not cl-functions) ;; byte-compile-warnings: (not cl-functions)
;; End: ;; End:
;;; yasnippet-tests.el ends here

File diff suppressed because it is too large Load Diff