1
1
; ;; beluga-mode.el --- Major mode for Beluga source code -*- coding : utf-8 ; lexical-binding :t -*-
2
2
3
- ; ; Copyright (C) 2009-2018 Free Software Foundation, Inc.
3
+ ; ; Copyright (C) 2012 Brigitte Pientka
4
4
5
5
; ; Author: Stefan Monnier <[email protected] >
6
6
33
33
34
34
; ;; Code:
35
35
36
- (eval-when -compile (require 'cl-lib ))
36
+ (eval-and -compile (require 'cl-lib ))
37
37
(require 'smie )
38
+ (require 'comint )
38
39
39
40
(require 'ansi-color )
40
- (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter )
41
41
42
42
(provide 'beluga-unicode-input-method )
43
43
(require 'quail )
@@ -173,7 +173,7 @@ in unicode using Font Lock mode."
173
173
" Return non-nil if PROCESS is alive.
174
174
A process is considered alive if its status is `run' , `open' ,
175
175
`listen' , `connect' or `stop' ."
176
- (and (not (eq process nil ))
176
+ (and (not (null process))
177
177
(memq (process-status process)
178
178
'(run open listen connect stop))))
179
179
@@ -207,19 +207,29 @@ Regexp match data 0 points to the chars."
207
207
; ; Return nil because we're not adding any face property.
208
208
nil )
209
209
210
+ (defcustom beluga-font-lock-symbols t
211
+ " Whether apply font lock for symbols or not."
212
+ :type 'boolean
213
+ :group 'beluga )
214
+
215
+ (defcustom beluga-font-lock-symbols-alist nil
216
+ " Whether apply font lock for symbols or not."
217
+ :type '(list boolean)
218
+ :group 'beluga )
219
+
210
220
(defun beluga-font-lock-symbols-keywords ()
211
221
" Beluga-mode font lock for keywords."
212
222
(when (and (fboundp 'compose-region ) beluga-font-lock-symbols)
213
223
(let ((alist nil ))
214
224
(dolist (x beluga-font-lock-symbols-alist)
215
- (when (and (if (fboundp 'char-displayable-p )
216
- (char-displayable-p (if (consp (cdr x)) (cadr x) (cdr x)))
217
- t )
218
- (not (assoc (car x) alist))) ; Not yet in alist.
219
- (push x alist)))
225
+ (when (and (if (fboundp 'char-displayable-p )
226
+ (char-displayable-p (if (consp (cdr x)) (cadr x) (cdr x)))
227
+ t )
228
+ (not (assoc (car x) alist))) ; Not yet in alist.
229
+ (push x alist)))
220
230
(when alist
221
- `((,(regexp-opt (mapcar #'car alist) t )
222
- (0 (beluga-font-lock-compose-symbol ', alist )
231
+ `((,(regexp-opt (mapcar #'car alist) t )
232
+ (0 (beluga-font-lock-compose-symbol ', alist )
223
233
; ; In Emacs-21, if the `override' field is nil, the face
224
234
; ; expressions is only evaluated if the text has currently
225
235
; ; no face. So force evaluation by using `keep' .
@@ -264,9 +274,8 @@ Note that this will also match the \"and\" keyword!")
264
274
265
275
; ; ------ process management ----- ;;
266
276
267
- (defvar beluga--proc ()
277
+ (defvar-local beluga--proc ()
268
278
" Contain the process running beli." )
269
- (make-variable-buffer-local 'beluga--proc )
270
279
271
280
(defvar beluga--output-wait-time
272
281
0.025
@@ -309,9 +318,8 @@ This is a graceful termination."
309
318
310
319
; ; ----- Stuff for hole overlays ----- ;;
311
320
312
- (defvar beluga--holes-overlays ()
321
+ (defvar-local beluga--holes-overlays ()
313
322
" Will contain the list of hole overlays so that they can be resetted." )
314
- (make-variable-buffer-local 'beluga--holes-overlays )
315
323
316
324
(defun beluga-sorted-holes ()
317
325
" Sort beluga holes."
@@ -404,7 +412,7 @@ This is a graceful termination."
404
412
; ; We could also just use `process-send-string' , but then we wouldn't
405
413
; ; have the input text in the buffer to separate the various prompts.
406
414
(goto-char (point-max ))
407
- (insert ( concat " %:" cmd) )
415
+ (insert " %:" cmd)
408
416
(comint-send-input )
409
417
(beluga--wait proc))))
410
418
@@ -431,11 +439,10 @@ This is a graceful termination."
431
439
(beluga-interactive-error (list (format " %s " (substring resp 2 )))))
432
440
resp))
433
441
434
- (defvar beluga--last-load-time
442
+ (defvar-local beluga--last-load-time
435
443
'(0 0 0 0 )
436
444
" The last time the file was loaded into the Beluga interpreter.
437
445
This variable is updated by `beluga--maybe-save-load-current-buffer' ." )
438
- (make-variable-buffer-local 'beluga--last-load-time )
439
446
440
447
(defun beluga--should-reload-p ()
441
448
" Decide whether the current buffer should be reloaded into beli.
@@ -471,33 +478,34 @@ returned. Else, nil is returned."
471
478
; ; "!". This bang-variant will use beluga--rpc! under the hood, so you
472
479
; ; get an exception-raising variant of every function for free.
473
480
474
- (defun beluga--generate-format-string (args )
475
- " Construct the format string from the ARGS."
476
- (cons
477
- " %s"
478
- (mapcar
479
- (lambda (x )
480
- (if (stringp x)
481
- x
482
- (cdr x)))
483
- args)))
484
-
485
- (defun beluga--generate-arg-list (args )
486
- " Construct a list of symbols representing the function arguments from ARGS."
487
- (mapcar 'car (cl-remove-if 'stringp args)))
488
-
489
- (defun beluga--define-command (rpc name realname args )
490
- " Define a beli command for RPC.
481
+ (eval-and-compile
482
+ (defun beluga--generate-format-string (args )
483
+ " Construct the format string from the ARGS."
484
+ (cons
485
+ " %s"
486
+ (mapcar
487
+ #' (lambda (x )
488
+ (if (stringp x)
489
+ x
490
+ (cdr x)))
491
+ args)))
492
+
493
+ (defun beluga--generate-arg-list (args )
494
+ " Construct a list of symbols representing the function arguments from ARGS."
495
+ (mapcar #'car (cl-remove-if #'stringp args)))
496
+
497
+ (defun beluga--define-command (rpc name realname args )
498
+ " Define a beli command for RPC.
491
499
The command has elisp name NAME and string name REALNAME, and takes ARGS."
492
- (let ((arglist (beluga--generate-arg-list args))
493
- (fmt (beluga--generate-format-string args)))
494
- `(defun , name , arglist
495
- (, rpc
496
- (format
497
- ; ; construct the format string
498
- ,(mapconcat 'identity fmt " " )
499
- ; ; construct the argument list
500
- , realname ,@arglist )))))
500
+ (let ((arglist (beluga--generate-arg-list args))
501
+ (fmt (beluga--generate-format-string args)))
502
+ `(defun , name , arglist
503
+ (, rpc
504
+ (format
505
+ ; ; construct the format string
506
+ ,(mapconcat 'identity fmt " " )
507
+ ; ; construct the argument list
508
+ , realname ,@arglist ) )))))
501
509
502
510
(defmacro beluga-define-command (name realname args )
503
511
" Macro to provide `beluga--rpc' to `beluga--define-command' .
@@ -825,7 +833,8 @@ Otherwise, `match-string' 1 will contain the name of the matched short.")
825
833
((looking-at beluga-punct-re) (goto-char (match-end 0 )))
826
834
((not (zerop (skip-syntax-forward " w_'" ))))
827
835
; ; In case of non-ASCII punctuation.
828
- ((not (zerop (skip-syntax-forward " ." )))))
836
+ ((not (zerop (skip-syntax-forward " ." ))))
837
+ (t nil ))
829
838
(point ))))))
830
839
831
840
(defun beluga-short-pragma-before-p ()
@@ -842,26 +851,28 @@ Return the starting position of the short pragma; else, nil."
842
851
(defun beluga-smie-backward-token ()
843
852
" Skip all previous whitespace and comments."
844
853
(forward-comment (- (point-max )))
845
- (cond
846
- ((and (eq ?\. (char-before ))
847
- (looking-at " [ \t ]*$" ) ; ; "[ \t]*\\ (?:$\\ |[0-9]\\ (\\ )\\ )"
848
- (not (looking-back " \\ .\\ ." (- (point ) 2 ))))
849
- ; ; Either an LF-terminating dot, or a projection-dot.
850
- (progn (forward-char -1 ) " ;." ))
851
- ((setq pos (beluga-short-pragma-before-p))
852
- (goto-char pos)
853
- " --shortpragma" )
854
- (t
855
- (buffer-substring-no-properties
856
- (point )
857
- (progn
858
- (cond
859
- ((looking-back beluga-punct-re (- (point ) 2 ) 'greedy )
860
- (goto-char (match-beginning 0 )))
861
- ((not (zerop (skip-syntax-backward " w_'" ))))
862
- ; ; In case of non-ASCII punctuation.
863
- ((not (zerop (skip-syntax-backward " ." )))))
864
- (point ))))))
854
+ (let ((pos nil ))
855
+ (cond
856
+ ((and (eq ?\. (char-before ))
857
+ (looking-at " [ \t ]*$" ) ; ; "[ \t]*\\ (?:$\\ |[0-9]\\ (\\ )\\ )"
858
+ (not (looking-back " \\ .\\ ." (- (point ) 2 ))))
859
+ ; ; Either an LF-terminating dot, or a projection-dot.
860
+ (progn (forward-char -1 ) " ;." ))
861
+ ((setq pos (beluga-short-pragma-before-p))
862
+ (goto-char pos)
863
+ " --shortpragma" )
864
+ (t
865
+ (buffer-substring-no-properties
866
+ (point )
867
+ (progn
868
+ (cond
869
+ ((looking-back beluga-punct-re (- (point ) 2 ) 'greedy )
870
+ (goto-char (match-beginning 0 )))
871
+ ((not (zerop (skip-syntax-backward " w_'" ))))
872
+ ; ; In case of non-ASCII punctuation.
873
+ ((not (zerop (skip-syntax-backward " ." ))))
874
+ (t nil ))
875
+ (point )))))))
865
876
866
877
(defun beluga-smie-grammar (bnf resolvers precs )
867
878
" Get smie grammar based on BNF, RESOLVERS, and PRECS."
@@ -1007,6 +1018,14 @@ Return the starting position of the short pragma; else, nil."
1007
1018
`(or ,@beluga-fat-arrows )
1008
1019
" A pattern for use in pcase that matches any fat arrow string." )
1009
1020
1021
+ (defconst beluga-type-declaration-keywords
1022
+ '(" inductive" " coinductive" " LF" " stratified" )
1023
+ " The different keywords that introduce a type definition." )
1024
+
1025
+ (defconst beluga-type-declaration-keywords-re
1026
+ (regexp-opt beluga-type-declaration-keywords 'symbols )
1027
+ " A regular expression that matches any type definition keyword." )
1028
+
1010
1029
(defun beluga-rule-parent-p (parents )
1011
1030
" Check whether PARENTS is a parent of the current token."
1012
1031
`(smie-rule-parent-p ,@parents ))
@@ -1075,14 +1094,6 @@ Return the starting position of the short pragma; else, nil."
1075
1094
;;;### autoload
1076
1095
(add-to-list 'auto-mode-alist '(" \\ .s?bel\\ '" . beluga-mode))
1077
1096
1078
- (defconst beluga-type-declaration-keywords
1079
- '(" inductive" " coinductive" " LF" " stratified" )
1080
- " The different keywords that introduce a type definition." )
1081
-
1082
- (defconst beluga-type-declaration-keywords-re
1083
- (regexp-opt beluga-type-declaration-keywords 'symbols )
1084
- " A regular expression that matches any type definition keyword." )
1085
-
1086
1097
;;;### autoload
1087
1098
(define-derived-mode beluga-mode prog-mode " Beluga"
1088
1099
" Major mode to edit Beluga source code."
@@ -1105,6 +1116,9 @@ Return the starting position of the short pragma; else, nil."
1105
1116
(append '(?| ) (if (boundp 'electric-indent-chars )
1106
1117
electric-indent-chars
1107
1118
'(?\n ))))
1119
+
1120
+ (add-hook 'compilation-filter-hook #'ansi-color-compilation-filter )
1121
+
1108
1122
; QUAIL
1109
1123
(add-hook 'beluga-mode-hook
1110
1124
(lambda () (set-input-method " beluga-unicode" )))
0 commit comments