Skip to content

Commit 4295eb3

Browse files
committed
Allow using cljfmt for formatting
1 parent 6c4a0c4 commit 4295eb3

File tree

5 files changed

+64
-6
lines changed

5 files changed

+64
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ Syntax has been significantly reworked.
1212
- Metadata highlights following form as `meta.metadata`
1313
- Allow reader-invisible forms like comma, newline, reader comment and meta almost everywhere between meaningful forms
1414

15+
Other changes:
16+
17+
- Allow using `cljfmt` for formatting (requires `cljfmt` binary on `$PATH`)
18+
1519
### 3.8.0 - Aug 8, 2024
1620

1721
- `clojure_sublimed_reindent` command that reindents entire buffer if selection is empty and only selected lines if not

Clojure Sublimed.sublime-settings

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
// E.g. (set! *warn-on-reflection* true)
4949
"eval_shared": "",
5050

51+
// formatter, "sublimed" or "cljfmt". Latter requires `cljfmt` to be on $PATH
52+
"formatter": "sublimed",
53+
5154
// reformat file on save, false by default
5255
"format_on_save": false
5356
}

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,15 @@ Want to put your parser to test? Check out [syntax_test_edn.edn](./test_syntax/s
3333

3434
# Formatter/indenter
3535

36-
Clojure Sublimed includes optional support for [Simple Clojure Formatting rules](https://tonsky.me/blog/clojurefmt/). It doesn’t require REPL connection, any Clojure runtime or external tools.
36+
Clojure Sublimed includes support for both [Simple Clojure Formatting rules](https://tonsky.me/blog/clojurefmt/) and [cljfmt](https://github.com/weavejester/cljfmt/).
37+
38+
Simple Clojure Formatting doesn’t require REPL connection, any Clojure runtime or external tools. It is enabled by default.
39+
40+
`cljfmt` requires `cljfmt` binary to be on `$PATH`. Enable it by setting `"formatter": "cljfmt"` in Clojure Sublimed settings.
3741

3842
To reformat whole file, run `Clojure Sublimed: Reindent`. If you have non-empty selection, it will only reformat selected lines.
3943

40-
To enable reindenting/formatting on save, add `format_on_save: true` to settings. ([See how to edit settings](#editing-settings))
44+
To enable reindenting/formatting on save, add `"format_on_save": true` to settings. ([See how to edit settings](#editing-settings))
4145

4246
To enable correct indentations as you type code, rebind `Enter` to `Clojure Sublimed: Insert Newline`:
4347

cs_cljfmt.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import os, sublime, subprocess
2+
3+
def indent_lines(view, selections, edit):
4+
regions = [region for region in selections if not region.empty()]
5+
if not regions:
6+
regions = [sublime.Region(0, view.size())]
7+
replacements = []
8+
for region in regions:
9+
text = view.substr(region)
10+
try:
11+
cmd = 'cljfmt.exe' if 'windows' == sublime.platform() else 'cljfmt'
12+
cwd = None
13+
if file := view.file_name():
14+
cwd = os.path.dirname(file)
15+
elif folders := view.window().folders():
16+
cwd = folders[0]
17+
18+
proc = subprocess.run([cmd, 'fix', '-'],
19+
input = text,
20+
text = True,
21+
capture_output = True,
22+
check = True,
23+
cwd = cwd)
24+
except FileNotFoundError:
25+
sublime.error_message(f'`{cmd}` is not on $PATH')
26+
raise
27+
if 'Failed' not in proc.stderr:
28+
replacements.append((region, proc.stdout))
29+
30+
if replacements:
31+
selections = [(view.rowcol(r.a), view.rowcol(r.b)) for r in selections]
32+
change_id_sel = view.change_id()
33+
for region, string in replacements:
34+
transformed_region = view.transform_region_from(region, change_id_sel)
35+
view.replace(edit, transformed_region, string)
36+
37+
selections.clear()
38+
for ((rowa, cola), (rowb, colb)) in selections:
39+
a = view.text_point(rowa, cola)
40+
b = view.text_point(rowb, colb)
41+
selections.add(sublime.Region(a, b))

cs_indent.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sublime, sublime_plugin
2-
from . import cs_common, cs_parser
2+
from . import cs_cljfmt, cs_common, cs_parser
33

44
def search_path(node, pos):
55
"""
@@ -119,20 +119,26 @@ def indent_lines(view, selections, edit):
119119

120120
class ClojureSublimedReindentBufferOnSave(sublime_plugin.EventListener):
121121
def on_pre_save(self, view):
122-
if cs_common.setting("format_on_save", False) and view.syntax().name == 'Clojure (Sublimed)':
122+
if cs_common.setting("format_on_save", False) and ('Clojure' in view.syntax().name or 'EDN' in view.syntax().name):
123123
view.run_command('clojure_sublimed_reindent_buffer')
124124

125125
class ClojureSublimedReindentBufferCommand(sublime_plugin.TextCommand):
126126
def run(self, edit):
127127
view = self.view
128128
with cs_common.Measure("Reindent Buffer {} chars", view.size()):
129-
indent_lines(view, [sublime.Region(0, view.size())], edit)
129+
if 'cljfmt' == cs_common.setting('formatter'):
130+
cs_cljfmt.indent_lines(view, [sublime.Region(0, view.size())], edit)
131+
else:
132+
indent_lines(view, [sublime.Region(0, view.size())], edit)
130133

131134
class ClojureSublimedReindentLinesCommand(sublime_plugin.TextCommand):
132135
def run(self, edit):
133136
view = self.view
134137
with cs_common.Measure("Reindent Lines {}", view.sel()):
135-
indent_lines(view, view.sel(), edit)
138+
if 'cljfmt' == cs_common.setting('formatter'):
139+
cs_cljfmt.indent_lines(view, view.sel(), edit)
140+
else:
141+
indent_lines(view, view.sel(), edit)
136142

137143
class ClojureSublimedReindentCommand(sublime_plugin.TextCommand):
138144
def run(self, edit):

0 commit comments

Comments
 (0)