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' ;
611import { TextDocument } from 'vscode-languageserver-textdocument' ;
712import {
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' ;
1824import { 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' ;
2226import { 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' ;
2627import { yamlDocumentsCache } from '../parser/yaml-documents' ;
28+ import { matchOffsetToDocument } from '../utils/arrUtils' ;
29+ import { BlockStringRewriter } from '../utils/block-string-rewriter' ;
2730import { 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
3435interface YamlDiagnosticData {
3536 schemaUri : string [ ] ;
@@ -38,11 +39,13 @@ interface YamlDiagnosticData {
3839}
3940export 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 . range , document ) ) ;
6064 result . push ( ...this . getKeyOrderActions ( params . context . diagnostics , document ) ) ;
6165 result . push ( ...this . getQuickFixForPropertyOrValueMismatch ( params . context . diagnostics , document ) ) ;
6266
@@ -243,6 +247,57 @@ export class YamlCodeActions {
243247 return results ;
244248 }
245249
250+ private getConvertStringToBlockStyleActions ( range : Range , document : TextDocument ) : CodeAction [ ] {
251+ const yamlDocument = yamlDocumentsCache . getYamlDocument ( document ) ;
252+
253+ const startOffset : number = range ? document . offsetAt ( range . start ) : 0 ;
254+ const endOffset : number = range ? document . offsetAt ( range . end ) : Infinity ;
255+
256+ const results : CodeAction [ ] = [ ] ;
257+ for ( const singleYamlDocument of yamlDocument . documents ) {
258+ const matchingNodes : Scalar < string > [ ] = [ ] ;
259+ visit ( singleYamlDocument . internalDocument , ( key , node ) => {
260+ if ( isScalar ( node ) ) {
261+ if (
262+ ( startOffset <= node . range [ 0 ] && node . range [ 2 ] <= endOffset ) ||
263+ ( node . range [ 0 ] <= startOffset && endOffset <= node . range [ 2 ] )
264+ ) {
265+ if ( node . type === 'QUOTE_DOUBLE' || node . type === 'QUOTE_SINGLE' ) {
266+ if ( typeof node . value === 'string' && ( node . value . indexOf ( '\n' ) >= 0 || node . value . length > this . lineWidth ) ) {
267+ matchingNodes . push ( < Scalar < string > > node ) ;
268+ }
269+ }
270+ }
271+ }
272+ } ) ;
273+ for ( const node of matchingNodes ) {
274+ const range = Range . create ( document . positionAt ( node . range [ 0 ] ) , document . positionAt ( node . range [ 2 ] ) ) ;
275+ const rewriter = new BlockStringRewriter ( this . indentation , this . lineWidth ) ;
276+ const foldedBlockScalar = rewriter . writeFoldedBlockScalar ( node ) ;
277+ if ( foldedBlockScalar !== null ) {
278+ results . push (
279+ CodeAction . create (
280+ l10n . t ( 'convertToFoldedBlockString' ) ,
281+ createWorkspaceEdit ( document . uri , [ TextEdit . replace ( range , foldedBlockScalar ) ] ) ,
282+ CodeActionKind . Refactor
283+ )
284+ ) ;
285+ }
286+ const literalBlockScalar = rewriter . writeLiteralBlockScalar ( node ) ;
287+ if ( literalBlockScalar !== null ) {
288+ results . push (
289+ CodeAction . create (
290+ l10n . t ( 'convertToLiteralBlockString' ) ,
291+ createWorkspaceEdit ( document . uri , [ TextEdit . replace ( range , literalBlockScalar ) ] ) ,
292+ CodeActionKind . Refactor
293+ )
294+ ) ;
295+ }
296+ }
297+ }
298+ return results ;
299+ }
300+
246301 private getKeyOrderActions ( diagnostics : Diagnostic [ ] , document : TextDocument ) : CodeAction [ ] {
247302 const results : CodeAction [ ] = [ ] ;
248303 for ( const diagnostic of diagnostics ) {
0 commit comments