Skip to content

Commit 8b0aeb6

Browse files
committed
Add g:clojure_highlight_clojure_core (default true)
Use the new b:clojure_syntax_without_core_keywords option in vim-clojure-static to get accurate highlighting for a buffer that has a :refer-clojure clause.
1 parent 5a9a317 commit 8b0aeb6

File tree

3 files changed

+94
-27
lines changed

3 files changed

+94
-27
lines changed

autoload/vim_clojure_highlight.clj

+82-22
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,101 @@
11
(ns vim-clojure-highlight
2-
(:require [clojure.string :as string]))
2+
(:require [clojure.set :as set]
3+
[clojure.string :as string])
4+
(:import (clojure.lang MultiFn)))
35

4-
(def ^:private TYPE->SYNTAX-GROUP
5-
{:macro "clojureMacro"
6-
:fn "clojureFunc"
7-
:def "clojureVariable"})
6+
;;;;;;;;;;;;;;;;;;;; Copied from vim-clojure-static.generate ;;;;;;;;;;;;;;;;;;;
87

9-
(defn- external-refs [ns]
10-
(remove #(= "clojure.core" (-> % peek meta :ns str)) (ns-refers ns)))
8+
(defn- fn-var? [v]
9+
(let [f @v]
10+
(or (contains? (meta v) :arglists)
11+
(fn? f)
12+
(instance? MultiFn f))))
1113

12-
(defn- aliased-refs [ns]
14+
(def special-forms
15+
"http://clojure.org/special_forms"
16+
'#{def if do let quote var fn loop recur throw try catch finally
17+
monitor-enter monitor-exit . new set!})
18+
19+
(def keyword-groups
20+
"Special forms, constants, and every public var in clojure.core keyed by
21+
syntax group name."
22+
(let [exceptions '#{throw try catch finally}
23+
builtins {"clojureConstant" '#{nil}
24+
"clojureBoolean" '#{true false}
25+
"clojureSpecial" (apply disj special-forms exceptions)
26+
"clojureException" exceptions
27+
"clojureCond" '#{case cond cond-> cond->> condp if-let
28+
if-not if-some when when-first when-let
29+
when-not when-some}
30+
;; Imperative looping constructs (not sequence functions)
31+
"clojureRepeat" '#{doseq dotimes while}}
32+
coresyms (set/difference (set (keys (ns-publics 'clojure.core)))
33+
(set (mapcat peek builtins)))
34+
group-preds [["clojureDefine" #(re-seq #"\Adef(?!ault)" (str %))]
35+
["clojureMacro" #(:macro (meta (ns-resolve 'clojure.core %)))]
36+
["clojureFunc" #(fn-var? (ns-resolve 'clojure.core %))]
37+
["clojureVariable" identity]]]
38+
(first
39+
(reduce
40+
(fn [[m syms] [group pred]]
41+
(let [group-syms (set (filterv pred syms))]
42+
[(assoc m group group-syms)
43+
(set/difference syms group-syms)]))
44+
[builtins coresyms] group-preds))))
45+
46+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47+
48+
(def core-symbol->syntax-group
49+
"A map of symbols from clojure.core mapped to syntax group name."
50+
(reduce
51+
(fn [m [group syms]]
52+
(reduce
53+
(fn [m sym]
54+
(assoc m sym group))
55+
m syms))
56+
{} keyword-groups))
57+
58+
(defn clojure-core?
59+
"Is this var from clojure.core?"
60+
[var]
61+
(= "clojure.core" (-> var meta :ns str)))
62+
63+
(defn refers [ns include-clojure-core?]
64+
(if include-clojure-core?
65+
(ns-refers ns)
66+
(remove (comp clojure-core? peek) (ns-refers ns))))
67+
68+
(defn aliased-refers [ns]
1369
(mapcat
1470
(fn [[alias alias-ns]]
1571
(mapv #(vector (symbol (str alias \/ (first %))) (peek %))
1672
(ns-publics alias-ns)))
1773
(ns-aliases ns)))
1874

19-
(defn- var-type [v]
75+
(defn var-type [v]
2076
(let [f @v m (meta v)]
21-
(cond (:macro m) :macro
22-
(or (contains? m :arglists)
23-
(fn? f)
24-
(instance? clojure.lang.MultiFn f)) :fn
25-
:else :def)))
77+
(cond (clojure-core? v) (core-symbol->syntax-group (:name m))
78+
(:macro m) "clojureMacro"
79+
(fn-var? v) "clojureFunc"
80+
:else "clojureVariable")))
2681

27-
(defn- syntax-keyword-dictionary [ns-refs]
82+
(defn syntax-keyword-dictionary [ns-refs]
2883
(->> ns-refs
2984
(group-by (comp var-type peek))
30-
(mapv (fn [[type sym->vars]]
31-
(->> sym->vars
85+
(mapv (fn [[type sym->var]]
86+
(->> sym->var
3287
(mapv (comp pr-str str first))
3388
(string/join \,)
34-
(format "'%s': [%s]" (TYPE->SYNTAX-GROUP type)))))
89+
(format "'%s': [%s]" type))))
3590
(string/join \,)
3691
(format "let b:clojure_syntax_keywords = { %s }")))
3792

38-
(defn ns-syntax-command [ns hi-locals?]
39-
(syntax-keyword-dictionary (concat (external-refs ns)
40-
(aliased-refs ns)
41-
(when hi-locals? (ns-publics ns)))))
93+
(defn ns-syntax-command [ns & opts]
94+
(let [{:keys [local-vars clojure-core]
95+
:or {local-vars true clojure-core true}} (apply hash-map opts)
96+
refs (refers ns clojure-core)
97+
dict (syntax-keyword-dictionary (concat refs
98+
(aliased-refers ns)
99+
(when local-vars (ns-publics ns))))]
100+
(str "let b:clojure_syntax_without_core_keywords = " (if clojure-core 1 0)
101+
" | " dict)))

autoload/vim_clojure_highlight.vim

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ function! vim_clojure_highlight#syntax_match_references(...)
1717

1818
try
1919
call s:require()
20-
let ns = "'" . fireplace#ns()
21-
let hi_locals = (a:0 && a:1 == 0) ? 'false' : 'true'
22-
execute fireplace#evalparse("(vim-clojure-highlight/ns-syntax-command " . ns . " " . hi_locals . ")")
20+
21+
let ns = "'" . fireplace#ns()
22+
let opts = (a:0 > 0 && !a:1) ? ' :local-vars false' : ''
23+
let opts .= (a:0 > 1 && !a:2) ? ' :clojure-core false' : ''
24+
25+
execute fireplace#evalparse("(vim-clojure-highlight/ns-syntax-command " . ns . opts . ")")
2326
let &syntax = &syntax
2427
catch /./
2528
endtry

plugin/vim_clojure_highlight.vim

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ if !exists('g:clojure_highlight_local_vars')
88
let g:clojure_highlight_local_vars = 1
99
endif
1010

11+
if !exists('g:clojure_highlight_clojure_core')
12+
let g:clojure_highlight_clojure_core = 1
13+
endif
14+
1115
function! s:syntax_match_references()
1216
if g:clojure_highlight_references
13-
call vim_clojure_highlight#syntax_match_references(g:clojure_highlight_local_vars)
17+
call vim_clojure_highlight#syntax_match_references(g:clojure_highlight_local_vars, g:clojure_highlight_clojure_core)
1418
endif
1519
endfunction
1620

@@ -20,7 +24,7 @@ function! s:toggle_clojure_highlight_references()
2024
if g:clojure_highlight_references
2125
call s:syntax_match_references()
2226
else
23-
unlet! b:clojure_syntax_keywords
27+
unlet! b:clojure_syntax_keywords b:clojure_syntax_without_core_keywords
2428
let &syntax = &syntax
2529
endif
2630
endfunction

0 commit comments

Comments
 (0)