mirror of
https://github.com/prdlk/leetcode.git
synced 2026-11-02 13:12:44 +00:00
feat(cli): prioritize uncommitted solutions in picker ordering
This commit is contained in:
1 parent
0ccd9794f0
commit
a7ab989d57
1 file changed
+38
-5
+38
-5
@@ -9,10 +9,12 @@
|
||||
*
|
||||
* Every run backfills the db's solutions table with created_at (from the
|
||||
* file's birthtime, mtime when the filesystem has none) so ordering works for
|
||||
* files that predate the db. Ordering is per command — test lists the most
|
||||
* recently tested first (never-tested after, by name); submit lists the most
|
||||
* recently created first. Nothing is ever hidden. Exit 0 of leetcode-cli
|
||||
* stamps last_tested / last_submitted.
|
||||
* files that predate the db. Files git reports as modified, added or
|
||||
* untracked come first, newest edit first — the problem being worked on is
|
||||
* the focused option, so Enter runs it without a search. The rest are ordered
|
||||
* per command — test lists the most recently tested first (never-tested
|
||||
* after, by name); submit lists the most recently created first. Nothing is
|
||||
* ever hidden. Exit 0 of leetcode-cli stamps last_tested / last_submitted.
|
||||
*
|
||||
* Library: side-effect-free on import — nothing scans the filesystem until
|
||||
* runOnSolution() is called.
|
||||
@@ -29,6 +31,29 @@ function lcNumber(rel: string): number | undefined {
|
||||
return m ? Number(m[1]) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* work/-relative paths of solutions git sees as modified, added or untracked,
|
||||
* mapped to their mtime. Empty outside a git checkout.
|
||||
*/
|
||||
function dirtySolutions(scanned: Set<string>): Map<string, number> {
|
||||
const git = Bun.spawnSync(
|
||||
["git", "status", "--porcelain", "-z", "--untracked-files=all", "--", WORK_DIR],
|
||||
{ cwd: ROOT },
|
||||
);
|
||||
const dirty = new Map<string, number>();
|
||||
if (!git.success) return dirty;
|
||||
const entries = git.stdout.toString().split("\0");
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
const entry = entries[i]!;
|
||||
// renames/copies carry their source path as the next entry; skip it
|
||||
if (/[RC]/.test(entry.slice(0, 2))) i++;
|
||||
const rel = relative(WORK_DIR, join(ROOT, entry.slice(3)));
|
||||
// deletions and non-solution files are not in the scan
|
||||
if (scanned.has(rel)) dirty.set(rel, statSync(join(WORK_DIR, rel)).mtimeMs);
|
||||
}
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/** Fuzzy-pick a solution under work/ and run `leetcode <command>` on it. */
|
||||
export async function runOnSolution(
|
||||
command: "test" | "submit",
|
||||
@@ -61,7 +86,15 @@ export async function runOnSolution(
|
||||
return (command === "test" ? row?.lastTested : row?.createdAt) ?? undefined;
|
||||
};
|
||||
|
||||
const dirty = dirtySolutions(new Set(scanned));
|
||||
const files = scanned.sort((a, b) => {
|
||||
const ma = dirty.get(a);
|
||||
const mb = dirty.get(b);
|
||||
if (ma !== mb) {
|
||||
if (ma === undefined) return 1;
|
||||
if (mb === undefined) return -1;
|
||||
return mb - ma;
|
||||
}
|
||||
const ka = sortKey(a);
|
||||
const kb = sortKey(b);
|
||||
if (ka !== kb) {
|
||||
@@ -91,7 +124,7 @@ export async function runOnSolution(
|
||||
value: f,
|
||||
label: basename(f),
|
||||
hint: parsed
|
||||
? `${stage} · ${parsed.difficulty} · ${parsed.category}`
|
||||
? `${dirty.has(f) ? "uncommitted · " : ""}${stage} · ${parsed.difficulty} · ${parsed.category}`
|
||||
: f,
|
||||
};
|
||||
}),
|
||||
|
||||
Reference in new issue
Block a user