mirror of
https://github.com/bobwen-dev/hunter
synced 2025-04-12 00:55:41 +02:00
improved navigation/turbo-cd
This commit is contained in:
parent
b163a9f4b4
commit
e4850e38b6
22
src/fail.rs
22
src/fail.rs
@ -70,10 +70,6 @@ pub enum HError {
|
|||||||
INotifyError(String),
|
INotifyError(String),
|
||||||
#[fail(display = "Tags not loaded yet")]
|
#[fail(display = "Tags not loaded yet")]
|
||||||
TagsNotLoadedYetError,
|
TagsNotLoadedYetError,
|
||||||
#[fail(display = "Input cancelled!")]
|
|
||||||
MiniBufferCancelledInput,
|
|
||||||
#[fail(display = "Empty input!")]
|
|
||||||
MiniBufferEmptyInput,
|
|
||||||
#[fail(display = "Undefined key: {:?}", key)]
|
#[fail(display = "Undefined key: {:?}", key)]
|
||||||
WidgetUndefinedKeyError{key: Key},
|
WidgetUndefinedKeyError{key: Key},
|
||||||
#[fail(display = "Terminal has been resized!")]
|
#[fail(display = "Terminal has been resized!")]
|
||||||
@ -107,7 +103,11 @@ pub enum HError {
|
|||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
FileError(crate::files::FileError),
|
FileError(crate::files::FileError),
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
Nix(#[cause] nix::Error)
|
Nix(#[cause] nix::Error),
|
||||||
|
#[fail(display = "Refresh parent widget!")]
|
||||||
|
RefreshParent,
|
||||||
|
#[fail(display = "Refresh parent widget!")]
|
||||||
|
MiniBufferEvent(crate::minibuffer::MiniBufferEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HError {
|
impl HError {
|
||||||
@ -134,12 +134,6 @@ impl HError {
|
|||||||
pub fn tags_not_loaded<T>() -> HResult<T> {
|
pub fn tags_not_loaded<T>() -> HResult<T> {
|
||||||
Err(HError::TagsNotLoadedYetError)
|
Err(HError::TagsNotLoadedYetError)
|
||||||
}
|
}
|
||||||
pub fn minibuffer_cancel<T>() -> HResult<T> {
|
|
||||||
Err(HError::MiniBufferCancelledInput)
|
|
||||||
}
|
|
||||||
pub fn minibuffer_empty<T>() -> HResult<T> {
|
|
||||||
Err(HError::MiniBufferEmptyInput)
|
|
||||||
}
|
|
||||||
pub fn undefined_key<T>(key: Key) -> HResult<T> {
|
pub fn undefined_key<T>(key: Key) -> HResult<T> {
|
||||||
Err(HError::WidgetUndefinedKeyError { key: key })
|
Err(HError::WidgetUndefinedKeyError { key: key })
|
||||||
}
|
}
|
||||||
@ -417,6 +411,12 @@ impl From<KeyBindError> for HError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::minibuffer::MiniBufferEvent> for HError {
|
||||||
|
fn from(e: crate::minibuffer::MiniBufferEvent) -> Self {
|
||||||
|
HError::MiniBufferEvent(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Fail, Debug, Clone)]
|
#[derive(Fail, Debug, Clone)]
|
||||||
pub enum KeyBindError {
|
pub enum KeyBindError {
|
||||||
|
@ -631,6 +631,13 @@ impl FileBrowser {
|
|||||||
self.draw().log();
|
self.draw().log();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Err(HError::RefreshParent) = bookmark {
|
||||||
|
self.refresh().log();
|
||||||
|
self.draw().log();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return bookmark;
|
return bookmark;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -876,11 +883,146 @@ impl FileBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn turbo_cd(&mut self) -> HResult<()> {
|
pub fn turbo_cd(&mut self) -> HResult<()> {
|
||||||
let dir = self.core.minibuffer("cd")?;
|
use crate::minibuffer::MiniBufferEvent::*;
|
||||||
|
|
||||||
let path = std::path::PathBuf::from(&dir);
|
// Return and reset on cancel
|
||||||
let dir = File::new_from_path(&path.canonicalize()?)?;
|
let orig_dir = self.cwd()?.clone();
|
||||||
self.main_widget_goto(&dir)?;
|
let orig_dir_selected_file = self.selected_file()?;
|
||||||
|
let mut orig_dir_filter = self.main_widget()?
|
||||||
|
.content
|
||||||
|
.get_filter();
|
||||||
|
|
||||||
|
// For current dir
|
||||||
|
let mut selected_file = Some(orig_dir_selected_file.clone());
|
||||||
|
let mut filter = Some(orig_dir_filter.clone());
|
||||||
|
|
||||||
|
// Helper function to restore any previous filter/selection
|
||||||
|
let dir_restore =
|
||||||
|
|s: &mut FileBrowser, filter: Option<Option<String>>, file: Option<File>| {
|
||||||
|
s.main_widget_mut()
|
||||||
|
.map(|mw| {
|
||||||
|
filter.map(|f| mw.set_filter(f));
|
||||||
|
file.map(|f| mw.select_file(&f));
|
||||||
|
}).log();
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let input = self.core.minibuffer_continuous("nav");
|
||||||
|
// dbg!(&input);
|
||||||
|
// self.refresh().log();
|
||||||
|
// self.draw().log();
|
||||||
|
|
||||||
|
match input {
|
||||||
|
// While minibuffer runs it steals all events, thus explicit refresh/redraw
|
||||||
|
Err(HError::RefreshParent) => {
|
||||||
|
self.refresh().log();
|
||||||
|
self.draw().log();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Err(HError::MiniBufferEvent(event)) => {
|
||||||
|
match event {
|
||||||
|
// Done here, restore filter, but leave selection as is
|
||||||
|
Done(_) | Empty => {
|
||||||
|
dir_restore(self, filter.take(), None);
|
||||||
|
self.core.minibuffer_clear().log();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NewInput(input) => {
|
||||||
|
// Don't filter anything until a letter appears
|
||||||
|
if input.as_str() == "." || input.as_str() == ".." {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.ends_with('/') {
|
||||||
|
match input.as_str() {
|
||||||
|
"../" => {
|
||||||
|
dir_restore(self,
|
||||||
|
filter.take(),
|
||||||
|
selected_file.take());
|
||||||
|
self.go_back().log();
|
||||||
|
self.core.minibuffer_clear().log();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let sel = self.selected_file()?;
|
||||||
|
|
||||||
|
if sel.is_dir() {
|
||||||
|
dir_restore(self,
|
||||||
|
filter.take(),
|
||||||
|
selected_file.take());
|
||||||
|
self.main_widget_goto(&sel)?;
|
||||||
|
self.core.minibuffer_clear().log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save current filter, if existing, before overwriting it
|
||||||
|
// Type is Option<Option<_>>, because filter itself is Option<_>
|
||||||
|
if filter.is_none() {
|
||||||
|
let dir_filter = self.main_widget()?
|
||||||
|
.content
|
||||||
|
.get_filter();
|
||||||
|
filter = Some(dir_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To restore on leave/cancel
|
||||||
|
if selected_file.is_none() {
|
||||||
|
selected_file = Some(self.selected_file()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.main_widget_mut()?
|
||||||
|
.set_filter(Some(input));
|
||||||
|
}
|
||||||
|
// Restore original directory and filter/selection
|
||||||
|
Cancelled => {
|
||||||
|
self.main_widget_goto(&orig_dir)?;
|
||||||
|
// Special case, because all others fail if directory isn't ready anyway
|
||||||
|
self.main_async_widget_mut()?
|
||||||
|
.widget
|
||||||
|
.on_ready(move |mw,_| {
|
||||||
|
let mw = mw?;
|
||||||
|
mw.set_filter(orig_dir_filter.take());
|
||||||
|
mw.select_file(&orig_dir_selected_file);
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CycleNext => {
|
||||||
|
// Because of filtering the selected file isn't just at n+1
|
||||||
|
let oldpos = self.main_widget()?.get_selection();
|
||||||
|
|
||||||
|
let mw = self.main_widget_mut()?;
|
||||||
|
mw.move_down();
|
||||||
|
mw.update_selected_file(oldpos);
|
||||||
|
|
||||||
|
// Refresh preview and draw header, too
|
||||||
|
self.refresh().log();
|
||||||
|
self.draw().log();
|
||||||
|
|
||||||
|
// Explicitly selected
|
||||||
|
selected_file = Some(self.selected_file()?);
|
||||||
|
}
|
||||||
|
CyclePrev => {
|
||||||
|
// Because of filtering the selected file isn't just at n-1
|
||||||
|
let oldpos = self.main_widget()?.get_selection();
|
||||||
|
|
||||||
|
let mw = self.main_widget_mut()?;
|
||||||
|
mw.move_up();
|
||||||
|
mw.update_selected_file(oldpos);
|
||||||
|
|
||||||
|
// Refresh preview and draw header, too
|
||||||
|
self.refresh().log();
|
||||||
|
self.draw().log();
|
||||||
|
|
||||||
|
// Explicitly selected
|
||||||
|
selected_file = Some(self.selected_file()?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1121,13 +1263,36 @@ impl FileBrowser {
|
|||||||
|
|
||||||
pub fn show_procview(&mut self) -> HResult<()> {
|
pub fn show_procview(&mut self) -> HResult<()> {
|
||||||
self.preview_widget().map(|preview| preview.cancel_animation()).log();
|
self.preview_widget().map(|preview| preview.cancel_animation()).log();
|
||||||
self.proc_view.lock()?.popup()?;
|
let procview = self.proc_view.clone();
|
||||||
|
loop {
|
||||||
|
match procview.lock()?.popup() {
|
||||||
|
// Ignore refresh
|
||||||
|
Err(HError::RefreshParent) => continue,
|
||||||
|
Err(HError::TerminalResizedError) |
|
||||||
|
Err(HError::WidgetResizedError) => self.resize().log(),
|
||||||
|
_ => break
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_log(&mut self) -> HResult<()> {
|
pub fn show_log(&mut self) -> HResult<()> {
|
||||||
self.preview_widget().map(|preview| preview.cancel_animation()).log();
|
self.preview_widget().map(|preview| preview.cancel_animation()).log();
|
||||||
self.log_view.lock()?.popup()?;
|
loop {
|
||||||
|
let res = self.log_view.lock()?.popup();
|
||||||
|
|
||||||
|
if let Err(HError::RefreshParent) = res {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(HError::TerminalResizedError) = res {
|
||||||
|
self.resize().log();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
102
src/listview.rs
102
src/listview.rs
@ -602,20 +602,38 @@ impl ListView<Files>
|
|||||||
// Only set this, search is on-the-fly
|
// Only set this, search is on-the-fly
|
||||||
self.searching = Some(input);
|
self.searching = Some(input);
|
||||||
}
|
}
|
||||||
Err(HError::MiniBufferInputUpdated(input)) => {
|
Err(HError::RefreshParent) => {
|
||||||
let file = self.content
|
self.refresh().log();
|
||||||
.find_file_with_name(&input)
|
|
||||||
.cloned();
|
|
||||||
|
|
||||||
file.map(|f| self.select_file(&f));
|
|
||||||
|
|
||||||
self.draw().log();
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
},
|
}
|
||||||
Err(HError::MiniBufferEmptyInput) |
|
Err(HError::MiniBufferEvent(ev)) => {
|
||||||
Err(HError::MiniBufferCancelledInput) => {
|
use crate::minibuffer::MiniBufferEvent::*;
|
||||||
self.select_file(&selected_file);
|
|
||||||
|
match ev {
|
||||||
|
Done(_) => {}
|
||||||
|
NewInput(input) => {
|
||||||
|
let file = self.content
|
||||||
|
.find_file_with_name(&input)
|
||||||
|
.cloned();
|
||||||
|
|
||||||
|
file.map(|f| self.select_file(&f));
|
||||||
|
|
||||||
|
self.draw().log();
|
||||||
|
|
||||||
|
self.searching = Some(input);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Empty | Cancelled => {
|
||||||
|
self.select_file(&selected_file);
|
||||||
|
}
|
||||||
|
CycleNext => {
|
||||||
|
self.search_next().log();
|
||||||
|
}
|
||||||
|
CyclePrev => {
|
||||||
|
self.search_prev().log();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => { }
|
_ => { }
|
||||||
}
|
}
|
||||||
@ -688,35 +706,61 @@ impl ListView<Files>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_filter(&mut self, filter: Option<String>) {
|
||||||
|
let prev_len = self.len();
|
||||||
|
let selected_file = self.clone_selected_file();
|
||||||
|
|
||||||
|
self.content.set_filter(filter);
|
||||||
|
|
||||||
|
// Only do something if filter changed something
|
||||||
|
if self.len() != prev_len {
|
||||||
|
self.refresh().ok();
|
||||||
|
self.select_file(&selected_file);
|
||||||
|
// Clear away that wouldn't get drawn over
|
||||||
|
if self.len() < prev_len {
|
||||||
|
self.core.clear().ok();
|
||||||
|
}
|
||||||
|
self.draw().ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn filter(&mut self) -> HResult<()> {
|
fn filter(&mut self) -> HResult<()> {
|
||||||
|
use crate::minibuffer::MiniBufferEvent::*;
|
||||||
|
|
||||||
let selected_file = self.selected_file().clone();
|
let selected_file = self.selected_file().clone();
|
||||||
|
let mut prev_filter = self.content.get_filter();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let filter = self.core.minibuffer_continuous("filter");
|
let filter = self.core.minibuffer_continuous("filter");
|
||||||
|
|
||||||
match filter {
|
match filter {
|
||||||
Err(HError::MiniBufferInputUpdated(input)) => {
|
Err(HError::MiniBufferEvent(event)) => {
|
||||||
self.content.set_filter(Some(input));
|
match event {
|
||||||
self.refresh().ok();
|
Done(filter) => {
|
||||||
|
self.core.show_status(&format!("Filtering with: \"{}\"",
|
||||||
|
&filter)).log();
|
||||||
|
|
||||||
self.select_file(&selected_file);
|
self.set_filter(Some(filter));
|
||||||
self.draw().ok();
|
}
|
||||||
|
NewInput(input) => {
|
||||||
continue;
|
self.set_filter(Some(input.clone()));
|
||||||
}
|
continue;
|
||||||
Err(HError::MiniBufferEmptyInput) |
|
}
|
||||||
Err(HError::MiniBufferCancelledInput) => {
|
Empty => {
|
||||||
self.content.set_filter(None);
|
self.set_filter(None);
|
||||||
self.refresh().ok();
|
}
|
||||||
self.select_file(&selected_file);
|
Cancelled => {
|
||||||
|
self.set_filter(prev_filter.take());
|
||||||
|
self.select_file(&selected_file);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let msgstr = filter.clone().unwrap_or(String::from(""));
|
|
||||||
self.core.show_status(&format!("Filtering with: \"{}\"", msgstr)).log();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -128,6 +128,16 @@ impl History {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum MiniBufferEvent {
|
||||||
|
Done(String),
|
||||||
|
NewInput(String),
|
||||||
|
Empty,
|
||||||
|
Cancelled,
|
||||||
|
CycleNext,
|
||||||
|
CyclePrev
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MiniBuffer {
|
pub struct MiniBuffer {
|
||||||
core: WidgetCore,
|
core: WidgetCore,
|
||||||
@ -171,8 +181,8 @@ impl MiniBuffer {
|
|||||||
self.core.screen()?.cursor_hide().log();
|
self.core.screen()?.cursor_hide().log();
|
||||||
|
|
||||||
match self.popup() {
|
match self.popup() {
|
||||||
Err(HError::MiniBufferCancelledInput) => self.input_cancelled()?,
|
event @ Err(HError::MiniBufferEvent(_)) => event?,
|
||||||
err @ Err(HError::MiniBufferInputUpdated(_)) => err?,
|
err @ Err(HError::RefreshParent) => err?,
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -186,7 +196,6 @@ impl MiniBuffer {
|
|||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.input.clear();
|
self.input.clear();
|
||||||
self.position = 0;
|
self.position = 0;
|
||||||
self.history.reset();
|
|
||||||
self.completions.clear();
|
self.completions.clear();
|
||||||
self.last_completion = None;
|
self.last_completion = None;
|
||||||
}
|
}
|
||||||
@ -255,6 +264,11 @@ impl MiniBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn history_up(&mut self) -> HResult<()> {
|
pub fn history_up(&mut self) -> HResult<()> {
|
||||||
|
if self.query.as_str() == "nav" {
|
||||||
|
return Err(MiniBufferEvent::CyclePrev)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if let Ok(historic) = self.history.get_prev(&self.query) {
|
if let Ok(historic) = self.history.get_prev(&self.query) {
|
||||||
self.position = historic.len();
|
self.position = historic.len();
|
||||||
self.input = historic;
|
self.input = historic;
|
||||||
@ -263,6 +277,11 @@ impl MiniBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn history_down(&mut self) -> HResult<()> {
|
pub fn history_down(&mut self) -> HResult<()> {
|
||||||
|
if self.query.as_str() == "nav" {
|
||||||
|
return Err(MiniBufferEvent::CycleNext)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if let Ok(historic) = self.history.get_next(&self.query) {
|
if let Ok(historic) = self.history.get_next(&self.query) {
|
||||||
self.position = historic.len();
|
self.position = historic.len();
|
||||||
self.input = historic;
|
self.input = historic;
|
||||||
@ -340,16 +359,16 @@ impl MiniBuffer {
|
|||||||
|
|
||||||
pub fn input_cancelled(&self) -> HResult<()> {
|
pub fn input_cancelled(&self) -> HResult<()> {
|
||||||
self.core.show_status("Input cancelled").log();
|
self.core.show_status("Input cancelled").log();
|
||||||
return HError::minibuffer_cancel()
|
return Err(MiniBufferEvent::Cancelled)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_updated(&self) -> HResult<()> {
|
pub fn input_updated(&self) -> HResult<()> {
|
||||||
return HError::input_updated(self.input.clone())
|
return Err(MiniBufferEvent::NewInput(self.input.clone()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_empty(&self) -> HResult<()> {
|
pub fn input_empty(&self) -> HResult<()> {
|
||||||
self.core.show_status("Empty!").log();
|
self.core.show_status("Empty!").log();
|
||||||
return HError::minibuffer_empty()
|
return Err(MiniBufferEvent::Empty)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,15 @@ pub fn open(files: Vec<File>,
|
|||||||
act_base.map(|act| action_view.content.push(act)).ok();
|
act_base.map(|act| action_view.content.push(act)).ok();
|
||||||
act_sub.map(|act| action_view.content.push(act)).ok();
|
act_sub.map(|act| action_view.content.push(act)).ok();
|
||||||
|
|
||||||
action_view.popup()
|
loop {
|
||||||
|
// TODO: Handle this properly
|
||||||
|
match action_view.popup() {
|
||||||
|
Err(HError::RefreshParent) => continue,
|
||||||
|
Err(HError::WidgetResizedError) => continue,
|
||||||
|
Err(HError::TerminalResizedError) => continue,
|
||||||
|
r @ _ => break r
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -355,6 +363,7 @@ impl QuickAction {
|
|||||||
files: Vec<File>,
|
files: Vec<File>,
|
||||||
core: &WidgetCore,
|
core: &WidgetCore,
|
||||||
proc_view: Arc<Mutex<ProcView>>) -> HResult<()> {
|
proc_view: Arc<Mutex<ProcView>>) -> HResult<()> {
|
||||||
|
use crate::minibuffer::MiniBufferEvent::*;;
|
||||||
|
|
||||||
let answers = self.queries
|
let answers = self.queries
|
||||||
.iter()
|
.iter()
|
||||||
@ -364,7 +373,7 @@ impl QuickAction {
|
|||||||
if acc.is_err() { return acc; }
|
if acc.is_err() { return acc; }
|
||||||
|
|
||||||
match core.minibuffer(query) {
|
match core.minibuffer(query) {
|
||||||
Err(HError::MiniBufferEmptyInput) => {
|
Err(HError::MiniBufferEvent(Empty)) => {
|
||||||
acc.as_mut()
|
acc.as_mut()
|
||||||
.map(|acc| acc.push((OsString::from(query),
|
.map(|acc| acc.push((OsString::from(query),
|
||||||
OsString::from(""))))
|
OsString::from(""))))
|
||||||
|
@ -139,6 +139,15 @@ impl WidgetCore {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn minibuffer_clear(&self) -> HResult<()> {
|
||||||
|
self.minibuffer
|
||||||
|
.lock()?
|
||||||
|
.as_mut()?
|
||||||
|
.clear();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn minibuffer(&self, query: &str) -> HResult<String> {
|
pub fn minibuffer(&self, query: &str) -> HResult<String> {
|
||||||
let answer = self.minibuffer
|
let answer = self.minibuffer
|
||||||
.lock()?
|
.lock()?
|
||||||
@ -338,7 +347,11 @@ pub trait Widget {
|
|||||||
print!("\x1b_Ga=d,d=y,y={}\x1b\\", ypos+1);
|
print!("\x1b_Ga=d,d=y,y={}\x1b\\", ypos+1);
|
||||||
}
|
}
|
||||||
let result = self.run_widget();
|
let result = self.run_widget();
|
||||||
self.get_core()?.clear().log();
|
match result {
|
||||||
|
Err(HError::RefreshParent) => {},
|
||||||
|
_ => self.get_core()?.clear().log()
|
||||||
|
}
|
||||||
|
|
||||||
self.get_core()?.get_sender().send(Events::ExclusiveEvent(None))?;
|
self.get_core()?.get_sender().send(Events::ExclusiveEvent(None))?;
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -364,17 +377,15 @@ pub trait Widget {
|
|||||||
match self.on_event(input) {
|
match self.on_event(input) {
|
||||||
err @ Err(HError::PopupFinnished) |
|
err @ Err(HError::PopupFinnished) |
|
||||||
err @ Err(HError::Quit) |
|
err @ Err(HError::Quit) |
|
||||||
err @ Err(HError::MiniBufferCancelledInput) => err?,
|
|
||||||
err @ Err(HError::MiniBufferInputUpdated(_)) => err?,
|
|
||||||
err @ Err(HError::WidgetResizedError) => err?,
|
err @ Err(HError::WidgetResizedError) => err?,
|
||||||
|
event @ Err(HError::MiniBufferEvent(_)) => event?,
|
||||||
err @ Err(_) => err.log(),
|
err @ Err(_) => err.log(),
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
}
|
}
|
||||||
self.get_core()?.get_sender().send(Events::RequestInput)?;
|
self.get_core()?.get_sender().send(Events::RequestInput)?;
|
||||||
}
|
}
|
||||||
Events::WidgetReady => {
|
Events::WidgetReady => {
|
||||||
self.refresh().log();
|
return Err(HError::RefreshParent);
|
||||||
self.draw().log();
|
|
||||||
}
|
}
|
||||||
Events::Status(status) => {
|
Events::Status(status) => {
|
||||||
self.get_core()?.show_status(&status).log();
|
self.get_core()?.show_status(&status).log();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user