mirror of
https://github.com/ByteAtATime/raycast-linux.git
synced 2025-09-08 15:10:34 +00:00
feat(snippets): add import snippet feature
Currently, our application does not support snippets without keywords. We will have to figure out why it's possible to have a text replacement item without the text to replace.
This commit is contained in:
parent
15dbf0692a
commit
56813684e1
16 changed files with 433 additions and 114 deletions
|
@ -20,10 +20,7 @@ pub struct ExpansionEngine {
|
|||
}
|
||||
|
||||
impl ExpansionEngine {
|
||||
pub fn new(
|
||||
snippet_manager: Arc<SnippetManager>,
|
||||
input_manager: Arc<dyn InputManager>,
|
||||
) -> Self {
|
||||
pub fn new(snippet_manager: Arc<SnippetManager>, input_manager: Arc<dyn InputManager>) -> Self {
|
||||
Self {
|
||||
buffer: Arc::new(Mutex::new(String::with_capacity(BUFFER_SIZE))),
|
||||
snippet_manager,
|
||||
|
@ -33,8 +30,7 @@ impl ExpansionEngine {
|
|||
|
||||
pub fn start_listening(&self) -> anyhow::Result<()> {
|
||||
let engine = Arc::new(self.clone_for_thread());
|
||||
self.input_manager
|
||||
.start_listening(Box::new(move |event| {
|
||||
self.input_manager.start_listening(Box::new(move |event| {
|
||||
engine.handle_key_press(event);
|
||||
}))?;
|
||||
Ok(())
|
||||
|
|
|
@ -47,8 +47,7 @@ impl InputManager for RdevInputManager {
|
|||
let callback_clone = callback.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
let cb = move |event: rdev::Event| {
|
||||
match event.event_type {
|
||||
let cb = move |event: rdev::Event| match event.event_type {
|
||||
rdev::EventType::KeyPress(key) => {
|
||||
if key == Key::ShiftLeft || key == Key::ShiftRight {
|
||||
*shift_clone_press.lock().unwrap() = true;
|
||||
|
@ -64,7 +63,6 @@ impl InputManager for RdevInputManager {
|
|||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
};
|
||||
if let Err(error) = rdev::listen(cb) {
|
||||
eprintln!("rdev error: {:?}", error)
|
||||
|
@ -387,7 +385,7 @@ impl InputManager for EvdevInputManager {
|
|||
}
|
||||
_ => {
|
||||
xkb_state.update_key(keycode.into(), direction);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,9 @@ impl SnippetManager {
|
|||
})
|
||||
})?;
|
||||
|
||||
snippets_iter.collect::<Result<Vec<_>, _>>().map_err(|e| e.into())
|
||||
snippets_iter
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
pub fn update_snippet(
|
||||
|
|
|
@ -3,9 +3,26 @@ pub mod input_manager;
|
|||
pub mod manager;
|
||||
pub mod types;
|
||||
|
||||
use crate::error::AppError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{AppHandle, Manager};
|
||||
use types::Snippet;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct ImportSnippet {
|
||||
name: String,
|
||||
text: String,
|
||||
keyword: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ImportResult {
|
||||
snippets_added: u32,
|
||||
duplicates_skipped: u32,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn create_snippet(
|
||||
app: AppHandle,
|
||||
|
@ -43,4 +60,33 @@ pub fn delete_snippet(app: AppHandle, id: i64) -> Result<(), String> {
|
|||
app.state::<manager::SnippetManager>()
|
||||
.delete_snippet(id)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
#[tauri::command]
|
||||
pub fn import_snippets(app: AppHandle, json_content: String) -> Result<ImportResult, String> {
|
||||
let snippets: Vec<ImportSnippet> =
|
||||
serde_json::from_str(&json_content).map_err(|e| e.to_string())?;
|
||||
|
||||
let manager = app.state::<manager::SnippetManager>();
|
||||
let mut snippets_added = 0;
|
||||
let mut duplicates_skipped = 0;
|
||||
|
||||
for snippet in snippets {
|
||||
let keyword = snippet.keyword;
|
||||
|
||||
match manager.create_snippet(snippet.name, keyword, snippet.text) {
|
||||
Ok(_) => snippets_added += 1,
|
||||
Err(AppError::Rusqlite(rusqlite::Error::SqliteFailure(e, Some(msg))))
|
||||
if e.code == rusqlite::ErrorCode::ConstraintViolation
|
||||
&& msg.contains("UNIQUE constraint failed: snippets.keyword") =>
|
||||
{
|
||||
duplicates_skipped += 1;
|
||||
}
|
||||
Err(e) => return Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ImportResult {
|
||||
snippets_added,
|
||||
duplicates_skipped,
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue