Simple replace implementation
This commit is contained in:
parent
133b8ca667
commit
dd459efe06
6 changed files with 120 additions and 4 deletions
|
|
@ -41,6 +41,9 @@ enable-vim-bindings = Enable Vim bindings
|
|||
find-placeholder = Find...
|
||||
find-previous = Find previous
|
||||
find-next = Find next
|
||||
replace-placeholder = Replace...
|
||||
replace = Replace
|
||||
replace-all = Replace all
|
||||
|
||||
# Menu
|
||||
|
||||
|
|
|
|||
7
res/icons/replace-all-symbolic.svg
Normal file
7
res/icons/replace-all-symbolic.svg
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.70892 2.29365C7.52159 2.10591 7.26735 2.00028 7.00213 2C6.17371 1.99912 5.5 2 5 2C4 2 3.00004 3.00107 3 4C2.99998 4.5 2.99851 5.56725 2.99805 5.99894L0.998047 5.99681L3.99379 10L6.99804 6.0032L4.99804 6.00107C4.99835 5.71751 4.9987 5.52735 4.99804 5C4.99739 4.47265 5.47193 4 6.00049 4C6.50049 4 6.54487 3.99952 7 4C7.26522 4.00028 7.51968 3.8952 7.70742 3.70786C7.89515 3.52052 8.00078 3.26628 8.00106 3.00107C8.00135 2.73585 7.89626 2.48138 7.70892 2.29365Z" fill="#232323"/>
|
||||
<rect x="9" y="1" width="6" height="4" rx="0.5" fill="#232323"/>
|
||||
<rect x="4" y="11" width="6" height="4" rx="0.5" fill="#232323"/>
|
||||
<path opacity="0.67" fill-rule="evenodd" clip-rule="evenodd" d="M6.5 9C6.22386 9 6 9.22386 6 9.5V10H10.5C10.7761 10 11 10.2239 11 10.5V13H11.5C11.7761 13 12 12.7761 12 12.5V9.5C12 9.22386 11.7761 9 11.5 9H6.5Z" fill="#232323"/>
|
||||
<path opacity="0.33" fill-rule="evenodd" clip-rule="evenodd" d="M8.5 7C8.22386 7 8 7.22386 8 7.5V8H12.5C12.7761 8 13 8.22386 13 8.5V11H13.5C13.7761 11 14 10.7761 14 10.5V7.5C14 7.22386 13.7761 7 13.5 7H8.5Z" fill="#232323"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
5
res/icons/replace-symbolic.svg
Normal file
5
res/icons/replace-symbolic.svg
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.70892 2.29365C7.52159 2.10591 7.26735 2.00028 7.00213 2C6.17371 1.99912 5.5 2 5 2C4 2 3.00004 3.00107 3 4C2.99998 4.5 2.99851 5.56725 2.99805 5.99894L0.998047 5.99681L3.99379 10L6.99804 6.0032L4.99804 6.00107C4.99835 5.71751 4.9987 5.52735 4.99804 5C4.99739 4.47265 5.47193 4 6.00049 4C6.50049 4 6.54487 3.99952 7 4C7.26522 4.00028 7.51968 3.8952 7.70742 3.70786C7.89515 3.52052 8.00078 3.26628 8.00106 3.00107C8.00135 2.73585 7.89626 2.48138 7.70892 2.29365Z" fill="#232323"/>
|
||||
<rect x="9" y="1" width="6" height="4" rx="0.5" fill="#232323"/>
|
||||
<rect x="5" y="11" width="6" height="4" rx="0.5" fill="#232323"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 724 B |
|
|
@ -37,6 +37,8 @@ impl IconCache {
|
|||
bundle!("go-up-symbolic", 16);
|
||||
bundle!("list-add-symbolic", 16);
|
||||
bundle!("object-select-symbolic", 16);
|
||||
bundle!("replace-symbolic", 16);
|
||||
bundle!("replace-all-symbolic", 16);
|
||||
bundle!("window-close-symbolic", 16);
|
||||
|
||||
Self { cache }
|
||||
|
|
|
|||
71
src/main.rs
71
src/main.rs
|
|
@ -184,6 +184,8 @@ pub enum Message {
|
|||
Find(Option<bool>),
|
||||
FindNext,
|
||||
FindPrevious,
|
||||
FindReplace,
|
||||
FindReplaceAll,
|
||||
FindReplaceValueChanged(String),
|
||||
FindSearchValueChanged(String),
|
||||
GitProjectStatus(Vec<(String, PathBuf, Vec<GitStatus>)>),
|
||||
|
|
@ -267,6 +269,7 @@ pub struct App {
|
|||
context_page: ContextPage,
|
||||
text_box_id: widget::Id,
|
||||
find_opt: Option<bool>,
|
||||
find_replace_id: widget::Id,
|
||||
find_replace_value: String,
|
||||
find_search_id: widget::Id,
|
||||
find_search_value: String,
|
||||
|
|
@ -976,6 +979,7 @@ impl Application for App {
|
|||
context_page: ContextPage::Settings,
|
||||
text_box_id: widget::Id::unique(),
|
||||
find_opt: None,
|
||||
find_replace_id: widget::Id::unique(),
|
||||
find_replace_value: String::new(),
|
||||
find_search_id: widget::Id::unique(),
|
||||
find_search_value: String::new(),
|
||||
|
|
@ -1242,6 +1246,22 @@ impl Application for App {
|
|||
// Focus correct input
|
||||
return self.update_focus();
|
||||
}
|
||||
Message::FindReplace => {
|
||||
if !self.find_search_value.is_empty() {
|
||||
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||
tab.replace(&self.find_search_value, &self.find_replace_value);
|
||||
}
|
||||
}
|
||||
|
||||
// Focus correct input
|
||||
return self.update_focus();
|
||||
}
|
||||
Message::FindReplaceAll => {
|
||||
log::warn!("FIND REPLACE ALL");
|
||||
|
||||
// Focus correct input
|
||||
return self.update_focus();
|
||||
}
|
||||
Message::FindReplaceValueChanged(value) => {
|
||||
self.find_replace_value = value;
|
||||
}
|
||||
|
|
@ -1876,7 +1896,7 @@ impl Application for App {
|
|||
}
|
||||
|
||||
if let Some(replace) = &self.find_opt {
|
||||
let text_input =
|
||||
let find_input =
|
||||
widget::text_input::text_input(fl!("find-placeholder"), &self.find_search_value)
|
||||
.id(self.find_search_id.clone())
|
||||
.on_input(Message::FindSearchValueChanged)
|
||||
|
|
@ -1890,7 +1910,7 @@ impl Application for App {
|
|||
.into(),
|
||||
);
|
||||
let find_widget = widget::row::with_children(vec![
|
||||
text_input.into(),
|
||||
find_input.into(),
|
||||
widget::tooltip(
|
||||
button(icon_cache_get("go-up-symbolic", 16))
|
||||
.on_press(Message::FindPrevious)
|
||||
|
|
@ -1920,9 +1940,52 @@ impl Application for App {
|
|||
.padding(space_xxs)
|
||||
.spacing(space_xxs);
|
||||
|
||||
let mut column = widget::column::with_capacity(2).push(find_widget);
|
||||
if *replace {
|
||||
let replace_input = widget::text_input::text_input(
|
||||
fl!("replace-placeholder"),
|
||||
&self.find_replace_value,
|
||||
)
|
||||
.id(self.find_replace_id.clone())
|
||||
.on_input(Message::FindReplaceValueChanged)
|
||||
.on_submit(Message::FindReplace)
|
||||
.width(Length::Fixed(320.0))
|
||||
.trailing_icon(
|
||||
button(icon_cache_get("edit-clear-symbolic", 16))
|
||||
.on_press(Message::FindReplaceValueChanged(String::new()))
|
||||
.style(style::Button::Icon)
|
||||
.into(),
|
||||
);
|
||||
let replace_widget = widget::row::with_children(vec![
|
||||
replace_input.into(),
|
||||
widget::tooltip(
|
||||
button(icon_cache_get("replace-symbolic", 16))
|
||||
.on_press(Message::FindReplace)
|
||||
.padding(space_xxs)
|
||||
.style(style::Button::Icon),
|
||||
fl!("replace"),
|
||||
widget::tooltip::Position::Top,
|
||||
)
|
||||
.into(),
|
||||
widget::tooltip(
|
||||
button(icon_cache_get("replace-all-symbolic", 16))
|
||||
.on_press(Message::FindReplaceAll)
|
||||
.padding(space_xxs)
|
||||
.style(style::Button::Icon),
|
||||
fl!("replace-all"),
|
||||
widget::tooltip::Position::Top,
|
||||
)
|
||||
.into(),
|
||||
])
|
||||
.align_items(Alignment::Center)
|
||||
.padding(space_xxs)
|
||||
.spacing(space_xxs);
|
||||
|
||||
column = column.push(replace_widget);
|
||||
}
|
||||
|
||||
tab_column = tab_column.push(
|
||||
widget::cosmic_container::container(find_widget)
|
||||
.layer(cosmic_theme::Layer::Primary),
|
||||
widget::cosmic_container::container(column).layer(cosmic_theme::Layer::Primary),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
36
src/tab.rs
36
src/tab.rs
|
|
@ -200,6 +200,42 @@ impl EditorTab {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn replace(&self, value: &str, replace: &str) -> bool {
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
let mut cursor = editor.cursor();
|
||||
let start_line = cursor.line;
|
||||
while cursor.line < editor.with_buffer(|buffer| buffer.lines.len()) {
|
||||
if let Some(index) = editor.with_buffer(|buffer| {
|
||||
buffer.lines[cursor.line]
|
||||
.text()
|
||||
.match_indices(value)
|
||||
.filter_map(|(i, _)| {
|
||||
if cursor.line != start_line || i >= cursor.index {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.next()
|
||||
}) {
|
||||
cursor.index = index;
|
||||
let mut end = cursor;
|
||||
end.index = index + value.len();
|
||||
|
||||
editor.start_change();
|
||||
editor.delete_range(cursor, end);
|
||||
cursor = editor.insert_at(cursor, replace, None);
|
||||
editor.set_cursor(cursor);
|
||||
editor.finish_change();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cursor.line += 1;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// Code adapted from cosmic-text ViEditor search
|
||||
pub fn search(&self, value: &str, forwards: bool) -> bool {
|
||||
let mut editor = self.editor.lock().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue