Skip to content

Inline and fix syntax table #559

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

### Changes

* Inline definition of `clojure-mode-syntax-table` and support `'` quotes in symbols and commas as whitespace.
* Enhance add arity refactoring to support a `defn` inside a reader conditional.
* Enhance add arity refactoring to support new forms: `letfn`, `fn`, `defmacro`, `defmethod`, `defprotocol`, `reify` and `proxy`.

Expand Down
48 changes: 38 additions & 10 deletions clojure-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,47 @@ Out-of-the box `clojure-mode' understands lein, boot, gradle,
"Keymap for Clojure mode.")

(defvar clojure-mode-syntax-table
(let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
(modify-syntax-entry ?\{ "(}" table)
(modify-syntax-entry ?\} "){" table)
(let ((table (make-syntax-table)))
;; Initialize ASCII charset as symbol syntax
(modify-syntax-entry '(0 . 127) "_" table)

;; Word syntax
(modify-syntax-entry '(?0 . ?9) "w" table)
(modify-syntax-entry '(?a . ?z) "w" table)
(modify-syntax-entry '(?A . ?Z) "w" table)

;; Whitespace
(modify-syntax-entry ?\s " " table)
(modify-syntax-entry ?\xa0 " " table) ; non-breaking space
(modify-syntax-entry ?\t " " table)
(modify-syntax-entry ?\f " " table)
(modify-syntax-entry ?, " " table)

;; Delimiters
(modify-syntax-entry ?\( "()" table)
(modify-syntax-entry ?\) ")(" table)
(modify-syntax-entry ?\[ "(]" table)
(modify-syntax-entry ?\] ")[" table)
(modify-syntax-entry ?? "_ p" table) ; ? is a prefix outside symbols
(modify-syntax-entry ?# "_ p" table) ; # is allowed inside keywords (#399)
(modify-syntax-entry ?\{ "(}" table)
(modify-syntax-entry ?\} "){" table)

;; Prefix chars
(modify-syntax-entry ?` "'" table)
(modify-syntax-entry ?~ "'" table)
(modify-syntax-entry ?^ "'" table)
(modify-syntax-entry ?@ "'" table)
(modify-syntax-entry ?? "_ p" table) ; ? is a prefix outside symbols
(modify-syntax-entry ?# "_ p" table) ; # is allowed inside keywords (#399)
(modify-syntax-entry ?' "_ p" table) ; ' is allowed anywhere but the start of symbols

;; Others
(modify-syntax-entry ?\; "<" table) ; comment start
(modify-syntax-entry ?\n ">" table) ; comment end
(modify-syntax-entry ?\" "\"" table) ; string
(modify-syntax-entry ?\\ "\\" table) ; escape

table)
"Syntax table for Clojure mode.
Inherits from `emacs-lisp-mode-syntax-table'.")
"Syntax table for Clojure mode.")

(defconst clojure--prettify-symbols-alist
'(("fn" . ?λ)))
Expand Down Expand Up @@ -745,10 +773,10 @@ Called by `imenu--generic-function'."
(goto-char start)))))

(eval-and-compile
(defconst clojure--sym-forbidden-rest-chars "][\";\'@\\^`~\(\)\{\}\\,\s\t\n\r"
(defconst clojure--sym-forbidden-rest-chars "][\";@\\^`~\(\)\{\}\\,\s\t\n\r"
"A list of chars that a Clojure symbol cannot contain.
See definition of 'macros': URL `http://git.io/vRGLD'.")
(defconst clojure--sym-forbidden-1st-chars (concat clojure--sym-forbidden-rest-chars "0-9:")
(defconst clojure--sym-forbidden-1st-chars (concat clojure--sym-forbidden-rest-chars "0-9:'")
"A list of chars that a Clojure symbol cannot start with.
See the for-loop: URL `http://git.io/vRGTj' lines: URL
`http://git.io/vRGIh', URL `http://git.io/vRGLE' and value
Expand Down Expand Up @@ -1924,7 +1952,7 @@ DIRECTION is `forward' or `backward'."
(goto-char end)
(clojure-forward-logical-sexp)
(unless (or (clojure--in-string-p) (clojure--in-comment-p))
(setq candidate (thing-at-point 'symbol)))))))
(setq candidate (string-remove-prefix "'" (thing-at-point 'symbol))))))))
candidate))

(defun clojure-find-ns ()
Expand Down
19 changes: 15 additions & 4 deletions test/clojure-mode-font-lock-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ TESTS are lists of the form (content (start end expected-face)*). For each test
check that each `expected-face` is found in `content` between `start` and `end`.

DESCRIPTION is the description of the spec."
(declare (indent 1))
`(it ,description
(dolist (test (quote ,tests))
(apply #'expect-faces-at test))))
Expand Down Expand Up @@ -417,6 +418,16 @@ DESCRIPTION is the description of the spec."
(9 10 nil)
(12 29 nil)))

(when-fontifying-it "should handle quotes in tail of symbols and keywords"
("'quot'ed'/sy'm'bol''"
(2 9 font-lock-type-face)
(10 20 nil))

(":qu'ote'd''/key'word'"
(2 11 font-lock-type-face)
(12 12 default)
(13 21 clojure-keyword-face)))

(when-fontifying-it "should handle very complex stuff"
(" ve/yCom|pLex.stu-ff"
(3 4 font-lock-type-face)
Expand Down Expand Up @@ -787,8 +798,8 @@ DESCRIPTION is the description of the spec."
("(def foo \"usage\" \"hello\" )"
(18 24 font-lock-string-face))

("(def foo \"usage\" \n \"hello\")"
(21 27 font-lock-string-face))
("(def foo \"usage\" \n \"hello\")"
(21 27 font-lock-string-face))

("(def foo \n \"usage\" \"hello\")"
(13 19 font-lock-doc-face))
Expand Down Expand Up @@ -854,8 +865,8 @@ DESCRIPTION is the description of the spec."

(when-fontifying-it "should handle keyword-meta"
("^:meta-data"
(1 1 nil)
(2 11 clojure-keyword-face)))
(1 1 nil)
(2 11 clojure-keyword-face)))

(when-fontifying-it "should handle a keyword with allowed characters"
(":aaa#bbb"
Expand Down
2 changes: 2 additions & 0 deletions test/utils/test-helper.el
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

(defmacro with-clojure-buffer (text &rest body)
"Create a temporary buffer, insert TEXT, switch to clojure-mode and evaluate BODY."
(declare (indent 1))
`(with-temp-buffer
(erase-buffer)
(insert ,text)
Expand All @@ -49,6 +50,7 @@ AFTER.
BODY should contain the refactoring that transforms BEFORE into AFTER.

DESCRIPTION is the description of the spec."
(declare (indent 1))
`(it ,description
(with-clojure-buffer ,before
,@body
Expand Down