branch: elpa/j-mode
commit 5dca69ca557310104fcca1e86960c261857f2f21
Author: LdBeth <[email protected]>
Commit: LdBeth <[email protected]>
Improved string handling
Added font lock for multi-line string. Changed one line string
font lock behavior so an open quote does not span multiple
lines.
---
j-console.el | 13 ++++++++-
j-font-lock.el | 84 ++++++++++++++++++++++++++++++++++++++++++++++++----------
j-mode.el | 16 ++++++-----
3 files changed, 92 insertions(+), 21 deletions(-)
diff --git a/j-console.el b/j-console.el
index 7998205e37..fa28fce342 100644
--- a/j-console.el
+++ b/j-console.el
@@ -128,7 +128,7 @@ the containing buffer"
(session (j-console-ensure-session)))
(pop-to-buffer (process-buffer session))
(goto-char (point-max))
- (insert (format "\n%s\n" region))
+ (insert (format "%s" region))
(comint-send-input)))
(defun j-console-execute-line ()
@@ -141,6 +141,17 @@ the containing buffer"
(interactive)
(j-console-execute-region (point-min) (point-max)))
+;;XXX should maybe check that we are indeed in an explicit def, unlike
+;;elisp counterpart
+(defun j-console-execute-definition ()
+ "Send the current explicit definition to a running J session."
+ (interactive)
+ (save-excursion
+ (mark-defun)
+ (let ((start (point))
+ (end (mark)))
+ (j-console-execute-region start end))))
+
(provide 'j-console)
;;; j-console.el ends here
diff --git a/j-font-lock.el b/j-font-lock.el
index 18bee08b70..4ecfb576fe 100644
--- a/j-font-lock.el
+++ b/j-font-lock.el
@@ -88,19 +88,61 @@
;; (modify-syntax-entry ?\: "_" table)
(modify-syntax-entry ?\( "()" table)
(modify-syntax-entry ?\) ")(" table)
- (modify-syntax-entry ?\' "\"" table)
- (modify-syntax-entry ?N "w 1" table)
- (modify-syntax-entry ?B "w 2" table)
+ (modify-syntax-entry ?\' "." table)
+ ;; (modify-syntax-entry ?N "w 1" table)
+ ;; (modify-syntax-entry ?B "w 2" table)
(modify-syntax-entry ?\n ">" table)
- (modify-syntax-entry ?\r ">" table)
+ ;; (modify-syntax-entry ?\r ">" table)
table)
"Syntax table for j-mode")
(defalias 'j-mode-syntax-propertize
(syntax-propertize-rules
- ("^\\()\\)" (1 "."))
+ ("\\(N\\)\\(B\\)\\." (1 "w 1") (2 "w 2"))
+ ("\\(?:0\\|noun\\)\s+\\(?::\s*0\\|define\\)"
+ (0 (j-font-lock-multiline-string ?:)))
+ ("^\\()\\)" (1 (j-font-lock-multiline-string ?\))))
+ ("{{)n" (0 (j-font-lock-multiline-string ?\{)))
+ ("}}" (0 (j-font-lock-multiline-string ?\})))
("{{\\()\\)" (1 "."))
- ("\\('\\)`?[0-9A-Z_a-z ]*\\('\\)\s*=[.:]" (1 ".") (2 "."))))
+ ("\\('\\)`?[0-9A-Z_a-z ]*\\('\\)\s*=[.:]" (1 ".") (2 "."))
+ ("\\('\\)\\(?:[^'\n]\\|''\\)*\\('\\)" (1 "\"") (2 "\""))))
+
+(defun j-font-lock-multiline-string (arg)
+ (pcase arg
+ (?: (let* ((ppss (save-excursion (backward-char 2) (syntax-ppss)))
+ (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss)))
+ (eol (pos-eol)))
+ (unless string-start
+ (put-text-property eol (1+ eol)
+ 'syntax-table (string-to-syntax "|")))
+ nil))
+ (?\{ (let* ((ppss (save-excursion (backward-char 4) (syntax-ppss)))
+ (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss)))
+ (quote-starting-pos (- (point) 4)))
+ (unless string-start
+ (put-text-property quote-starting-pos (1+ quote-starting-pos)
+ 'syntax-table (string-to-syntax "|"))
+ (put-text-property (+ 2 quote-starting-pos) (+ 3
quote-starting-pos)
+ 'syntax-table (string-to-syntax ".")))
+ nil))
+ (?\) (let* ((ppss (save-excursion (backward-char 2) (syntax-ppss)))
+ (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss)))
+ (quote-starting-pos (- (point) 1)))
+ (if (and string-start (eql (char-after string-start)
+ ?\n))
+ (put-text-property (1- quote-starting-pos) quote-starting-pos
+ 'syntax-table (string-to-syntax "|")))
+ (string-to-syntax ".")))
+ (?\} (let* ((ppss (save-excursion (backward-char 2) (syntax-ppss)))
+ (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss)))
+ (quote-end-pos (point)))
+ (if (and string-start (eql (char-after string-start)
+ ?\{))
+ (put-text-property (1- quote-end-pos) quote-end-pos
+ 'syntax-table (string-to-syntax "|")))
+ nil))))
+
(defvar j-font-lock-constants
'(
@@ -174,11 +216,11 @@
(append j-font-lock-len-3-others j-font-lock-len-2-others
j-font-lock-len-1-others))
(defvar j-font-lock-len-3-conjunctions
- '("&.:" "F.." "F.:" "F:." "F::" " ::" " :."))
+ '("&.:" "F.." "F.:" "F:." "F::"))
(defvar j-font-lock-len-2-conjunctions
'("t." "S:" "L:" "H." "D:" "D." "d." "F." "F:" "m."
"&:" "&." "@:" "@." "`:" "!:" "!." ";." "[." "]."
- "^:" " ." " :"))
+ "^:"))
(defvar j-font-lock-len-1-conjunctions
'("&" "@" "`" "\""))
(defvar j-font-lock-conjunctions
@@ -237,21 +279,35 @@
(,(regexp-opt j-font-lock-len-1-verbs) . 'j-verb-face)
(,(regexp-opt j-font-lock-len-1-adverbs) . 'j-adverb-face)
(,(regexp-opt j-font-lock-len-1-conjunctions) . 'j-conjunction-face)
+ (,(rx (or bol (+ "\s")) (group (or ":" "." ":." "::")))
+ (1 'j-conjunction-face))
;;(,(regexp-opt j-font-lock-len-1-others) . 'j-other-face)
)
"J Mode font lock keys words")
+(defun j-font-lock-docstring-p (state)
+ "Detect if multi-line string should be docstring."
+ (save-excursion
+ (goto-char (nth 8 state))
+ (beginning-of-line)
+ (not (looking-at-p "[_'`a-zA-Z0-9\s]+=[.:]"))))
+
(defun j-font-lock-syntactic-face-function (state)
"Function for detection of string vs. Comment. Note: J comments
are three chars longs, there is no easy / evident way to handle
this in emacs and it poses problems"
- (if (nth 3 state) font-lock-string-face
- (let* ((start-pos (nth 8 state)))
- (and (<= (+ start-pos 3) (point-max))
- (eq (char-after start-pos) ?N)
+ (let* ((start-pos (nth 8 state)))
+ (cond
+ ((nth 3 state) (if (and
+ (eql (char-after start-pos) ?\n)
+ (j-font-lock-docstring-p state))
+ font-lock-doc-face
+ font-lock-string-face))
+ ((and (<= (+ start-pos 3) (point-max))
+ (eql (char-after start-pos) ?N)
(string= (buffer-substring-no-properties
start-pos (+ start-pos 3))
- "NB.")
- font-lock-comment-face))))
+ "NB."))
+ font-lock-comment-face))))
(provide 'j-font-lock)
diff --git a/j-mode.el b/j-mode.el
index 1cc0ea7de5..3f2743cb03 100644
--- a/j-mode.el
+++ b/j-mode.el
@@ -82,6 +82,7 @@
"for.")))
(seq (or "for" "goto" "label")
(regexp "_[a-zA-Z]+\\."))))
+ (seq bol ":" eol)
(seq (regexp "[_a-zA-Z0-9]+") (? "'")
(* "\s") "=" (or "." ":") (* "\s")
(or "{{"
@@ -151,15 +152,16 @@ contents of current line."
(back-to-indentation)
(let* ((tentative-indent (j-compute-indentation))
;;FIXME doesn't handle comments correctly
- (indent (if (looking-at j-dedenting-keywords-regexp)
- (max 0 (- tentative-indent j-indent-offset))
- tentative-indent))
+ (indent (cond
+ ((looking-at j-dedenting-keywords-regexp)
+ (max 0 (- tentative-indent j-indent-offset)))
+ ((looking-at ":") 0)
+ (t tentative-indent)))
(delta (- indent (current-indentation))))
;; (message "###DEBUGi:%d t:%d" indent tentative-indent)
(indent-line-to indent)
(back-to-indentation)
- (goto-char (max (point) (+ old-point delta))))
- )))
+ (goto-char (max (point) (+ old-point delta)))))))
(defun j-which-explict-definition ()
"Return nil, `:one-liner' or `:multi-liner' depending on what
@@ -220,6 +222,7 @@ contents of current line."
(define-key map (kbd "C-c C-c") 'j-console-execute-buffer)
(define-key map (kbd "C-c C-r") 'j-console-execute-region)
(define-key map (kbd "C-c C-l") 'j-console-execute-line)
+ (define-key map (kbd "C-M-x") 'j-console-execute-definition)
(define-key map (kbd "C-c h") 'j-help-lookup-symbol)
(define-key map (kbd "C-c C-h") 'j-help-lookup-symbol-at-point)
map)
@@ -232,6 +235,7 @@ contents of current line."
["Execute Buffer" j-console-execute-buffer t]
["Execute Region" j-console-execute-region t]
["Execute Line" j-console-execute-line t]
+ ["Execute Definition" j-console-execute-definition t]
"---"
["J Symbol Look-up" j-help-lookup-symbol t]
["J Symbol Dynamic Look-up" j-help-lookup-symbol-at-point t]
@@ -256,7 +260,7 @@ contents of current line."
beginning-of-defun-function #'j-beginning-of-explicit-definition
end-of-defun-function #'j-end-of-explicit-definition
font-lock-comment-start-skip
- "NB. *"
+ "NB\\. *"
font-lock-defaults
'(j-font-lock-keywords
nil nil nil nil