Skip to content

Commit 770a83d

Browse files
authored
Merge pull request #152 from immerrr/fix-compat-with-new-rx-package
Fix compatibility with new rx package from Emacs 27
2 parents 95c64bb + 99c7431 commit 770a83d

File tree

4 files changed

+158
-87
lines changed

4 files changed

+158
-87
lines changed

.travis.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1-
language: emacs-lisp
1+
dist: xenial
2+
language: minimal
23
sudo: no
34
addons:
45
apt:
56
packages:
67
- lua5.2
78
env:
9+
- EVM_EMACS=emacs-26.1-travis-linux-xenial
10+
- EVM_EMACS=emacs-26.2-travis-linux-xenial
11+
- EVM_EMACS=emacs-git-snapshot-travis-linux-xenial
812
- EVM_EMACS=emacs-24.3-travis
913
- EVM_EMACS=emacs-24.4-travis
1014
- EVM_EMACS=emacs-24.5-travis
1115
- EVM_EMACS=emacs-25.1-travis
1216
- EVM_EMACS=emacs-25.2-travis
1317
- EVM_EMACS=emacs-25.3-travis
14-
# - EVM_EMACS=emacs-git-snapshot-travis
18+
matrix:
19+
allow_failures:
20+
- env: EVM_EMACS=emacs-git-snapshot-travis-linux-xenial
21+
fast_finish: true
1522
before_install:
1623
- curl -fsSkL https://gist.github.com/rejeep/ebcd57c3af83b049833b/raw > travis.sh && source ./travis.sh
1724
- evm install "$EVM_EMACS" --use --skip
25+
- emacs --version
1826
install:
1927
- cask install
2028
script:

lua-mode.el

Lines changed: 128 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -101,80 +101,120 @@
101101
(require 'compile))
102102

103103
(eval-and-compile
104-
(defvar lua-rx-constituents)
105-
(defvar rx-parent)
106-
107-
(defun lua-rx-to-string (form &optional no-group)
108-
"Lua-specific replacement for `rx-to-string'.
104+
(if (fboundp #'rx-let)
105+
(progn
106+
;; Emacs 27+ way of customizing rx
107+
(defvar lua--rx-bindings)
108+
109+
(setq
110+
lua--rx-bindings
111+
'((symbol (&rest x) (seq symbol-start (or x) symbol-end))
112+
(ws (* (any " \t")))
113+
(ws+ (+ (any " \t")))
114+
115+
(lua-name (symbol (seq (+ (any alpha "_")) (* (any alnum "_")))))
116+
(lua-funcname (seq lua-name (* ws "." ws lua-name)
117+
(opt ws ":" ws lua-name)))
118+
(lua-funcheader
119+
;; Outer (seq ...) is here to shy-group the definition
120+
(seq (or (seq (symbol "function") ws (group-n 1 lua-funcname))
121+
(seq (group-n 1 lua-funcname) ws "=" ws
122+
(symbol "function")))))
123+
(lua-number
124+
(seq (or (seq (+ digit) (opt ".") (* digit))
125+
(seq (* digit) (opt ".") (+ digit)))
126+
(opt (regexp "[eE][+-]?[0-9]+"))))
127+
(lua-assignment-op (seq "=" (or buffer-end (not (any "=")))))
128+
(lua-token (or "+" "-" "*" "/" "%" "^" "#" "==" "~=" "<=" ">=" "<"
129+
">" "=" ";" ":" "," "." ".." "..."))
130+
(lua-keyword
131+
(symbol "and" "break" "do" "else" "elseif" "end" "for" "function"
132+
"goto" "if" "in" "local" "not" "or" "repeat" "return"
133+
"then" "until" "while"))))
134+
135+
(defmacro lua-rx (&rest regexps)
136+
(eval `(rx-let ,lua--rx-bindings
137+
(rx ,@regexps))))
138+
139+
(defun lua-rx-to-string (form &optional no-group)
140+
(rx-let-eval lua--rx-bindings
141+
(rx-to-string form no-group))))
142+
(progn
143+
;; Pre-Emacs 27 way of customizing rx
144+
(defvar lua-rx-constituents)
145+
(defvar rx-parent)
146+
147+
(defun lua-rx-to-string (form &optional no-group)
148+
"Lua-specific replacement for `rx-to-string'.
109149
110150
See `rx-to-string' documentation for more information FORM and
111151
NO-GROUP arguments."
112-
(let ((rx-constituents lua-rx-constituents))
113-
(rx-to-string form no-group)))
152+
(let ((rx-constituents lua-rx-constituents))
153+
(rx-to-string form no-group)))
114154

115-
(defmacro lua-rx (&rest regexps)
116-
"Lua-specific replacement for `rx'.
155+
(defmacro lua-rx (&rest regexps)
156+
"Lua-specific replacement for `rx'.
117157
118158
See `rx' documentation for more information about REGEXPS param."
119-
(cond ((null regexps)
120-
(error "No regexp"))
121-
((cdr regexps)
122-
(lua-rx-to-string `(and ,@regexps) t))
123-
(t
124-
(lua-rx-to-string (car regexps) t))))
159+
(cond ((null regexps)
160+
(error "No regexp"))
161+
((cdr regexps)
162+
(lua-rx-to-string `(and ,@regexps) t))
163+
(t
164+
(lua-rx-to-string (car regexps) t))))
125165

126-
(defun lua--new-rx-form (form)
127-
"Add FORM definition to `lua-rx' macro.
166+
(defun lua--new-rx-form (form)
167+
"Add FORM definition to `lua-rx' macro.
128168
129169
FORM is a cons (NAME . DEFN), see more in `rx-constituents' doc.
130170
This function enables specifying new definitions using old ones:
131171
if DEFN is a list that starts with `:rx' symbol its second
132172
element is itself expanded with `lua-rx-to-string'. "
133-
(let ((name (car form))
134-
(form-definition (cdr form)))
135-
(when (and (listp form-definition) (eq ':rx (car form-definition)))
136-
(setcdr form (lua-rx-to-string (cadr form-definition) 'nogroup)))
137-
(push form lua-rx-constituents)))
138-
139-
(defun lua--rx-symbol (form)
140-
;; form is a list (symbol XXX ...)
141-
;; Skip initial 'symbol
142-
(setq form (cdr form))
143-
;; If there's only one element, take it from the list, otherwise wrap the
144-
;; whole list into `(or XXX ...)' form.
145-
(setq form (if (eq 1 (length form))
146-
(car form)
147-
(append '(or) form)))
148-
(rx-form `(seq symbol-start ,form symbol-end) rx-parent))
149-
150-
(setq lua-rx-constituents (copy-sequence rx-constituents))
151-
152-
(mapc #'lua--new-rx-form
153-
`((symbol lua--rx-symbol 1 nil)
154-
(ws . "[ \t]*") (ws+ . "[ \t]+")
155-
(lua-name :rx (symbol (regexp "[[:alpha:]_]+[[:alnum:]_]*")))
156-
(lua-funcname
157-
:rx (seq lua-name (* ws "." ws lua-name)
158-
(opt ws ":" ws lua-name)))
159-
(lua-funcheader
160-
;; Outer (seq ...) is here to shy-group the definition
161-
:rx (seq (or (seq (symbol "function") ws (group-n 1 lua-funcname))
162-
(seq (group-n 1 lua-funcname) ws "=" ws
163-
(symbol "function")))))
164-
(lua-number
165-
:rx (seq (or (seq (+ digit) (opt ".") (* digit))
166-
(seq (* digit) (opt ".") (+ digit)))
167-
(opt (regexp "[eE][+-]?[0-9]+"))))
168-
(lua-assignment-op
169-
:rx (seq "=" (or buffer-end (not (any "=")))))
170-
(lua-token
171-
:rx (or "+" "-" "*" "/" "%" "^" "#" "==" "~=" "<=" ">=" "<"
172-
">" "=" ";" ":" "," "." ".." "..."))
173-
(lua-keyword
174-
:rx (symbol "and" "break" "do" "else" "elseif" "end" "for" "function"
175-
"goto" "if" "in" "local" "not" "or" "repeat" "return"
176-
"then" "until" "while")))
177-
))
173+
(let ((name (car form))
174+
(form-definition (cdr form)))
175+
(when (and (listp form-definition) (eq ':rx (car form-definition)))
176+
(setcdr form (lua-rx-to-string (cadr form-definition) 'nogroup)))
177+
(push form lua-rx-constituents)))
178+
179+
(defun lua--rx-symbol (form)
180+
;; form is a list (symbol XXX ...)
181+
;; Skip initial 'symbol
182+
(setq form (cdr form))
183+
;; If there's only one element, take it from the list, otherwise wrap the
184+
;; whole list into `(or XXX ...)' form.
185+
(setq form (if (eq 1 (length form))
186+
(car form)
187+
(append '(or) form)))
188+
(rx-form `(seq symbol-start ,form symbol-end) rx-parent))
189+
190+
(setq lua-rx-constituents (copy-sequence rx-constituents))
191+
192+
(mapc #'lua--new-rx-form
193+
`((symbol lua--rx-symbol 1 nil)
194+
(ws . "[ \t]*") (ws+ . "[ \t]+")
195+
(lua-name :rx (symbol (regexp "[[:alpha:]_]+[[:alnum:]_]*")))
196+
(lua-funcname
197+
:rx (seq lua-name (* ws "." ws lua-name)
198+
(opt ws ":" ws lua-name)))
199+
(lua-funcheader
200+
;; Outer (seq ...) is here to shy-group the definition
201+
:rx (seq (or (seq (symbol "function") ws (group-n 1 lua-funcname))
202+
(seq (group-n 1 lua-funcname) ws "=" ws
203+
(symbol "function")))))
204+
(lua-number
205+
:rx (seq (or (seq (+ digit) (opt ".") (* digit))
206+
(seq (* digit) (opt ".") (+ digit)))
207+
(opt (regexp "[eE][+-]?[0-9]+"))))
208+
(lua-assignment-op
209+
:rx (seq "=" (or buffer-end (not (any "=")))))
210+
(lua-token
211+
:rx (or "+" "-" "*" "/" "%" "^" "#" "==" "~=" "<=" ">=" "<"
212+
">" "=" ";" ":" "," "." ".." "..."))
213+
(lua-keyword
214+
:rx (symbol "and" "break" "do" "else" "elseif" "end" "for" "function"
215+
"goto" "if" "in" "local" "not" "or" "repeat" "return"
216+
"then" "until" "while")))
217+
))))
178218

179219

180220
;; Local variables
@@ -1101,8 +1141,11 @@ DIRECTION has to be either 'forward or 'backward."
11011141
(defun lua-goto-matching-block-token (&optional parse-start direction)
11021142
"Find block begion/end token matching the one at the point.
11031143
This function moves the point to the token that matches the one
1104-
at the current point. Returns the point position of the first character of
1105-
the matching token if successful, nil otherwise."
1144+
at the current point. Returns the point position of the first character of
1145+
the matching token if successful, nil otherwise.
1146+
1147+
Optional PARSE-START is a position to which the point should be moved first.
1148+
DIRECTION has to be 'forward or 'backward ('forward by default)."
11061149
(if parse-start (goto-char parse-start))
11071150
(let ((case-fold-search nil))
11081151
(if (looking-at lua-indentation-modifier-regexp)
@@ -1114,7 +1157,10 @@ the matching token if successful, nil otherwise."
11141157
(defun lua-goto-matching-block (&optional noreport)
11151158
"Go to the keyword balancing the one under the point.
11161159
If the point is on a keyword/brace that starts a block, go to the
1117-
matching keyword that ends the block, and vice versa."
1160+
matching keyword that ends the block, and vice versa.
1161+
1162+
If optional NOREPORT is non-nil, it won't flag an error if there
1163+
is no block open/close open."
11181164
(interactive)
11191165
;; search backward to the beginning of the keyword if necessary
11201166
(if (eq (char-syntax (following-char)) ?w)
@@ -1129,7 +1175,7 @@ matching keyword that ends the block, and vice versa."
11291175
"Move 1 line forward (back if BACK is non-nil) skipping blank lines.
11301176
11311177
Moves point 1 line forward (or backward) skipping lines that contain
1132-
no Lua code besides comments. The point is put to the beginning of
1178+
no Lua code besides comments. The point is put to the beginning of
11331179
the line.
11341180
11351181
Returns final value of point as integer or nil if operation failed."
@@ -1160,7 +1206,7 @@ Returns final value of point as integer or nil if operation failed."
11601206
t)
11611207
"\\)"
11621208
"\\s *\\="))
1163-
"Regexp that matches the ending of a line that needs continuation
1209+
"Regexp that matches the ending of a line that needs continuation.
11641210
11651211
This regexp starts from eol and looks for a binary operator or an unclosed
11661212
block intro (i.e. 'for' without 'do' or 'if' without 'then') followed by
@@ -1179,15 +1225,15 @@ an optional whitespace till the end of the line.")
11791225
t)
11801226
"\\($\\|[^" lua-operator-class "]\\)"
11811227
"\\)"))
1182-
"Regexp that matches a line that continues previous one
1228+
"Regexp that matches a line that continues previous one.
11831229
11841230
This regexp means, starting from point there is an optional whitespace followed
1185-
by Lua binary operator. Lua is very liberal when it comes to continuation line,
1231+
by Lua binary operator. Lua is very liberal when it comes to continuation line,
11861232
so we're safe to assume that every line that starts with a binop continues
11871233
previous one even though it looked like an end-of-statement.")
11881234

11891235
(defun lua-last-token-continues-p ()
1190-
"Returns true if the last token on this line is a continuation token."
1236+
"Return non-nil if the last token on this line is a continuation token."
11911237
(let ((line-begin (line-beginning-position))
11921238
(line-end (line-end-position)))
11931239
(save-excursion
@@ -1201,7 +1247,7 @@ previous one even though it looked like an end-of-statement.")
12011247
(re-search-backward lua-cont-eol-regexp line-begin t))))
12021248

12031249
(defun lua-first-token-continues-p ()
1204-
"Returns true if the first token on this line is a continuation token."
1250+
"Return non-nil if the first token on this line is a continuation token."
12051251
(let ((line-end (line-end-position)))
12061252
(save-excursion
12071253
(beginning-of-line)
@@ -1219,14 +1265,15 @@ previous one even though it looked like an end-of-statement.")
12191265
"\\_>\\)")))
12201266

12211267
(defun lua-first-token-starts-block-p ()
1222-
"Returns true if the first token on this line is a block starter token."
1268+
"Return non-nil if the first token on this line is a block starter token."
12231269
(let ((line-end (line-end-position)))
12241270
(save-excursion
12251271
(beginning-of-line)
12261272
(re-search-forward (concat "\\s *" lua-block-starter-regexp) line-end t))))
12271273

12281274
(defun lua-is-continuing-statement-p (&optional parse-start)
1229-
"Return non-nil if the line continues a statement.
1275+
"Return non-nil if the line at PARSE-START continues a statement.
1276+
12301277
More specifically, return the point in the line that is continued.
12311278
The criteria for a continuing statement are:
12321279
@@ -1246,8 +1293,10 @@ The criteria for a continuing statement are:
12461293
(lua-last-token-continues-p)))))))
12471294

12481295
(defun lua-make-indentation-info-pair (found-token found-pos)
1249-
"This is a helper function to lua-calculate-indentation-info. Don't
1250-
use standalone."
1296+
"Create a pair from FOUND-TOKEN and FOUND-POS for indentation calculation.
1297+
1298+
This is a helper function to lua-calculate-indentation-info.
1299+
Don't use standalone."
12511300
(cond
12521301
;; function is a bit tricky to indent right. They can appear in a lot ot
12531302
;; different contexts. Until I find a shortcut, I'll leave it with a simple
@@ -1321,17 +1370,17 @@ use standalone."
13211370
(- lua-indent-level))))))
13221371

13231372
(defun lua-add-indentation-info-pair (pair info)
1324-
"Add the given indentation info pair to the list of indentation information.
1373+
"Add the given indentation info PAIR to the list of indentation INFO.
13251374
This function has special case handling for two tokens: remove-matching,
1326-
and replace-matching. These two tokens are cleanup tokens that remove or
1375+
and replace-matching. These two tokens are cleanup tokens that remove or
13271376
alter the effect of a previously recorded indentation info.
13281377
13291378
When a remove-matching token is encountered, the last recorded info, i.e.
1330-
the car of the list is removed. This is used to roll-back an indentation of a
1379+
the car of the list is removed. This is used to roll-back an indentation of a
13311380
block opening statement when it is closed.
13321381
13331382
When a replace-matching token is seen, the last recorded info is removed,
1334-
and the cdr of the replace-matching info is added in its place. This is used
1383+
and the cdr of the replace-matching info is added in its place. This is used
13351384
when a middle-of the block (the only case is 'else') is seen on the same line
13361385
the block is opened."
13371386
(cond

test/test-font-lock.el

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,20 @@ _table.sort(foobar)
8181

8282

8383
(describe "Fontification of function headers"
84-
(it "fontifies simple headers"
84+
(it "fontifies function <name>(...) headers"
85+
(expect "function bar() end"
86+
:to-be-fontified-as '(("function" keyword "bar" function-name "end" keyword))))
87+
(it "fontifies local function <name>(...) headers"
88+
(expect "local function baz() end"
89+
:to-be-fontified-as '(("local" keyword "function" keyword "baz" function-name "end" keyword))))
90+
(it "fontifies <name> = function (...) headers"
91+
(expect "qux = function() end"
92+
:to-be-fontified-as '(("qux" function-name "function" keyword "end" keyword))))
93+
(it "fontifies local <name> = function (...) headers"
94+
(expect "local quux = function() end"
95+
:to-be-fontified-as '(("local" keyword "quux" function-name "function" keyword "end" keyword))))
96+
97+
(it "fontifies different variations of headers altogether"
8598
(expect
8699
;; Check all defun variants, check embedded defuns
87100
"\

test/utils.el

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,12 @@ This is a mere typing/reading aid for lua-mode's font-lock tests."
139139
(butlast
140140
(split-string
141141
(with-lua-buffer
142-
(insert (replace-regexp-in-string "^\\s *" "" (lua-join-lines strs)))
143-
(font-lock-fontify-buffer)
144-
(indent-region (point-min) (point-max))
145-
(buffer-substring-no-properties
146-
(point-min) (point-max)))
142+
(let ((inhibit-message t))
143+
(insert (replace-regexp-in-string "^\\s *" "" (lua-join-lines strs)))
144+
(font-lock-fontify-buffer)
145+
(indent-region (point-min) (point-max))
146+
(buffer-substring-no-properties
147+
(point-min) (point-max))))
147148
"\n" nil)))
148149

149150
(defun lua-insert-goto-<> (strs)

0 commit comments

Comments
 (0)