mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 00:45:54 +00:00
71 lines
2.5 KiB
Rust
71 lines
2.5 KiB
Rust
//! Sample OpenIDEA plugin. Build with `../build.sh hello` (see plugins/README.md).
|
|
|
|
wit_bindgen::generate!({
|
|
world: "plugin",
|
|
path: "../../wit",
|
|
});
|
|
|
|
use openidea::plugin::host::{self, LogLevel, NotificationLevel};
|
|
|
|
struct Hello;
|
|
|
|
impl Guest for Hello {
|
|
fn activate(ctx: Context) -> Result<(), String> {
|
|
host::log(LogLevel::Info, &format!("hello {} activated", ctx.plugin_version));
|
|
host::register_command("insert-date", "Hello: Insert Date", Some("Hello"));
|
|
host::register_command("word-count", "Hello: Word Count of Active File", Some("Hello"));
|
|
Ok(())
|
|
}
|
|
|
|
fn deactivate() {
|
|
host::log(LogLevel::Info, "hello deactivated");
|
|
}
|
|
|
|
fn run_command(id: String, _arg: Option<String>) -> Result<Option<String>, String> {
|
|
match id.as_str() {
|
|
"insert-date" => {
|
|
let date = today();
|
|
host::insert_text(&date);
|
|
Ok(Some(date))
|
|
}
|
|
"word-count" => {
|
|
let path = host::active_file().ok_or("no file is open in the editor")?;
|
|
let text = host::read_file(&path)?;
|
|
let words = text.split_whitespace().count();
|
|
let lines = text.lines().count();
|
|
let name = path.rsplit(['/', '\\']).next().unwrap_or(&path);
|
|
let body = format!("{words} words, {lines} lines, {} characters", text.chars().count());
|
|
host::show_notification(NotificationLevel::Info, &format!("Word count: {name}"), &body);
|
|
Ok(Some(body))
|
|
}
|
|
other => Err(format!("unknown command: {other}")),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Today's UTC date as `YYYY-MM-DD` (WASI wall clock).
|
|
fn today() -> String {
|
|
let secs = std::time::SystemTime::now()
|
|
.duration_since(std::time::UNIX_EPOCH)
|
|
.map(|d| d.as_secs() as i64)
|
|
.unwrap_or(0);
|
|
let (y, m, d) = civil_from_days(secs.div_euclid(86_400));
|
|
format!("{y:04}-{m:02}-{d:02}")
|
|
}
|
|
|
|
/// Howard Hinnant's days-to-civil algorithm.
|
|
fn civil_from_days(z: i64) -> (i64, u32, u32) {
|
|
let z = z + 719_468;
|
|
let era = z.div_euclid(146_097);
|
|
let doe = z.rem_euclid(146_097);
|
|
let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365;
|
|
let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
|
|
let mp = (5 * doy + 2) / 153;
|
|
let d = (doy - (153 * mp + 2) / 5 + 1) as u32;
|
|
let m = if mp < 10 { mp + 3 } else { mp - 9 } as u32;
|
|
let y = yoe + era * 400 + i64::from(m <= 2);
|
|
(y, m, d)
|
|
}
|
|
|
|
export!(Hello);
|