90 lines
2.0 KiB
TypeScript
90 lines
2.0 KiB
TypeScript
|
|
/**
|
||
|
|
* Section context resolver: determines current section from editor cursor position.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { Editor } from "obsidian";
|
||
|
|
import { splitIntoSections } from "../mapping/sectionParser";
|
||
|
|
|
||
|
|
export interface SectionRef {
|
||
|
|
file: string;
|
||
|
|
heading: string | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export type ZoneKind = "content" | "note_links" | "candidates" | "root";
|
||
|
|
|
||
|
|
export interface SectionContext {
|
||
|
|
file: string;
|
||
|
|
heading: string | null;
|
||
|
|
zoneKind: ZoneKind;
|
||
|
|
sectionIndex: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
const NOTE_LINKS_HEADING = "Note-Verbindungen";
|
||
|
|
const CANDIDATES_HEADING = "Kandidaten";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Determine section context from editor cursor position.
|
||
|
|
*/
|
||
|
|
export function resolveSectionContext(
|
||
|
|
editor: Editor,
|
||
|
|
filePath: string
|
||
|
|
): SectionContext {
|
||
|
|
const content = editor.getValue();
|
||
|
|
const cursor = editor.getCursor();
|
||
|
|
const cursorLine = cursor.line;
|
||
|
|
|
||
|
|
const sections = splitIntoSections(content);
|
||
|
|
|
||
|
|
// Find section containing cursor line
|
||
|
|
let currentSectionIndex = -1;
|
||
|
|
for (let i = 0; i < sections.length; i++) {
|
||
|
|
const section = sections[i];
|
||
|
|
if (!section) continue;
|
||
|
|
if (
|
||
|
|
section.startLine <= cursorLine &&
|
||
|
|
cursorLine < section.endLine
|
||
|
|
) {
|
||
|
|
currentSectionIndex = i;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// If no section found, use root (content before first heading)
|
||
|
|
if (currentSectionIndex === -1) {
|
||
|
|
return {
|
||
|
|
file: filePath,
|
||
|
|
heading: null,
|
||
|
|
zoneKind: "root",
|
||
|
|
sectionIndex: 0,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
const currentSection = sections[currentSectionIndex];
|
||
|
|
if (!currentSection) {
|
||
|
|
return {
|
||
|
|
file: filePath,
|
||
|
|
heading: null,
|
||
|
|
zoneKind: "root",
|
||
|
|
sectionIndex: 0,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
// Determine zone kind based on heading
|
||
|
|
let zoneKind: ZoneKind = "content";
|
||
|
|
const heading = currentSection.heading;
|
||
|
|
if (heading === NOTE_LINKS_HEADING) {
|
||
|
|
zoneKind = "note_links";
|
||
|
|
} else if (heading === CANDIDATES_HEADING) {
|
||
|
|
zoneKind = "candidates";
|
||
|
|
} else if (heading === null) {
|
||
|
|
zoneKind = "root";
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
file: filePath,
|
||
|
|
heading: heading,
|
||
|
|
zoneKind,
|
||
|
|
sectionIndex: currentSectionIndex,
|
||
|
|
};
|
||
|
|
}
|