Skip to content

Commit 8ad6f5f

Browse files
authored
Merge pull request #2009 from SillyCoon/fix-deftype-formatter-case
Fix deftype formatter case
2 parents 21304f0 + 17f8000 commit 8ad6f5f

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Changes to Calva.
44

55
## [Unreleased]
66

7+
- Fix (formatter): [Indenter and formatter fails while typing out body of deftype method](https://github.com/BetterThanTomorrow/calva/issues/1957)
8+
79
## [2.0.323] - 2023-01-07
810

911
- Fix: [Provider completions not handling errors gracefully](https://github.com/BetterThanTomorrow/calva/issues/2006)

src/calva-fmt/src/format.ts

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import {
1717
} from '../../../out/cljs-lib/cljs-lib';
1818
import * as util from '../../utilities';
1919
import { isUndefined, cloneDeep } from 'lodash';
20+
import { LispTokenCursor } from '../../cursor-doc/token-cursor';
21+
22+
const FormatDepthDefaults = {
23+
deftype: 2,
24+
};
2025

2126
export async function indentPosition(position: vscode.Position, document: vscode.TextDocument) {
2227
const editor = util.getActiveTextEditor();
@@ -67,7 +72,7 @@ export async function formatRangeEdits(
6772
text,
6873
document.getText(),
6974
rangeTuple,
70-
document.eol == 2 ? '\r\n' : '\n'
75+
_convertEolNumToStringNotation(document.eol)
7176
);
7277
if (newText) {
7378
return [vscode.TextEdit.replace(range, newText)];
@@ -94,20 +99,14 @@ export async function formatPositionInfo(
9499
extraConfig = {}
95100
) {
96101
const doc: vscode.TextDocument = editor.document;
97-
const pos: vscode.Position = editor.selection.active;
98-
const index = doc.offsetAt(pos);
99-
const mirroredDoc: MirroredDocument = getDocument(doc);
100-
const cursor = mirroredDoc.getTokenCursor(index);
101-
const formatDepth = extraConfig['format-depth'] ? extraConfig['format-depth'] : 1;
102-
const isComment = cursor.getFunctionName() === 'comment';
103-
const config = { ...extraConfig, 'comment-form?': isComment };
104-
let formatRange = cursor.rangeForList(formatDepth);
105-
if (!formatRange) {
106-
formatRange = cursor.rangeForCurrentForm(index);
107-
if (!formatRange || !formatRange.includes(index)) {
108-
return;
109-
}
102+
const index = doc.offsetAt(editor.selection.active);
103+
const cursor = getDocument(doc).getTokenCursor(index);
104+
105+
const formatRange = _calculateFormatRange(extraConfig, cursor, index);
106+
if (!formatRange?.includes(index)) {
107+
return;
110108
}
109+
111110
const formatted: {
112111
'range-text': string;
113112
range: number[];
@@ -116,9 +115,12 @@ export async function formatPositionInfo(
116115
doc.getText(),
117116
formatRange,
118117
index,
119-
doc.eol == 2 ? '\r\n' : '\n',
118+
_convertEolNumToStringNotation(doc.eol),
120119
onType,
121-
config
120+
{
121+
...extraConfig,
122+
'comment-form?': cursor.getFunctionName() === 'comment',
123+
}
122124
);
123125
const range: vscode.Range = new vscode.Range(
124126
doc.positionAt(formatted.range[0]),
@@ -135,6 +137,21 @@ export async function formatPositionInfo(
135137
};
136138
}
137139

140+
function _calculateFormatRange(
141+
config: { 'format-depth'?: number },
142+
cursor: LispTokenCursor,
143+
index: number
144+
) {
145+
const formatDepth = config?.['format-depth'] ?? _formatDepth(cursor);
146+
return cursor.rangeForList(formatDepth) ?? cursor.rangeForCurrentForm(index);
147+
}
148+
149+
function _formatDepth(cursor: LispTokenCursor) {
150+
const cursorClone = cursor.clone();
151+
cursorClone.backwardFunction(1);
152+
return FormatDepthDefaults?.[cursorClone.getFunctionName()] ?? 1;
153+
}
154+
138155
export async function formatPosition(
139156
editor: vscode.TextEditor,
140157
onType: boolean = false,
@@ -195,7 +212,7 @@ export function trimWhiteSpacePositionCommand(editor: vscode.TextEditor) {
195212
export async function formatCode(code: string, eol: number) {
196213
const d = {
197214
'range-text': code,
198-
eol: eol == 2 ? '\r\n' : '\n',
215+
eol: _convertEolNumToStringNotation(eol),
199216
config: await config.getConfig(),
200217
};
201218
const result = jsify(formatText(d));
@@ -249,3 +266,7 @@ async function _formatRange(
249266
return result['range-text'];
250267
}
251268
}
269+
270+
function _convertEolNumToStringNotation(eol: vscode.EndOfLine) {
271+
return eol == 2 ? '\r\n' : '\n';
272+
}

src/cljs-lib/test/calva/fmt/formatter_test.cljs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
1515
baz)")
1616

17+
(def deftype-all-text
18+
"(deftype MyType [arg1 arg2]\n IMyProto\n (method1 [this]\n (smth)))")
19+
1720
(deftest format-text-at-idx
1821
(is (= "(defn bar
1922
[x]
@@ -28,6 +31,8 @@ baz)")
2831
(:range (sut/format-text-at-idx {:eol "\n" :all-text "(\n\n,)" :range [0 5] :idx 2}))))
2932
(is (= "()"
3033
(:range-text (sut/format-text-at-idx {:eol "\n" :all-text "(\n\n,)" :range [0 5] :idx 2}))))
34+
(is (= "(deftype MyType [arg1 arg2]\n IMyProto\n (method1 [this]\n (smth)))"
35+
(:range-text (sut/format-text-at-idx {:eol "\n" :all-text deftype-all-text :range [0 76] :idx 68}))))
3136
;; TODO: Figure out why the extra space is not removed
3237
#_(is (= "a c"
3338
(:range-text (sut/format-text-at-idx {:eol "\n" :all-text "a c" :range [0 4] :idx 2})))))

0 commit comments

Comments
 (0)