-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathse-macros.el
55 lines (49 loc) · 2.01 KB
/
se-macros.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
(defmacro se-create-mode (prefix parent &optional docstring &rest body)
"A macro for defining structured editing based modes. This
macro should contain best practices at the cost of customization.
PREFIX should be the mode's name, properly capitalized. PREFIX
in lowercase is used as a namespace. The created mode can be
activated by PREFIX-mode, all lower case.
PARENT should be either nil or a mode to derive the new mode
from.
DOCSTRING is an optional string to document your mode. It is
highly recommend you do not leave this out.
BODY should contain any code to be executed when the mode starts.
It is expected that `se-inf-start' is called.
Example:
(se-create-mode \"se-Ruby\" ruby-mode
\"A structured editing based mode for Ruby files.\"
(se-inf-start ...))
=> se-ruby-mode"
(declare (indent 2) (debug t))
(cl-macrolet ((idf (&rest args)
`(intern (downcase (format ,@args)))))
`(progn
(define-derived-mode
,(idf "%s-mode" prefix)
,(or parent
;; keep emacs version <24 compatability
(if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
,(format "%s" prefix)
,docstring
,@body
(unless (lookup-key ,(idf "%s-mode-map" prefix) (kbd "M-s"))
;; only bind if unbound
(define-key ,(idf "%s-mode-map" prefix) (kbd "M-s") #'se-navigation-mode))
(add-hook 'se-navigation-mode-hook
',(idf "%s-parse-file" prefix) nil t)
(add-hook 'before-change-functions
#'se-mode-push-parse-tree nil t))
(defun ,(idf "%s-parse-file" prefix) ()
"Only parses when navigation mode is active to prevent
the navigation mode hook from calling `se-inf-parse-file' when
deactivating. Additionally, only parses when
`se-mode-parse-tree' is nil. Most often one should use
`se-inf-parse-file' instead.
This function was created for use with
`se-mode-push-parse-tree' (which should set `se-mode-parse-tree'
to nil) in the `before-change-functions' hook."
(when (and se-navigation-mode
(null se-mode-parse-tree))
(se-inf-parse-file))))))
(provide 'se-macros)