Skip to content

Commit 30b12a8

Browse files
committed
Refactor and implement "arg-spec"
* Add `mldoc-propertizer*` variable instead of that passed by argument * Split `mldoc--propertize-args` and `mldoc--propertize-args` "arg-spec" notation is like `(args ", " :type " " :name)`
1 parent 6a61c78 commit 30b12a8

File tree

3 files changed

+74
-27
lines changed

3 files changed

+74
-27
lines changed

README.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ MLDoc has APIs for end users and Lisp package developers.
2424
**** Example
2525
#+BEGIN_SRC emacs-lisp
2626
(defcustom mldoc-foo-function-spec
27-
'(return-type " " function "(" (args ", " type " " name) ")")
27+
'(return-type " " function "(" (args ", " :type " " :name) ")")
2828
"MLDoc display spec for Foo function call."
2929
:group 'mldoc-foo
3030
:type 'sexp)

mldoc.el

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353

5454
(defvar-local mldoc-returns-string t
5555
"When not-NIL, MLDoc functions return ElDoc complatible string.")
56+
57+
(defvar-local mldoc-propertizer* nil
58+
"Dynamic bound list of propertizers.")
5659

5760
;; Utility functions
5861
(defsubst mldoc-in-string ()
@@ -80,31 +83,47 @@ The definition is (lambda ARGLIST [DOCSTRING] BODY...)."
8083
(mapconcat #'identity (apply #'mldoc--build-list doc) "")
8184
doc))))
8285

83-
(defun mldoc--propertize-args (args current-arg arg-separator)
84-
"Return propertized string by `ARGS' list, `CURRENT-ARG' and `ARG-SEPARATOR'."
86+
(defun mldoc--propertize-arg (arg is-current-arg arg-spec)
87+
"Propertize `ARG' by `IS-CURRENT-ARG' and `ARG-SPEC'."
88+
(cl-loop
89+
for spec in arg-spec
90+
collect
91+
(if (stringp spec)
92+
spec
93+
(let ((v (plist-get arg spec)))
94+
(if (null v)
95+
""
96+
(if (and is-current-arg (eq :name spec))
97+
(propertize v 'face '(:weight bold))
98+
(mldoc--propertize-keyword arg spec)))))))
99+
100+
(defun mldoc--propertize-args (args current-arg arg-separator &optional arg-spec)
101+
"Return propertized string by `ARGS' list, `CURRENT-ARG', `ARG-SEPARATOR' and `ARG-SPEC'."
85102
(mapconcat
86103
#'identity
87104
(cl-loop for arg in args
88105
for n = 0 then (1+ n)
89-
collect (if (not (and current-arg (eq n current-arg)))
90-
arg
91-
(propertize arg 'face '(:weight bold))))
106+
append
107+
(mldoc--propertize-arg
108+
(if (stringp arg) (list :name arg) arg)
109+
(eq current-arg n)
110+
(or arg-spec (list :name))))
92111
(or arg-separator ", ")))
93112

94113
(defun mldoc--propertizers-to-list (propertizer)
95114
"Return list for function `propertize' by `PROPERTIZER' alist."
96115
(cl-loop for (p . sym) in propertizer
97116
append (list p (symbol-value sym))))
98117

99-
(defun mldoc--propertize-keyword (values key propertizers)
118+
(defun mldoc--propertize-keyword (values key)
100119
"Return propertized string `KEY' in `VALUES' plist, by `FACES'."
101120
(let* ((val (plist-get values key))
102-
(str (if (stringp val)
103-
val
104-
(funcall val)))
105-
(prop (cdr-safe (assq key propertizers))))
121+
(str (if (functionp val)
122+
(funcall val)
123+
val))
124+
(prop (cdr-safe (assq key mldoc-propertizer*))))
106125
(if (null prop)
107-
str
126+
(or str "")
108127
(apply #'propertize str (mldoc--propertizers-to-list prop)))))
109128

110129
(cl-defmacro mldoc-list (spec &key function propertizers args current-arg values)
@@ -126,20 +145,20 @@ plist `values'
126145
"
127146
(setq values (plist-put values :function function))
128147
(setq values (plist-put values :args args))
129-
(setq propertizers (append propertizers mldoc-default-eldoc-propertizers))
130-
131-
(cl-loop
132-
for s in spec collect
133-
(cond
134-
((stringp s) s)
135-
((symbolp s)
136-
(if (not (keywordp s))
137-
(symbol-value s)
138-
(mldoc--propertize-keyword values s propertizers)))
139-
((listp s)
140-
(if (eq 'args (car s))
141-
(mldoc--propertize-args args current-arg (nth 1 s))
142-
(apply (car s) (cdr s)))))))
148+
(let ((mldoc-propertizer*
149+
(append propertizers mldoc-default-eldoc-propertizers)))
150+
(cl-loop
151+
for s in spec collect
152+
(cond
153+
((stringp s) s)
154+
((symbolp s)
155+
(if (not (keywordp s))
156+
(symbol-value s)
157+
(mldoc--propertize-keyword values s)))
158+
((listp s)
159+
(if (eq 'args (car s))
160+
(mldoc--propertize-args args current-arg (nth 1 s) (cddr s))
161+
(apply (car s) (cdr s))))))))
143162

144163
(defun mldoc-eldoc-function ()
145164
"ElDoc backend function by MLDoc package."

tests/mldoc-test.el

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,35 @@
4040
,(mldoc--build-list '(:foo ": " :function)
4141
:function "f" :values (list :foo "hoge"))
4242
,(list "hoge" ": "
43-
(propertize "f" 'face font-lock-function-name-face))))))
43+
(propertize "f" 'face font-lock-function-name-face)))
44+
("Spec has arg list"
45+
,(mldoc--build-list '(:function "(" (args ", ") ")")
46+
:function "f"
47+
:args '("a" "b" "c")
48+
:current-arg 2)
49+
,(list (propertize "f" 'face font-lock-function-name-face)
50+
"("
51+
(concat "a, " (propertize "b" 'face '(:weight bold)) ", c")
52+
")"))
53+
)))
54+
(cl-loop for (desc actual expected) in data
55+
do (should (equal (cons desc expected) (cons desc actual))))))
56+
57+
(ert-deftest mldoc-test--propertize-arg ()
58+
(let ((data
59+
;; (mldoc--propertize-arg arg is-current-arg arg-spec)
60+
`(("Simple argument"
61+
,(mldoc--propertize-arg '(:name "a") nil '(:name))
62+
,(list "a"))
63+
("Simple argument and current argument"
64+
,(mldoc--propertize-arg '(:name "a") t '(:name))
65+
,(list (propertize "a" 'face '(:weight bold))))
66+
("Argument has :name and :type"
67+
,(mldoc--propertize-arg '(:name "a" :type "string")
68+
nil
69+
'(:name " / " :type))
70+
,(list "a" " / "
71+
(propertize "string" 'face font-lock-function-name-face))))))
4472
(cl-loop for (desc actual expected) in data
4573
do (should (equal (cons desc expected) (cons desc actual))))))
4674

0 commit comments

Comments
 (0)