0dd173f113
- new read-only export hel_entry(name): the entry's canonical stored form, or "" - Mark correct now also stores the name (keeps the entry); unmark keeps the stored name and just drops the hash (wraps add/rm for an ephemeral entry so the right hash is removed) - Store button shows "Stored ✓" (disabled, ocean outline) when the name is already in the catalog, "Store" otherwise - when a typed name already exists, the field adopts the full stored spec on blur (real mode/seq/date/parent) instead of a default-extended parse
80 lines
2.9 KiB
Rust
80 lines
2.9 KiB
Rust
use hel::lk::{LK, LKRef};
|
|
use hel::parser::command_parser;
|
|
use hel::repl::{LKEval, LKRead};
|
|
use hel::structs::LKOut;
|
|
use hel::utils::editor::{password, Editor};
|
|
use parking_lot::ReentrantMutex;
|
|
use std::cell::RefCell;
|
|
use std::sync::Arc;
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
lazy_static! {
|
|
static ref STATE: LKRef = Arc::new(ReentrantMutex::new(RefCell::new(LK::new())));
|
|
}
|
|
|
|
/// Run a single hel command line and return its combined output.
|
|
#[wasm_bindgen]
|
|
pub fn hel_command(cmd: String) -> String {
|
|
let editor = Editor::new();
|
|
let mut lkread = LKRead::new(editor, "> ".to_string(), STATE.clone());
|
|
lkread.input = Some(cmd);
|
|
let lkeval = lkread.read();
|
|
let lkprint = lkeval.eval();
|
|
lkprint.out.output().join("\n")
|
|
}
|
|
|
|
/// Parse a password spec (e.g. `exa91` or `exa91 20R 99 2020-01-01`) and return
|
|
/// the canonical normalized form hel actually uses (name + mode + seq + date +
|
|
/// comment), without touching state. Returns the input unchanged if it does not
|
|
/// parse. Used by the UI to rewrite the name field on blur.
|
|
#[wasm_bindgen]
|
|
pub fn hel_parse(spec: String) -> String {
|
|
match command_parser::name(&spec) {
|
|
Ok(p) => p.to_string().trim().to_string(),
|
|
Err(_) => spec,
|
|
}
|
|
}
|
|
|
|
/// Parse a spec and return just the entry name hel resolves it to. Handles a
|
|
/// leading prefix (e.g. `*P0 test1 …` → `test1`), which a naive first-token
|
|
/// split would get wrong. Falls back to the first whitespace token.
|
|
#[wasm_bindgen]
|
|
pub fn hel_parse_name(spec: String) -> String {
|
|
match command_parser::name(&spec) {
|
|
Ok(p) => p.name,
|
|
Err(_) => spec.split_whitespace().next().unwrap_or("").to_string(),
|
|
}
|
|
}
|
|
|
|
/// Look up an entry by its exact name and return its canonical stored form
|
|
/// (`name [len]mode seq date comment ^parent`), or "" if it is not in the catalog.
|
|
/// Read-only. The UI uses this to detect "already stored" and to use the real stored
|
|
/// spec (its mode/seq/date/parent) instead of the bare name the user typed.
|
|
#[wasm_bindgen]
|
|
pub fn hel_entry(name: String) -> String {
|
|
let cell = STATE.lock();
|
|
let lk = cell.borrow();
|
|
match lk.db.get(&name).or_else(|| lk.ls.get(&name)) {
|
|
Some(p) => p.lock().borrow().to_string().trim().to_string(),
|
|
None => String::new(),
|
|
}
|
|
}
|
|
|
|
/// Run a whole multi-line script (every `add …` line, `set …`, etc.) against the
|
|
/// shared state in one call. Used to bulk-import a pasted catalog (e.g. the text
|
|
/// of the Notion page) and to load the persisted catalog from localStorage.
|
|
#[wasm_bindgen]
|
|
pub fn hel_load_script(script: String) -> String {
|
|
let out = LKOut::new();
|
|
match command_parser::script(&script) {
|
|
Ok(cmds) => {
|
|
for cmd in cmds {
|
|
let print = LKEval::new(Editor::new(), cmd, STATE.clone(), password).eval();
|
|
print.out.copy(&out);
|
|
}
|
|
}
|
|
Err(e) => out.e(format!("error: {}", e)),
|
|
}
|
|
out.output().join("\n")
|
|
}
|