smart-snippet tutorial?

29 views
Skip to first unread message

Peter Michaux

unread,
Feb 5, 2008, 2:22:56 PM2/5/08
to smart-snippet
Hi,

I'm new to Emacs and have tried to get snippet.el working with no
luck. Now I'm looking at smart-snippet.el and it looks like it has a
better feature set. Is there a smart-snippet tutorial that takes a
bare Emacs install and shows all the things that need to be done to
get smart-snippet working with various major mode files (regardless of
how those major-modes were written)?

Thanks,
Peter

Saptarshi Guha

unread,
Feb 5, 2008, 2:38:43 PM2/5/08
to smart-...@googlegroups.com
Hi,
Some very basic instructions.
Suppose you keep downloaded .el files in ~/site-lisp
then your .emacs should look like

(setq load-path (cons (expand-file-name "~/site-lisp") load-path)
;;start smart-snippet stuff
(require 'smart-snippet)
;;Following only works during html helper mode
(require 'html-helper-mode)
(smart-snippet-with-abbrev-tables (html-helper-mode-abbrev-table)
("href" "<a href=\"$$\">$.</a>" t) ;;(A)
)
;;For python
(smart-snippet-with-abbrev-tables (python-mode-abbrev-table) (
"for" "for $${element} in $${sequence}:\n$>$." 'bol?) ;;(B)
)


generally, the lines look like

1. (smart-snippet-with-abbrev-tables (MODENAME-mode-abbrev-table)
2. The snippet and activation code look like
("ACTIVATION" "REPLACEMENT" CONDITION)

So in (A)
typing href starts the smart snippet and replaces it with <a href="$
$">$.</a>
a)The $$ wont be seen actually, it is a dummy for a variable, i.e you
it will be highlighted waiting for your input. Press TAB to move to
next parameter or out of the paramater
b)\" places " in the replacement text
c)The $. is the place to keep the cursor at the end
d)the 't' informs smart snippet to activate all the time as opposed
to bol (see (B))

In (B)
a)for triggers the smart snippet
b)$${element} is a named parameter, which you can use again in the
snippet replacement. So when the user changes the value the first time
it is reflected everywhere else the $${element} is used. Press TAB to
move to next parameter.
c)$> indents, which is required for python
d)'bol? evaluates to true only when you type for at the logical
beginning of the line, since e.g you don't want for to be expanded in
a comment

It is helpful reading the source.

Hope this helps.

Regards
Saptarshi

Saptarshi Guha | saptars...@gmail.com | http://www.stat.purdue.edu/~sguha
What does "it" mean in the sentence "What time is it?"?

Peter Michaux

unread,
Feb 5, 2008, 4:54:16 PM2/5/08
to smart-snippet
Hi Saptarshi,

Thanks for the instructions.

On Feb 5, 11:38 am, Saptarshi Guha <saptarshi.g...@gmail.com> wrote:
> Hi,
> Some very basic instructions.
> Suppose you keep downloaded .el files in ~/site-lisp
> then your .emacs should look like

I have set up the following to test. I have only one file in my ~/site-
lisp/ directory. That is the file ~/site-lisp/smart-snippet.el. Any
my .emacs file is only the following

; --------------------------------------

(setq load-path (cons (expand-file-name "~/site-lisp") load-path))

(require 'smart-snippet)

(require 'python)
(smart-snippet-with-abbrev-tables (python-mode-abbrev-table) (
"for" "for $${element} in $${sequence}:\n$>$." 'bol?)
)

; --------------------------------------

When I open a file called ~/temp.py, I can see that Emacs goes into
the Python major mode. When I type for and press tab or space, nothing
happens.

Why doesn't it work?

Thanks,
Peter

Saptarshi Guha

unread,
Feb 5, 2008, 5:08:38 PM2/5/08
to smart-...@googlegroups.com
Hello,
My mistake, I forgot to mention that you need to add the following
lines just after (require 'smart-snippet)
(dolist (hook '(python-mode-hook
;;html-helper-mode-hook
;;LaTeX-mode-hook
;;ruby-mode-hook
;;emacs-lisp-mode-hook
;;text-mode-hook
))
(add-hook hook (lambda () (abbrev-mode 1) )))
This turns on abbrev-mode (abbrev-mode 1) for the modes listed in the
dolist list.
I have commented out the lines you might not need (as of now).
Hope this works for you.
Regards
Saptarshi

Saptarshi Guha | saptars...@gmail.com | http://www.stat.purdue.edu/~sguha
This novel is not to be tossed lightly aside, but to be hurled with
great force.
-- Dorothy Parker

Peter Michaux

unread,
Feb 5, 2008, 5:29:02 PM2/5/08
to smart-snippet
On Feb 5, 2:08 pm, Saptarshi Guha <saptarshi.g...@gmail.com> wrote:
> Hello,
> My mistake, I forgot to mention that you need to add the following
> lines just after (require 'smart-snippet)
> (dolist (hook '(python-mode-hook
> ;;html-helper-mode-hook
> ;;LaTeX-mode-hook
> ;;ruby-mode-hook
> ;;emacs-lisp-mode-hook
> ;;text-mode-hook
> ))
> (add-hook hook (lambda () (abbrev-mode 1) )))

Ahh yes. That does work. Thank you. Now when I type "for" and press
space the snippet is typed. This is different than TextMate. TextMate
uses a tab after they abbreviation to insert the snippet. In TextMate
a space doesn't initiate a snippet. Can the TextMate behavior be done
with smart-snippet.el?

Thanks,
Peter

Saptarshi Guha

unread,
Feb 5, 2008, 5:51:05 PM2/5/08
to smart-...@googlegroups.com
>
Hi,
That is a nice question and also bumps against the end of skills.
This is something resident experts like pluskid(the author) and
others might be able to answer.
It does make for a very nice enhancement.

My knowledge of abbrev-mode (which, i think, smart-snippet uses) is
that abbreviations are replaced whenever a 'punctuation character' is
inserted, however maybe there is a workaround.

Over to others.
Regards
Saptarshi

Saptarshi Guha

unread,
Feb 5, 2008, 7:50:33 PM2/5/08
to smart-...@googlegroups.com
Hello,
So i was browsing around and came across to a very nice emacs blog
http://www.emacsblog.org/2007/03/12/tab-completion-everywhere/
and found this code(slightly modified)

(defun indent-or-expand ()
(interactive)
(if (and
(or (bobp) (= ?w (char-syntax (char-before))))
(or (eobp) (not (= ?w (char-syntax (char-after))))))
(expand-abbrev)
(indent-according-to-mode)))
(defun my-tab-fix ()
(local-set-key [tab] 'indent-or-expand))
(add-hook 'python-mode-hook 'my-tab-fix)

This maps tab to abbrev completion yet still allowing for tab
completion/line indent etc. Reading the web page, we understand the it
uses the regular function "indent-according-to-mode" if not at a word
boundary.
So now you can start the activation with Tab but can't move between
fields.

However, there is one problem, it overrides smart-snippets's field
movement i.e can't to move to next field using TAB.
A fix would be to check for the current keymap, if it is snippet-map
then call the indent-according-to-mode or the regular snippet function.

Can anyone suggest a way?
Thanks
Saptarshi

Saptarshi Guha | saptars...@gmail.com | http://www.stat.purdue.edu/~sguha
if it GLISTENS, gobble it!!

Saptarshi Guha

unread,
Feb 5, 2008, 8:32:40 PM2/5/08
to smart-...@googlegroups.com
Hi,
Place this before (require 'smart-snippet), though I think the
location does not matter

(defun indent-or-expand ()
(interactive)
(if (and
(or (bobp) (= ?w (char-syntax (char-before))))
(or (eobp) (not (= ?w (char-syntax (char-after))))))
(expand-abbrev)
(indent-according-to-mode)))
(defun my-tab-fix () (global-set-key (kbd "TAB") 'indent-or-expand))
(add-hook 'python-mode-hook 'my-tab-fix) ;;repeat line for different
modes

Now you can tab to initiate.
Regards
Saptarshi

Saptarshi Guha | saptars...@gmail.com | http://www.stat.purdue.edu/~sguha
I live the way I type; fast, with a lot of mistakes.

Chiyuan Zhang

unread,
Feb 6, 2008, 12:27:59 AM2/6/08
to smart-...@googlegroups.com
Yes, it is activated whenever a 'punctuation character', or a
'non-word character' is inserted. It is the behavior of the
build-in Emacs abbrev feature. And that's also why I made snippet
'smart' -- you can apply conditions to your snippet: take the
'for' for example, you'd like it to expand into something like
"for $${element} in $${sequence}:\n$>$." . But you never want
it to be expanded when typing a sentence in comment,
so you write your snippet like this:

("for" "for $${element} in $${sequence}:\n$>$." (not in-comment?))

more investigation shows that generally you only like `for' to
expand when type at the beginning of line (or only after some spaces),
so generally you like:

("for" "for $${element} in $${sequence}:\n$>$." bol?)

Thus, when you type

for

and press space it will get expanded, but when you type

# this is a comment for my program

the `for' won't get expanded. So you never think about when to press
TAB to expand your snippet. Emacs handles it for you (of course, you
should write the condition for a snippet smartly). Another example
is the double-quote character `"' in c-mode:

("\"" "\"$.\"" '(not (c-in-literal)))
("\"" "\\\"$." '(eq (c-in-literal) 'string))

You see, in normal case, it gets expanded into a pair of double-quote
""
But if I'm currently already inside a string, it get escaped:
"|"
^--< here is cursor, and I type `"', it gets

"\""

2008/2/6, Saptarshi Guha <saptars...@gmail.com>:

Chiyuan Zhang

unread,
Feb 6, 2008, 12:39:03 AM2/6/08
to smart-...@googlegroups.com
2008/2/6, Saptarshi Guha <saptars...@gmail.com>:

>
> Hello,
> So i was browsing around and came across to a very nice emacs blog
> http://www.emacsblog.org/2007/03/12/tab-completion-everywhere/
> and found this code(slightly modified)
>
> (defun indent-or-expand ()
> (interactive)
> (if (and
> (or (bobp) (= ?w (char-syntax (char-before))))
> (or (eobp) (not (= ?w (char-syntax (char-after))))))
> (expand-abbrev)
> (indent-according-to-mode)))
> (defun my-tab-fix ()
> (local-set-key [tab] 'indent-or-expand))
> (add-hook 'python-mode-hook 'my-tab-fix)
>
> This maps tab to abbrev completion yet still allowing for tab
> completion/line indent etc. Reading the web page, we understand the it
> uses the regular function "indent-according-to-mode" if not at a word
> boundary.
> So now you can start the activation with Tab but can't move between
> fields.
>
> However, there is one problem, it overrides smart-snippets's field
> movement i.e can't to move to next field using TAB.
> A fix would be to check for the current keymap, if it is snippet-map
> then call the indent-according-to-mode or the regular snippet function.
>
Hi, if you really like it: if this code

(memq (and snippet (snippet-bound snippet))
(overlays-at (point)))

returns non-nil, then you can determine you're currently inside a snippet
and invoke snippet-next-field.

pluskid

unread,
Feb 6, 2008, 12:54:33 AM2/6/08
to smart-snippet
Hi, I've included your tutorial in the wiki:
http://code.google.com/p/smart-snippet/wiki/Tutorial

It's a pity that google code wiki add arbitrary wired color to the
text. It
just think all codes are python. :(
> Saptarshi Guha | saptarshi.g...@gmail.com |http://www.stat.purdue.edu/~sguha

Peter Michaux

unread,
Feb 7, 2008, 1:38:05 AM2/7/08
to smart-snippet
On Feb 5, 4:50 pm, Saptarshi Guha <saptarshi.g...@gmail.com> wrote:
> Hello,
> So i was browsing around and came across to a very nice emacs blog
> http://www.emacsblog.org/2007/03/12/tab-completion-everywhere/
> and found this code(slightly modified)
>
> (defun indent-or-expand ()
> (interactive)
> (if (and
> (or (bobp) (= ?w (char-syntax (char-before))))
> (or (eobp) (not (= ?w (char-syntax (char-after))))))
> (expand-abbrev)
> (indent-according-to-mode)))
> (defun my-tab-fix ()
> (local-set-key [tab] 'indent-or-expand))
> (add-hook 'python-mode-hook 'my-tab-fix)
>
> This maps tab to abbrev completion yet still allowing for tab
> completion/line indent etc. Reading the web page, we understand the it
> uses the regular function "indent-according-to-mode" if not at a word
> boundary.
> So now you can start the activation with Tab but can't move between
> fields.
>
> However, there is one problem, it overrides smart-snippets's field
> movement i.e can't to move to next field using TAB.
> A fix would be to check for the current keymap, if it is snippet-map
> then call the indent-according-to-mode or the regular snippet function.

Thanks for this information! I combined this with Chiyuan Zhang's
information to get the following code.

Right now I'm playing with snippet.el and I think this would translate
to smart-snippet.el.

have a file called python-snippets.el

;-------------------------------------

(snippet-with-abbrev-table
'python-mode-abbrev-table
("for" . "for $${element} in $${sequence}:")
("im" . "import $$")
("if" . "if $${True}:")
("wh" . "while $${True}:"))

(provide 'python-snippets)

; ------------------------------------

and in my .emacs file I have the following

(defun indent-or-expand ()
(interactive)

(if (and (or (bobp) ; at beginning of buffer
(= ?w (char-syntax (char-before)))) ; is the char
before point a word char?
(or (eobp) ; at end of buffer
(not (= ?w (char-syntax (char-after))))) ; is char
after point a non-word char?
) ; end conditional
(expand-abbrev)
(if (memq (and snippet (snippet-bound snippet))
(overlays-at (point)))
(snippet-next-field)
(indent-according-to-mode)
)
)
)

(defun my-tab-fix ()
(local-set-key [tab] 'indent-or-expand))

(add-hook 'python-mode-hook
(lambda ()
(require 'snippet)
(require 'python-snippets)
(my-tab-fix)
)
)

; -------------------------------

Note abbrev-mode is off for python mode.

So far this is very similar to TextMate behavior.

Thanks again,
Peter
Reply all
Reply to author
Forward
0 new messages