-
-
Save sids/407276 to your computer and use it in GitHub Desktop.
colored REPL for Clojure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; all code in this function lifted from the clojure-mode function | |
;;; from clojure-mode.el | |
(defcustom sids/clojure-mode-font-lock-comment-sexp nil | |
"Set to non-nil in order to enable font-lock of (comment...) | |
forms. This option is experimental. Changing this will require a | |
restart (ie. M-x clojure-mode) of existing clojure mode buffers." | |
:type 'boolean) | |
(defconst sids/clojure-font-lock-keywords | |
(eval-when-compile | |
`( ;; Definitions. | |
(,(concat "(\\(?:clojure.core/\\)?\\(" | |
(regexp-opt '("defn" "defn-" "def" "def-" "defonce" | |
"defmulti" "defmethod" "defmacro" | |
"defstruct" "deftype" "defprotocol" | |
"defrecord" "defvar" "defunbound" | |
"defalias" "defhinted" | |
"defnk" "defn-memo")) | |
;; Function declarations. | |
"\\)\\>" | |
;; Any whitespace | |
"[ \r\n\t]*" | |
;; Possibly type or metadata | |
"\\(?:#^\\(?:{[^}]*}\\|\\sw+\\)[ \r\n\t]*\\)?" | |
"\\(\\sw+\\)?") | |
(1 font-lock-keyword-face) | |
(2 font-lock-function-name-face nil t)) | |
;; Deprecated functions | |
(,(concat | |
"(\\(?:clojure.core/\\)?" | |
(regexp-opt | |
'("add-watcher" "remove-watcher" "add-classpath") t) | |
"\\>") | |
1 font-lock-warning-face) | |
;; Control structures | |
(,(concat | |
"(\\(?:clojure.core/\\)?" | |
(regexp-opt | |
'("let" "letfn" "do" | |
"cond" "condp" | |
"for" "loop" "recur" | |
"when" "when-not" "when-let" "when-first" | |
"if" "if-let" "if-not" | |
"." ".." "->" "->>" "doto" | |
"and" "or" | |
"dosync" "doseq" "dotimes" "dorun" "doall" | |
"load" "import" "unimport" "ns" "in-ns" "refer" | |
"try" "catch" "finally" "throw" | |
"with-open" "with-local-vars" "binding" | |
"gen-class" "gen-and-load-class" "gen-and-save-class" | |
"handler-case" "handle") t) | |
"\\>") | |
. 1) | |
;; Built-ins | |
(,(concat | |
"(\\(?:clojure.core/\\)?" | |
(regexp-opt | |
'("*" "*1" "*2" "*3" "*agent*" | |
"*allow-unresolved-vars*" "*assert*" "*clojure-version*" "*command-line-args*" "*compile-files*" | |
"*compile-path*" "*e" "*err*" "*file*" "*flush-on-newline*" | |
"*in*" "*macro-meta*" "*math-context*" "*ns*" "*out*" | |
"*print-dup*" "*print-length*" "*print-level*" "*print-meta*" "*print-readably*" | |
"*read-eval*" "*source-path*" "*use-context-classloader*" "*warn-on-reflection*" "+" | |
"-" "/" | |
"<" "<=" "=" "==" ">" | |
">=" "accessor" "aclone" | |
"agent" "agent-errors" "aget" "alength" "alias" | |
"all-ns" "alter" "alter-meta!" "alter-var-root" "amap" | |
"ancestors" "and" "apply" "areduce" "array-map" | |
"aset" "aset-boolean" "aset-byte" "aset-char" "aset-double" | |
"aset-float" "aset-int" "aset-long" "aset-short" "assert" | |
"assoc" "assoc!" "assoc-in" "associative?" "atom" | |
"await" "await-for" "await1" "bases" "bean" | |
"bigdec" "bigint" "binding" "bit-and" "bit-and-not" | |
"bit-clear" "bit-flip" "bit-not" "bit-or" "bit-set" | |
"bit-shift-left" "bit-shift-right" "bit-test" "bit-xor" "boolean" | |
"boolean-array" "booleans" "bound-fn" "bound-fn*" "butlast" | |
"byte" "byte-array" "bytes" "cast" "char" | |
"char-array" "char-escape-string" "char-name-string" "char?" "chars" | |
"chunk" "chunk-append" "chunk-buffer" "chunk-cons" "chunk-first" | |
"chunk-next" "chunk-rest" "chunked-seq?" "class" "class?" | |
"clear-agent-errors" "clojure-version" "coll?" "comment" "commute" | |
"comp" "comparator" "compare" "compare-and-set!" "compile" | |
"complement" "concat" "cond" "condp" "conj" | |
"conj!" "cons" "constantly" "construct-proxy" "contains?" | |
"count" "counted?" "create-ns" "create-struct" "cycle" | |
"dec" "decimal?" "declare" "definline" "defmacro" | |
"defmethod" "defmulti" "defn" "defn-" "defonce" | |
"defstruct" "delay" "delay?" "deliver" "deref" | |
"derive" "descendants" "destructure" "disj" "disj!" | |
"dissoc" "dissoc!" "distinct" "distinct?" "doall" | |
"doc" "dorun" "doseq" "dosync" "dotimes" | |
"doto" "double" "double-array" "doubles" "drop" | |
"drop-last" "drop-while" "empty" "empty?" "ensure" | |
"enumeration-seq" "eval" "even?" "every?" | |
"extend" "extend-protocol" "extend-type" "extends?" "extenders" | |
"false?" "ffirst" "file-seq" "filter" "find" "find-doc" | |
"find-ns" "find-var" "first" "float" "float-array" | |
"float?" "floats" "flush" "fn" "fn?" | |
"fnext" "for" "force" "format" "future" | |
"future-call" "future-cancel" "future-cancelled?" "future-done?" "future?" | |
"gen-class" "gen-interface" "gensym" "get" "get-in" | |
"get-method" "get-proxy-class" "get-thread-bindings" "get-validator" "hash" | |
"hash-map" "hash-set" "identical?" "identity" "if-let" | |
"if-not" "ifn?" "import" "in-ns" "inc" | |
"init-proxy" "instance?" "int" "int-array" "integer?" | |
"interleave" "intern" "interpose" "into" "into-array" | |
"ints" "io!" "isa?" "iterate" "iterator-seq" | |
"juxt" "key" "keys" "keyword" "keyword?" | |
"last" "lazy-cat" "lazy-seq" "let" "letfn" | |
"line-seq" "list" "list*" "list?" "load" | |
"load-file" "load-reader" "load-string" "loaded-libs" "locking" | |
"long" "long-array" "longs" "loop" "macroexpand" | |
"macroexpand-1" "make-array" "make-hierarchy" "map" "map?" | |
"mapcat" "max" "max-key" "memfn" "memoize" | |
"merge" "merge-with" "meta" "method-sig" "methods" | |
"min" "min-key" "mod" "name" "namespace" | |
"neg?" "newline" "next" "nfirst" "nil?" | |
"nnext" "not" "not-any?" "not-empty" "not-every?" | |
"not=" "ns" "ns-aliases" "ns-imports" "ns-interns" | |
"ns-map" "ns-name" "ns-publics" "ns-refers" "ns-resolve" | |
"ns-unalias" "ns-unmap" "nth" "nthnext" "num" | |
"number?" "odd?" "or" "parents" "partial" | |
"partition" "pcalls" "peek" "persistent!" "pmap" | |
"pop" "pop!" "pop-thread-bindings" "pos?" "pr" | |
"pr-str" "prefer-method" "prefers" "primitives-classnames" "print" | |
"print-ctor" "print-doc" "print-dup" "print-method" "print-namespace-doc" | |
"print-simple" "print-special-doc" "print-str" "printf" "println" | |
"println-str" "prn" "prn-str" "promise" "proxy" | |
"proxy-call-with-super" "proxy-mappings" "proxy-name" "proxy-super" "push-thread-bindings" | |
"pvalues" "quot" "rand" "rand-int" "range" | |
"ratio?" "rational?" "rationalize" "re-find" "re-groups" | |
"re-matcher" "re-matches" "re-pattern" "re-seq" "read" | |
"read-line" "read-string" "reify" "reduce" "ref" "ref-history-count" | |
"ref-max-history" "ref-min-history" "ref-set" "refer" "refer-clojure" | |
"release-pending-sends" "rem" "remove" "remove-method" "remove-ns" | |
"repeat" "repeatedly" "replace" "replicate" | |
"require" "reset!" "reset-meta!" "resolve" "rest" | |
"resultset-seq" "reverse" "reversible?" "rseq" "rsubseq" | |
"satisfies?" "second" "select-keys" "send" "send-off" "seq" | |
"seq?" "seque" "sequence" "sequential?" "set" | |
"set-validator!" "set?" "short" "short-array" "shorts" | |
"shutdown-agents" "slurp" "some" "sort" "sort-by" | |
"sorted-map" "sorted-map-by" "sorted-set" "sorted-set-by" "sorted?" | |
"special-form-anchor" "special-symbol?" "split-at" "split-with" "str" | |
"stream?" "string?" "struct" "struct-map" "subs" | |
"subseq" "subvec" "supers" "swap!" "symbol" | |
"symbol?" "sync" "syntax-symbol-anchor" "take" "take-last" | |
"take-nth" "take-while" "test" "the-ns" "time" | |
"to-array" "to-array-2d" "trampoline" "transient" "tree-seq" | |
"true?" "type" "unchecked-add" "unchecked-dec" "unchecked-divide" | |
"unchecked-inc" "unchecked-multiply" "unchecked-negate" "unchecked-remainder" "unchecked-subtract" | |
"underive" "unquote" "unquote-splicing" "update-in" "update-proxy" | |
"use" "val" "vals" "var-get" "var-set" | |
"var?" "vary-meta" "vec" "vector" "vector?" | |
"when" "when-first" "when-let" "when-not" "while" | |
"with-bindings" "with-bindings*" "with-in-str" "with-loading-context" "with-local-vars" | |
"with-meta" "with-open" "with-out-str" "with-precision" "xml-seq" | |
) t) | |
"\\>") | |
1 font-lock-builtin-face) | |
;; (fn name? args ...) | |
(,(concat "(\\(?:clojure.core/\\)?\\(fn\\)[ \t]+" | |
;; Possibly type | |
"\\(?:#^\\sw+[ \t]*\\)?" | |
;; Possibly name | |
"\\(\\sw+\\)?" ) | |
(1 font-lock-keyword-face) | |
(2 font-lock-function-name-face nil t)) | |
;;Other namespaces in clojure.jar | |
(,(concat | |
"(\\(?:\.*/\\)?" | |
(regexp-opt | |
'(;clojure.inpsector | |
"atom?" "collection-tag" "get-child" "get-child-count" "inspect" | |
"inspect-table" "inspect-tree" "is-leaf" "list-model" "list-provider" | |
;clojure.main | |
"load-script" "main" "repl" "repl-caught" "repl-exception" | |
"repl-prompt" "repl-read" "skip-if-eol" "skip-whitespace" "with-bindings" | |
;clojure.set | |
"difference" "index" "intersection" "join" "map-invert" | |
"project" "rename" "rename-keys" "select" "union" | |
;clojure.stacktrace | |
"e" "print-cause-trace" "print-stack-trace" "print-throwable" "print-trace-element" | |
;clojure.template | |
"do-template" "apply-template" | |
;clojure.test | |
"*initial-report-counters*" "*load-tests*" "*report-counters*" "*stack-trace-depth*" "*test-out*" | |
"*testing-contexts*" "*testing-vars*" "are" "assert-any" "assert-expr" | |
"assert-predicate" "compose-fixtures" "deftest" "deftest-" "file-position" | |
"function?" "get-possibly-unbound-var" "inc-report-counter" "is" "join-fixtures" | |
"report" "run-all-tests" "run-tests" "set-test" "successful?" | |
"test-all-vars" "test-ns" "test-var" "testing" "testing-contexts-str" | |
"testing-vars-str" "try-expr" "use-fixtures" "with-test" "with-test-out" | |
;clojure.walk | |
"keywordize-keys" "macroexpand-all" "postwalk" "postwalk-demo" "postwalk-replace" | |
"prewalk" "prewalk-demo" "prewalk-replace" "stringify-keys" "walk" | |
;clojure.xml | |
"*current*" "*sb*" "*stack*" "*state*" "attrs" | |
"content" "content-handler" "element" "emit" "emit-element" | |
;clojure.zip | |
"append-child" "branch?" "children" "down" "edit" | |
"end?" "insert-child" "insert-left" "insert-right" "left" | |
"leftmost" "lefts" "make-node" "next" "node" | |
"path" "prev" "remove" "replace" "right" | |
"rightmost" "rights" "root" "seq-zip" "up" | |
) t) | |
"\\>") | |
1 font-lock-type-face) | |
;; Constant values (keywords). | |
("\\<:\\(\\sw\\|#\\)+\\>" 0 font-lock-builtin-face) | |
;; Meta type annotation #^Type | |
("#^\\sw+" 0 font-lock-type-face) | |
("\\<io\\!\\>" 0 font-lock-warning-face))) | |
"Default expressions to highlight in Clojure mode.") | |
(defun sids/clojure-font-lock-setup () | |
(interactive) | |
(set (make-local-variable 'lisp-indent-function) | |
'clojure-indent-function) | |
(set (make-local-variable 'lisp-doc-string-elt-property) | |
'clojure-doc-string-elt) | |
(set (make-local-variable 'font-lock-multiline) t) | |
(add-to-list 'font-lock-extend-region-functions | |
'clojure-font-lock-extend-region-def t) | |
(when clojure-mode-font-lock-comment-sexp | |
(add-to-list 'font-lock-extend-region-functions | |
'clojure-font-lock-extend-region-comment t) | |
(make-local-variable 'clojure-font-lock-keywords) | |
(add-to-list 'clojure-font-lock-keywords | |
'clojure-font-lock-mark-comment t) | |
(set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)) | |
(setq font-lock-defaults | |
'(clojure-font-lock-keywords ; keywords | |
nil nil | |
(("+-*/.<>=!?$%_&~^:@" . "w")) ; syntax alist | |
nil | |
(font-lock-mark-block-function . mark-defun) | |
(font-lock-syntactic-face-function | |
. lisp-font-lock-syntactic-face-function)))) | |
(add-hook 'slime-repl-mode-hook | |
(lambda () | |
;(font-lock-mode nil) | |
(sids/clojure-font-lock-setup) | |
;(font-lock-mode t) | |
)) | |
(defadvice slime-repl-emit (after sr-emit-ad activate) | |
(with-current-buffer (slime-output-buffer) | |
(add-text-properties slime-output-start slime-output-end | |
'(font-lock-face slime-repl-output-face | |
rear-nonsticky (font-lock-face))))) | |
(defadvice slime-repl-insert-prompt (after sr-prompt-ad activate) | |
(with-current-buffer (slime-output-buffer) | |
(let ((inhibit-read-only t)) | |
(add-text-properties slime-repl-prompt-start-mark (point-max) | |
'(font-lock-face slime-repl-prompt-face | |
rear-nonsticky | |
(slime-repl-prompt | |
read-only | |
font-lock-face | |
intangible)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment