Skip to content

Commit fb6eba7

Browse files
committed
Add exact word and case matching option for replace
1 parent 191ec53 commit fb6eba7

File tree

6 files changed

+82
-29
lines changed

6 files changed

+82
-29
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rfd = {version = "0.14.1"}
1818
indexmap = "2.2.6"
1919
nohash-hasher = "0.2.0"
2020
serde_json = "1.0.120"
21+
regex-lite = "0.1.6"
2122

2223
#[patch."https://github.com/nmeylan/json-parser-flat-format.git"]
2324
#json-flat-parser = {path = "/home/nmeylan/dev/ragnarok/json-flat-parser"}

src/panels.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub struct SearchReplacePanel<'array> {
3131
pub enum ReplaceMode {
3232
Simple,
3333
Regex,
34+
ExactWord,
35+
MatchingCase,
3436
}
3537
impl Default for ReplaceMode {
3638
fn default() -> Self {
@@ -181,25 +183,53 @@ impl <'array>super::View<Option<SearchReplaceResponse<'array>>> for SearchReplac
181183
ui.end_row();
182184

183185
ui.label("");
184-
let mut text = RichText::new(".*");
186+
let mut replace_match_case_text = RichText::new("Cc");
187+
let mut replace_exact_word_text = RichText::new("W");
188+
let mut replace_regex_text = RichText::new(".*");
189+
if matches!(self.replace_mode, ReplaceMode::MatchingCase) {
190+
replace_match_case_text = replace_match_case_text.color(ACTIVE_COLOR);
191+
}
192+
if matches!(self.replace_mode, ReplaceMode::ExactWord) {
193+
replace_exact_word_text = replace_exact_word_text.color(ACTIVE_COLOR);
194+
}
185195
if matches!(self.replace_mode, ReplaceMode::Regex) {
186-
text = text.color(ACTIVE_COLOR);
196+
replace_regex_text = replace_regex_text.color(ACTIVE_COLOR);
187197
}
188-
let enable_regex = Button::new(text);
198+
let replace_regex_mode = Button::new(replace_regex_text);
199+
let replace_exact_word_mode = Button::new(replace_exact_word_text);
200+
let replace_match_case_mode = Button::new(replace_match_case_text);
189201
let mut replace_response = ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
190202
if self.selected_columns.borrow().len() == 0 {
191203
button = button.sense(Sense::hover());
192204
}
193205
let response_button_replace = ui.add(button);
194-
let mut response = ui.add(enable_regex);
195-
response = response.on_hover_ui(|ui| { ui.label("Regex"); });
196-
if response.clicked() {
206+
let mut response_replace_regex_mode = ui.add(replace_regex_mode);
207+
response_replace_regex_mode = response_replace_regex_mode.on_hover_ui(|ui| { ui.label("Regex"); });
208+
if response_replace_regex_mode.clicked() {
197209
if matches!(self.replace_mode, ReplaceMode::Regex) {
198210
self.replace_mode = ReplaceMode::Simple;
199211
} else {
200212
self.replace_mode = ReplaceMode::Regex;
201213
}
202214
}
215+
let mut response_replace_exact_word_mode = ui.add(replace_exact_word_mode);
216+
response_replace_exact_word_mode = response_replace_exact_word_mode.on_hover_ui(|ui| { ui.label("Exact word"); });
217+
if response_replace_exact_word_mode.clicked() {
218+
if matches!(self.replace_mode, ReplaceMode::ExactWord) {
219+
self.replace_mode = ReplaceMode::Simple;
220+
} else {
221+
self.replace_mode = ReplaceMode::ExactWord;
222+
}
223+
}
224+
let mut response_replace_match_case_mode = ui.add(replace_match_case_mode);
225+
response_replace_match_case_mode = response_replace_match_case_mode.on_hover_ui(|ui| { ui.label("Matching case"); });
226+
if response_replace_match_case_mode.clicked() {
227+
if matches!(self.replace_mode, ReplaceMode::MatchingCase) {
228+
self.replace_mode = ReplaceMode::Simple;
229+
} else {
230+
self.replace_mode = ReplaceMode::MatchingCase;
231+
}
232+
}
203233
response_button_replace
204234
}).inner;
205235
ui.end_row();

src/parser/mod.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use json_flat_parser::{FlatJsonValue, JsonArrayEntries, JSONParser, ParseOptions
1212
use rayon::iter::ParallelIterator;
1313
use rayon::iter::IntoParallelIterator;
1414
use rayon::prelude::{ParallelSliceMut};
15+
use regex_lite::Regex;
1516
use crate::array_table::{Column, NON_NULL_FILTER_VALUE};
1617
use crate::panels::{ReplaceMode, SearchReplaceResponse};
1718

@@ -317,7 +318,7 @@ pub fn replace_occurrences(previous_parse_result: &Vec<JsonArrayEntries<String>>
317318
if column_ids.contains(&entry.pointer.column_id) {
318319
if let Some(ref value) = entry.value {
319320
match search_replace_response.replace_mode {
320-
ReplaceMode::Simple => {
321+
ReplaceMode::MatchingCase => {
321322
new_values.push((
322323
FlatJsonValue {
323324
pointer: entry.pointer.clone(),
@@ -326,7 +327,21 @@ pub fn replace_occurrences(previous_parse_result: &Vec<JsonArrayEntries<String>>
326327
json_array_entry.index
327328
));
328329
}
329-
ReplaceMode::Regex => {}
330+
ReplaceMode::Regex => {
331+
let re = Regex::new(search_replace_response.search_criteria.as_str()).unwrap();
332+
let new_value = re.replace_all(value, search_replace_response.replace_value.as_str()).to_string();
333+
new_values.push((FlatJsonValue { pointer: entry.pointer.clone(), value: Some(new_value), }, json_array_entry.index));
334+
}
335+
ReplaceMode::ExactWord => {
336+
let re = Regex::new(&format!(r"\b{}\b", regex_lite::escape(search_replace_response.search_criteria.as_str()))).unwrap();
337+
let new_value = re.replace_all(value, search_replace_response.replace_value.as_str()).to_string();
338+
new_values.push((FlatJsonValue { pointer: entry.pointer.clone(), value: Some(new_value), }, json_array_entry.index));
339+
}
340+
ReplaceMode::Simple => {
341+
let re = Regex::new(&format!("(?i){}", regex_lite::escape(search_replace_response.search_criteria.as_str()))).unwrap();
342+
let new_value = re.replace_all(value, search_replace_response.replace_value.as_str()).to_string();
343+
new_values.push((FlatJsonValue { pointer: entry.pointer.clone(), value: Some(new_value), }, json_array_entry.index));
344+
}
330345
}
331346
}
332347
}

web/json-editor.js

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ function makeMutClosure(arg0, arg1, dtor, f) {
228228
return real;
229229
}
230230
function __wbg_adapter_28(arg0, arg1) {
231-
wasm.wasm_bindgen__convert__closures__invoke0_mut__h563050111f8647d1(arg0, arg1);
231+
wasm.wasm_bindgen__convert__closures__invoke0_mut__h5f2f14d0e5bf9f7d(arg0, arg1);
232232
}
233233

234234
function __wbg_adapter_31(arg0, arg1) {
@@ -400,6 +400,14 @@ function __wbg_get_imports() {
400400
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
401401
takeObject(arg0);
402402
};
403+
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
404+
const ret = getStringFromWasm0(arg0, arg1);
405+
return addHeapObject(ret);
406+
};
407+
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
408+
const ret = getObject(arg0);
409+
return addHeapObject(ret);
410+
};
403411
imports.wbg.__wbindgen_cb_drop = function(arg0) {
404412
const obj = takeObject(arg0).original;
405413
if (obj.cnt-- == 1) {
@@ -409,14 +417,6 @@ function __wbg_get_imports() {
409417
const ret = false;
410418
return ret;
411419
};
412-
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
413-
const ret = getStringFromWasm0(arg0, arg1);
414-
return addHeapObject(ret);
415-
};
416-
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
417-
const ret = getObject(arg0);
418-
return addHeapObject(ret);
419-
};
420420
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
421421
const obj = getObject(arg1);
422422
const ret = typeof(obj) === 'string' ? obj : undefined;
@@ -1636,28 +1636,28 @@ function __wbg_get_imports() {
16361636
const ret = wasm.memory;
16371637
return addHeapObject(ret);
16381638
};
1639-
imports.wbg.__wbindgen_closure_wrapper475 = function(arg0, arg1, arg2) {
1640-
const ret = makeMutClosure(arg0, arg1, 43, __wbg_adapter_28);
1639+
imports.wbg.__wbindgen_closure_wrapper818 = function(arg0, arg1, arg2) {
1640+
const ret = makeMutClosure(arg0, arg1, 197, __wbg_adapter_28);
16411641
return addHeapObject(ret);
16421642
};
1643-
imports.wbg.__wbindgen_closure_wrapper975 = function(arg0, arg1, arg2) {
1644-
const ret = makeMutClosure(arg0, arg1, 234, __wbg_adapter_31);
1643+
imports.wbg.__wbindgen_closure_wrapper985 = function(arg0, arg1, arg2) {
1644+
const ret = makeMutClosure(arg0, arg1, 238, __wbg_adapter_31);
16451645
return addHeapObject(ret);
16461646
};
1647-
imports.wbg.__wbindgen_closure_wrapper1425 = function(arg0, arg1, arg2) {
1648-
const ret = makeMutClosure(arg0, arg1, 414, __wbg_adapter_34);
1647+
imports.wbg.__wbindgen_closure_wrapper1533 = function(arg0, arg1, arg2) {
1648+
const ret = makeMutClosure(arg0, arg1, 436, __wbg_adapter_34);
16491649
return addHeapObject(ret);
16501650
};
1651-
imports.wbg.__wbindgen_closure_wrapper1427 = function(arg0, arg1, arg2) {
1652-
const ret = makeMutClosure(arg0, arg1, 414, __wbg_adapter_37);
1651+
imports.wbg.__wbindgen_closure_wrapper1535 = function(arg0, arg1, arg2) {
1652+
const ret = makeMutClosure(arg0, arg1, 436, __wbg_adapter_37);
16531653
return addHeapObject(ret);
16541654
};
1655-
imports.wbg.__wbindgen_closure_wrapper1429 = function(arg0, arg1, arg2) {
1656-
const ret = makeMutClosure(arg0, arg1, 414, __wbg_adapter_37);
1655+
imports.wbg.__wbindgen_closure_wrapper1537 = function(arg0, arg1, arg2) {
1656+
const ret = makeMutClosure(arg0, arg1, 436, __wbg_adapter_37);
16571657
return addHeapObject(ret);
16581658
};
1659-
imports.wbg.__wbindgen_closure_wrapper1807 = function(arg0, arg1, arg2) {
1660-
const ret = makeMutClosure(arg0, arg1, 441, __wbg_adapter_42);
1659+
imports.wbg.__wbindgen_closure_wrapper1915 = function(arg0, arg1, arg2) {
1660+
const ret = makeMutClosure(arg0, arg1, 463, __wbg_adapter_42);
16611661
return addHeapObject(ret);
16621662
};
16631663

web/json-editor_bg.wasm

70.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)