Skip to content

Commit 237290b

Browse files
committed
updated test3
1 parent 0cfcd59 commit 237290b

6 files changed

Lines changed: 100 additions & 75 deletions

File tree

src/checker.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use crate::dictionary::{Dictionary, DictionaryManager};
22
use crate::language::Language;
3-
use crate::util::{is_cjk_text, sanitize_word};
3+
use crate::util::sanitize_word;
44
use dashmap::DashMap;
55
use rayon::prelude::*;
66
use serde::Serialize;
77
use std::collections::HashSet;
8-
use std::fs::{self, File};
9-
use std::io::Write;
8+
use std::fs;
109
use std::path::Path;
1110
use std::sync::Arc;
1211
use std::cmp::min;
@@ -42,7 +41,6 @@ pub struct SpellChecker {
4241
max_suggestions: usize,
4342
cache: Arc<DashMap<String, bool>>,
4443
ignore_list: HashSet<String>,
45-
user_dictionary_path: Option<String>,
4644
}
4745

4846
impl SpellChecker {
@@ -64,7 +62,6 @@ impl SpellChecker {
6462
max_suggestions: 5,
6563
cache: Arc::new(DashMap::new()),
6664
ignore_list: HashSet::new(),
67-
user_dictionary_path: None,
6865
})
6966
}
7067

@@ -116,7 +113,6 @@ impl SpellChecker {
116113

117114
for (line_idx, line) in lines.iter().enumerate() {
118115
let line_num = line_idx + 1;
119-
let mut line_offset = 0;
120116

121117
for mat in word_pattern.find_iter(line) {
122118
let word = mat.as_str();
@@ -128,8 +124,8 @@ impl SpellChecker {
128124
if self.ignore_list.contains(&word_lower) {
129125
words.push(WordCheck {
130126
word: word.to_string(),
131-
start: line_offset + start,
132-
end: line_offset + end,
127+
start,
128+
end,
133129
is_correct: true,
134130
suggestions: Vec::new(),
135131
line: line_num,
@@ -163,16 +159,14 @@ impl SpellChecker {
163159

164160
words.push(WordCheck {
165161
word: word.to_string(),
166-
start: line_offset + start,
167-
end: line_offset + end,
162+
start,
163+
end,
168164
is_correct,
169165
suggestions,
170166
line: line_num,
171167
column: start + 1,
172168
});
173169
}
174-
175-
line_offset += line.len() + 1; // +1 for newline character
176170
}
177171

178172
let accuracy = if total_words > 0 {
@@ -303,7 +297,7 @@ impl SpellChecker {
303297
self.cache.clear(); // Clear cache since ignore status changed
304298
}
305299

306-
pub fn import_dictionary(&self, path: &Path) -> anyhow::Result<()> {
300+
pub fn import_dictionary(&mut self, path: &Path) -> anyhow::Result<()> {
307301
// Read the file to detect language or use current language
308302
let content = fs::read_to_string(path)?;
309303

@@ -316,7 +310,7 @@ impl SpellChecker {
316310
};
317311

318312
// Import dictionary
319-
self.dictionary_manager.import_dictionary(path, language_to_use)?;
313+
self.dictionary_manager.import_dictionary(path.to_path_buf(), language_to_use)?;
320314

321315
// Clear cache since dictionary changed
322316
self.cache.clear();

src/dictionary.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
use crate::language::{Language, LanguageManager};
22
use dashmap::DashMap;
3-
use rayon::prelude::*;
43
use regex::Regex;
54
use std::collections::HashSet;
6-
use std::fs::{self, File};
5+
use std::fs::File;
76
use std::io::{BufRead, BufReader, Write};
87
use std::path::{Path, PathBuf};
98
use std::sync::Arc;
10-
use once_cell::sync::Lazy;
119

1210
#[derive(Debug, Clone)]
1311
pub struct Dictionary {
@@ -414,8 +412,8 @@ impl DictionaryManager {
414412
}
415413
}
416414

417-
pub fn import_dictionary(&mut self, path: &Path, language: Language) -> anyhow::Result<()> {
418-
self.add_custom_dictionary(path.to_path_buf(), language)
415+
pub fn import_dictionary(&mut self, path: PathBuf, language: Language) -> anyhow::Result<()> {
416+
self.add_custom_dictionary(path, language)
419417
}
420418

421419
pub fn export_dictionary(&self, language: &Language, path: &Path) -> anyhow::Result<()> {

src/editor.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use crate::checker::{DocumentAnalysis, WordCheck};
22
use eframe::egui;
3-
use std::collections::HashMap;
43

54
#[derive(Clone)]
65
pub struct TextEditor {
76
line_height: f32,
87
font_size: f32,
98
show_whitespace: bool,
109
wrap_lines: bool,
11-
char_width_cache: HashMap<char, f32>,
12-
error_cache: HashMap<usize, WordCheck>,
10+
char_width_cache: std::collections::HashMap<char, f32>,
11+
error_cache: std::collections::HashMap<usize, WordCheck>,
1312
last_analysis: Option<DocumentAnalysis>,
1413
}
1514

@@ -26,8 +25,8 @@ impl TextEditor {
2625
font_size: 14.0,
2726
show_whitespace: false,
2827
wrap_lines: true,
29-
char_width_cache: HashMap::new(),
30-
error_cache: HashMap::new(),
28+
char_width_cache: std::collections::HashMap::new(),
29+
error_cache: std::collections::HashMap::new(),
3130
last_analysis: None,
3231
}
3332
}
@@ -69,7 +68,7 @@ impl TextEditor {
6968
};
7069

7170
// Create a custom widget for the editor
72-
let (rect, response) = ui.allocate_exact_size(
71+
let (rect, _response) = ui.allocate_exact_size(
7372
egui::vec2(available_rect.width(), available_rect.height()),
7473
egui::Sense::click_and_drag(),
7574
);
@@ -116,7 +115,7 @@ impl TextEditor {
116115
fn draw_line_numbers(&self, ui: &egui::Ui, rect: egui::Rect, content: &str) {
117116
let painter = ui.painter();
118117
let line_count = content.lines().count().max(1);
119-
let line_number_color = ui.visuals().weak_text_color;
118+
let line_number_color = ui.visuals().weak_text_color();
120119

121120
for i in 0..line_count {
122121
let line_y = rect.top() + (i as f32 * self.line_height) + (self.line_height * 0.75);

src/gui.rs

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::editor::TextEditor;
33
use crate::language::{Language, LanguageManager};
44
use crate::sidebar::Sidebar;
55
use crate::theme::AtomTheme;
6-
use crate::{get_app_info, open_repository, open_sponsor_page};
6+
use crate::{open_repository, open_sponsor_page};
77
use eframe::egui;
88
use rfd::FileDialog;
99
use std::path::PathBuf;
@@ -164,20 +164,21 @@ impl SpellCheckerApp {
164164
}
165165

166166
// Perform spell check
167-
if let Ok(checker) = self.spell_checker.lock() {
168-
self.analysis = Some(checker.check_document(&self.state.document_content));
169-
if let Some(analysis) = &self.analysis {
170-
self.stats.total_words = analysis.total_words;
171-
self.stats.errors = analysis.misspelled_words;
172-
self.stats.last_check_duration = start_time.elapsed();
173-
self.stats.check_count += 1;
174-
175-
// Update text editor with analysis for highlighting
176-
self.text_editor.set_analysis(analysis.clone());
177-
self.last_spell_check = Some(analysis.clone());
178-
self.last_check_time = Instant::now();
179-
}
180-
}
167+
let analysis = {
168+
let checker = self.spell_checker.lock().unwrap();
169+
checker.check_document(&self.state.document_content)
170+
};
171+
172+
self.analysis = Some(analysis.clone());
173+
self.stats.total_words = analysis.total_words;
174+
self.stats.errors = analysis.misspelled_words;
175+
self.stats.last_check_duration = start_time.elapsed();
176+
self.stats.check_count += 1;
177+
178+
// Update text editor with analysis for highlighting
179+
self.text_editor.set_analysis(analysis.clone());
180+
self.last_spell_check = Some(analysis);
181+
self.last_check_time = Instant::now();
181182
}
182183

183184
fn open_file(&mut self, path: PathBuf) -> anyhow::Result<()> {
@@ -269,22 +270,24 @@ impl SpellCheckerApp {
269270
fn handle_pending_actions(&mut self) {
270271
// Handle adding words to dictionary
271272
if let Some(word) = self.pending_add_word.take() {
272-
if let Ok(mut checker) = self.spell_checker.lock() {
273+
{
274+
let mut checker = self.spell_checker.lock().unwrap();
273275
if checker.add_word_to_dictionary(&word).is_ok() {
274276
println!("Added word to dictionary: {}", word);
275-
self.check_spelling(); // Re-check with updated dictionary
276277
}
277278
}
279+
self.check_spelling(); // Re-check with updated dictionary
278280
}
279281

280282
// Handle ignoring words
281283
if let Some(word) = self.pending_ignore_word.take() {
282-
if let Ok(mut checker) = self.spell_checker.lock() {
284+
{
285+
let mut checker = self.spell_checker.lock().unwrap();
283286
if checker.ignore_word(&word).is_ok() {
284287
println!("Ignored word: {}", word);
285-
self.check_spelling(); // Re-check with updated ignore list
286288
}
287289
}
290+
self.check_spelling(); // Re-check with updated ignore list
288291
}
289292

290293
// Handle word replacement
@@ -304,14 +307,15 @@ impl SpellCheckerApp {
304307
.set_directory(self.state.last_directory.clone().unwrap_or_else(|| PathBuf::from(".")))
305308
.pick_file()
306309
{
307-
if let Ok(mut checker) = self.spell_checker.lock() {
310+
{
311+
let mut checker = self.spell_checker.lock().unwrap();
308312
if let Err(e) = checker.import_dictionary(&path) {
309313
eprintln!("Failed to import dictionary: {}", e);
310314
} else {
311315
println!("Imported dictionary from: {:?}", path);
312-
self.check_spelling();
313316
}
314317
}
318+
self.check_spelling();
315319
}
316320
}
317321

@@ -325,7 +329,8 @@ impl SpellCheckerApp {
325329
.set_directory(self.state.last_directory.clone().unwrap_or_else(|| PathBuf::from(".")))
326330
.save_file()
327331
{
328-
if let Ok(checker) = self.spell_checker.lock() {
332+
{
333+
let checker = self.spell_checker.lock().unwrap();
329334
if let Err(e) = checker.export_dictionary(&path) {
330335
eprintln!("Failed to export dictionary: {}", e);
331336
} else {
@@ -338,16 +343,19 @@ impl SpellCheckerApp {
338343
// Handle clear ignored words
339344
if self.pending_clear_ignored {
340345
self.pending_clear_ignored = false;
341-
if let Ok(mut checker) = self.spell_checker.lock() {
346+
{
347+
let mut checker = self.spell_checker.lock().unwrap();
342348
checker.clear_ignored_words();
343-
self.check_spelling();
344349
}
350+
self.check_spelling();
345351
}
346352
}
347353

348354
fn show_about_dialog(&mut self, ctx: &egui::Context) {
355+
let mut show_about = self.state.show_about;
356+
349357
egui::Window::new("About AtomSpell")
350-
.open(&mut self.state.show_about)
358+
.open(&mut show_about)
351359
.resizable(false)
352360
.collapsible(false)
353361
.anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
@@ -385,6 +393,8 @@ impl SpellCheckerApp {
385393
});
386394
});
387395
});
396+
397+
self.state.show_about = show_about;
388398
}
389399

390400
fn show_menu_bar(&mut self, ui: &mut egui::Ui) {
@@ -424,10 +434,13 @@ impl SpellCheckerApp {
424434
// Recent files
425435
if !self.state.recent_files.is_empty() {
426436
ui.menu_button("Recent Files", |ui| {
427-
for path in &self.state.recent_files {
437+
// Make a copy to avoid borrowing issues
438+
let recent_files = self.state.recent_files.clone();
439+
for path in &recent_files {
428440
if let Some(filename) = path.file_name().and_then(|n| n.to_str()) {
429441
if ui.button(format!("📄 {}", filename)).clicked() {
430-
if let Err(e) = self.open_file(path.clone()) {
442+
let path_clone = path.clone();
443+
if let Err(e) = self.open_file(path_clone) {
431444
eprintln!("Failed to open file: {}", e);
432445
}
433446
ui.close_menu();
@@ -459,7 +472,8 @@ impl SpellCheckerApp {
459472
let detected = self.language_manager.detect_language(&self.state.document_content);
460473
self.state.selected_language = detected;
461474
self.state.auto_detect_language = false;
462-
if let Ok(mut checker) = self.spell_checker.lock() {
475+
{
476+
let mut checker = self.spell_checker.lock().unwrap();
463477
let _ = checker.set_language(detected);
464478
}
465479
self.check_spelling();
@@ -523,7 +537,8 @@ impl SpellCheckerApp {
523537
).clicked() {
524538
self.state.selected_language = selected_language;
525539
self.state.auto_detect_language = false;
526-
if let Ok(mut checker) = self.spell_checker.lock() {
540+
{
541+
let mut checker = self.spell_checker.lock().unwrap();
527542
let _ = checker.set_language(*lang);
528543
}
529544
self.check_spelling();
@@ -612,7 +627,8 @@ impl SpellCheckerApp {
612627
).clicked() {
613628
self.state.selected_language = selected_language;
614629
self.state.auto_detect_language = false;
615-
if let Ok(mut checker) = self.spell_checker.lock() {
630+
{
631+
let mut checker = self.spell_checker.lock().unwrap();
616632
let _ = checker.set_language(*lang);
617633
}
618634
self.check_spelling();
@@ -666,7 +682,10 @@ impl SpellCheckerApp {
666682
ui.colored_label(egui::Color32::GREEN, "🔄 Auto");
667683
}
668684

669-
let word_count = self.spell_checker.lock().unwrap().word_count();
685+
let word_count = {
686+
let checker = self.spell_checker.lock().unwrap();
687+
checker.word_count()
688+
};
670689
ui.label(format!("Dict: {}", word_count));
671690

672691
if self.state.auto_detect_language {
@@ -690,9 +709,10 @@ impl SpellCheckerApp {
690709
.default_width(self.state.sidebar_width)
691710
.width_range(200.0..=500.0)
692711
.show_inside(ui, |ui| {
712+
let checker = self.spell_checker.lock().unwrap();
693713
self.state.sidebar_state.show(
694714
ui,
695-
&self.spell_checker.lock().unwrap(),
715+
&checker,
696716
&self.analysis,
697717
&self.state.document_content,
698718
&mut self.pending_add_word,
@@ -787,10 +807,6 @@ impl eframe::App for SpellCheckerApp {
787807
std::time::Duration::from_secs(30)
788808
}
789809

790-
fn persist_native_window(&self) -> bool {
791-
true
792-
}
793-
794810
fn persist_egui_memory(&self) -> bool {
795811
true
796812
}

src/lib.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ pub const APP_REPOSITORY: &str = "https://github.com/RR-Ralefaso/SpellChecker";
6363
pub const SPONSOR_URL: &str = "https://github.com/sponsors";
6464

6565
// Helper functions
66-
pub fn get_app_info() -> String {
67-
format!("{} v{}\nBy {}", APP_NAME, APP_VERSION, APP_AUTHOR)
68-
}
69-
7066
pub fn open_sponsor_page() -> Result<()> {
7167
open::that(SPONSOR_URL).map_err(|e| SpellCheckerError::Unknown(e.into()))
7268
}

0 commit comments

Comments
 (0)