MCPcopy Create free account
hub / github.com/chhoumann/MetaEdit / updateMultipleInFile

Method updateMultipleInFile

src/metaController.ts:673–739  ·  view source on GitHub ↗
(properties: Property[], file: TFile)

Source from the content-addressed store, hash-verified

671 }
672
673 private async updateMultipleInFile(properties: Property[], file: TFile): Promise<void> {
674 // Refuse a batch with ANY reserved YAML key BEFORE the write starts. This
675 // method splices body tags before writing frontmatter, so validating up
676 // front keeps the batch atomic: a reserved key never lets the tag/text
677 // edits land while the frontmatter write is the part that fails. A nested
678 // property carries its key in `path`, so every string segment is checked -
679 // not just `prop.key` - otherwise `setYamlPath` would only throw later,
680 // inside `processFrontMatter`, after the tag splice already wrote.
681 for (const prop of properties) {
682 if (prop.type !== MetaType.YAML) continue;
683 if (prop.path && prop.path.length > 0) {
684 for (const segment of prop.path) {
685 if (typeof segment === "string") this.assertWritableKey(segment);
686 }
687 } else {
688 this.assertWritableKey(prop.key);
689 }
690 }
691
692 await this.enqueueFileWrite(file, async () => {
693 const yamlProperties = properties.filter(prop => prop.type === MetaType.YAML && !prop.path);
694 const yamlPathProperties = properties.filter(prop => prop.type === MetaType.YAML && prop.path);
695 const tagProperties = properties.filter(prop => prop.type === MetaType.Tag);
696 const textProperties = properties.filter(prop => prop.type === MetaType.Dataview && prop.key);
697
698 // Splice body tags FIRST, while their parsed offsets still match the
699 // file. A later processFrontMatter write only touches the frontmatter,
700 // so it preserves these body edits; doing it the other way round would
701 // shift every body offset and stale the tag spans. Highest-offset-first
702 // keeps earlier spans valid as later ones change length; a stale span
703 // is skipped, never forced, so a batch never corrupts prose.
704 if (tagProperties.length > 0) {
705 let content = await this.app.vault.read(file);
706 for (const prop of [...tagProperties].sort((a, b) => (b.position?.start ?? 0) - (a.position?.start ?? 0))) {
707 const token = normalizeTagToken(String(prop.content));
708 if (!isValidTagToken(token)) {
709 log.logMessage(`MetaEdit skipped tag '${prop.key}': '${String(prop.content)}' is not a valid tag.`);
710 continue;
711 }
712 const updated = spliceTag(content, prop.position, prop.key, token);
713 if (updated === null) {
714 log.logMessage(`MetaEdit skipped tag '${prop.key}': its position no longer matches the note.`);
715 continue;
716 }
717 content = updated;
718 }
719 await this.app.vault.modify(file, content);
720 }
721
722 if (yamlProperties.length > 0 || yamlPathProperties.length > 0) {
723 await this.processFrontMatter(file, (frontmatter) => {
724 for (const prop of yamlProperties) {
725 frontmatter[prop.key] = prop.content;
726 }
727 for (const prop of yamlPathProperties) {
728 setYamlPath(frontmatter, prop.path, prop.content, {createParents: false, createLeaf: false});
729 }
730 });

Callers 2

handleProgressPropsMethod · 0.95
callUpdateMultipleFunction · 0.80

Calls 9

assertWritableKeyMethod · 0.95
enqueueFileWriteMethod · 0.95
processFrontMatterMethod · 0.95
normalizeTagTokenFunction · 0.90
isValidTagTokenFunction · 0.90
spliceTagFunction · 0.90
setYamlPathFunction · 0.90
logMessageMethod · 0.65

Tested by 1

callUpdateMultipleFunction · 0.64