refactor: separate fields flow to smaller files

This commit is contained in:
2026-07-19 08:20:51 +05:00
parent 01661dc60e
commit 93b299e6ad
7 changed files with 599 additions and 542 deletions
+118
View File
@@ -0,0 +1,118 @@
import { resolveTaskLocations } from "@/commands/resolveTaskLocations";
import {
findFieldRange,
replaceFrontmatterField,
} from "@/frontmatter/frontmatterFields";
import {
isTaskFileName,
TASK_LANGUAGE_ID,
} from "@/model/taskFile";
import { IConfigProvider, IFileSystem } from "@/ports";
import * as vscode from "vscode";
import { resolveTaskFolderForPath } from "./resolveTaskFolder";
export type FrontmatterEditDeps = {
fs: IFileSystem;
config: IConfigProvider;
};
export const EditableField = {
STATUS: "status",
PRIORITY: "priority",
ASSIGNEE: "assignee",
TAGS: "tags",
} as const;
export type EditableField = (typeof EditableField)[keyof typeof EditableField];
function isTaskDocument(document: vscode.TextDocument): boolean {
if (document.languageId === TASK_LANGUAGE_ID) return true;
return isTaskFileName(document.fileName);
}
export async function resolveDocument(
uriArg?: string,
): Promise<vscode.TextDocument | undefined> {
if (typeof uriArg === "string" && uriArg.length > 0) {
const uri = vscode.Uri.parse(uriArg);
return vscode.workspace.openTextDocument(uri);
}
const active = vscode.window.activeTextEditor?.document;
if (active && isTaskDocument(active)) {
return active;
}
return undefined;
}
export function workspaceCwdFor(
document: vscode.TextDocument,
): string | undefined {
const folder = vscode.workspace.getWorkspaceFolder(document.uri);
return folder?.uri.fsPath;
}
export async function applyFieldValue(
document: vscode.TextDocument,
key: EditableField,
value: string,
): Promise<boolean> {
const text = document.getText();
const result = replaceFrontmatterField(text, key, value);
if (!result.ok) {
void vscode.window.showErrorMessage(
result.reason === "no-field"
? `Field "${key}" not found in frontmatter`
: "No YAML frontmatter in this file",
);
return false;
}
const valueRange = findFieldRange(text, key);
if (!valueRange) {
const full = new vscode.Range(
document.positionAt(0),
document.positionAt(text.length),
);
const edit = new vscode.WorkspaceEdit();
edit.replace(document.uri, full, result.content);
return vscode.workspace.applyEdit(edit);
}
const range = new vscode.Range(
valueRange.startLine,
valueRange.startCol,
valueRange.endLine,
valueRange.endCol,
);
const edit = new vscode.WorkspaceEdit();
edit.replace(document.uri, range, value);
return vscode.workspace.applyEdit(edit);
}
export function getCurrentFieldValue(
text: string,
field: string,
): string | undefined {
const range = findFieldRange(text, field);
if (!range) return undefined;
const lines = text.split(/\r?\n/);
const raw = lines[range.startLine]!.slice(
range.startCol,
range.endCol,
).trim();
if (
(raw.startsWith('"') && raw.endsWith('"')) ||
(raw.startsWith("'") && raw.endsWith("'"))
) {
return raw.slice(1, raw.length - 1);
}
return raw;
}
export async function resolveTaskFolder(
document: vscode.TextDocument,
config: IConfigProvider,
): Promise<string | undefined> {
const locations = resolveTaskLocations(config);
return resolveTaskFolderForPath(document.fileName, locations);
}