From 27bcb413a503db621d6a2001f952dc65ab553d0d Mon Sep 17 00:00:00 2001 From: "Jose A. Ortega Ruiz" Date: Wed, 19 Nov 2008 00:59:43 +0100 Subject: [PATCH 1/2] Emacs factor-mode: better font lock: constructors, setters and parent types (with accompanying custom faces). --- misc/factor.el | 222 +++++++++++++++++++++++++++---------------------- 1 file changed, 121 insertions(+), 101 deletions(-) diff --git a/misc/factor.el b/misc/factor.el index 6204bdbef6..c18a3102e7 100644 --- a/misc/factor.el +++ b/misc/factor.el @@ -113,6 +113,14 @@ value from the existing code in the buffer." "Face for type (tuple) names." :group 'factor-faces) +(defface factor-font-lock-constructor (factor--face font-lock-type-face) + "Face for constructors ()." + :group 'factor-faces) + +(defface factor-font-lock-setter-word (factor--face font-lock-function-name-face) + "Face for setter words (>>foo)." + :group 'factor-faces) + (defface factor-font-lock-parsing-word (factor--face font-lock-keyword-face) "Face for parsing words." :group 'factor-faces) @@ -146,6 +154,12 @@ value from the existing code in the buffer." (defconst factor--regex-type-definition (factor--regex-second-word '("TUPLE:"))) +(defconst factor--regex-parent-type "^TUPLE: +[^ ]+ +< +\\([^ ]+\\)") + +(defconst factor--regex-constructor "<[^ >]+>") + +(defconst factor--regex-setter "\\W>>[^ ]+\\b") + (defconst factor--regex-symbol-definition (factor--regex-second-word '("SYMBOL:"))) @@ -166,6 +180,9 @@ value from the existing code in the buffer." (,factor--regex-parsing-words-ext . 'factor-font-lock-parsing-word) (,factor--regex-word-definition 2 'factor-font-lock-word-definition) (,factor--regex-type-definition 2 'factor-font-lock-type-definition) + (,factor--regex-parent-type 1 'factor-font-lock-type-definition) + (,factor--regex-constructor . 'factor-font-lock-constructor) + (,factor--regex-setter . 'factor-font-lock-setter-word) (,factor--regex-symbol-definition 2 'factor-font-lock-symbol-definition) (,factor--regex-using-line 1 'factor-font-lock-vocabulary-name) (,factor--regex-use-line 1 'factor-font-lock-vocabulary-name)) @@ -217,6 +234,109 @@ value from the existing code in the buffer." (modify-syntax-entry ?\) ")(" factor-mode-syntax-table) (modify-syntax-entry ?\" "\" " factor-mode-syntax-table))) + +;;; Factor mode indentation: + +(make-variable-buffer-local + (defvar factor-indent-width factor-default-indent-width + "Indentation width in factor buffers. A local variable.")) + +(defconst factor--regexp-word-start + (let ((sws '("" ":" "TUPLE" "MACRO" "MACRO:" "M"))) + (format "^\\(%s\\): " (mapconcat 'identity sws "\\|")))) + +(defun factor--guess-indent-width () + "Chooses an indentation value from existing code." + (let ((word-cont "^ +[^ ]") + (iw)) + (save-excursion + (beginning-of-buffer) + (while (not iw) + (if (not (re-search-forward factor--regexp-word-start nil t)) + (setq iw factor-default-indent-width) + (forward-line) + (when (looking-at word-cont) + (setq iw (current-indentation)))))) + iw)) + +(defsubst factor--ppss-brackets-depth () + (nth 0 (syntax-ppss))) + +(defsubst factor--ppss-brackets-start () + (nth 1 (syntax-ppss))) + +(defsubst factor--line-indent (pos) + (save-excursion (goto-char pos) (current-indentation))) + +(defconst factor--regex-closing-paren "[])}]") +(defsubst factor--at-closing-paren-p () + (looking-at factor--regex-closing-paren)) + +(defsubst factor--at-first-char-p () + (= (- (point) (line-beginning-position)) (current-indentation))) + +(defconst factor--regex-single-liner + (format "^%s" (regexp-opt '("DEFER:" "GENERIC:" "IN:" "PRIVATE>" " (factor--ppss-brackets-depth) 0)) + (let ((op (factor--ppss-brackets-start))) + (when (> (line-number-at-pos) (line-number-at-pos op)) + (if (factor--at-closing-paren-p) + (factor--line-indent op) + (+ (factor--line-indent op) factor-indent-width))))))) + +(defun factor--indent-definition () + (save-excursion + (beginning-of-line) + (when (factor--at-begin-of-def) 0))) + +(defun factor--indent-continuation () + (save-excursion + (forward-line -1) + (beginning-of-line) + (if (bobp) 0 + (if (looking-at "^[ \t]*$") + (factor--indent-continuation) + (if (factor--at-end-of-def) + (- (current-indentation) factor-indent-width) + (if (factor--at-begin-of-def) + (+ (current-indentation) factor-indent-width) + (current-indentation))))))) + +(defun factor--calculate-indentation () + "Calculate Factor indentation for line at point." + (or (and (bobp) 0) + (factor--indent-definition) + (factor--indent-in-brackets) + (factor--indent-continuation) + 0)) + +(defun factor--indent-line () + "Indent current line as Factor code" + (let ((target (factor--calculate-indentation)) + (pos (- (point-max) (point)))) + (if (= target (current-indentation)) + (if (< (current-column) (current-indentation)) + (back-to-indentation)) + (beginning-of-line) + (delete-horizontal-space) + (indent-to target) + (if (> (- (point-max) pos) (point)) + (goto-char (- (point-max) pos)))))) + ;;; Factor mode commands: @@ -314,105 +434,6 @@ value from the existing code in the buffer." (define-key factor-mode-map [return] 'newline-and-indent) (define-key factor-mode-map [tab] 'indent-for-tab-command) - -;;; Factor mode indentation: - -(make-variable-buffer-local - (defvar factor-indent-width factor-default-indent-width - "Indentation width in factor buffers. A local variable.")) - -(defconst factor--regexp-word-start - (let ((sws '("" ":" "TUPLE" "MACRO" "MACRO:" "M"))) - (format "^\\(%s\\): " (mapconcat 'identity sws "\\|")))) - -(defun factor--guess-indent-width () - "Chooses an indentation value from existing code." - (let ((word-cont "^ +[^ ]") - (iw)) - (save-excursion - (beginning-of-buffer) - (while (not iw) - (if (not (re-search-forward factor--regexp-word-start nil t)) - (setq iw factor-default-indent-width) - (forward-line) - (when (looking-at word-cont) - (setq iw (current-indentation)))))) - iw)) - -(defsubst factor--ppss-brackets-depth () - (nth 0 (syntax-ppss))) - -(defsubst factor--ppss-brackets-start () - (nth 1 (syntax-ppss))) - -(defsubst factor--line-indent (pos) - (save-excursion (goto-char pos) (current-indentation))) - -(defconst factor--regex-closing-paren "[])}]") -(defsubst factor--at-closing-paren-p () - (looking-at factor--regex-closing-paren)) - -(defsubst factor--at-first-char-p () - (= (- (point) (line-beginning-position)) (current-indentation))) - -(defconst factor--regex-single-liner - (format "^%s" (regexp-opt '("USE:" "IN:" "PRIVATE>" " (factor--ppss-brackets-depth) 0)) - (let ((op (factor--ppss-brackets-start))) - (when (> (line-number-at-pos) (line-number-at-pos op)) - (if (factor--at-closing-paren-p) - (factor--line-indent op) - (+ (factor--line-indent op) factor-indent-width))))))) - -(defun factor--indent-definition () - (save-excursion - (beginning-of-line) - (when (looking-at "\\([^ ]\\|^\\)+:") 0))) - -(defun factor--indent-continuation () - (save-excursion - (forward-line -1) - (beginning-of-line) - (if (bobp) 0 - (if (looking-at "^[ \t]*$") - (factor--indent-continuation) - (if (factor--at-end-of-def) - (- (current-indentation) factor-indent-width) - (if (factor--indent-definition) - (+ (current-indentation) factor-indent-width) - (current-indentation))))))) - -(defun factor--calculate-indentation () - "Calculate Factor indentation for line at point." - (or (and (bobp) 0) - (factor--indent-definition) - (factor--indent-in-brackets) - (factor--indent-continuation) - 0)) - -(defun factor-indent-line () - "Indent current line as Factor code" - (let ((target (factor--calculate-indentation)) - (pos (- (point-max) (point)))) - (if (= target (current-indentation)) - (if (< (current-column) (current-indentation)) - (back-to-indentation)) - (beginning-of-line) - (delete-horizontal-space) - (indent-to target) - (if (> (- (point-max) pos) (point)) - (goto-char (- (point-max) pos)))))) ;; Factor mode: @@ -426,12 +447,11 @@ value from the existing code in the buffer." (use-local-map factor-mode-map) (setq major-mode 'factor-mode) (setq mode-name "Factor") - (set (make-local-variable 'indent-line-function) #'factor-indent-line) (set (make-local-variable 'comment-start) "! ") (set (make-local-variable 'font-lock-defaults) '(factor-font-lock-keywords t nil nil nil)) (set-syntax-table factor-mode-syntax-table) - (set (make-local-variable 'indent-line-function) 'factor-indent-line) + (set (make-local-variable 'indent-line-function) 'factor--indent-line) (setq factor-indent-width (factor--guess-indent-width)) (setq indent-tabs-mode nil) (run-hooks 'factor-mode-hook)) From dad3a5ead1db0e54a2d647c507cb9c6552b70a2d Mon Sep 17 00:00:00 2001 From: "Jose A. Ortega Ruiz" Date: Wed, 19 Nov 2008 02:00:00 +0100 Subject: [PATCH 2/2] Emacs factor-mode: correct indentation for field setters after constructors. --- misc/factor.el | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/misc/factor.el b/misc/factor.el index c18a3102e7..f75cb7f359 100644 --- a/misc/factor.el +++ b/misc/factor.el @@ -281,10 +281,27 @@ value from the existing code in the buffer." (defsubst factor--at-begin-of-def () (looking-at "\\([^ ]\\|^\\)+:")) +(defsubst factor--looking-at-emptiness () + (looking-at "^[ \t]*$")) + (defun factor--at-end-of-def () (or (looking-at ".*;[ \t]*$") (looking-at factor--regex-single-liner))) +(defun factor--at-setter-line () + (save-excursion + (beginning-of-line) + (if (not (factor--looking-at-emptiness)) + (re-search-forward factor--regex-setter (line-end-position) t) + (forward-line -1) + (or (factor--at-constructor-line) + (factor--at-setter-line))))) + +(defun factor--at-constructor-line () + (save-excursion + (beginning-of-line) + (re-search-forward factor--regex-constructor (line-end-position) t))) + (defun factor--indent-in-brackets () (save-excursion (beginning-of-line) @@ -303,14 +320,28 @@ value from the existing code in the buffer." (beginning-of-line) (when (factor--at-begin-of-def) 0))) +(defun factor--indent-setter-line () + (when (factor--at-setter-line) + (save-excursion + (beginning-of-line) + (let ((indent (when (factor--at-constructor-line) (current-indentation)))) + (while (not (or indent + (bobp) + (factor--at-begin-of-def) + (factor--at-end-of-def))) + (if (factor--at-constructor-line) + (setq indent (+ (current-indentation) factor-indent-width)) + (forward-line -1))) + indent)))) + (defun factor--indent-continuation () (save-excursion (forward-line -1) (beginning-of-line) (if (bobp) 0 - (if (looking-at "^[ \t]*$") + (if (factor--looking-at-emptiness) (factor--indent-continuation) - (if (factor--at-end-of-def) + (if (or (factor--at-end-of-def) (factor--at-setter-line)) (- (current-indentation) factor-indent-width) (if (factor--at-begin-of-def) (+ (current-indentation) factor-indent-width) @@ -321,6 +352,7 @@ value from the existing code in the buffer." (or (and (bobp) 0) (factor--indent-definition) (factor--indent-in-brackets) + (factor--indent-setter-line) (factor--indent-continuation) 0))