simple way to add to yas-snippet-dirs

638 views
Skip to first unread message

Perry Smith

unread,
Dec 22, 2013, 9:49:35 AM12/22/13
to smart-...@googlegroups.com
I could easily have overlooked something but I did not see an easy way
to add to the list of snippet dirs while maintaining the idea that the
first directory is special since it is the place that new snippets
will be saved.

rspec-mode for example does this:

  (setq yas-snippet-dirs (cons rspec-snippets-dir (yas-snippet-dirs)))
  (yas-load-directory rspec-snippets-dir))

but the problem is that adding to the front of the list disturbs what
the user might have set up as their place to put new snippets.  So,
really, the nicest place to add to the list is the 2nd element keeping
the 1st element which may be set to something like
~/.emacs.d/snippets.

This function does this addition but I don't really claim to be a true
lisp hacker.

(defun yas-add-to-dirs ( elt )
  "Add ELT to `yas-snippet-dirs'"
  (unless (listp yas-snippet-dirs)
    (setq yas-snippet-dirs (list yas-snippet-dirs)))
  (unless (member elt yas-snippet-dirs)
    (if (null yas-snippet-dirs)
    (setq yas-snippet-dirs (list elt))
      (push elt (cdr yas-snippet-dirs))))
  (yas-load-directory elt t)
  yas-snippet-dirs)

I hope folks find it useful enough to be added to yasnippet.  If you
want, I can generate a pull request.

João Távora

unread,
Dec 23, 2013, 4:36:44 AM12/23/13
to smart-...@googlegroups.com
Perry Smith <ped...@gmail.com> writes:
> I could easily have overlooked something but I did not see an easy way
> to add to the list of snippet dirs while maintaining the idea that the
> first directory is special since it is the place that new snippets
> will be saved.
>
> rspec-mode for example does this:
>
> (setq yas-snippet-dirs (cons rspec-snippets-dir (yas-snippet-dirs)))
>
If rspec-mode does that then maybe it shouldn't.

If you are doing that in your config, then you can also use emacs's own
`add-to-list' with its APPEND arg set to any non-nil value. It'll add to
the end of the list. If you really need to add to the second position,
use `setq', is it really that more complex?

(setq yas-snippet-dirs (cons (car yas-snippet-dirs)
(cons my-dir
(rest yas-snippet-dirs))))

or an even simpler one-liner

(setcdr yas-snippet-dirs (cons my-dir (rest yas-snippet-dirs)))

> This function does this addition but I don't really claim to be a true
> lisp hacker.
>
> (defun yas-add-to-dirs ( elt )

I appreciate the effort, but I don't think there's a strong enough use
case for this. Fancy list manipulation functions belong either in emacs
itself or user's own customizations.

João

Perry Smith

unread,
Dec 23, 2013, 1:26:34 PM12/23/13
to smart-...@googlegroups.com
Its up to you.  The folks that write packages don't seem to get the two subtle parts: the 1st element is special and yas-load-directory needs to be called as well.

Plus, sometimes yas-snippet-dirs is not a list but a single element (yas-load-directory sets yas-snippet-dirs to the argument if it was originally null) and it could also be null (in theory).

João Távora

unread,
Dec 23, 2013, 8:26:40 PM12/23/13
to Perry Smith, smart-...@googlegroups.com
> Its up to you. The folks that write packages don't seem to get the two
> subtle parts: the 1st element is special and yas-load-directory needs to be
> called as well.

Your point being?

Burdening yasnippet's API with a reinvention of the language's list
manipulation, on the other hand, really seems like a questionable idea.

By the way, I am curious to know who are these "folks"? Maybe they (or
you) can help me complete and/or improve the clarity of:

http://capitaomorte.github.io/yasnippet/snippet-organization.html

Also, normal practice is to setup `yas-snippet-dirs' first, and then
call `yas-global-mode'. Note that `yas-load-directory' doesn't _need_ to
be called at all. You _can_ call `yas-load-directory' on an existing dir
to load snippets into memory, you don't need to add that directory to
`yas-snippet-dirs' at all.

> Plus, sometimes yas-snippet-dirs is not a list but a single element
> (yas-load-directory sets yas-snippet-dirs to the argument if it was
> originally null) and it could also be null (in theory).

Again, I don't follow your train of thought. If your point is that it is
convoluted, I can possibly agree, but:

- it's done like that for backward-compatibility reasons and changing it
would case unwanted breakage in existing user's configuration;

- it's not at all uncommon in lisp to have designs where a symbol refer
to polymorphic structures. And it's *very* common in Emacs. To
understand what I mean, do "M-x apropos-documentation" and input the
string "can also be".

Dmitry Gutov

unread,
Dec 31, 2013, 1:40:18 AM12/31/13
to smart-...@googlegroups.com, Perry Smith
I also think that this would be a good idea.

вторник, 24 декабря 2013 г., 5:26:40 UTC+4 пользователь Joao написал:

Burdening yasnippet's API with a reinvention of the language's list
manipulation, on the other hand, really seems like a questionable idea.

What part of `yas-add-to-dirs' looks like a reinvention of list manupulation? Your data structure is weird, so this function tries to account for the historical oddities.

If every package has to implement this logic to integrate with Yasnippet, it would be better if Yasnippet itself included such a function.
 

By the way, I am curious to know who are these "folks"? Maybe they (or
you) can help me complete and/or improve the clarity of:

http://capitaomorte.github.io/yasnippet/snippet-organization.html

Documentation is good, but it doesn't help with code duplication.

Also, `C-h v yas-snippet-dirs' is good enough for the subject in question.
 
Also, normal practice is to setup `yas-snippet-dirs' first, and then
call `yas-global-mode'. Note that `yas-load-directory' doesn't _need_ to
be called at all. You _can_ call `yas-load-directory' on an existing dir
to load snippets into memory, you don't need to add that directory to
`yas-snippet-dirs' at all.

rspec-mode provides a function `
rspec-install-snippets' which adds the package's snippets subdirectory to yas-snippet-dirs.
Since rspec-mode is autoloaded, we can't really recommend calling that function before the user calls `yas-global-mode', which happens somewhere in the init file.

Instead, we recommend putting the call to this function in `eval-after-load' block, and at that time calling `yas-load-directory' is justified.
 
- it's not at all uncommon in lisp to have designs where a symbol refer
  to polymorphic structures. And it's *very* common in Emacs. To
  understand what I mean, do "M-x apropos-documentation" and input the
  string "can also be".

Just like it's common to have polymorphic variables, it's likewise common to provide accessor functions for them.

João Távora

unread,
Dec 31, 2013, 7:31:28 AM12/31/13
to Dmitry Gutov, smart-...@googlegroups.com, Perry Smith
Dmitry Gutov <raa...@gmail.com> writes:

>> Burdening yasnippet's API with a reinvention of the language's list
>> manipulation, on the other hand, really seems like a questionable idea.
> What part of `yas-add-to-dirs' looks like a reinvention of list
> manupulation? Your data structure is weird, so this function tries to
> account for the historical oddities.

(setcdr yas-snippet-dirs (cons my-dir (rest yas-snippet-dirs)))

does what the OP requested: add to the second place in a list. Its a
one-liner and works with every list I know.

It also doesn't try to hide the weirdness. I've already agreed that the
polymorphic is weird. Try writing a docstring for the `yas-add-to-dirs'
originally provided by the OP.

I am convinced that less is more. Providing less of an

> If every package has to implement this logic to integrate with Yasnippet,
> it would be better if Yasnippet itself included such a function.

I'm not sure I understand the logic, but read below. Packages should
leave yas-snippet-dirs untouched. It's a user customization variable! It
should be set where yasnippet is setup.

> Since rspec-mode is autoloaded, we can't really recommend calling that
> function before the user calls `yas-global-mode', which happens
> somewhere in the init file.

I don't think it has anything to do with autoloads. If you recommend
something that touches yas-snippet-dirs it has to be done in yasnippet's
setup snippet before `yas-global-mode' or via custom.

>> Instead, we recommend putting the call to this function in
> `eval-after-load' block, and at that time calling `yas-load-directory'
> is justified.

I don't know if I am missing something, but here's are lots of
possibilitites.

1) If your rspec-snippets are an opt-in, recommend to the yasnippet
users they want them to their yas-snippet-dirs before issuing
`yas-global-mode'. Thanks to yasnippet's jit-loading feature, that
takes very little time and snippets will only be loaded when
rspec-mode kicks in.

2) If you want your rspec-snippets to be active by default for all
yasnippet users then I'm afraid you have to call `yas-load-directory'
in your major-mode's hook. It would have to be conditionalized to
`yas-minor-mode' and some logic that detects if `yas-reload-all' has
happened in the meantime. At the moment there is no
`yas-reload-all-hook' so you could use `add-function' or advice.

But it's arguable that users will like it if they M-x yas-reload-all
and some snippets they didn't know show up since that command has
"cleanse" semantics.

3) Lastly if you really want to mess with `yas-snippet-dirs' in
`rspec-install-snippets', use

(when (listp yas-snippet-dirs)
(add-to-list 'yas-snippet-dirs dir 'append))

It's two lines and quite readable. It won't work if it's an atom, but
then you shouldn't touch it if it is. Not to mention you shouldn't
touch a user customization variables.

BTW what specific eval-after-load hook are you talking about? rspec-mode
or yasnippet's?

>> - it's not at all uncommon in lisp to have designs where a symbol refer
>> to polymorphic structures. And it's *very* common in Emacs. To
>> understand what I mean, do "M-x apropos-documentation" and input the
>> string "can also be".
> Just like it's common to have polymorphic variables, it's likewise common
> to provide accessor functions for them.

Really? I'm not sure I follow. Here are the first two Emacs variables
that I found by the dumb "M-x apropos-documentation" for "can also be"

comment-use-syntax
Variable: Non-nil if syntax-tables can be used instead of regexps.
Can also be `undecided' which means that a somewhat expensive test
will
...

----------------
minibuffer-completion-table
Variable: Alist or obarray used for completion in the minibuffer.
This becomes the ALIST argument to `try-completion' and
`all-completions'.
The value can also be a list of strings or a hash table.

The value may alternatively be a function, which is given three
arguments:
STRING, the current buffer contents;
PREDICATE, the predicate for filtering possible matches;
CODE, which says what kind of things to do.
CODE can be nil, t or `lambda':
nil -- return the best completion of STRING, or nil if there is
none.
t -- return a list of all possible completions of STRING.
lambda -- return t if STRING is a valid completion as it stands.

Are there specialized accessor functions for these variables? Or do we
use `setq', and `add-to-list' and whatnot? I am not sure I follow your
reasoning.

Perry Smith

unread,
Dec 31, 2013, 9:13:08 AM12/31/13
to João Távora, Dmitry Gutov, smart-...@googlegroups.com

On Dec 31, 2013, at 6:31 AM, João Távora <joaot...@gmail.com> wrote:

(setcdr yas-snippet-dirs (cons my-dir (rest yas-snippet-dirs)))

does what the OP requested: add to the second place in a list. Its a
one-liner and works with every list I know.

It does not work if yas-snippet-dirs is null and it does not work if it is set to a historical value of a single string.

signature.asc

João Távora

unread,
Dec 31, 2013, 9:37:15 AM12/31/13
to Perry Smith, Dmitry Gutov, smart-...@googlegroups.com
Right. My mistake. You have to check for `consp' first or use
add-to-list. Anyway see the rest of my reply to Dmitry to understand why
you probably shouldn't be setting the user's yas-snippet-dirs in the
first place.

João Távora

unread,
Dec 31, 2013, 3:38:50 PM12/31/13
to Dmitry Gutov, smart-...@googlegroups.com, Perry Smith
On Tue, Dec 31, 2013 at 3:05 PM, Dmitry Gutov <raa...@gmail.com> wrote:
> On 31.12.2013 16:31, João Távora wrote:
>>
>> (setcdr yas-snippet-dirs (cons my-dir (rest yas-snippet-dirs)))
>>
>> does what the OP requested: add to the second place in a list. Its a
>> one-liner and works with every list I know.
> Like mentioned, it doesn't handle all possible values.

Fair enough, see my reply.

>> It also doesn't try to hide the weirdness. I've already agreed that the
>> polymorphic is weird. Try writing a docstring for the `yas-add-to-dirs'
>> originally provided by the OP.
> The docstring wouldn't describe the exact manipulation of the value. It
> would say something like "adds a new location to use snippets from".
>> I am convinced that less is more. Providing less of an
> The sentence is cut short here.

Sorry. I was going to write "providing less interface is less prone to error".

>>> If every package has to implement this logic to integrate with Yasnippet,
>>> it would be better if Yasnippet itself included such a function.
>>
>>
>> I'm not sure I understand the logic, but read below. Packages should
>> leave yas-snippet-dirs untouched. It's a user customization variable! It
>> should be set where yasnippet is setup.
>
>
> We allow the user to explicitly use our snippet directory. If they don't,
> the variable is left untouched.
>
> Asking the user to customize it manually is unrealistic. The path to our
> snippets directory is
> "/home/gutov/.emacs.d/elpa/yasnippet-YYYYMMDD.XYZ/snippets": it changes with
> each package update.

But I meant the rspec-mode/snippets directory. That's the directory
that you should
recommend that users add to the end (or to the second position) of
yas-snippet dirs.

And, as you know, you can abbreviate /home/gutov with ~. And I'm
pretty sure emacs
also provides a variable that takes you directory to ~/.emacs.d/elpa.
Consistently
finding the rspec-mode snippet dir from there should be easy. A short
enough snippet
should provide that.

And I even think, rspec mode could provide a variable that points
directly to its snippet
directory. And that variable can be set in rspec-autoloads.el or something.

This is my preferred alternative.

>>> Since rspec-mode is autoloaded, we can't really recommend calling that
>>> function before the user calls `yas-global-mode', which happens
>>> somewhere in the init file.
>> I don't think it has anything to do with autoloads.
> It has everything to do with autoloads because `rspec-install-snippets' is
> in `rspec-mode.el', which is autoloaded. Calling it would force the loading
> of the package.

But I never stated that you should call that function. I stated the opposite.

>> 2) If you want your rspec-snippets to be active by default for all
>> yasnippet users then I'm afraid you have to call `yas-load-directory'
>> in your major-mode's hook.
> Wouldn't it have to make the same work each time rspec-mode is enabled, as
> opposed to only loading the directory once?

It could well detect that it has performed that work already, by using
a global variable.
The only problem would be that a yas-reload-call wouldn't set that
variable to nil again.

But, yes, in my opinion that is replicating work already done by the
jit-loading logic.
That is why I added 1) as a preferred alternative to 2).

>> It would have to be conditionalized to ... some logic that detects if
>> `yas-reload-all' has happened in the meantime.
> Not sure if I follow. Why?

Because if you call load-directory in the major-mode hook, then an interactive
call to yas-reload-all will clear the snippets thus loaded and reload everything
fresh from yas-snippet-dirs. Therefore, a user working in a rspec-mode buffer
will loose his rspec mode snippets.

>> 3) Lastly if you really want to mess with `yas-snippet-dirs' in
>> `rspec-install-snippets', use
>>
>> (when (listp yas-snippet-dirs)
>> (add-to-list 'yas-snippet-dirs dir 'append))
>>
>> It's two lines and quite readable. It won't work if it's an atom, but
>> then you shouldn't touch it if it is.
> Why? In that case the value's just equivalent to a list with that value
> inside. Where does it say that it's otherwise special?

Because if it's an atom probably the the user wants a single snippets directory
and noone messing with it.

>> Not to mention you shouldn't
>> touch a user customization variables.
> There's nothing wrong in providing a convenience function that modifies a
> `defcustom' value. Using that macro only means that the user should be able
> to modify the variable using Customize interface, not that it's untouchable.
> Take a look at the definition of `find-file-hook', for example.

Fair enough.

>> BTW what specific eval-after-load hook are you talking about? rspec-mode
>> or yasnippet's?
> rspec-mode's. Have you looked at its README? It's right there under
> Installation: https://github.com/pezra/rspec-mode/

I have. I see you're using add-to-list in your "install-snippets". Is that not
working? I stated before I don't consider that the best option, but if it works
for you...

> Okay, I'll rephrase that: just like it's common to have variables with
> complex values, it's common to provide accessors for them. An easy example
> is `defstruct' and accessor functions it generates. For something different,
> see code different code examples in SICP.

The reason defstruct defines accessors is for hiding its implementation, which
is commonly based on arrays, but need not be as per hyperspec at least I think.
It's not for convenience. Lists in lisp are fundamental
data-structures and that's a
fundamental difference. They come with a whole dictionary of manipulators.
Doesn't mean you cant add to it, but it just doesn't make sense to me
in this case.

> The latter doesn't have much to do with Emacs, so it's not the best possible
> example, sorry. But yours are not better:

I disagree. The examples of complex datastructures which are modified
by using list manipulators. Arguably comment-use-syntax isn't a good
one, I just took
the first hit. But the minibuffer completion table, or any other
table, is something you
add to using push and add-to-list. I might want to add to its existing
value, why not?
If I need to do that, I'll have to check its type. But maybe there's a
reason that it isn't
easy, maybe it's not meant to be added to like that. Just like
yas-snippet-dirs. I designed
it to be set by users, not packages, and you should try to adhere to
that and not fight it.

I didn't look and really don't have time to. But I suspect there are many
"atom or list" variables that don't come with specialized accessors.

Lastly, worry not, because I plan to drop compatibility for the single
string value in
yas-snippet-dirs. I am also redesigning the snippet expansion engine
in conjunction
with stefan and we hope it will have a nice programmatic approach to
defining snippets
as macros. Have a look in the snippet-engine branch.

Dmitry Gutov

unread,
Dec 31, 2013, 10:05:40 AM12/31/13
to João Távora, smart-...@googlegroups.com, Perry Smith
On 31.12.2013 16:31, Jo�o T�vora wrote:
> (setcdr yas-snippet-dirs (cons my-dir (rest yas-snippet-dirs)))
>
> does what the OP requested: add to the second place in a list. Its a
> one-liner and works with every list I know.

Like mentioned, it doesn't handle all possible values.

> It also doesn't try to hide the weirdness. I've already agreed that the
> polymorphic is weird. Try writing a docstring for the `yas-add-to-dirs'
> originally provided by the OP.

The docstring wouldn't describe the exact manipulation of the value. It
would say something like "adds a new location to use snippets from".

> I am convinced that less is more. Providing less of an

The sentence is cut short here.

>> If every package has to implement this logic to integrate with Yasnippet,
>> it would be better if Yasnippet itself included such a function.
>
> I'm not sure I understand the logic, but read below. Packages should
> leave yas-snippet-dirs untouched. It's a user customization variable! It
> should be set where yasnippet is setup.

We allow the user to explicitly use our snippet directory. If they
don't, the variable is left untouched.

Asking the user to customize it manually is unrealistic. The path to our
snippets directory is
"/home/gutov/.emacs.d/elpa/yasnippet-YYYYMMDD.XYZ/snippets": it changes
with each package update.

>> Since rspec-mode is autoloaded, we can't really recommend calling that
>> function before the user calls `yas-global-mode', which happens
>> somewhere in the init file.
>
> I don't think it has anything to do with autoloads.

It has everything to do with autoloads because `rspec-install-snippets'
is in `rspec-mode.el', which is autoloaded. Calling it would force the
loading of the package.

> 2) If you want your rspec-snippets to be active by default for all
> yasnippet users then I'm afraid you have to call `yas-load-directory'
> in your major-mode's hook.

Wouldn't it have to make the same work each time rspec-mode is enabled,
as opposed to only loading the directory once?

> It would have to be conditionalized to ... some logic that detects if
> `yas-reload-all' has happened in the meantime.

Not sure if I follow. Why?

> 3) Lastly if you really want to mess with `yas-snippet-dirs' in
> `rspec-install-snippets', use
>
> (when (listp yas-snippet-dirs)
> (add-to-list 'yas-snippet-dirs dir 'append))
>
> It's two lines and quite readable. It won't work if it's an atom, but
> then you shouldn't touch it if it is.

Why? In that case the value's just equivalent to a list with that value
inside. Where does it say that it's otherwise special?

> Not to mention you shouldn't
> touch a user customization variables.

There's nothing wrong in providing a convenience function that modifies
a `defcustom' value. Using that macro only means that the user should be
able to modify the variable using Customize interface, not that it's
untouchable. Take a look at the definition of `find-file-hook', for example.

> BTW what specific eval-after-load hook are you talking about? rspec-mode
> or yasnippet's?

rspec-mode's. Have you looked at its README? It's right there under
Installation: https://github.com/pezra/rspec-mode/

>>> - it's not at all uncommon in lisp to have designs where a symbol refer
>>> to polymorphic structures. And it's *very* common in Emacs. To
>>> understand what I mean, do "M-x apropos-documentation" and input the
>>> string "can also be".
>> Just like it's common to have polymorphic variables, it's likewise common
>> to provide accessor functions for them.
>
> Really? I'm not sure I follow. Here are the first two Emacs variables
> that I found by the dumb "M-x apropos-documentation" for "can also be"

Okay, I'll rephrase that: just like it's common to have variables with
complex values, it's common to provide accessors for them. An easy
example is `defstruct' and accessor functions it generates. For
something different, see code different code examples in SICP.

The latter doesn't have much to do with Emacs, so it's not the best
possible example, sorry. But yours are not better:

> comment-use-syntax
> Variable: Non-nil if syntax-tables can be used instead of regexps.
> Can also be `undecided' which means that a somewhat expensive test
> will
> ...

When you change the value of this variable (for example, in a major mode
function), you never care about the previous value it had. There's no
need for anything other than `setq', at all.

> ----------------
> minibuffer-completion-table
> Variable: Alist or obarray used for completion in the minibuffer.
> This becomes the ALIST argument to `try-completion' and
> `all-completions'.
> The value can also be a list of strings or a hash table.
>
> The value may alternatively be a function, which is given three
> arguments:
> STRING, the current buffer contents;
> PREDICATE, the predicate for filtering possible matches;
> CODE, which says what kind of things to do.
> CODE can be nil, t or `lambda':
> nil -- return the best completion of STRING, or nil if there is
> none.
> t -- return a list of all possible completions of STRING.
> lambda -- return t if STRING is a valid completion as it stands.
>
> Are there specialized accessor functions for these variables? Or do we
> use `setq', and `add-to-list' and whatnot? I am not sure I follow your
> reasoning.

Again, you only set its value to one of the possible values without
regard to what this variable was set to before.

Unlike the proposed `yas-add-to-dirs', I can't even imagine an interface
to changing its value that would be more useful than `setq'.

João Távora

unread,
Jan 1, 2014, 11:36:52 AM1/1/14
to Dmitry Gutov, smart-...@googlegroups.com, Perry Smith
João Távora <joaot...@gmail.com> writes:
> And I even think, rspec mode could provide a variable that points
> directly to its snippet
> directory. And that variable can be set in rspec-autoloads.el or something.
>
> This is my preferred alternative.

So I took a look at rspec-mode and here's what I think is a simple
solution. Have a look at the idea I propose in my github fork
(capitaomorte/rspec-mode) and tell me if you find any problems in it.

This is the diff. Although I don't use elpa I tested with both
rspec-mode (from a local tarball) and GNU ELPA's yasnippet (a tad
outdated). Still, it loaded and worked fine.

João

diff --git a/README.md b/README.md
index e5f1559..a730be7 100644
--- a/README.md
+++ b/README.md
@@ -9,13 +9,12 @@ adding the following to your init file:
(add-to-list 'load-path "/path/to/rspec-mode")
(require 'rspec-mode)

-Provided you have `yasnippet` installed, you can load the snippets:
+Provided you have `yasnippet` installed, you can load the snippets by
+adding the rspec-mode snippets directory to `yas-snippet-dirs`

- (eval-after-load 'rspec-mode
- '(rspec-install-snippets))
-
-(This isn't done automatically to avoid conflicts with snippets you
-may already have set up.)
+ (eval-after-load 'yasnippet
+ '(progn
+ (add-to-list 'yas-snippet-dirs rspec-snippets-dir t)))

## Usage
If `rspec-mode` is installed properly, it will be started
diff --git a/rspec-mode.el b/rspec-mode.el
index 5dafcdd..eaddfac 100644
--- a/rspec-mode.el
+++ b/rspec-mode.el
@@ -227,17 +227,12 @@ Not used when running specs using Zeus or Spring."
(setq imenu-create-index-function 'imenu-default-create-index-function)
(setq imenu-generic-expression rspec-imenu-generic-expression))

+;;;###autoload
(defvar rspec-snippets-dir
(let ((current (or load-file-name (buffer-file-name))))
(expand-file-name "snippets" (file-name-directory current)))
"The directory containing rspec snippets.")

-(defun rspec-install-snippets ()
- "Add `rspec-snippets-dir' to `yas-snippet-dirs' and load snippets from it."
- (require 'yasnippet)
- (add-to-list 'yas-snippet-dirs rspec-snippets-dir t)
- (yas-load-directory rspec-snippets-dir))
-
(defun rspec-class-from-file-name ()
"Guess the name of the class the spec is for."
(let* ((name (file-relative-name (buffer-file-name)

Dmitry Gutov

unread,
Jan 6, 2014, 3:07:32 AM1/6/14
to João Távora, smart-...@googlegroups.com, Perry Smith
On 01.01.2014 00:38, Jo�o T�vora wrote:
>> Asking the user to customize it manually is unrealistic. The path to our
>> snippets directory is
>> "/home/gutov/.emacs.d/elpa/yasnippet-YYYYMMDD.XYZ/snippets": it changes with
>> each package update.
>
> But I meant the rspec-mode/snippets directory. That's the directory
> that you should
> recommend that users add to the end (or to the second position) of
> yas-snippet dirs.

Yes, sorry, that was a typo. Replace "yasnippet" with "rspec-mode" above.

> And I even think, rspec mode could provide a variable that points
> directly to its snippet
> directory. And that variable can be set in rspec-autoloads.el or something.
>
> This is my preferred alternative.

Yep, we have that. Guess recommending users make use of it wasn't a
natural first choice for me because when you say "customize", I think of
the Customize interface, and it only accepts literal values, naturally.

>>> It's two lines and quite readable. It won't work if it's an atom, but
>>> then you shouldn't touch it if it is.
>> Why? In that case the value's just equivalent to a list with that value
>> inside. Where does it say that it's otherwise special?
>
> Because if it's an atom probably the the user wants a single snippets directory
> and noone messing with it.

If they don't want anyone messing with it, they won't call
`rspec-install-snippet'. And if they do call it, they might expect it to
work.

The `yas-snippet-dirs' docstring doesn't say anything about non-list
value prohibiting anyone from changing it.

>>> BTW what specific eval-after-load hook are you talking about? rspec-mode
>>> or yasnippet's?
>> rspec-mode's. Have you looked at its README? It's right there under
>> Installation: https://github.com/pezra/rspec-mode/
>
> I have. I see you're using add-to-list in your "install-snippets". Is that not
> working? I stated before I don't consider that the best option, but if it works
> for you...

Yes, it works. Probably because so far none of the users actually set
`yas-snippet-dirs' to a single string. We might say then that Perry's
question is mostly hypothetical, but not handling the documented
possible values looks bad anyway.

> Lists in lisp are fundamental
> data-structures and that's a
> fundamental difference. They come with a whole dictionary of manipulators.
> Doesn't mean you cant add to it, but it just doesn't make sense to me
> in this case.

But when a value can also contain a string, it can't really be
considered a list, can it? If it could only be a list, this whole thread
wouldn't exist.

> Lastly, worry not, because I plan to drop compatibility for the single
> string value in
> yas-snippet-dirs.

Good to know.

> I am also redesigning the snippet expansion engine
> in conjunction
> with stefan and we hope it will have a nice programmatic approach to
> defining snippets
> as macros. Have a look in the snippet-engine branch.

Thanks, but the latest commit there is a month old. Is that the right
branch?

João Távora

unread,
Jan 6, 2014, 3:52:50 AM1/6/14
to Dmitry Gutov, smart-...@googlegroups.com, Perry Smith
On Mon, Jan 6, 2014 at 8:07 AM, Dmitry Gutov <raa...@gmail.com> wrote:
> On 01.01.2014 00:38, João Távora wrote:
>> as macros. Have a look in the snippet-engine branch.
> Thanks, but the latest commit there is a month old. Is that the right
> branch?

Yes it's a month old, but it's certainly not dead. It's resting :-)

--
João Távora
Reply all
Reply to author
Forward
0 new messages