Function bodies 92 total
test_fmt_source_empty_url function · rust · L744-L747 (4 LOC)src-tauri/src/commands.rs
fn test_fmt_source_empty_url() {
let s = fmt_source("VSCode", Some(""), None);
assert_eq!(s, "VSCode");
}test_tag_color_index_range function · rust · L750-L755 (6 LOC)src-tauri/src/commands.rs
fn test_tag_color_index_range() {
for tag in &["rust", "react", "ux", "design", "backend", "frontend"] {
let idx = tag_color_index(tag);
assert!(idx >= 0 && idx < 8, "Color index {} out of range for tag '{}'", idx, tag);
}
}test_format_pack_markdown function · rust · L758-L1084 (327 LOC)src-tauri/src/commands.rs
fn test_format_pack_markdown() {
let pack = ContextPack {
id: "p1".into(), title: "Test Pack".into(), description: Some("A test".into()),
constraints: Some("Be concise".into()), questions: Some("What is X?".into()),
item_ids: vec!["i1".into()], export_format: "markdown".into(),
created_at: "2026-03-28T12:00:00Z".into(), updated_at: "2026-03-28T12:00:00Z".into(),
};
let items = vec![CaptureItem {
id: "i1".into(), content: "Hello world".into(), content_type: "text".into(),
source_app: "Chrome".into(), source_url: Some("https://example.com".into()),
source_title: Some("Example".into()), tags: vec![], char_count: 11,
is_archived: false, created_at: "2026-03-28T12:00:00Z".into(), updated_at: "2026-03-28T12:00:00Z".into(),
}];
let out = format_pack(&pack, &items, "markdown");
assert!(out.contains("# Test Pack"));
assert!(out.contains("Heltest_format_pack_claude_xml function · rust · L779-L790 (12 LOC)src-tauri/src/commands.rs
fn test_format_pack_claude_xml() {
let pack = ContextPack {
id: "p1".into(), title: "XML Test".into(), description: Some("desc".into()),
constraints: None, questions: None,
item_ids: vec![], export_format: "claude".into(),
created_at: "2026-03-28T12:00:00Z".into(), updated_at: "2026-03-28T12:00:00Z".into(),
};
let out = format_pack(&pack, &[], "claude");
assert!(out.contains("<context>"));
assert!(out.contains("</context>"));
assert!(out.contains("<title>XML Test</title>"));
}make_test_db function · rust · L791-L795 (5 LOC)src-tauri/src/commands.rs
fn make_test_db() -> Database {
let dir = std::env::temp_dir().join(format!("ri-test-{}", uuid::Uuid::new_v4()));
Database::new(dir).expect("test db")
}test_db_init_and_insert function · rust · L798-L812 (15 LOC)src-tauri/src/commands.rs
fn test_db_init_and_insert() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let id = uuid::Uuid::new_v4().to_string();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, source_url, source_title, tags, char_count, is_archived, created_at, updated_at)
VALUES (?1, ?2, 'text', ?3, NULL, NULL, '[]', ?4, 0, ?5, ?6)",
rusqlite::params![id, "test content", "TestApp", 12i64, now, now],
).expect("insert");
let count: i64 = conn.query_row("SELECT COUNT(*) FROM items", [], |r| r.get(0)).unwrap();
assert_eq!(count, 1);
}test_fts_search function · rust · L815-L832 (18 LOC)src-tauri/src/commands.rs
fn test_fts_search() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let id = uuid::Uuid::new_v4().to_string();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, source_url, source_title, tags, char_count, is_archived, created_at, updated_at)
VALUES (?1, ?2, 'text', 'App', NULL, NULL, '[]', 20, 0, ?3, ?4)",
rusqlite::params![id, "unique searchable content here", now, now],
).expect("insert");
let count: i64 = conn.query_row(
"SELECT COUNT(*) FROM items i JOIN items_fts ON items_fts.rowid = i.rowid AND items_fts MATCH 'searchable'",
[], |r| r.get(0),
).unwrap();
assert_eq!(count, 1);
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
test_dedup_detection function · rust · L835-L859 (25 LOC)src-tauri/src/commands.rs
fn test_dedup_detection() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, tags, char_count, is_archived, created_at, updated_at)
VALUES ('id1', 'duplicate text', 'text', 'App', '[]', 14, 0, ?1, ?2)",
rusqlite::params![now, now],
).expect("insert");
let exists: bool = conn.query_row(
"SELECT COUNT(*) > 0 FROM (SELECT content FROM items WHERE is_archived = 0 ORDER BY created_at DESC LIMIT 100) WHERE content = ?1",
rusqlite::params!["duplicate text"],
|row| row.get(0),
).unwrap();
assert!(exists, "Should detect duplicate");
let not_exists: bool = conn.query_row(
"SELECT COUNT(*) > 0 FROM (SELECT content FROM items WHERE is_archived = 0 ORDER BY created_at DESC LIMIT 100) WHERE content = ?1",
test_archived_items_not_in_dedup function · rust · L862-L880 (19 LOC)src-tauri/src/commands.rs
fn test_archived_items_not_in_dedup() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let now = chrono::Utc::now().to_rfc3339();
// Insert as archived
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, tags, char_count, is_archived, created_at, updated_at)
VALUES ('id1', 'archived text', 'text', 'App', '[]', 13, 1, ?1, ?2)",
rusqlite::params![now, now],
).expect("insert");
let exists: bool = conn.query_row(
"SELECT COUNT(*) > 0 FROM (SELECT content FROM items WHERE is_archived = 0 ORDER BY created_at DESC LIMIT 100) WHERE content = ?1",
rusqlite::params!["archived text"],
|row| row.get(0),
).unwrap();
assert!(!exists, "Archived items should not be in dedup check");
}test_format_pack_chatgpt function · rust · L883-L901 (19 LOC)src-tauri/src/commands.rs
fn test_format_pack_chatgpt() {
let pack = ContextPack {
id: "p1".into(), title: "GPT Test".into(), description: Some("summary".into()),
constraints: Some("constraint1".into()), questions: Some("q1".into()),
item_ids: vec!["i1".into()], export_format: "chatgpt".into(),
created_at: "2026-03-28T12:00:00Z".into(), updated_at: "2026-03-28T12:00:00Z".into(),
};
let items = vec![CaptureItem {
id: "i1".into(), content: "Test content".into(), content_type: "text".into(),
source_app: "Slack".into(), source_url: None, source_title: Some("Channel".into()),
tags: vec![], char_count: 12, is_archived: false,
created_at: "2026-03-28T14:30:00Z".into(), updated_at: "2026-03-28T14:30:00Z".into(),
}];
let out = format_pack(&pack, &items, "chatgpt");
assert!(out.contains("# Context Pack: GPT Test"));
assert!(out.contains("**Summary:** summary"));
test_format_pack_cursor function · rust · L904-L915 (12 LOC)src-tauri/src/commands.rs
fn test_format_pack_cursor() {
let pack = ContextPack {
id: "p1".into(), title: "Cursor Test".into(), description: Some("bg".into()),
constraints: None, questions: None,
item_ids: vec![], export_format: "cursor".into(),
created_at: "2026-03-28T12:00:00Z".into(), updated_at: "2026-03-28T12:00:00Z".into(),
};
let out = format_pack(&pack, &[], "cursor");
assert!(out.contains("# Project Context: Cursor Test"));
assert!(out.contains("## Background"));
assert!(out.contains("None specified"));
}test_format_pack_empty_title function · rust · L918-L927 (10 LOC)src-tauri/src/commands.rs
fn test_format_pack_empty_title() {
let pack = ContextPack {
id: "p1".into(), title: "".into(), description: None,
constraints: None, questions: None,
item_ids: vec![], export_format: "markdown".into(),
created_at: "2026-03-28T12:00:00Z".into(), updated_at: "2026-03-28T12:00:00Z".into(),
};
let out = format_pack(&pack, &[], "markdown");
assert!(out.contains("# Context Pack"), "Empty title should use fallback");
}test_tags_table function · rust · L930-L948 (19 LOC)src-tauri/src/commands.rs
fn test_tags_table() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO tags (name, use_count, last_used_at, color_index) VALUES ('test-tag', 1, ?1, 3)",
rusqlite::params![now],
).expect("insert tag");
// Upsert same tag
conn.execute(
"INSERT INTO tags (name, use_count, last_used_at, color_index) VALUES ('test-tag', 1, ?1, 3) ON CONFLICT(name) DO UPDATE SET use_count = use_count + 1",
rusqlite::params![now],
).expect("upsert tag");
let count: i64 = conn.query_row("SELECT use_count FROM tags WHERE name = 'test-tag'", [], |r| r.get(0)).unwrap();
assert_eq!(count, 2, "Tag use_count should be incremented on upsert");
}test_packs_table_crud function · rust · L951-L972 (22 LOC)src-tauri/src/commands.rs
fn test_packs_table_crud() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO packs (id, title, description, constraints_text, questions, item_ids, export_format, created_at, updated_at) VALUES ('p1', 'Test', 'Desc', NULL, NULL, '[\"i1\",\"i2\"]', 'markdown', ?1, ?2)",
rusqlite::params![now, now],
).expect("insert pack");
let title: String = conn.query_row("SELECT title FROM packs WHERE id = 'p1'", [], |r| r.get(0)).unwrap();
assert_eq!(title, "Test");
let item_ids: String = conn.query_row("SELECT item_ids FROM packs WHERE id = 'p1'", [], |r| r.get(0)).unwrap();
let ids: Vec<String> = serde_json::from_str(&item_ids).unwrap();
assert_eq!(ids, vec!["i1", "i2"]);
// Delete
conn.execute("DELETE FROM packs WHERE id = 'p1'", []).expect("delete");
let count: i64 = conn.query_rowtest_settings_table function · rust · L975-L990 (16 LOC)src-tauri/src/commands.rs
fn test_settings_table() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
conn.execute(
"INSERT INTO settings (key, value) VALUES ('theme', 'dark')", [],
).expect("insert");
// Upsert
conn.execute(
"INSERT INTO settings (key, value) VALUES ('theme', 'light') ON CONFLICT(key) DO UPDATE SET value = 'light'", [],
).expect("upsert");
let val: String = conn.query_row("SELECT value FROM settings WHERE key = 'theme'", [], |r| r.get(0)).unwrap();
assert_eq!(val, "light");
}Repobility · code-quality intelligence · https://repobility.com
test_fts_update_sync function · rust · L993-L1024 (32 LOC)src-tauri/src/commands.rs
fn test_fts_update_sync() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, tags, char_count, is_archived, created_at, updated_at)
VALUES ('u1', 'original content xyz', 'text', 'App', '[]', 20, 0, ?1, ?2)",
rusqlite::params![now, now],
).expect("insert");
// FTS should find original
let count: i64 = conn.query_row(
"SELECT COUNT(*) FROM items_fts WHERE items_fts MATCH 'xyz'", [], |r| r.get(0),
).unwrap();
assert_eq!(count, 1);
// Update content
conn.execute("UPDATE items SET content = 'updated content abc' WHERE id = 'u1'", []).expect("update");
// FTS should find new content
let count_new: i64 = conn.query_row(
"SELECT COUNT(*) FROM items_fts WHERE items_fts MATCH 'abc'", [], |r| r.get(0)test_fts_delete_sync function · rust · L1027-L1044 (18 LOC)src-tauri/src/commands.rs
fn test_fts_delete_sync() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
let now = chrono::Utc::now().to_rfc3339();
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, tags, char_count, is_archived, created_at, updated_at)
VALUES ('d1', 'deletable content zzz', 'text', 'App', '[]', 21, 0, ?1, ?2)",
rusqlite::params![now, now],
).expect("insert");
conn.execute("DELETE FROM items WHERE id = 'd1'", []).expect("delete");
let count: i64 = conn.query_row(
"SELECT COUNT(*) FROM items_fts WHERE items_fts MATCH 'zzz'", [], |r| r.get(0),
).unwrap();
assert_eq!(count, 0, "FTS should be cleaned up after delete");
}test_fmt_time_edge_cases function · rust · L1047-L1055 (9 LOC)src-tauri/src/commands.rs
fn test_fmt_time_edge_cases() {
// December
assert_eq!(fmt_time("2026-12-25T00:00:00Z"), "Dec 25, 00:00");
// Single digit day
assert_eq!(fmt_time("2026-03-01T23:59:00Z"), "Mar 1, 23:59");
// Very short string
assert_eq!(fmt_time(""), "");
assert_eq!(fmt_time("2026"), "2026");
}test_tag_color_deterministic function · rust · L1058-L1063 (6 LOC)src-tauri/src/commands.rs
fn test_tag_color_deterministic() {
// Same tag should always give same color
let c1 = tag_color_index("research");
let c2 = tag_color_index("research");
assert_eq!(c1, c2, "Same tag must produce same color index");
}test_multiple_items_ordering function · rust · L1066-L1083 (18 LOC)src-tauri/src/commands.rs
fn test_multiple_items_ordering() {
let db = make_test_db();
let conn = db.conn.lock().unwrap();
for i in 0..5 {
let now = format!("2026-03-28T{:02}:00:00Z", 10 + i);
conn.execute(
"INSERT INTO items (id, content, content_type, source_app, tags, char_count, is_archived, created_at, updated_at)
VALUES (?1, ?2, 'text', 'App', '[]', 10, 0, ?3, ?4)",
rusqlite::params![format!("id{}", i), format!("item {}", i), now, now],
).expect("insert");
}
// Query ordered by created_at DESC
let mut stmt = conn.prepare("SELECT id FROM items ORDER BY created_at DESC LIMIT 5").unwrap();
let ids: Vec<String> = stmt.query_map([], |r| r.get(0)).unwrap().filter_map(|r| r.ok()).collect();
assert_eq!(ids, vec!["id4", "id3", "id2", "id1", "id0"], "Items should be newest first");
}new function · rust · L10-L22 (13 LOC)src-tauri/src/db.rs
pub fn new(data_dir: PathBuf) -> Result<Self, String> {
std::fs::create_dir_all(&data_dir).map_err(|e| e.to_string())?;
let db_path = data_dir.join("data.db");
let conn = Connection::open(&db_path).map_err(|e| e.to_string())?;
// Enable WAL mode
conn.execute_batch("PRAGMA journal_mode=WAL;").map_err(|e| e.to_string())?;
// Run migrations
Self::migrate(&conn)?;
Ok(Self { conn: Mutex::new(conn) })
}migrate function · rust · L23-L113 (91 LOC)src-tauri/src/db.rs
fn migrate(conn: &Connection) -> Result<(), String> {
conn.execute_batch(
"
CREATE TABLE IF NOT EXISTS items (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
content_type TEXT NOT NULL DEFAULT 'text',
source_app TEXT NOT NULL DEFAULT 'Unknown',
source_url TEXT,
source_title TEXT,
tags TEXT NOT NULL DEFAULT '[]',
char_count INTEGER NOT NULL DEFAULT 0,
is_archived INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_items_created_at ON items(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_items_is_archived ON items(is_archived);
CREATE INDEX IF NOT EXISTS idx_items_source_app ON items(source_app);
CREATE TABLE IF NOT EXISTS tags (
name TEXT PRIMdbg function · rust · L14-L22 (9 LOC)src-tauri/src/lib.rs
fn dbg(msg: &str) {
let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
let path = format!("{}/.research-inbox/debug.log", home);
if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open(&path) {
let _ = writeln!(f, "{}", msg);
let _ = f.flush();
}
}Repobility · open methodology · https://repobility.com/research/
run function · rust · L25-L118 (94 LOC)src-tauri/src/lib.rs
pub fn run() {
let data_dir = dirs_data_dir();
let database = Database::new(data_dir).expect("Failed to initialize database");
tauri::Builder::default()
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_fs::init())
.manage(database)
.setup(|app| {
dbg("STARTUP");
// System tray menu
let capture_item = MenuItemBuilder::with_id("capture", "Capture ⇧⌘S").build(app)?;
let sep1 = PredefinedMenuItem::separator(app)?;
let show_item = MenuItemBuilder::with_id("show", "Open Inbox").build(app)?;
let sep2 = PredefinedMenuItem::separator(app)?;
let quit_item = MenuItemBuilder::with_id("quit", "Quit Research Inbox").build(app)?;
let menu = MenuBuilder::new(app)
.item(&capture_item)
.item(&sep1)do_capture_flow function · rust · L127-L184 (58 LOC)src-tauri/src/lib.rs
fn do_capture_flow(app: &AppHandle) {
use std::process::Command;
dbg("do_capture_flow");
// 1. Detect foreground app NOW
let app_info = source_detect::get_foreground_app();
dbg(&format!("app: {}", app_info.app_name));
// 2. Snapshot old clipboard via same binary (consistent comparison)
let old_clip = read_clipboard_rich();
dbg(&format!("old: text_len={}, images={}", old_clip.text.len(), old_clip.image_paths.len()));
// 3. Simulate ⌘C
simulate_cmd_c();
std::thread::sleep(std::time::Duration::from_millis(300));
// 4. Read clipboard again (including HTML images)
let clip = read_clipboard_rich();
dbg(&format!("new: text_len={}, images={}", clip.text.len(), clip.image_paths.len()));
// Did clipboard change? (text changed OR new images appeared)
let has_new_content = clip.text != old_clip.text
|| (!clip.image_paths.is_empty() && clip.image_paths != old_clip.image_paths);
dbg(&format!("has_new_content: {}", has_simulate_cmd_c function · rust · L188-L231 (44 LOC)src-tauri/src/lib.rs
fn simulate_cmd_c() {
dbg("simulate_cmd_c: CGEvent in-process");
#[cfg(target_os = "macos")]
{
#[link(name = "CoreGraphics", kind = "framework")]
#[link(name = "CoreFoundation", kind = "framework")]
extern "C" {
fn CGEventSourceCreate(stateID: i32) -> *mut std::ffi::c_void;
fn CGEventCreateKeyboardEvent(source: *mut std::ffi::c_void, keycode: u16, key_down: bool) -> *mut std::ffi::c_void;
fn CGEventSetFlags(event: *mut std::ffi::c_void, flags: u64);
fn CGEventPost(tap: u32, event: *mut std::ffi::c_void);
fn CFRelease(cf: *mut std::ffi::c_void);
}
unsafe {
// Use HIDSystemState (1) — this source type is what Maccy uses for synthetic input
let source = CGEventSourceCreate(1);
dbg(&format!("CGEvent source null: {}", source.is_null()));
let key_c: u16 = 8;
let cmd_flag: u64 = 0x00100000; // kCGEventFlagMaskCommand
read_clipboard_rich function · rust · L240-L264 (25 LOC)src-tauri/src/lib.rs
fn read_clipboard_rich() -> ClipboardContent {
use std::process::Command;
let binary = find_script("clipboard_read");
let home = std::env::var("HOME").unwrap_or_else(|_| ".".into());
let images_dir = format!("{}/.research-inbox/images", home);
let output = Command::new(&binary).arg(&images_dir).output();
match output {
Ok(o) if o.status.success() => {
let json_str = String::from_utf8_lossy(&o.stdout);
if let Ok(v) = serde_json::from_str::<serde_json::Value>(&json_str) {
let text = v["text"].as_str().unwrap_or("").to_string();
let image_paths: Vec<String> = v["image_paths"].as_array()
.map(|arr| arr.iter().filter_map(|p| p.as_str().map(|s| s.to_string())).collect())
.unwrap_or_default();
return ClipboardContent { text, image_paths };
}
}
Ok(o) => { dbg(&format!("clipboard_read failed: {}", String::from_utf8_lossy(&oget_clipboard_text_only function · rust · L267-L272 (6 LOC)src-tauri/src/lib.rs
fn get_clipboard_text_only() -> Option<String> {
use std::process::Command;
let output = Command::new("pbpaste").output().ok()?;
let text = String::from_utf8_lossy(&output.stdout).to_string();
if text.is_empty() { None } else { Some(text) }
}request_input_monitoring function · rust · L278-L314 (37 LOC)src-tauri/src/lib.rs
fn request_input_monitoring() {
#[cfg(target_os = "macos")]
{
#[link(name = "CoreGraphics", kind = "framework")]
extern "C" {
fn CGEventTapCreate(
tap: u32, place: u32, options: u32,
events_of_interest: u64,
callback: extern "C" fn(u32, u32, *mut std::ffi::c_void, *mut std::ffi::c_void) -> *mut std::ffi::c_void,
user_info: *mut std::ffi::c_void,
) -> *mut std::ffi::c_void;
fn CFRelease(cf: *mut std::ffi::c_void);
}
extern "C" fn dummy_callback(_: u32, _: u32, event: *mut std::ffi::c_void, _: *mut std::ffi::c_void) -> *mut std::ffi::c_void {
event
}
unsafe {
let key_down_mask: u64 = 1 << 10; // kCGEventKeyDown
let tap = CGEventTapCreate(
1, // kCGSessionEventTap
0, // kCGHeadInsertEventTap
1, // kCGEventTapOptionListenOnly
key_down_mdummy_callback function · rust · L291-L294 (4 LOC)src-tauri/src/lib.rs
extern "C" fn dummy_callback(_: u32, _: u32, event: *mut std::ffi::c_void, _: *mut std::ffi::c_void) -> *mut std::ffi::c_void {
event
}find_script function · rust · L315-L324 (10 LOC)src-tauri/src/lib.rs
fn find_script(name: &str) -> String {
let exe = std::env::current_exe().unwrap_or_default();
let exe_dir = exe.parent().unwrap_or(std::path::Path::new("."));
let bundle = exe_dir.parent().unwrap_or(exe_dir).join("Resources").join("scripts").join(name);
if bundle.exists() { return bundle.to_string_lossy().to_string(); }
let dev = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts").join(name);
if dev.exists() { return dev.to_string_lossy().to_string(); }
name.to_string()
}Want this analysis on your repo? https://repobility.com/scan/
toggle_panel function · rust · L325-L336 (12 LOC)src-tauri/src/lib.rs
fn toggle_panel(app: &AppHandle) {
if let Some(w) = app.get_webview_window("panel") {
if w.is_visible().unwrap_or(false) {
let _ = w.hide();
} else {
let _ = w.show();
let _ = w.set_focus();
}
}
}dirs_data_dir function · rust · L337-L343 (7 LOC)src-tauri/src/lib.rs
fn dirs_data_dir() -> std::path::PathBuf {
let home = std::env::var("HOME")
.or_else(|_| std::env::var("USERPROFILE"))
.unwrap_or_else(|_| ".".to_string());
std::path::PathBuf::from(home).join(".research-inbox")
}main function · rust · L3-L6 (4 LOC)src-tauri/src/main.rs
fn main() {
app_lib::run();
}default function · rust · L60-L72 (13 LOC)src-tauri/src/models.rs
fn default() -> Self {
Self {
capture_hotkey: "Alt+Super+C".to_string(),
panel_hotkey: "Alt+Super+R".to_string(),
quick_tag_on_capture: false,
default_export_format: "markdown".to_string(),
max_capture_size_kb: 50,
launch_at_login: true,
theme: "system".to_string(),
language: "en".to_string(),
data_location: "~/.research-inbox/".to_string(),
}
}get_foreground_app function · rust · L4-L33 (30 LOC)src-tauri/src/source_detect.rs
pub fn get_foreground_app() -> AppInfo {
use std::process::Command;
// Use osascript for reliable app name + window title detection
let app_name = Command::new("osascript")
.arg("-e")
.arg(r#"tell application "System Events" to get name of first application process whose frontmost is true"#)
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.unwrap_or_else(|| "Unknown".to_string());
let window_title = Command::new("osascript")
.arg("-e")
.arg(r#"tell application "System Events" to get title of front window of first application process whose frontmost is true"#)
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.unwrap_or_default();
let url_from_title = extract_url_from_title(&window_title, &app_name);
AppInfo {
app_name,
window_title,
uget_foreground_app function · rust · L36-L42 (7 LOC)src-tauri/src/source_detect.rs
pub fn get_foreground_app() -> AppInfo {
AppInfo {
app_name: "Unknown".to_string(),
window_title: String::new(),
url_from_title: None,
}
}extract_url_from_title function · rust · L43-L63 (21 LOC)src-tauri/src/source_detect.rs
pub fn extract_url_from_title(title: &str, app_name: &str) -> Option<String> {
let browsers = ["Google Chrome", "Chrome", "Arc", "Safari", "Firefox", "Edge", "Brave", "Opera", "Vivaldi"];
if !browsers.iter().any(|b| app_name.contains(b)) {
return None;
}
// Try to extract URL from window title
for word in title.split_whitespace() {
if (word.starts_with("http://") || word.starts_with("https://")) && word.contains('.') {
return Some(word.to_string());
}
}
// Some browsers show "Page Title - domain.com - Browser"
let parts: Vec<&str> = title.split(" - ").collect();
for part in parts.iter().rev() {
let trimmed = part.trim();
if trimmed.contains('.') && !trimmed.contains(' ') && trimmed.len() > 3 {
return Some(format!("https://{}", trimmed));
}
}test_extract_url_from_chrome_title function · rust · L72-L98 (27 LOC)src-tauri/src/source_detect.rs
fn test_extract_url_from_chrome_title() {
// "google/zx" has a slash so it's not detected as domain — correct behavior
let url = extract_url_from_title("GitHub - google/zx - Google Chrome", "Google Chrome");
assert_eq!(url, None);
// Real domain in title
let url = extract_url_from_title("My Page - example.com - Google Chrome", "Google Chrome");
assert_eq!(url, Some("https://example.com".to_string()));
}
#[test]
fn test_extract_url_with_https() {
let url = extract_url_from_title("My Page https://example.com/page", "Google Chrome");
assert_eq!(url, Some("https://example.com/page".to_string()));
}
#[test]
fn test_no_url_for_non_browser() {
let url = extract_url_from_title("Some Window Title", "Telegram");
assert_eq!(url, None);
}
#[test]
fn test_extract_url_arc() {
let url = extract_url_from_title("docs.rs - Arc", "Arc");
assert_eq!(url, Some("https:/Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
test_extract_url_with_https function · rust · L83-L86 (4 LOC)src-tauri/src/source_detect.rs
fn test_extract_url_with_https() {
let url = extract_url_from_title("My Page https://example.com/page", "Google Chrome");
assert_eq!(url, Some("https://example.com/page".to_string()));
}test_no_url_for_non_browser function · rust · L89-L92 (4 LOC)src-tauri/src/source_detect.rs
fn test_no_url_for_non_browser() {
let url = extract_url_from_title("Some Window Title", "Telegram");
assert_eq!(url, None);
}test_no_url_for_plain_title function · rust · L101-L104 (4 LOC)src-tauri/src/source_detect.rs
fn test_no_url_for_plain_title() {
let url = extract_url_from_title("My Document", "Google Chrome");
assert_eq!(url, None);
}‹ prevpage 2 / 2