mirror of
https://github.com/ynqa/jnv.git
synced 2026-05-03 23:59:16 -05:00
chore: use promkit-widgets v0.2.0 and remove promkit-core crate, render.rs
This commit is contained in:
Generated
+539
-512
File diff suppressed because it is too large
Load Diff
+9
-7
@@ -12,21 +12,23 @@ readme = "README.md"
|
||||
anyhow = "1.0.97"
|
||||
arboard = { version = "3.4.1", features = ["wayland-data-control"] }
|
||||
async-trait = "0.1.88"
|
||||
clap = { version = "4.5.34", features = ["derive"] }
|
||||
clap = { version = "4.5.41", features = ["derive"] }
|
||||
duration-string = { version = "0.5.2", features = ["serde"] }
|
||||
derive_builder = "0.20.2"
|
||||
dirs = "6.0.0"
|
||||
futures = "0.3.30"
|
||||
promkit-widgets = { version = "0.2.0", features = ["jsonstream", "listbox", "text", "texteditor"] }
|
||||
serde = "1.0.219"
|
||||
tokio = { version = "1.44.1", features = ["full"] }
|
||||
tokio-stream = "0.1.16"
|
||||
toml = "0.9.2"
|
||||
|
||||
# jaq dependencies
|
||||
# TODO: bump up to v2.x.x
|
||||
jaq-core = "1.2.1"
|
||||
jaq-interpret = "1.2.1"
|
||||
jaq-parse = "1.0.2"
|
||||
jaq-std = "1.2.1"
|
||||
promkit-core = "0.1.0"
|
||||
promkit-widgets = { version = "0.1.0", features = ["jsonstream", "listbox", "text", "texteditor"] }
|
||||
serde = "1.0.219"
|
||||
tokio = { version = "1.44.1", features = ["full"] }
|
||||
tokio-stream = "0.1.16"
|
||||
toml = "0.8.20"
|
||||
|
||||
# The profile that 'cargo dist' will build with
|
||||
[profile.dist]
|
||||
|
||||
+6
-4
@@ -1,10 +1,12 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use promkit_core::crossterm::{
|
||||
event::{KeyCode, KeyModifiers},
|
||||
style::{Attribute, Attributes, Color, ContentStyle},
|
||||
use promkit_widgets::{
|
||||
core::crossterm::{
|
||||
event::{KeyCode, KeyModifiers},
|
||||
style::{Attribute, Attributes, Color, ContentStyle},
|
||||
},
|
||||
text_editor::Mode,
|
||||
};
|
||||
use promkit_widgets::text_editor::Mode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::time::Duration;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use promkit_core::crossterm::style::{Attribute, Attributes, Color, ContentStyle};
|
||||
use promkit_widgets::core::crossterm::style::{Attribute, Attributes, Color, ContentStyle};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use promkit_core::crossterm::event::{
|
||||
use promkit_widgets::core::crossterm::event::{
|
||||
Event, KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
+7
-7
@@ -1,13 +1,13 @@
|
||||
use std::{future::Future, pin::Pin};
|
||||
|
||||
use promkit_core::{
|
||||
crossterm::{
|
||||
event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers},
|
||||
style::{Color, ContentStyle},
|
||||
},
|
||||
Pane, PaneFactory,
|
||||
};
|
||||
use promkit_widgets::{
|
||||
core::{
|
||||
crossterm::{
|
||||
event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers},
|
||||
style::{Color, ContentStyle},
|
||||
},
|
||||
Pane, PaneFactory,
|
||||
},
|
||||
text::{self, Text},
|
||||
text_editor,
|
||||
};
|
||||
|
||||
+8
-8
@@ -1,14 +1,14 @@
|
||||
use jaq_interpret::{Ctx, FilterT, ParseCtx, RcIter, Val};
|
||||
use promkit_core::{
|
||||
crossterm::{
|
||||
event::Event,
|
||||
style::{Attribute, Attributes, Color, ContentStyle},
|
||||
},
|
||||
pane::Pane,
|
||||
PaneFactory,
|
||||
};
|
||||
|
||||
use promkit_widgets::{
|
||||
core::{
|
||||
crossterm::{
|
||||
event::Event,
|
||||
style::{Attribute, Attributes, Color, ContentStyle},
|
||||
},
|
||||
pane::Pane,
|
||||
PaneFactory,
|
||||
},
|
||||
jsonstream::{self, format::RowFormatter, jsonz, JsonStream},
|
||||
serde_json::{self, Deserializer, Value},
|
||||
text::{self, Text},
|
||||
|
||||
+1
-3
@@ -7,8 +7,8 @@ use std::{
|
||||
use anyhow::anyhow;
|
||||
use clap::Parser;
|
||||
use config::Config;
|
||||
use promkit_core::crossterm::style::Attribute;
|
||||
use promkit_widgets::{
|
||||
core::crossterm::style::Attribute,
|
||||
jsonstream::format::RowFormatter,
|
||||
listbox::{self, Listbox},
|
||||
text_editor::{self, TextEditor},
|
||||
@@ -25,8 +25,6 @@ use processor::{
|
||||
ViewProvider, Visualizer,
|
||||
};
|
||||
mod prompt;
|
||||
mod render;
|
||||
use render::{PaneIndex, Renderer, EMPTY_PANE};
|
||||
mod search;
|
||||
use search::{IncrementalSearcher, SearchProvider};
|
||||
|
||||
|
||||
+20
-15
@@ -1,12 +1,17 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use promkit_core::{crossterm::event::Event, pane::Pane};
|
||||
use promkit_widgets::core::{
|
||||
crossterm::event::Event,
|
||||
pane::{Pane, EMPTY_PANE},
|
||||
render::SharedRenderer,
|
||||
};
|
||||
use tokio::{sync::Mutex, task::JoinHandle};
|
||||
|
||||
use crate::{PaneIndex, Renderer, EMPTY_PANE};
|
||||
pub mod init;
|
||||
pub use init::ViewProvider;
|
||||
|
||||
use crate::prompt::Index;
|
||||
pub mod monitor;
|
||||
pub mod spinner;
|
||||
|
||||
@@ -58,7 +63,7 @@ impl Processor {
|
||||
&self,
|
||||
query: String,
|
||||
shared_visualizer: Arc<Mutex<impl Visualizer>>,
|
||||
shared_renderer: Arc<Mutex<Renderer>>,
|
||||
shared_renderer: SharedRenderer<Index>,
|
||||
) -> JoinHandle<()> {
|
||||
let shared = self.shared.clone();
|
||||
tokio::spawn(async move {
|
||||
@@ -83,16 +88,16 @@ impl Processor {
|
||||
}
|
||||
{
|
||||
// TODO: error handling
|
||||
let _ = shared_renderer.lock().await.update_and_draw([
|
||||
(
|
||||
PaneIndex::Guide,
|
||||
maybe_guide.unwrap_or(EMPTY_PANE.to_owned()),
|
||||
),
|
||||
(
|
||||
PaneIndex::Processor,
|
||||
maybe_resp.unwrap_or(EMPTY_PANE.to_owned()),
|
||||
),
|
||||
]);
|
||||
let _ = shared_renderer
|
||||
.update([
|
||||
(Index::Guide, maybe_guide.unwrap_or(EMPTY_PANE.to_owned())),
|
||||
(
|
||||
Index::Processor,
|
||||
maybe_resp.unwrap_or(EMPTY_PANE.to_owned()),
|
||||
),
|
||||
])
|
||||
.render()
|
||||
.await;
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -102,7 +107,7 @@ impl Processor {
|
||||
shared_visualizer: Arc<Mutex<impl Visualizer>>,
|
||||
area: (u16, u16),
|
||||
query: String,
|
||||
shared_renderer: Arc<Mutex<Renderer>>,
|
||||
shared_renderer: SharedRenderer<Index>,
|
||||
) {
|
||||
{
|
||||
let mut shared_state = self.shared.lock().await;
|
||||
@@ -124,7 +129,7 @@ impl Processor {
|
||||
&self,
|
||||
shared_visualizer: Arc<Mutex<impl Visualizer>>,
|
||||
query: String,
|
||||
shared_renderer: Arc<Mutex<Renderer>>,
|
||||
shared_renderer: SharedRenderer<Index>,
|
||||
) {
|
||||
{
|
||||
let mut shared_state = self.shared.lock().await;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use promkit_widgets::core::render::SharedRenderer;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use super::{Context, State, Visualizer};
|
||||
use crate::{config::JsonViewerKeybinds, PaneIndex, Renderer};
|
||||
use crate::{config::JsonViewerKeybinds, prompt::Index};
|
||||
|
||||
#[async_trait]
|
||||
pub trait ViewProvider {
|
||||
@@ -29,7 +30,7 @@ impl ViewInitializer {
|
||||
provider: &'a mut T,
|
||||
item: &'static str,
|
||||
area: (u16, u16),
|
||||
shared_renderer: Arc<Mutex<Renderer>>,
|
||||
shared_renderer: SharedRenderer<Index>,
|
||||
keybinds: JsonViewerKeybinds,
|
||||
) -> anyhow::Result<impl Visualizer + 'a> {
|
||||
{
|
||||
@@ -51,9 +52,9 @@ impl ViewInitializer {
|
||||
{
|
||||
// TODO: error handling
|
||||
let _ = shared_renderer
|
||||
.lock()
|
||||
.await
|
||||
.update_and_draw([(PaneIndex::Processor, pane)]);
|
||||
.update([(Index::Processor, pane)])
|
||||
.render()
|
||||
.await;
|
||||
}
|
||||
|
||||
Ok(visualizer)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use promkit_core::{grapheme::StyledGraphemes, Pane};
|
||||
use promkit_widgets::core::{grapheme::StyledGraphemes, render::SharedRenderer, Pane};
|
||||
use tokio::{sync::Mutex, task::JoinHandle, time::Duration};
|
||||
|
||||
use crate::prompt::Index;
|
||||
|
||||
use super::{Context, State};
|
||||
use crate::{PaneIndex, Renderer};
|
||||
|
||||
const LOADING_FRAMES: [&str; 10] = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
||||
|
||||
@@ -19,7 +20,7 @@ impl SpinnerSpawner {
|
||||
|
||||
pub fn spawn_spin_task(
|
||||
&self,
|
||||
shared_renderer: Arc<Mutex<Renderer>>,
|
||||
shared_renderer: SharedRenderer<Index>,
|
||||
spin_duration: Duration,
|
||||
) -> JoinHandle<()> {
|
||||
let shared = self.shared.clone();
|
||||
@@ -42,9 +43,9 @@ impl SpinnerSpawner {
|
||||
{
|
||||
// TODO: error handling
|
||||
let _ = shared_renderer
|
||||
.lock()
|
||||
.await
|
||||
.update_and_draw([(PaneIndex::Processor, pane)]);
|
||||
.update([(Index::Processor, pane)])
|
||||
.render()
|
||||
.await;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+95
-82
@@ -2,17 +2,23 @@ use std::{io, sync::Arc, time::Duration};
|
||||
|
||||
use arboard::Clipboard;
|
||||
use futures::StreamExt;
|
||||
use promkit_core::{
|
||||
crossterm::{
|
||||
cursor,
|
||||
event::{Event, EventStream, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers},
|
||||
execute,
|
||||
style::{Color, ContentStyle},
|
||||
terminal::{self, disable_raw_mode, enable_raw_mode},
|
||||
use promkit_widgets::{
|
||||
core::{
|
||||
crossterm::{
|
||||
cursor,
|
||||
event::{
|
||||
Event, EventStream, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers,
|
||||
},
|
||||
execute,
|
||||
style::{Color, ContentStyle},
|
||||
terminal::{self, disable_raw_mode, enable_raw_mode},
|
||||
},
|
||||
pane::EMPTY_PANE,
|
||||
render::{Renderer, SharedRenderer},
|
||||
PaneFactory,
|
||||
},
|
||||
PaneFactory,
|
||||
text::{self, Text},
|
||||
};
|
||||
use promkit_widgets::text::{self, Text};
|
||||
use tokio::{
|
||||
sync::{mpsc, Mutex, RwLock},
|
||||
task::JoinHandle,
|
||||
@@ -20,8 +26,8 @@ use tokio::{
|
||||
|
||||
use crate::{
|
||||
config::{event::Matcher, Keybinds, ReactivityControl},
|
||||
Context, ContextMonitor, Editor, PaneIndex, Processor, Renderer, SearchProvider,
|
||||
SpinnerSpawner, ViewInitializer, ViewProvider, Visualizer, EMPTY_PANE,
|
||||
Context, ContextMonitor, Editor, Processor, SearchProvider, SpinnerSpawner, ViewInitializer,
|
||||
ViewProvider, Visualizer,
|
||||
};
|
||||
|
||||
fn spawn_debouncer<T: Send + 'static>(
|
||||
@@ -90,6 +96,14 @@ enum Focus {
|
||||
Processor,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Index {
|
||||
Editor = 0,
|
||||
Guide = 1,
|
||||
Search = 2,
|
||||
Processor = 3,
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
item: &'static str,
|
||||
@@ -105,15 +119,19 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
|
||||
let size = terminal::size()?;
|
||||
|
||||
let shared_renderer = Arc::new(Mutex::new(Renderer::try_init_draw(
|
||||
[
|
||||
editor.create_editor_pane(size.0, size.1),
|
||||
EMPTY_PANE.to_owned(),
|
||||
EMPTY_PANE.to_owned(),
|
||||
EMPTY_PANE.to_owned(),
|
||||
],
|
||||
no_hint,
|
||||
)?));
|
||||
let shared_renderer = SharedRenderer::new(
|
||||
Renderer::try_new_with_panes(
|
||||
[
|
||||
(Index::Editor, editor.create_editor_pane(size.0, size.1)),
|
||||
(Index::Guide, EMPTY_PANE.to_owned()),
|
||||
(Index::Search, EMPTY_PANE.to_owned()),
|
||||
(Index::Processor, EMPTY_PANE.to_owned()),
|
||||
]
|
||||
.into_iter(),
|
||||
true,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
|
||||
let ctx = Arc::new(Mutex::new(Context::new(size)));
|
||||
|
||||
@@ -190,24 +208,23 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
kind: KeyEventKind::Press,
|
||||
state: KeyEventState::NONE,
|
||||
}) => {
|
||||
let mut pane = EMPTY_PANE.to_owned();
|
||||
if context_monitor.is_idle().await {
|
||||
processor_copy_tx.send(()).await?;
|
||||
} else {
|
||||
} else if !no_hint{
|
||||
let size = terminal::size()?;
|
||||
pane = text::State {
|
||||
text: Text::from("Failed to copy while rendering is in progress.".to_string()),
|
||||
style: ContentStyle {
|
||||
foreground_color: Some(Color::Yellow),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}.create_pane(size.0, size.1);
|
||||
}
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Guide, pane),
|
||||
])?;
|
||||
shared_renderer.update([
|
||||
(
|
||||
Index::Guide,
|
||||
text::State {
|
||||
text: Text::from("Failed to copy while rendering is in progress.".to_string()),
|
||||
style: ContentStyle {
|
||||
foreground_color: Some(Color::Yellow),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}.create_pane(size.0, size.1),
|
||||
),
|
||||
]).render().await?;
|
||||
}
|
||||
},
|
||||
Event::Key(KeyEvent {
|
||||
@@ -223,25 +240,23 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
}) => {
|
||||
match focus {
|
||||
Focus::Editor => {
|
||||
let mut pane = EMPTY_PANE.to_owned();
|
||||
if context_monitor.is_idle().await {
|
||||
focus = Focus::Processor;
|
||||
editor_focus_tx.send(false).await?;
|
||||
} else {
|
||||
} else if !no_hint{
|
||||
let size = terminal::size()?;
|
||||
pane = text::State {
|
||||
text: Text::from("Failed to switch pane while rendering is in progress.".to_string()),
|
||||
style: ContentStyle {
|
||||
foreground_color: Some(Color::Yellow),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}.create_pane(size.0, size.1);
|
||||
}
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Guide, pane),
|
||||
])?;
|
||||
shared_renderer.update([
|
||||
(
|
||||
Index::Guide,
|
||||
text::State {
|
||||
text: Text::from("Failed to switch pane while rendering is in progress.".to_string()),
|
||||
style: ContentStyle {
|
||||
foreground_color: Some(Color::Yellow),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}.create_pane(size.0, size.1)),
|
||||
]).render().await?;
|
||||
}
|
||||
},
|
||||
Focus::Processor => {
|
||||
@@ -290,25 +305,23 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
editor.create_guide_pane(size.0, size.1),
|
||||
)
|
||||
};
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Editor, editor_pane),
|
||||
(PaneIndex::Guide, guide_pane),
|
||||
])?;
|
||||
}
|
||||
shared_renderer.update([
|
||||
(Index::Editor, editor_pane),
|
||||
(Index::Guide, if !no_hint { guide_pane } else { EMPTY_PANE.to_owned() }),
|
||||
]).render().await?;
|
||||
}
|
||||
Some(()) = editor_copy_rx.recv() => {
|
||||
let text = {
|
||||
let editor = shared_editor.write().await;
|
||||
let editor = shared_editor.read().await;
|
||||
editor.text()
|
||||
};
|
||||
let guide = copy_to_clipboard(&text);
|
||||
let size = terminal::size()?;
|
||||
let pane = guide.create_pane(size.0, size.1);
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Guide, pane),
|
||||
])?;
|
||||
if !no_hint {
|
||||
let size = terminal::size()?;
|
||||
let pane = guide.create_pane(size.0, size.1);
|
||||
shared_renderer.update([
|
||||
(Index::Guide, pane),
|
||||
]).render().await?;
|
||||
}
|
||||
}
|
||||
Some(event) = editor_event_rx.recv() => {
|
||||
@@ -331,11 +344,11 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
)
|
||||
};
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Editor, editor_pane),
|
||||
(PaneIndex::Guide, guide_pane),
|
||||
(PaneIndex::Search, searcher_pane),
|
||||
])?;
|
||||
shared_renderer.update([
|
||||
(Index::Editor, editor_pane),
|
||||
(Index::Guide, if !no_hint { guide_pane } else { EMPTY_PANE.to_owned() }),
|
||||
(Index::Search, searcher_pane),
|
||||
]).render().await?;
|
||||
}
|
||||
}
|
||||
else => {
|
||||
@@ -358,12 +371,12 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
Some(()) = processor_copy_rx.recv() => {
|
||||
let visualizer = shared_visualizer.lock().await;
|
||||
let guide = copy_to_clipboard(&visualizer.content_to_copy().await);
|
||||
let size = terminal::size()?;
|
||||
let pane = guide.create_pane(size.0, size.1);
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Guide, pane),
|
||||
])?;
|
||||
if !no_hint {
|
||||
let size = terminal::size()?;
|
||||
let pane = guide.create_pane(size.0, size.1);
|
||||
shared_renderer.update([
|
||||
(Index::Guide, pane),
|
||||
]).render().await?;
|
||||
}
|
||||
}
|
||||
Some(event) = processor_event_rx.recv() => {
|
||||
@@ -372,9 +385,9 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
visualizer.create_pane_from_event((size.0, size.1), &event).await
|
||||
};
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Processor, pane),
|
||||
])?;
|
||||
shared_renderer.update([
|
||||
(Index::Processor, pane),
|
||||
]).render().await?;
|
||||
}
|
||||
}
|
||||
Some(query) = last_query_rx.recv() => {
|
||||
@@ -394,11 +407,11 @@ pub async fn run<T: ViewProvider + SearchProvider>(
|
||||
)
|
||||
};
|
||||
{
|
||||
shared_renderer.lock().await.update_and_draw([
|
||||
(PaneIndex::Editor, editor_pane),
|
||||
(PaneIndex::Guide, guide_pane),
|
||||
(PaneIndex::Search, searcher_pane),
|
||||
])?;
|
||||
shared_renderer.update([
|
||||
(Index::Editor, editor_pane),
|
||||
(Index::Guide, if !no_hint { guide_pane } else { EMPTY_PANE.to_owned() }),
|
||||
(Index::Search, searcher_pane),
|
||||
]).render().await?;
|
||||
}
|
||||
let text = {
|
||||
let editor = shared_editor.read().await;
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use promkit_core::{crossterm::cursor, pane::Pane, terminal::Terminal};
|
||||
|
||||
// TODO: One Guide is sufficient.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum PaneIndex {
|
||||
Editor = 0,
|
||||
Guide = 1,
|
||||
Search = 2,
|
||||
Processor = 3,
|
||||
}
|
||||
|
||||
pub static EMPTY_PANE: LazyLock<Pane> = LazyLock::new(|| Pane::new(vec![], 0));
|
||||
const PANE_SIZE: usize = PaneIndex::Processor as usize + 1;
|
||||
|
||||
pub struct Renderer {
|
||||
no_hint: bool,
|
||||
terminal: Terminal,
|
||||
panes: [Pane; PANE_SIZE],
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
pub fn try_init_draw(init_panes: [Pane; PANE_SIZE], no_hint: bool) -> anyhow::Result<Self> {
|
||||
let mut ret = Self {
|
||||
no_hint,
|
||||
terminal: Terminal {
|
||||
position: cursor::position()?,
|
||||
},
|
||||
panes: init_panes,
|
||||
};
|
||||
ret.terminal.draw(&ret.panes)?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn update_and_draw<I: IntoIterator<Item = (PaneIndex, Pane)>>(
|
||||
&mut self,
|
||||
iter: I,
|
||||
) -> anyhow::Result<()> {
|
||||
for (index, pane) in iter {
|
||||
if self.no_hint && index == PaneIndex::Guide {
|
||||
continue;
|
||||
}
|
||||
self.panes[index as usize] = pane;
|
||||
}
|
||||
self.terminal.draw(&self.panes)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -2,8 +2,10 @@ use std::{collections::BTreeSet, sync::Arc};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use async_trait::async_trait;
|
||||
use promkit_core::{pane::Pane, PaneFactory};
|
||||
use promkit_widgets::listbox::{self, Listbox};
|
||||
use promkit_widgets::{
|
||||
core::{pane::Pane, PaneFactory},
|
||||
listbox::{self, Listbox},
|
||||
};
|
||||
use tokio::{
|
||||
sync::{Mutex, RwLock},
|
||||
task::JoinHandle,
|
||||
|
||||
Reference in New Issue
Block a user