refactor: separate fields flow to smaller files
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user