Skip to content

Commit d669f4a

Browse files
committed
Refactoring action to change strings into block scalars
Adds two new refactoring actions to turn quoted strings into block strings. eg. if you have the following ```yaml root: "value1\value2" ``` There are two refactoring actions so that it can be turned into ```yaml root: >- value1 value2 ``` or ```yaml root: |- value1 value2 ``` Fixes #1119 Signed-off-by: David Thompson <[email protected]>
1 parent 86a61da commit d669f4a

13 files changed

+628
-24
lines changed

.vscode/tasks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
{
77
"label": "watch typescript",
88
"type": "shell",
9-
"command": "yarn run watch",
9+
"command": "npm run watch",
1010
"presentation": {
1111
"reveal": "never"
1212
},

l10n/bundle.l10n.de.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "Flow-Stil-Mapping ist verboten",
5353
"flowStyleSeqForbidden": "Flow-Stil-Sequenz ist verboten",
5454
"unUsedAnchor": "Nicht verwendeter Anker \"{0}\"",
55-
"unUsedAlias": "Nicht aufgelöstes Alias \"{0}\""
55+
"unUsedAlias": "Nicht aufgelöstes Alias \"{0}\"",
56+
"convertToFoldedBlockString": "Konvertieren Sie die Zeichenfolge in eine gefaltete Blockzeichenfolge",
57+
"convertToLiteralBlockString": "Konvertieren Sie die Zeichenfolge in eine wörtliche Blockzeichenfolge"
5658
}

l10n/bundle.l10n.fr.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "Le mappage de style de flux est interdit",
5353
"flowStyleSeqForbidden": "La séquence de style Flow est interdite",
5454
"unUsedAnchor": "Ancre inutilisée '{0}'",
55-
"unUsedAlias": "Alias ​​non résolu '{0}'"
55+
"unUsedAlias": "Alias non résolu '{0}'",
56+
"convertToFoldedBlockString": "Convertir la chaîne en style de bloc pliée",
57+
"convertToLiteralBlockString": "Convertir la chaîne en style de bloc littérale"
5658
}

l10n/bundle.l10n.ja.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "フロースタイルのマッピングは禁止されています",
5353
"flowStyleSeqForbidden": "フロースタイルのシーケンスは禁止されています",
5454
"unUsedAnchor": "未使用のアンカー \"{0}\"",
55-
"unUsedAlias": "未解決のエイリアス \"{0}\""
55+
"unUsedAlias": "未解決のエイリアス \"{0}\"",
56+
"convertToFoldedBlockString": "文字列を折り畳みブロック文字列に変換する",
57+
"convertToLiteralBlockString": "文字列をリテラルブロック文字列に変換する"
5658
}

l10n/bundle.l10n.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "Flow style mapping is forbidden",
5353
"flowStyleSeqForbidden": "Flow style sequence is forbidden",
5454
"unUsedAnchor": "Unused anchor \"{0}\"",
55-
"unUsedAlias": "Unresolved alias \"{0}\""
55+
"unUsedAlias": "Unresolved alias \"{0}\"",
56+
"convertToFoldedBlockString": "Convert string to folded block string",
57+
"convertToLiteralBlockString": "Convert string to literal block string"
5658
}

l10n/bundle.l10n.ko.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "Flow 스타일 맵 사용이 금지됨",
5353
"flowStyleSeqForbidden": "Flow 스타일 시퀀스 사용이 금지됨",
5454
"unUsedAnchor": "사용되지 않은 앵커 \"{0}\"",
55-
"unUsedAlias": "해결되지 않은 별칭 \"{0}\""
55+
"unUsedAlias": "해결되지 않은 별칭 \"{0}\"",
56+
"convertToFoldedBlockString": "문자열을 접힌 블록 문자열로 변환합니다.",
57+
"convertToLiteralBlockString": "문자열을 리터럴 블록 문자열로 변환합니다."
5658
}

l10n/bundle.l10n.zh-cn.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "禁止使用 flow 样式的映射",
5353
"flowStyleSeqForbidden": "禁止使用 flow 样式的序列",
5454
"unUsedAnchor": "未使用的锚点 \"{0}\"",
55-
"unUsedAlias": "未解析的别名 \"{0}\""
55+
"unUsedAlias": "未解析的别名 \"{0}\"",
56+
"convertToFoldedBlockString": "将字符串转换为折叠块字符串",
57+
"convertToLiteralBlockString": "将字符串转换为文字块字符串"
5658
}

l10n/bundle.l10n.zh-tw.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
"flowStyleMapForbidden": "禁止使用 Flow 風格的對應",
5353
"flowStyleSeqForbidden": "禁止使用 Flow 風格的序列",
5454
"unUsedAnchor": "未使用的錨點 \"{0}\"",
55-
"unUsedAlias": "未解析的別名 \"{0}\""
55+
"unUsedAlias": "未解析的別名 \"{0}\"",
56+
"convertToFoldedBlockString": "將字串轉換為折疊塊字串",
57+
"convertToLiteralBlockString": "將字串轉換為文字區塊字串"
5658
}

src/languageservice/services/yamlCodeActions.ts

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import * as l10n from '@vscode/l10n';
7+
import * as _ from 'lodash';
8+
import * as path from 'path';
9+
import { ErrorCode } from 'vscode-json-languageservice';
10+
import { ClientCapabilities, CodeActionParams } from 'vscode-languageserver-protocol';
611
import { TextDocument } from 'vscode-languageserver-textdocument';
712
import {
813
CodeAction,
@@ -14,22 +19,18 @@ import {
1419
TextEdit,
1520
WorkspaceEdit,
1621
} from 'vscode-languageserver-types';
17-
import { ClientCapabilities, CodeActionParams } from 'vscode-languageserver-protocol';
22+
import { CST, isMap, isScalar, isSeq, Scalar, visit, YAMLMap } from 'yaml';
23+
import { SourceToken } from 'yaml/dist/parse/cst';
1824
import { YamlCommands } from '../../commands';
19-
import * as path from 'path';
20-
import { TextBuffer } from '../utils/textBuffer';
21-
import { LanguageSettings } from '../yamlLanguageService';
25+
import { ASTNode } from '../jsonASTTypes';
2226
import { YAML_SOURCE } from '../parser/jsonParser07';
23-
import { getFirstNonWhitespaceCharacterAfterOffset } from '../utils/strings';
24-
import { matchOffsetToDocument } from '../utils/arrUtils';
25-
import { CST, isMap, isSeq, YAMLMap } from 'yaml';
2627
import { yamlDocumentsCache } from '../parser/yaml-documents';
28+
import { matchOffsetToDocument } from '../utils/arrUtils';
29+
import { BlockStringRewriter } from '../utils/block-string-rewriter';
2730
import { FlowStyleRewriter } from '../utils/flow-style-rewriter';
28-
import { ASTNode } from '../jsonASTTypes';
29-
import * as _ from 'lodash';
30-
import { SourceToken } from 'yaml/dist/parse/cst';
31-
import { ErrorCode } from 'vscode-json-languageservice';
32-
import * as l10n from '@vscode/l10n';
31+
import { getFirstNonWhitespaceCharacterAfterOffset } from '../utils/strings';
32+
import { TextBuffer } from '../utils/textBuffer';
33+
import { LanguageSettings } from '../yamlLanguageService';
3334

3435
interface YamlDiagnosticData {
3536
schemaUri: string[];
@@ -38,11 +39,13 @@ interface YamlDiagnosticData {
3839
}
3940
export class YamlCodeActions {
4041
private indentation = ' ';
42+
private lineWidth = 80;
4143

4244
constructor(private readonly clientCapabilities: ClientCapabilities) {}
4345

44-
configure(settings: LanguageSettings): void {
46+
configure(settings: LanguageSettings, printWidth: number): void {
4547
this.indentation = settings.indentation;
48+
this.lineWidth = printWidth;
4649
}
4750

4851
getCodeAction(document: TextDocument, params: CodeActionParams): CodeAction[] | undefined {
@@ -57,6 +60,7 @@ export class YamlCodeActions {
5760
result.push(...this.getTabToSpaceConverting(params.context.diagnostics, document));
5861
result.push(...this.getUnusedAnchorsDelete(params.context.diagnostics, document));
5962
result.push(...this.getConvertToBlockStyleActions(params.context.diagnostics, document));
63+
result.push(...this.getConvertStringToBlockStyleActions(params.context.diagnostics, document));
6064
result.push(...this.getKeyOrderActions(params.context.diagnostics, document));
6165
result.push(...this.getQuickFixForPropertyOrValueMismatch(params.context.diagnostics, document));
6266

@@ -243,6 +247,49 @@ export class YamlCodeActions {
243247
return results;
244248
}
245249

250+
private getConvertStringToBlockStyleActions(diagnostics: Diagnostic[], document: TextDocument): CodeAction[] {
251+
const yamlDocument = yamlDocumentsCache.getYamlDocument(document);
252+
253+
const results: CodeAction[] = [];
254+
for (const singleYamlDocument of yamlDocument.documents) {
255+
const matchingNodes: Scalar<string>[] = [];
256+
visit(singleYamlDocument.internalDocument, (key, node) => {
257+
if (isScalar(node)) {
258+
if (node.type === 'QUOTE_DOUBLE' || node.type === 'QUOTE_SINGLE') {
259+
if (typeof node.value === 'string' && (node.value.indexOf('\n') >= 0 || node.value.length > this.lineWidth)) {
260+
matchingNodes.push(<Scalar<string>>node);
261+
}
262+
}
263+
}
264+
});
265+
for (const node of matchingNodes) {
266+
const range = Range.create(document.positionAt(node.range[0]), document.positionAt(node.range[2]));
267+
const rewriter = new BlockStringRewriter(this.indentation, this.lineWidth);
268+
const foldedBlockScalar = rewriter.writeFoldedBlockScalar(node);
269+
if (foldedBlockScalar !== null) {
270+
results.push(
271+
CodeAction.create(
272+
l10n.t('convertToFoldedBlockString'),
273+
createWorkspaceEdit(document.uri, [TextEdit.replace(range, foldedBlockScalar)]),
274+
CodeActionKind.Refactor
275+
)
276+
);
277+
}
278+
const literalBlockScalar = rewriter.writeLiteralBlockScalar(node);
279+
if (literalBlockScalar !== null) {
280+
results.push(
281+
CodeAction.create(
282+
l10n.t('convertToLiteralBlockString'),
283+
createWorkspaceEdit(document.uri, [TextEdit.replace(range, literalBlockScalar)]),
284+
CodeActionKind.Refactor
285+
)
286+
);
287+
}
288+
}
289+
}
290+
return results;
291+
}
292+
246293
private getKeyOrderActions(diagnostics: Diagnostic[], document: TextDocument): CodeAction[] {
247294
const results: CodeAction[] = [];
248295
for (const diagnostic of diagnostics) {

0 commit comments

Comments
 (0)