mirror of
https://github.com/danbulant/monaco-yaml
synced 2026-05-25 21:01:58 +00:00
fix: add colon position to key node
This commit is contained in:
parent
84e82b52f7
commit
ed907a9096
10 changed files with 206 additions and 16 deletions
18
.vscode/launch.json
vendored
Normal file
18
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"name": "vscode-jest-tests",
|
||||
"request": "launch",
|
||||
"args": ["--runInBand"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -142,6 +142,7 @@ export class NumberASTNodeImpl extends ASTNodeImpl implements NumberASTNode {
|
|||
export class StringASTNodeImpl extends ASTNodeImpl implements StringASTNode {
|
||||
public type: 'string' = 'string';
|
||||
public value: string;
|
||||
public isKey: boolean;
|
||||
|
||||
constructor(parent: ASTNode, offset: number, length?: number) {
|
||||
super(parent, offset, length);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode {
|
|||
instance.endPosition - key.startPosition
|
||||
);
|
||||
|
||||
result.colonOffset = key.colonPosition;
|
||||
|
||||
// Technically, this is an arbitrary node in YAML
|
||||
// I doubt we would get a better string representation by parsing it
|
||||
const keyNode = new StringASTNodeImpl(
|
||||
|
|
@ -69,6 +71,7 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode {
|
|||
key.endPosition - key.startPosition
|
||||
);
|
||||
keyNode.value = key.value;
|
||||
keyNode.isKey = true;
|
||||
|
||||
// TODO: calculate the correct NULL range.
|
||||
const valueNode = instance.value
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export class YAMLCompletion {
|
|||
|
||||
public configure(settings: LanguageSettings) {
|
||||
if (settings) {
|
||||
this.completionEnabled = settings.completion;
|
||||
this.completionEnabled = settings.completion !== false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export class YAMLHover {
|
|||
|
||||
public configure(languageSettings: LanguageSettings) {
|
||||
if (languageSettings) {
|
||||
this.shouldHover = !!languageSettings.hover;
|
||||
this.shouldHover = languageSettings.hover !== false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export class YAMLValidation {
|
|||
|
||||
public configure(raw: LanguageSettings) {
|
||||
if (raw) {
|
||||
this.validationEnabled = raw.validate;
|
||||
this.validationEnabled = raw.validate !== false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { ASTNode } from './jsonLanguageTypes';
|
||||
import { JSONDocument, IProblem } from './parser/jsonParser';
|
||||
import { getPosition } from './utils/documentPositionCalculator';
|
||||
|
||||
export class SingleYAMLDocument extends JSONDocument {
|
||||
public lines;
|
||||
public lines: number[];
|
||||
public errors: IProblem[];
|
||||
public warnings: IProblem[];
|
||||
|
||||
|
|
@ -23,6 +24,116 @@ export class SingleYAMLDocument extends JSONDocument {
|
|||
return super.getNodeFromOffset(offset, true);
|
||||
}
|
||||
|
||||
// getNodeFromOffsetEndInclusive(offset: number): ASTNode {
|
||||
// if (!this.root) {
|
||||
// return;
|
||||
// }
|
||||
// if (
|
||||
// offset < this.root.offset ||
|
||||
// offset > this.root.offset + this.root.length
|
||||
// ) {
|
||||
// // We somehow are completely outside the document
|
||||
// // This is unexpected
|
||||
// console.log('Attempting to resolve node outside of document');
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// function* sliding2(nodes: ASTNode[]) {
|
||||
// for (let i = 0; i < nodes.length; i ++) {
|
||||
// yield [nodes[i], i === nodes.length ? null : nodes[i + 1]];
|
||||
// }
|
||||
// }
|
||||
|
||||
// const onLaterLine = (offset: number, node: ASTNode) => {
|
||||
// const { line: actualLine } = getPosition(offset, this.lines);
|
||||
// const { line: nodeEndLine } = getPosition(
|
||||
// node.offset + node.length,
|
||||
// this.lines
|
||||
// );
|
||||
|
||||
// return actualLine > nodeEndLine;
|
||||
// };
|
||||
|
||||
// let findNode = (nodes: ASTNode[]): ASTNode => {
|
||||
// if (nodes.length === 0) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// const gen = sliding2(nodes);
|
||||
|
||||
// for (let [first, second] of gen) {
|
||||
// const end = second
|
||||
// ? second.offset
|
||||
// : first.parent.offset + first.parent.length;
|
||||
// if (offset >= first.offset && offset < end) {
|
||||
// const children = first.children;
|
||||
|
||||
// const foundChild = findNode(children);
|
||||
|
||||
// if (!foundChild && onLaterLine(offset, first)) {
|
||||
// return this.getNodeByIndent(this.lines, offset, this.root);
|
||||
// }
|
||||
|
||||
// return foundChild || first;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return null;
|
||||
// };
|
||||
|
||||
// return findNode(this.root.children) || this.root;
|
||||
// }
|
||||
|
||||
// private getNodeByIndent = (
|
||||
// lines: number[],
|
||||
// offset: number,
|
||||
// node: ASTNode
|
||||
// ) => {
|
||||
// const { line, column: indent } = getPosition(offset, this.lines);
|
||||
|
||||
// const children = node.children;
|
||||
|
||||
// function findNode(children: ASTNode[]) {
|
||||
// if (children.length > 0) {
|
||||
|
||||
// }
|
||||
// for (let idx = 0; idx < children.length; idx++) {
|
||||
// const child = children[idx];
|
||||
|
||||
// const { line: childLine, column: childCol } = getPosition(
|
||||
// child.offset,
|
||||
// lines
|
||||
// );
|
||||
|
||||
// if (childCol > indent) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// const newChildren = child.children;
|
||||
// const foundNode = findNode(newChildren);
|
||||
|
||||
// if (foundNode) {
|
||||
// return foundNode;
|
||||
// }
|
||||
|
||||
// // We have the right indentation, need to return based on line
|
||||
// if (childLine == line) {
|
||||
// return child;
|
||||
// }
|
||||
// if (childLine > line) {
|
||||
// // Get previous
|
||||
// idx - 1 >= 0 ? children[idx - 1] : child;
|
||||
// }
|
||||
// // Else continue loop to try next element
|
||||
// }
|
||||
|
||||
// // Special case, we found the correct
|
||||
// return children[children.length - 1];
|
||||
// }
|
||||
|
||||
// return findNode(children) || node;
|
||||
// };
|
||||
|
||||
public getNodeFromOffsetEndInclusive(offset: number): ASTNode {
|
||||
const collector: ASTNode[] = [];
|
||||
const findNode = (node: ASTNode): ASTNode => {
|
||||
|
|
@ -60,12 +171,8 @@ export class SingleYAMLDocument extends JSONDocument {
|
|||
|
||||
export class YAMLDocument {
|
||||
public documents: SingleYAMLDocument[];
|
||||
public errors;
|
||||
public warnings;
|
||||
|
||||
constructor(documents: SingleYAMLDocument[]) {
|
||||
this.documents = documents;
|
||||
this.errors = [];
|
||||
this.warnings = [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -492,11 +492,7 @@ function storeMappingPair(
|
|||
});
|
||||
|
||||
_result.mappings.push(mapping);
|
||||
_result.endPosition = valueNode
|
||||
? valueNode.endPosition
|
||||
: keyNode.endPosition + 1; // FIXME.workaround should be position of ':' indeed
|
||||
// }
|
||||
|
||||
_result.endPosition = mapping.endPosition;
|
||||
return _result;
|
||||
}
|
||||
|
||||
|
|
@ -646,7 +642,8 @@ function readPlainScalar(state: State, nodeIndent, withinFlowCollection) {
|
|||
_lineIndent,
|
||||
_kind = state.kind,
|
||||
_result = state.result,
|
||||
ch;
|
||||
ch,
|
||||
_colonPosition = -1;
|
||||
const state_result = ast.newScalar();
|
||||
state_result.plainScalar = true;
|
||||
state.result = state_result;
|
||||
|
|
@ -694,6 +691,7 @@ function readPlainScalar(state: State, nodeIndent, withinFlowCollection) {
|
|||
is_WS_OR_EOL(following) ||
|
||||
(withinFlowCollection && is_FLOW_INDICATOR(following))
|
||||
) {
|
||||
_colonPosition = state.position;
|
||||
break;
|
||||
}
|
||||
} else if (0x23 /* # */ === ch) {
|
||||
|
|
@ -750,6 +748,7 @@ function readPlainScalar(state: State, nodeIndent, withinFlowCollection) {
|
|||
state_result.startPosition,
|
||||
state_result.endPosition
|
||||
);
|
||||
state_result.colonPosition = _colonPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ export interface YAMLNode extends YAMLDocument {
|
|||
startPosition: number;
|
||||
endPosition: number;
|
||||
kind: Kind;
|
||||
colonPosition?: number; // Nearest colon position.
|
||||
anchorId?: string;
|
||||
valueObject?: any;
|
||||
parent: YAMLNode;
|
||||
|
|
@ -63,8 +64,7 @@ export interface YamlMap extends YAMLNode {
|
|||
mappings: YAMLMapping[];
|
||||
}
|
||||
export function newMapping(key: YAMLScalar, value: YAMLNode): YAMLMapping {
|
||||
const end = value ? value.endPosition : key.endPosition + 1; // FIXME.workaround, end should be defied by position of ':'
|
||||
// console.log('key: ' + key.value + ' ' + key.startPosition + '..' + key.endPosition + ' ' + value + ' end: ' + end);
|
||||
const end = value ? value.endPosition : key.colonPosition + 1;
|
||||
const node = {
|
||||
key,
|
||||
value,
|
||||
|
|
|
|||
62
test/yamlDocument.test.ts
Normal file
62
test/yamlDocument.test.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { TextDocument } from 'vscode-languageserver';
|
||||
import { parse as parseYAML } from '../src/languageservice/parser/yamlParser';
|
||||
|
||||
describe('SingleYAMLDocument tests', () => {
|
||||
function setup(content: string) {
|
||||
return TextDocument.create(
|
||||
'file://~/Desktop/vscode-k8s/test.yaml',
|
||||
'yaml',
|
||||
0,
|
||||
content
|
||||
);
|
||||
}
|
||||
|
||||
describe('getNodeFromOffsetEndInclusive', () => {
|
||||
const content = `a :
|
||||
b:
|
||||
|
||||
`;
|
||||
function parseSetup(offset: number) {
|
||||
const yamlDocs = parseYAML(content);
|
||||
|
||||
// Should be one doc only
|
||||
expect(yamlDocs.documents.length).toBe(1);
|
||||
return yamlDocs.documents[0].getNodeFromOffsetEndInclusive(offset);
|
||||
}
|
||||
|
||||
it('0', () => {
|
||||
const node = parseSetup(0);
|
||||
expect(node.value).toBe('a');
|
||||
expect(node.type).toBe('string');
|
||||
});
|
||||
|
||||
it('1', () => {
|
||||
const node = parseSetup(1);
|
||||
expect(node.value).toBe('a');
|
||||
expect(node.type).toBe('string');
|
||||
});
|
||||
|
||||
it('2', () => {
|
||||
const node = parseSetup(2);
|
||||
expect(node.type).toBe('property');
|
||||
});
|
||||
|
||||
it('6', () => {
|
||||
const node = parseSetup(6);
|
||||
expect(node.value).toBe('b');
|
||||
expect(node.type).toBe('string');
|
||||
});
|
||||
|
||||
it('7', () => {
|
||||
const node = parseSetup(7);
|
||||
expect(node.value).toBe('b');
|
||||
expect(node.type).toBe('string');
|
||||
});
|
||||
|
||||
it('8', () => {
|
||||
const node = parseSetup(8);
|
||||
expect(node.value).toBe('b');
|
||||
expect(node.type).toBe('string');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue