Current section

Files

Jump to
spellweaver priv bun node_modules cspell-config-lib dist CSpellConfigFile CSpellConfigFileYaml.js
Raw

priv/bun/node_modules/cspell-config-lib/dist/CSpellConfigFile/CSpellConfigFileYaml.js

import assert from 'node:assert';
import { isMap, isScalar, isSeq, parseDocument, Scalar, stringify, YAMLMap, YAMLSeq, } from 'yaml';
import { CSpellConfigFile } from '../CSpellConfigFile.js';
import { detectIndentAsNum } from '../serializers/util.js';
import { ParseError } from './Errors.js';
export class CSpellConfigFileYaml extends CSpellConfigFile {
url;
yamlDoc;
indent;
#settings;
constructor(url, yamlDoc, indent) {
super(url);
this.url = url;
this.yamlDoc = yamlDoc;
this.indent = indent;
this.#settings = yamlDoc.toJS();
}
get settings() {
return this.#settings;
}
addWords(wordsToAdd) {
const cfgWords = this.yamlDoc.get('words') || new YAMLSeq();
assert(isSeq(cfgWords), 'Expected words to be a YAML sequence');
const knownWords = new Set(cfgWords.items.map((item) => getScalarValue(item)));
wordsToAdd.forEach((w) => {
if (knownWords.has(w))
return;
cfgWords.add(w);
knownWords.add(w);
});
const sorted = sortWords(cfgWords.items);
sorted.forEach((item, index) => cfgWords.set(index, item));
cfgWords.items.length = sorted.length;
this.yamlDoc.set('words', cfgWords);
this.#settings = this.yamlDoc.toJS();
return this;
}
serialize() {
return stringify(this.yamlDoc, { indent: this.indent });
}
}
export function parseCSpellConfigFileYaml(file) {
const { url, content } = file;
try {
const doc = parseDocument(content);
// Force empty content to be a map.
if (doc.contents === null || (isScalar(doc.contents) && !doc.contents.value)) {
doc.contents = new YAMLMap();
}
if (!isMap(doc.contents)) {
throw new ParseError(url, `Invalid YAML content ${url}`);
}
const indent = detectIndentAsNum(content);
return new CSpellConfigFileYaml(url, doc, indent);
}
catch (e) {
if (e instanceof ParseError) {
throw e;
}
throw new ParseError(url, undefined, { cause: e });
}
}
function getScalarValue(node) {
if (isScalar(node)) {
return node.value;
}
return node;
}
function toScalar(node) {
if (isScalar(node)) {
return node;
}
return new Scalar(node);
}
function groupWords(words) {
const groups = [];
if (words.length === 0) {
return groups;
}
let currentGroup = [];
groups.push(currentGroup);
for (const word of words) {
if (isSectionHeader(word)) {
currentGroup = [];
groups.push(currentGroup);
}
currentGroup.push(cloneWord(word));
}
return groups;
}
function isSectionHeader(word) {
if (!isScalar(word) || (!word.commentBefore && !word.spaceBefore))
return false;
if (word.spaceBefore)
return true;
if (!word.commentBefore)
return false;
return word.commentBefore.includes('\n\n');
}
function adjustSectionHeader(word, prev, isFirstSection) {
// console.log('adjustSectionHeader %o', { word, prev, isFirstSection });
if (!isScalar(prev))
return;
let captureComment = isFirstSection;
if (prev.spaceBefore) {
word.spaceBefore = true;
captureComment = true;
delete prev.spaceBefore;
}
if (!prev.commentBefore)
return;
const originalComment = prev.commentBefore;
const lines = originalComment.split(/^\n/gm);
const lastLine = lines[lines.length - 1];
// console.log('adjustSectionHeader lines %o', { lines, isFirstSection, lastLine, originalComment });
captureComment = (captureComment && originalComment.trim() === lastLine.trim()) || originalComment.endsWith('\n');
let header = originalComment;
if (captureComment) {
delete prev.commentBefore;
}
else {
prev.commentBefore = lastLine;
lines.pop();
header = lines.join('\n');
}
if (word.commentBefore) {
header += header.endsWith('\n\n') ? '' : '\n';
header += header.endsWith('\n\n') ? '' : '\n';
header += word.commentBefore;
}
word.commentBefore = header;
// console.log('adjustSectionHeader after %o', { word, prev, isFirstSection, originalComment, lastLine, lines });
}
function sortWords(words) {
const compare = new Intl.Collator().compare;
const groups = groupWords(words);
let firstGroup = true;
for (const group of groups) {
const head = group[0];
group.sort((a, b) => {
return compare(getScalarValue(a), getScalarValue(b));
});
if (group[0] !== head && isScalar(head)) {
const first = (group[0] = toScalar(group[0]));
adjustSectionHeader(first, head, firstGroup);
}
firstGroup = false;
}
const result = groups.flat();
return result.map((w) => toScalar(w));
}
function cloneWord(word) {
if (isScalar(word)) {
return word.clone();
}
return word;
}
//# sourceMappingURL=CSpellConfigFileYaml.js.map