Skip to content

Commit 59c3513

Browse files
authored
feat(formatting/#785): Default format provider when no extension provider (#2022)
* Formatting * Formatting * Add default format strategy * Process indentation ranges * Additional cases * Hook up language configuration * Remove test that no longer applies
1 parent 9997784 commit 59c3513

13 files changed

+463
-98
lines changed

src/Core/Indentation.re

+33
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@
44
* Helpers for dealing with indentation level
55
*/
66

7+
open Utility;
8+
9+
let getLeadingWhitespace = (s: string) => {
10+
let rec loop = (i, spaces, tabs) =>
11+
if (i >= String.length(s)) {
12+
(spaces, tabs, false);
13+
} else {
14+
switch (s.[i]) {
15+
| ' ' => loop(i + 1, spaces + 1, tabs)
16+
| '\t' => loop(i + 1, spaces, tabs + 1)
17+
| _ => (spaces, tabs, true)
18+
};
19+
};
20+
21+
loop(0, 0, 0);
22+
};
23+
724
let getLevel = (settings: IndentationSettings.t, text: string) => {
825
let tabSize = settings.tabSize;
926

@@ -38,6 +55,22 @@ let getLevel = (settings: IndentationSettings.t, text: string) => {
3855
allWhitespace^ ? 0 : indentLevel^;
3956
};
4057

58+
let applyLevel =
59+
(~indentation: IndentationSettings.t, ~level: int, str: string) => {
60+
str
61+
|> StringEx.findNonWhitespace
62+
|> Option.map(idx => {
63+
let desiredWhitespace =
64+
switch (indentation.mode) {
65+
| Tabs => String.make(level, '\t')
66+
| Spaces => String.make(level * indentation.size, ' ')
67+
};
68+
69+
desiredWhitespace ++ String.sub(str, idx, String.length(str) - idx);
70+
})
71+
|> Option.value(~default=str);
72+
};
73+
4174
let getForBuffer = (~buffer, configuration: Configuration.t) => {
4275
let bufferIndentation = Buffer.getIndentation(buffer);
4376
switch (bufferIndentation) {

src/Core/IndentationGuesser.re

+3-17
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,6 @@ module Constants = {
88
let minSpaces = 2;
99
};
1010

11-
let getLeadingWhitespace = (s: string) => {
12-
let rec loop = (i, spaces, tabs) =>
13-
if (i >= String.length(s)) {
14-
(spaces, tabs, false);
15-
} else {
16-
switch (s.[i]) {
17-
| ' ' => loop(i + 1, spaces + 1, tabs)
18-
| '\t' => loop(i + 1, spaces, tabs + 1)
19-
| _ => (spaces, tabs, true)
20-
};
21-
};
22-
23-
loop(0, 0, 0);
24-
};
25-
2611
type t = {
2712
mode: IndentationSettings.mode,
2813
size: int,
@@ -62,7 +47,8 @@ let guessIndentation =
6247
let line = getLine(i);
6348
let prevLine = i == 0 ? "" : getLine(i - 1);
6449

65-
let (spaceCount, tabCount, foundChar) = getLeadingWhitespace(line);
50+
let (spaceCount, tabCount, foundChar) =
51+
Indentation.getLeadingWhitespace(line);
6652

6753
/* Only consider lines with non-whitespace */
6854
if (foundChar) {
@@ -75,7 +61,7 @@ let guessIndentation =
7561
};
7662

7763
let (prevSpaceCount, _, prevFoundChar) =
78-
getLeadingWhitespace(prevLine);
64+
Indentation.getLeadingWhitespace(prevLine);
7965
if (prevFoundChar) {
8066
let diff = abs(prevSpaceCount - spaceCount);
8167
if (diff >= Constants.minSpaces) {

src/Core/LanguageConfiguration.re

+63-26
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,34 @@ module BracketPair = {
9292
let endsWithOpenPair = ({openPair, _}, str) => {
9393
StringEx.endsWith(~postfix=openPair, str);
9494
};
95+
96+
let isJustClosingPair = ({closePair, _}, str) => {
97+
let len = String.length(str);
98+
99+
let rec loop = (foundPair, idx) =>
100+
if (idx >= len) {
101+
foundPair;
102+
} else if (foundPair) {
103+
false;
104+
// We found the closing pair... but there's other stuff after
105+
} else {
106+
let c = str.[idx];
107+
108+
if (c == ' ' || c == '\t') {
109+
loop(foundPair, idx + 1);
110+
} else if (c == closePair.[0]) {
111+
loop(true, idx + 1);
112+
} else {
113+
false;
114+
};
115+
};
116+
117+
if (String.length(closePair) == 1) {
118+
loop(false, 0);
119+
} else {
120+
false;
121+
};
122+
};
95123
};
96124

97125
let defaultBrackets: list(BracketPair.t) =
@@ -226,36 +254,45 @@ let toVimAutoClosingPairs = (syntaxScope: SyntaxScope.t, configuration: t) => {
226254
);
227255
};
228256

229-
let toAutoIndent =
257+
let shouldIncreaseIndent =
230258
(
231-
{increaseIndentPattern, decreaseIndentPattern, brackets, _},
232259
~previousLine as str,
233260
~beforePreviousLine as _,
261+
{increaseIndentPattern, brackets, _},
234262
) => {
235-
let increase =
236-
increaseIndentPattern
237-
|> Option.map(regex => OnigRegExp.test(str, regex))
238-
// If no indentation pattern, fall-back to bracket pair
239-
|> OptionEx.or_lazy(() =>
240-
Some(
241-
List.exists(
242-
bracket => BracketPair.endsWithOpenPair(bracket, str),
243-
brackets,
244-
),
245-
)
263+
increaseIndentPattern
264+
|> Option.map(regex => OnigRegExp.test(str, regex))
265+
// If no indentation pattern, fall-back to bracket pair
266+
|> OptionEx.or_lazy(() =>
267+
Some(
268+
List.exists(
269+
bracket => BracketPair.endsWithOpenPair(bracket, str),
270+
brackets,
271+
),
246272
)
247-
|> Option.value(~default=false);
248-
249-
let decrease =
250-
decreaseIndentPattern
251-
|> Option.map(regex => OnigRegExp.test(str, regex))
252-
|> Option.value(~default=false);
253-
254-
if (increase) {
255-
Vim.AutoIndent.IncreaseIndent;
256-
} else if (decrease) {
257-
Vim.AutoIndent.DecreaseIndent;
258-
} else {
259-
Vim.AutoIndent.KeepIndent;
273+
)
274+
|> Option.value(~default=false);
275+
};
276+
277+
let shouldDecreaseIndent = (~line, {decreaseIndentPattern, brackets, _}) => {
278+
decreaseIndentPattern
279+
|> Option.map(regex => OnigRegExp.test(line, regex))
280+
|> OptionEx.or_lazy(() => {
281+
Some(
282+
List.exists(
283+
bracket => BracketPair.isJustClosingPair(bracket, line),
284+
brackets,
285+
),
286+
)
287+
})
288+
|> Option.value(~default=false);
289+
};
290+
291+
let toAutoIndent = (languageConfig, ~previousLine, ~beforePreviousLine) => {
292+
let increase =
293+
shouldIncreaseIndent(~previousLine, ~beforePreviousLine, languageConfig);
294+
295+
if (increase) {Vim.AutoIndent.IncreaseIndent} else {
296+
Vim.AutoIndent.KeepIndent
260297
};
261298
};

src/Core/LanguageConfiguration.rei

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ type t = {
4040

4141
let default: t;
4242

43+
let shouldIncreaseIndent:
44+
(~previousLine: string, ~beforePreviousLine: option(string), t) => bool;
45+
46+
let shouldDecreaseIndent: (~line: string, t) => bool;
47+
4348
let decode: Json.decoder(t);
4449

4550
let toVimAutoClosingPairs: (SyntaxScope.t, t) => Vim.AutoClosingPairs.t;

src/Core/Utility/StringEx.re

+18-8
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,29 @@ let trimRight = str => {
112112
aux(length - 1);
113113
};
114114

115-
let indentation = str => {
116-
let rec loop = i =>
117-
if (i >= String.length(str)) {
118-
i;
119-
} else if (isSpace(str.[i])) {
120-
loop(i + 1);
115+
let findNonWhitespace = str => {
116+
let len = String.length(str);
117+
let rec loop = idx =>
118+
if (idx >= len) {
119+
None;
121120
} else {
122-
i;
121+
let char = str.[idx];
122+
if (char != '\t' && char != ' ') {
123+
Some(idx);
124+
} else {
125+
loop(idx + 1);
126+
};
123127
};
124-
125128
loop(0);
126129
};
127130

131+
let isOnlyWhitespace = str => {
132+
switch (findNonWhitespace(str)) {
133+
| None => true
134+
| Some(_) => false
135+
};
136+
};
137+
128138
let extractSnippet = (~maxLength, ~charStart, ~charEnd, text) => {
129139
let originalLength = String.length(text);
130140

0 commit comments

Comments
 (0)