branch: elpa/scala-mode commit 52091426ee319b4ec53799696bae75571f7ecbf6 Author: Josef Vlach <vlach.jo...@gmail.com> Commit: Sam Halliday <sam.halli...@gmail.com>
Support for identifiers consisting from operator characters (#138) * Pending whitespaces removal * Fixed typos * Support for identifiers consisting from operator characters --- scala-mode-fontlock.el | 4 +-- scala-mode-imenu.el | 18 ++++++------- scala-mode-syntax.el | 17 +++++++++--- scala-mode.el | 12 ++++----- test/scala-mode-test.el | 71 +++++++++++++++++++++++++++++++++++++------------ 5 files changed, 85 insertions(+), 37 deletions(-) diff --git a/scala-mode-fontlock.el b/scala-mode-fontlock.el index e919353..7617259 100644 --- a/scala-mode-fontlock.el +++ b/scala-mode-fontlock.el @@ -68,9 +68,9 @@ scala-mode has been reloaded." (defun scala-font-lock:mark-pattern1-part (&optional limit pattern-p) "Parses a part of val, var and case pattern (or id). Always parses a variable or constant name first and then type, leaving -the pointer at the next variablename, constnat name, list or +the pointer at the next variablename, constant name, list or Pattern3, if any, and setting up match data 1 (variable), -2 (constant) and 3 (type) acordingly. If there is no variable +2 (constant) and 3 (type) accordingly. If there is no variable name before the first type, then the match data for the variable name is nil. Returns t if something was matched or nil if nothing was found. diff --git a/scala-mode-imenu.el b/scala-mode-imenu.el index 0edc134..b02c61a 100644 --- a/scala-mode-imenu.el +++ b/scala-mode-imenu.el @@ -41,16 +41,16 @@ (if (listp (car member-info)) (let* ((current-member-info (car member-info)) (child-member-infos (cdr member-info)) - (current-member-result + (current-member-result (scala-imenu:destructure-for-build-imenu-candidate current-member-info parents)) (current-member-name (car current-member-result))) (if child-member-infos - (let ((current-member-members - (scala-imenu:build-child-members + (let ((current-member-members + (scala-imenu:build-child-members (append parents `(,current-member-info)) (cdr member-info)))) - `(,current-member-name . + `(,current-member-name . ,(cons current-member-result current-member-members))) current-member-result)) (scala-imenu:destructure-for-build-imenu-candidate member-info parents))) @@ -60,14 +60,14 @@ child parents)) child-members)) (defun scala-imenu:destructure-for-build-imenu-candidate (member-info parents) - (cl-destructuring-bind (member-name definition-type marker) - member-info (funcall scala-imenu:build-imenu-candidate + (cl-destructuring-bind (member-name definition-type marker) + member-info (funcall scala-imenu:build-imenu-candidate member-name definition-type marker parents))) (defun scala-imenu:default-build-imenu-candidate (member-name definition-type marker parents) - (let* ((all-names + (let* ((all-names (append (cl-mapcar (lambda (parent) (car parent)) parents) `(,member-name))) (member-string (mapconcat 'identity all-names "."))) @@ -88,7 +88,7 @@ (progn (looking-at scala-syntax:all-definition-re) (setq class-name (match-string-no-properties 2)) (setq definition-type (match-string-no-properties 1))) - `(,`(,class-name ,definition-type ,(point-marker)) . + `(,`(,class-name ,definition-type ,(point-marker)) . ,(scala-imenu:nested-members))))) (defun scala-imenu:parse-nested-from-beginning () @@ -118,7 +118,7 @@ (looking-at scala-syntax:all-definition-re) (let* ((member-name (match-string-no-properties 2)) (definition-type (match-string-no-properties 1))) - (if (member definition-type scala-imenu:nested-definition-types) + (if (member definition-type scala-imenu:nested-definition-types) (save-excursion (scala-imenu:parse-nested-from-beginning)) `(,member-name ,definition-type ,(point-marker))))) diff --git a/scala-mode-syntax.el b/scala-mode-syntax.el index 0249d99..f9591da 100644 --- a/scala-mode-syntax.el +++ b/scala-mode-syntax.el @@ -106,7 +106,7 @@ "\\|" scala-syntax:oneLineStringLiteral-re "\\)" )) ;; If you change this or any of the used regex, be sure to -;; maintain this or update propertize function acordingly: +;; maintain this or update propertize function accordingly: ;; group 1 = char start, 3 = char end ;; group 4 = multi-line string start, 6 = end ;; group 7 = string start, 9 = end @@ -600,6 +600,16 @@ symbol constituents (syntax 3)." (scala-syntax:put-syntax-table-property 0 '(3 . nil))) '(3 . nil))))))))) ;; symbol constituent syntax (3) also for the '_' +(defun scala-syntax:propertize-special-symbols (start end) + (save-excursion + (goto-char start) + (while (re-search-forward (concat "[" scala-syntax:opchar-group "]" scala-syntax:op-re) end t) + (let ((match-beg (match-beginning 0)) + (match-end (match-end 0)) + (match (match-string 0))) + (unless (member match '("/*" "//" "/**" "</" "*/")) + (put-text-property match-beg match-end 'syntax-table '(3 . nil))))))) + (defun scala-syntax:propertize-quotedid (start end) "Mark all `scala-syntax:quotedid-re' as symbol constituents (syntax 3)" (save-excursion @@ -614,6 +624,7 @@ symbol constituents (syntax 3)." (scala-syntax:propertize-char-and-string-literals start end) (scala-syntax:propertize-shell-preamble start end) (scala-syntax:propertize-underscore-and-idrest start end) + (scala-syntax:propertize-special-symbols start end) (scala-syntax:propertize-quotedid start end)) ;;;; @@ -934,14 +945,14 @@ not. A list must be either enclosed in parentheses or start with ;; Functions to help with finding the beginning and end of scala definitions. -(defconst scala-syntax:modifiers-re +(defconst scala-syntax:modifiers-re (regexp-opt '("override" "abstract" "final" "sealed" "implicit" "lazy" "private" "protected" "case") 'words)) (defconst scala-syntax:whitespace-delimeted-modifiers-re (concat "\\(?:" scala-syntax:modifiers-re "\\(?: *\\)" "\\)*")) -(defconst scala-syntax:definition-words-re +(defconst scala-syntax:definition-words-re (mapconcat 'regexp-quote '("class" "object" "trait" "val" "var" "def" "type") "\\|")) (defun scala-syntax:build-definition-re (words-re) diff --git a/scala-mode.el b/scala-mode.el index b5c35f5..13f6bcb 100644 --- a/scala-mode.el +++ b/scala-mode.el @@ -25,7 +25,7 @@ ;; Tested only for emacs 24 (unless (<= 24 emacs-major-version) (error - (format "The Scala mode has been tested only on Emacs version 24.2 (and not your Emacs version %s.%s)" + (format "The Scala mode has been tested only on Emacs version 24.2 (and not your Emacs version %s.%s)" emacs-major-version emacs-minor-version))) (defgroup scala nil @@ -72,12 +72,12 @@ If there is no plausible default, return nil." ;;;###autoload (defun scala-mode:set-scala-syntax-mode () - "Sets the syntax-table and other realted variables for the current buffer to those of scala-mode. Can be used to make some other major mode (such as sbt-mode) use scala syntax-table." + "Sets the syntax-table and other related variables for the current buffer to those of scala-mode. Can be used to make some other major mode (such as sbt-mode) use scala syntax-table." (set-syntax-table scala-syntax:syntax-table) (scala-mode:make-local-variables 'syntax-propertize-function 'parse-sexp-lookup-properties - 'forward-sexp-function) + 'forward-sexp-function) (add-hook 'syntax-propertize-extend-region-functions 'scala-syntax:propertize-extend-region) @@ -97,11 +97,11 @@ If there is no plausible default, return nil." (define-derived-mode scala-mode prog-mode "Scala" "Major mode for editing scala code. -When started, runs `scala-mode-hook'. +When started, runs `scala-mode-hook'. -\\{scala-mode-map}" +\\{scala-mode-map}" :syntax-table scala-syntax:syntax-table -; :group +; :group ; :abbrev (scala-mode:make-local-variables diff --git a/test/scala-mode-test.el b/test/scala-mode-test.el index 0f06c14..0539170 100644 --- a/test/scala-mode-test.el +++ b/test/scala-mode-test.el @@ -1,26 +1,26 @@ -(ert-deftest smt:quotedid () - (let* ((line "val `tvw xyz/*` = `abc def/*` + 123 /* comment `abc` abc */ + 456") - (exps "22203333333333301033333333333010222011022222220333330222011010222") ;; expected codes of syntax class - (expf "KKK-VVVVVVVVVVV-K---------------CCC-DDDOOOOOOOOOOOOOOOOOOOO---CCC") ;; expected font-locks - (line-length (length line))) +(defun smt:test (line exps expf) + "line - line of scala code +exps - expected codes of syntax class +expf - expected font-locks" + (let ((line-length (length line))) (with-temp-buffer (insert (format "package ensime object Ensime { %s }" line)) - (scala-mode) - (font-lock-ensure) - (re-search-backward (regexp-opt `(,line)) nil t) - (let ((end-point (+ (point) line-length)) - (acc-syntax "") - (acc-font "")) - (while (< (point) end-point) - (setq acc-syntax (concat acc-syntax (number-to-string (syntax-class (syntax-after (point)))))) - (setq acc-font (concat acc-font (font-lock-to-string (get-text-property (point) 'face)))) - (forward-char)) - (should (equal acc-syntax exps)) - (should (equal acc-font expf)))))) + (scala-mode) + (font-lock-ensure) + (re-search-backward (regexp-opt `(,line)) nil t) + (let ((end-point (+ (point) line-length)) + (acc-syntax "") + (acc-font "")) + (while (< (point) end-point) + (setq acc-syntax (concat acc-syntax (number-to-string (syntax-class (syntax-after (point)))))) + (setq acc-font (concat acc-font (font-lock-to-string (get-text-property (point) 'face)))) + (forward-char)) + (should (equal acc-syntax exps)) + (should (equal acc-font expf)))))) (defun font-lock-to-string (font-lock) (pcase font-lock @@ -30,4 +30,41 @@ object Ensime { ('font-lock-keyword-face "K") ('font-lock-comment-face "O") ('font-lock-comment-delimiter-face "D") + ('font-lock-doc-face "U") (_ "?"))) + +(ert-deftest smt:syntax-class-and-font-lock-test-1 () + (smt:test + "val `tvw xyz/*` = `abc def/*` + 123 /* comment `abc` abc */ + 456" + "22203333333333301033333333333010222011022222220333330222011010222" + "KKK-VVVVVVVVVVV-K---------------CCC-DDDOOOOOOOOOOOOOOOOOOOO---CCC")) + +(ert-deftest smt:syntax-class-and-font-lock-test-2 () + (smt:test + "val |+| = 123" + "2220333010222" + "KKK-VVV-K-CCC")) + +(ert-deftest smt:syntax-class-and-font-lock-test-3 () + (smt:test + "val a_|+| = 123" + "222023333010222" + "KKK-VVVVV-K-CCC")) + +(ert-deftest smt:syntax-class-and-font-lock-test-4 () + (smt:test + "val a = 123 /** hello */" + "222020102220111022222011" + "KKK-V-K-CCC-UUUUUUUUUUUU")) + +(ert-deftest smt:syntax-class-and-font-lock-test-5 () + (smt:test + "val a = <td>hello</td>" + "2220201012212222211221" + "KKK-V-K---------------")) + +(ert-deftest smt:syntax-class-and-font-lock-test-6 () + (smt:test + "// val |--| = 123" + "11022203333010222" + "DDDOOOOOOOOOOOOOO"))