This is my post second post in this series. After spending some time in lisp, I have managed auto-insert to work for actionscript.
Emacs has got Autoinserting which allows putting some predefined code in a file when you create it first time. This is a familiar concept for people who use IDEs like FlexBuilder for coding.
In flex builder when we create a class first time, it asks for the classname and other information like base class, interfaces and dump some code for the first time. Autoinserting is the answer to achieve such a functionality in emacs.
It works as follows:
- When you create a new file with .as extension, it prompts for the base class name
- Pressing ENTER will imply no base class otherwise it will insert the required code (import statement and extends string in the template)
- After that it asks for package name, again pressing ENTER will mean default (i.e top level package) otherwise package name given will be taken.
- It repeatedly keeps asking for the interfaces that you plan to implement, unless you press ENTER
Here is the required code you need to add to your .emacs file.
P.S :=> Don’t forget to set the flex-home variable
(auto-insert-mode t)
(setq auto-insert-alist
(append '(((actionscript-mode . "Actionscript Mode") . insert-as-template))
auto-insert-alist))
(defvar flex-home "C:/flex/sdk/framework/src")
(defun get-dot-seperated (file-name)
(interactive)
(setq file-name (substring file-name 1 )) ;; Get rid of the first /
(setq parts (split-string file-name "/")) ;; split string into parts based on /
;;Start creating . seperated import string
(setq file-dot-path "")
(while parts
(setq token (car parts))
(setq file-dot-path (concat file-dot-path "." token))
(setq parts (cdr parts)))
(substring file-dot-path 1))
(defun insert-as-template ()
(interactive)
(let ((baseclass (read-file-name "[]base class?" flex-home))
(package (read-string "[]Package?" ""))
;;(title (substring (file-name-nondirectory buffer-file-name) 0 -3))
(title (file-name-sans-extension (file-name-nondirectory buffer-file-name)))
(tab "t"))
(insert (concat
"package " package "n"
"{n"))
(setq hasBaseClass (not (or (= (length baseclass) 0)
(equal buffer-file-name baseclass))))
(when hasBaseClass
(setq foo (length flex-home))
(setq base-class-name (substring baseclass foo ( - (length baseclass) 3))) ;;get /mx/controls/Datagrid from full path
(insert (concat "import " (get-dot-seperated base-class-name) ";n")))
(setq point-for-imports (point))
(insert (concat "public class " title))
(if hasBaseClass
(insert (concat " extends " (file-name-sans-extension (file-name-nondirectory baseclass)))))
(setq point-after-class (point))
(insert (concat
"n"
"{n"
"n"
tab "//--------------------------------------------------------------------------n"
tab "//n"
tab "// Constructorn"
tab "//n"
tab "//--------------------------------------------------------------------------n"
"n"
tab "/**n"
tab "* Constructor.n"
tab "*/n"
tab "public function " title "()n"
tab "{n"
tab tab "//Start from heren" tab tab))
;;bookmark this point, so that we can place the cursor here when finished
(setq point-beginning (point))
(insert (concat
"n"
tab "}n"
"}n"
"}n"
)))
(setq imports-for-interfaces "")
(setq implements-string "")
(setq base-class-path "")
(setq prompt t)
(while prompt
(let ((interface (read-file-name "[]implements?" flex-home)))
(when (not (or (= (length interface) 0)
(equal buffer-file-name interface)))
(setq foo (length flex-home))
(setq interface-name (substring interface foo ( - (length interface) 3))) ;;get /mx/controls/Datagrid from full path
(setq imports-for-interfaces (concat imports-for-interfaces "import " (get-dot-seperated interface-name) ";n"))
(setq implements-string (concat implements-string (file-name-sans-extension (file-name-nondirectory interface-name)) ",")))
(if (or (= (length interface) 0)
(equal buffer-file-name interface))
(setq prompt nil))))
(when (> (length implements-string) 0)
(setq implements-string (substring implements-string 0 (1- (length implements-string))))
(goto-char point-after-class)
(insert (concat "nt" "implements " implements-string))
(setq point-beginning (+ point-beginning (length implements-string))))
(when (> (length imports-for-interfaces) 0)
(goto-char point-for-imports)
(insert (concat imports-for-interfaces "n"))
(setq point-beginning (+ point-beginning (length imports-for-interfaces))))
(goto-char point-beginning))
As a result I get this as my start file:
package src
{
import mx.controls.Tree;
import mx.controls.treeClasses.ITreeDataDescriptor;
import mx.collections.IViewCursor;
public class MyTree extends Tree
implements ITreeDataDescriptor,IViewCursor
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*/
public function MyTree()
{
//Start from here
}
}
}
Filed under: actionscript, emacs
I think you missed a trick here: emacs already has support for templating. Try M-: (require ‘tempo) M-x apropos tempo-define-template..
fgh