diff --git a/Cargo.lock b/Cargo.lock index f14317292..c2fc99829 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -827,6 +827,15 @@ dependencies = [ "which", ] +[[package]] +name = "helix-graphics" +version = "0.6.0" +dependencies = [ + "bitflags", + "crossterm", + "serde", +] + [[package]] name = "helix-loader" version = "0.6.0" @@ -906,7 +915,7 @@ dependencies = [ "cassowary", "crossterm", "helix-core", - "helix-view", + "helix-graphics", "serde", "unicode-segmentation", ] @@ -937,7 +946,9 @@ dependencies = [ "futures-util", "helix-core", "helix-dap", + "helix-graphics", "helix-lsp", + "helix-tui", "log", "once_cell", "serde", diff --git a/Cargo.toml b/Cargo.toml index a88c8bc37..6c47188a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "helix-view", "helix-term", "helix-tui", + "helix-graphics", "helix-ui", "helix-lsp", "helix-dap", diff --git a/helix-graphics/Cargo.toml b/helix-graphics/Cargo.toml new file mode 100644 index 000000000..e2a4cf246 --- /dev/null +++ b/helix-graphics/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "helix-graphics" +version = "0.6.0" +authors = ["Blaž Hrastnik "] +edition = "2021" +license = "MPL-2.0" +repository = "https://github.com/helix-editor/helix" +homepage = "https://helix-editor.com" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/ + +[features] +term = ["crossterm"] + +[dependencies] +bitflags = "1.3" +serde = { version = "1.0", features = ["derive"] } + +crossterm = { version = "0.23", optional = true } + +# TODO: graphics.rs tests rely on this, but we should remove that +# [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +# helix-tui = { path = "../helix-tui" } diff --git a/helix-view/src/graphics.rs b/helix-graphics/src/lib.rs similarity index 100% rename from helix-view/src/graphics.rs rename to helix-graphics/src/lib.rs diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 5913f9711..cc5ff0c4c 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -15,13 +15,16 @@ use helix_view::{align_view, editor::ConfigEvent, graphics::Rect, theme, Align, use crate::{ args::Args, - compositor::{Compositor, Event}, config::Config, - job::Jobs, keymap::Keymaps, ui::{self, overlay::overlayed}, }; +use helix_view::{ + compositor::{Compositor, Event}, + job::Jobs, +}; + use std::{ io::{stdin, stdout, Write}, sync::Arc, @@ -233,7 +236,7 @@ impl Application { // let area = *surface.area(); - let mut render_cx = crate::compositor::RenderContext { + let mut render_cx = helix_view::compositor::RenderContext { editor: &self.editor, surface, scroll: None, @@ -384,13 +387,13 @@ impl Application { } pub fn handle_idle_timeout(&mut self) { - use crate::compositor::EventResult; + use helix_view::compositor::EventResult; let editor_view = self .compositor .find::() .expect("expected at least one EditorView"); - let mut cx = crate::compositor::Context { + let mut cx = helix_view::compositor::Context { editor: &mut self.editor, jobs: &mut self.jobs, }; @@ -403,7 +406,7 @@ impl Application { &mut self, event: Option>, ) { - let mut cx = crate::compositor::Context { + let mut cx = helix_view::compositor::Context { editor: &mut self.editor, jobs: &mut self.jobs, }; diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 115e04a16..ac2266767 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -40,6 +40,11 @@ use helix_view::{ Document, DocumentId, Editor, ViewId, }; +use helix_view::{ + compositor::{self, Component, Compositor}, + job::{self, Job, Jobs}, +}; + use anyhow::{anyhow, bail, ensure, Context as _}; use fuzzy_matcher::FuzzyMatcher; use insert::*; @@ -47,11 +52,9 @@ use movement::Movement; use crate::{ args, - compositor::{self, Component, Compositor}, ui::{self, overlay::overlayed, FilePicker, Picker, Popup, Prompt, PromptEvent}, }; -use crate::job::{self, Job, Jobs}; use futures_util::{FutureExt, StreamExt}; use std::{collections::HashMap, fmt, future::Future}; use std::{collections::HashSet, num::NonZeroUsize}; @@ -74,7 +77,7 @@ pub struct Context<'a> { pub count: Option, pub editor: &'a mut Editor, - pub callback: Option, + pub callback: Option, pub on_next_key_callback: Option>, pub jobs: &'a mut Jobs, } diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs index b897b2d58..2ef8b5ff0 100644 --- a/helix-term/src/commands/dap.rs +++ b/helix-term/src/commands/dap.rs @@ -1,13 +1,13 @@ use super::{Context, Editor}; -use crate::{ - compositor::{self, Compositor}, - job::{Callback, Jobs}, - ui::{self, overlay::overlayed, FilePicker, Picker, Popup, Prompt, PromptEvent, Text}, -}; +use crate::ui::{self, overlay::overlayed, FilePicker, Picker, Popup, Prompt, PromptEvent, Text}; use helix_core::syntax::{DebugArgumentValue, DebugConfigCompletion}; use helix_dap::{self as dap, Client}; use helix_lsp::block_on; use helix_view::editor::Breakpoint; +use helix_view::{ + compositor::{self, Compositor}, + job::{Callback, Jobs}, +}; use serde_json::{to_value, Value}; use tokio_stream::wrappers::UnboundedReceiverStream; diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index 90a1ad7f8..3fafb03ee 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -9,10 +9,8 @@ use super::{align_view, push_jump, Align, Context, Editor}; use helix_core::Selection; use helix_view::editor::Action; -use crate::{ - compositor::{self, Compositor}, - ui::{self, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent}, -}; +use crate::ui::{self, overlay::overlayed, FileLocation, FilePicker, Popup, PromptEvent}; +use helix_view::compositor::{self, Compositor}; use std::borrow::Cow; diff --git a/helix-term/src/lib.rs b/helix-term/src/lib.rs index a945b20de..d7f527859 100644 --- a/helix-term/src/lib.rs +++ b/helix-term/src/lib.rs @@ -4,10 +4,8 @@ extern crate helix_view; pub mod application; pub mod args; pub mod commands; -pub mod compositor; pub mod config; pub mod health; -pub mod job; pub mod keymap; pub mod ui; pub use keymap::macros::*; diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index cf2644d29..b144a78b8 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -1,4 +1,4 @@ -use crate::compositor::{Component, Context, Event, EventResult, RenderContext}; +use helix_view::compositor::{Component, Context, Event, EventResult, RenderContext}; use helix_view::editor::CompleteAction; use std::borrow::Cow; diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index baa4bf563..e6f4c1096 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1,11 +1,11 @@ use crate::{ - commands, - compositor::{Component, Context, Event, EventResult, RenderContext}, - key, + commands, key, keymap::{KeymapResult, Keymaps}, ui::{Completion, ProgressSpinners}, }; +use helix_view::compositor::{Component, Context, Event, EventResult, RenderContext}; + use helix_core::{ coords_at_pos, encoding, graphemes::{ @@ -928,7 +928,7 @@ impl EditorView { editor.clear_idle_timer(); // don't retrigger } - pub fn handle_idle_timeout(&mut self, cx: &mut crate::compositor::Context) -> EventResult { + pub fn handle_idle_timeout(&mut self, cx: &mut helix_view::compositor::Context) -> EventResult { if self.completion.is_some() || !cx.editor.config().auto_completion || doc!(cx.editor).mode != Mode::Insert @@ -1163,7 +1163,7 @@ impl Component for EditorView { fn handle_event( &mut self, event: Event, - context: &mut crate::compositor::Context, + context: &mut helix_view::compositor::Context, ) -> EventResult { let mut cx = commands::Context { editor: context.editor, diff --git a/helix-term/src/ui/info.rs b/helix-term/src/ui/info.rs deleted file mode 100644 index 1530bd297..000000000 --- a/helix-term/src/ui/info.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::compositor::{Component, RenderContext}; -use helix_view::graphics::{Margin, Rect}; -use helix_view::info::Info; -use tui::widgets::{Block, Borders, Paragraph, Widget}; - -impl Component for Info { - fn render(&mut self, viewport: Rect, cx: &mut RenderContext<'_>) { - let text_style = cx.editor.theme.get("ui.text.info"); - let popup_style = cx.editor.theme.get("ui.popup.info"); - - // Calculate the area of the terminal to modify. Because we want to - // render at the bottom right, we use the viewport's width and height - // which evaluate to the most bottom right coordinate. - let width = self.width + 2 + 2; // +2 for border, +2 for margin - let height = self.height + 2; // +2 for border - let area = viewport.intersection(Rect::new( - viewport.width.saturating_sub(width), - viewport.height.saturating_sub(height + 2), // +2 for statusline - width, - height, - )); - cx.surface.clear_with(area, popup_style); - - let block = Block::default() - .title(self.title.as_str()) - .borders(Borders::ALL) - .border_style(popup_style); - - let margin = Margin { - vertical: 0, - horizontal: 1, - }; - let inner = block.inner(area).inner(&margin); - block.render(area, cx.surface); - - Paragraph::new(self.text.as_str()) - .style(text_style) - .render(inner, cx.surface); - } -} diff --git a/helix-term/src/ui/markdown.rs b/helix-term/src/ui/markdown.rs index 830f59a1b..6ed08dd92 100644 --- a/helix-term/src/ui/markdown.rs +++ b/helix-term/src/ui/markdown.rs @@ -1,4 +1,4 @@ -use crate::compositor::{Component, RenderContext}; +use helix_view::compositor::{Component, RenderContext}; use tui::text::{Span, Spans, Text}; use std::sync::Arc; diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 6c11618a1..8bc97d500 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -1,6 +1,6 @@ -use crate::{ - compositor::{Callback, Component, Compositor, Context, Event, EventResult, RenderContext}, - ctrl, key, shift, +use crate::{ctrl, key, shift}; +use helix_view::compositor::{ + Callback, Component, Compositor, Context, Event, EventResult, RenderContext, }; use tui::widgets::Table; diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 2dca870ba..7f7df2022 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -1,6 +1,5 @@ mod completion; pub(crate) mod editor; -mod info; mod markdown; pub mod menu; pub mod overlay; @@ -31,7 +30,7 @@ pub fn prompt( prompt: std::borrow::Cow<'static, str>, history_register: Option, completion_fn: impl FnMut(&Editor, &str) -> Vec + 'static, - callback_fn: impl FnMut(&mut crate::compositor::Context, &str, PromptEvent) + 'static, + callback_fn: impl FnMut(&mut helix_view::compositor::Context, &str, PromptEvent) + 'static, ) { let mut prompt = Prompt::new(prompt, history_register, completion_fn, callback_fn); // Calculate initial completion @@ -56,7 +55,7 @@ pub fn regex_prompt( prompt, history_register, completion_fn, - move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| { + move |cx: &mut helix_view::compositor::Context, input: &str, event: PromptEvent| { match event { PromptEvent::Abort => { let (view, doc) = current!(cx.editor); diff --git a/helix-term/src/ui/overlay.rs b/helix-term/src/ui/overlay.rs index 3efacdc91..c0e52654b 100644 --- a/helix-term/src/ui/overlay.rs +++ b/helix-term/src/ui/overlay.rs @@ -4,7 +4,7 @@ use helix_view::{ Editor, }; -use crate::compositor::{Component, Context, Event, EventResult, RenderContext}; +use helix_view::compositor::{Component, Context, Event, EventResult, RenderContext}; /// Contains a component placed in the center of the parent component pub struct Overlay { diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 67e780dac..c7381c997 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -1,8 +1,8 @@ use crate::{ - compositor::{Component, Compositor, Context, Event, EventResult, RenderContext}, ctrl, key, shift, ui::{self, EditorView}, }; +use helix_view::compositor::{Component, Compositor, Context, Event, EventResult, RenderContext}; use tui::widgets::{Block, BorderType, Borders}; use fuzzy_matcher::skim::SkimMatcherV2 as Matcher; diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs index 873d8540b..c58146e59 100644 --- a/helix-term/src/ui/popup.rs +++ b/helix-term/src/ui/popup.rs @@ -1,7 +1,5 @@ -use crate::{ - compositor::{Callback, Component, Context, Event, EventResult, RenderContext}, - ctrl, key, -}; +use crate::{ctrl, key}; +use helix_view::compositor::{Callback, Component, Context, Event, EventResult, RenderContext}; use helix_core::Position; use helix_view::{ diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index cb4318065..1b85758ec 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -1,4 +1,4 @@ -use crate::compositor::{Component, Compositor, Context, Event, EventResult, RenderContext}; +use helix_view::compositor::{Component, Compositor, Context, Event, EventResult, RenderContext}; use crate::{alt, ctrl, key, shift, ui}; use helix_view::input::KeyEvent; use helix_view::keyboard::KeyCode; diff --git a/helix-term/src/ui/text.rs b/helix-term/src/ui/text.rs index 00cd21db3..4097deb56 100644 --- a/helix-term/src/ui/text.rs +++ b/helix-term/src/ui/text.rs @@ -1,4 +1,4 @@ -use crate::compositor::{Component, RenderContext}; +use helix_view::compositor::{Component, RenderContext}; use helix_view::graphics::Rect; diff --git a/helix-tui/Cargo.toml b/helix-tui/Cargo.toml index e4cfbe4cd..26e1e1335 100644 --- a/helix-tui/Cargo.toml +++ b/helix-tui/Cargo.toml @@ -21,5 +21,5 @@ cassowary = "0.3" unicode-segmentation = "1.9" crossterm = { version = "0.23", optional = true } serde = { version = "1", "optional" = true, features = ["derive"]} -helix-view = { version = "0.6", path = "../helix-view", features = ["term"] } +helix-graphics = { version = "0.6", path = "../helix-graphics", features = ["term"] } helix-core = { version = "0.6", path = "../helix-core" } diff --git a/helix-tui/src/backend/crossterm.rs b/helix-tui/src/backend/crossterm.rs index eff098b35..69334f595 100644 --- a/helix-tui/src/backend/crossterm.rs +++ b/helix-tui/src/backend/crossterm.rs @@ -8,7 +8,7 @@ use crossterm::{ }, terminal::{self, Clear, ClearType}, }; -use helix_view::graphics::{Color, CursorKind, Modifier, Rect}; +use helix_graphics::{Color, CursorKind, Modifier, Rect}; use std::io::{self, Write}; pub struct CrosstermBackend { diff --git a/helix-tui/src/backend/mod.rs b/helix-tui/src/backend/mod.rs index c6c11019d..c3edbe98f 100644 --- a/helix-tui/src/backend/mod.rs +++ b/helix-tui/src/backend/mod.rs @@ -2,7 +2,7 @@ use std::io; use crate::buffer::Cell; -use helix_view::graphics::{CursorKind, Rect}; +use helix_graphics::{CursorKind, Rect}; #[cfg(feature = "crossterm")] mod crossterm; diff --git a/helix-tui/src/backend/test.rs b/helix-tui/src/backend/test.rs index 52474148e..db6be26d6 100644 --- a/helix-tui/src/backend/test.rs +++ b/helix-tui/src/backend/test.rs @@ -3,7 +3,7 @@ use crate::{ buffer::{Buffer, Cell}, }; use helix_core::unicode::width::UnicodeWidthStr; -use helix_view::graphics::{CursorKind, Rect}; +use helix_graphics::{CursorKind, Rect}; use std::{fmt::Write, io}; /// A backend used for the integration tests. diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index 21c53aadf..5dac08f8e 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -3,7 +3,7 @@ use helix_core::unicode::width::UnicodeWidthStr; use std::cmp::min; use unicode_segmentation::UnicodeSegmentation; -use helix_view::graphics::{Color, Modifier, Rect, Style}; +use helix_graphics::{Color, Modifier, Rect, Style}; /// A buffer cell #[derive(Debug, Clone, PartialEq)] @@ -87,7 +87,7 @@ impl Default for Cell { /// /// ``` /// use helix_tui::buffer::{Buffer, Cell}; -/// use helix_view::graphics::{Rect, Color, Style, Modifier}; +/// use helix_graphics::{Rect, Color, Style, Modifier}; /// /// let mut buf = Buffer::empty(Rect{x: 0, y: 0, width: 10, height: 5}); /// buf[(0, 2)].set_symbol("x"); @@ -179,7 +179,7 @@ impl Buffer { /// /// ``` /// # use helix_tui::buffer::Buffer; - /// # use helix_view::graphics::Rect; + /// # use helix_graphics::Rect; /// let rect = Rect::new(200, 100, 10, 10); /// let buffer = Buffer::empty(rect); /// // Global coordinates inside the Buffer's area @@ -204,7 +204,7 @@ impl Buffer { /// /// ``` /// # use helix_tui::buffer::Buffer; - /// # use helix_view::graphics::Rect; + /// # use helix_graphics::Rect; /// let rect = Rect::new(200, 100, 10, 10); /// let buffer = Buffer::empty(rect); /// // Global coordinates to the top corner of this Buffer's area @@ -243,7 +243,7 @@ impl Buffer { /// /// ``` /// # use helix_tui::buffer::Buffer; - /// # use helix_view::graphics::Rect; + /// # use helix_graphics::Rect; /// let rect = Rect::new(200, 100, 10, 10); /// let buffer = Buffer::empty(rect); /// assert_eq!(buffer.pos_of(0), (200, 100)); diff --git a/helix-tui/src/layout.rs b/helix-tui/src/layout.rs index e6a84aa04..5c79904a2 100644 --- a/helix-tui/src/layout.rs +++ b/helix-tui/src/layout.rs @@ -5,7 +5,7 @@ use cassowary::strength::{REQUIRED, WEAK}; use cassowary::WeightedRelation::*; use cassowary::{Constraint as CassowaryConstraint, Expression, Solver, Variable}; -use helix_view::graphics::{Margin, Rect}; +use helix_graphics::{Margin, Rect}; #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] pub enum Corner { @@ -115,7 +115,7 @@ impl Layout { /// # Examples /// ``` /// # use helix_tui::layout::{Constraint, Direction, Layout}; - /// # use helix_view::graphics::Rect; + /// # use helix_graphics::Rect; /// let chunks = Layout::default() /// .direction(Direction::Vertical) /// .constraints([Constraint::Length(5), Constraint::Min(0)].as_ref()) diff --git a/helix-tui/src/terminal.rs b/helix-tui/src/terminal.rs index 22e9232f3..de6d891af 100644 --- a/helix-tui/src/terminal.rs +++ b/helix-tui/src/terminal.rs @@ -1,5 +1,5 @@ use crate::{backend::Backend, buffer::Buffer}; -use helix_view::graphics::{CursorKind, Rect}; +use helix_graphics::{CursorKind, Rect}; use std::io; #[derive(Debug, Clone, PartialEq)] diff --git a/helix-tui/src/text.rs b/helix-tui/src/text.rs index 8a974ddba..713f6eb1c 100644 --- a/helix-tui/src/text.rs +++ b/helix-tui/src/text.rs @@ -21,7 +21,7 @@ //! ```rust //! # use helix_tui::widgets::Block; //! # use helix_tui::text::{Span, Spans}; -//! # use helix_view::graphics::{Color, Style}; +//! # use helix_graphics::{Color, Style}; //! // A simple string with no styling. //! // Converted to Spans(vec![ //! // Span { content: Cow::Borrowed("My title"), style: Style { .. } } @@ -48,7 +48,7 @@ //! ``` use helix_core::line_ending::str_is_line_ending; use helix_core::unicode::width::UnicodeWidthStr; -use helix_view::graphics::Style; +use helix_graphics::Style; use std::borrow::Cow; use unicode_segmentation::UnicodeSegmentation; @@ -92,7 +92,7 @@ impl<'a> Span<'a> { /// /// ```rust /// # use helix_tui::text::Span; - /// # use helix_view::graphics::{Color, Modifier, Style}; + /// # use helix_graphics::{Color, Modifier, Style}; /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC); /// Span::styled("My text", style); /// Span::styled(String::from("My text"), style); @@ -121,7 +121,7 @@ impl<'a> Span<'a> { /// /// ```rust /// # use helix_tui::text::{Span, StyledGrapheme}; - /// # use helix_view::graphics::{Color, Modifier, Style}; + /// # use helix_graphics::{Color, Modifier, Style}; /// # use std::iter::Iterator; /// let style = Style::default().fg(Color::Yellow); /// let span = Span::styled("Text", style); @@ -205,7 +205,7 @@ impl<'a> Spans<'a> { /// /// ```rust /// # use helix_tui::text::{Span, Spans}; - /// # use helix_view::graphics::{Color, Style}; + /// # use helix_graphics::{Color, Style}; /// let spans = Spans::from(vec![ /// Span::styled("My", Style::default().fg(Color::Yellow)), /// Span::raw(" text"), @@ -259,7 +259,7 @@ impl<'a> From> for String { /// /// ```rust /// # use helix_tui::text::Text; -/// # use helix_view::graphics::{Color, Modifier, Style}; +/// # use helix_graphics::{Color, Modifier, Style}; /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC); /// /// // An initial two lines of `Text` built from a `&str` @@ -307,7 +307,7 @@ impl<'a> Text<'a> { /// /// ```rust /// # use helix_tui::text::Text; - /// # use helix_view::graphics::{Color, Modifier, Style}; + /// # use helix_graphics::{Color, Modifier, Style}; /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC); /// Text::styled("The first line\nThe second line", style); /// Text::styled(String::from("The first line\nThe second line"), style); @@ -357,7 +357,7 @@ impl<'a> Text<'a> { /// /// ```rust /// # use helix_tui::text::Text; - /// # use helix_view::graphics::{Color, Modifier, Style}; + /// # use helix_graphics::{Color, Modifier, Style}; /// let style = Style::default().fg(Color::Yellow).add_modifier(Modifier::ITALIC); /// let mut raw_text = Text::raw("The first line\nThe second line"); /// let styled_text = Text::styled(String::from("The first line\nThe second line"), style); diff --git a/helix-tui/src/widgets/block.rs b/helix-tui/src/widgets/block.rs index 26223c3eb..b5d555477 100644 --- a/helix-tui/src/widgets/block.rs +++ b/helix-tui/src/widgets/block.rs @@ -4,7 +4,7 @@ use crate::{ text::{Span, Spans}, widgets::{Borders, Widget}, }; -use helix_view::graphics::{Rect, Style}; +use helix_graphics::{Rect, Style}; #[derive(Debug, Clone, Copy, PartialEq)] pub enum BorderType { @@ -32,7 +32,7 @@ impl BorderType { /// /// ``` /// # use helix_tui::widgets::{Block, BorderType, Borders}; -/// # use helix_view::graphics::{Style, Color}; +/// # use helix_graphics::{Style, Color}; /// Block::default() /// .title("Block") /// .borders(Borders::LEFT | Borders::RIGHT) diff --git a/helix-tui/src/widgets/mod.rs b/helix-tui/src/widgets/mod.rs index e5608a79e..b28a4df7e 100644 --- a/helix-tui/src/widgets/mod.rs +++ b/helix-tui/src/widgets/mod.rs @@ -23,7 +23,7 @@ pub use self::table::{Cell, Row, Table, TableState}; use crate::buffer::Buffer; use bitflags::bitflags; -use helix_view::graphics::Rect; +use helix_graphics::Rect; bitflags! { /// Bitflags that can be composed to set the visible borders essentially on the block widget. diff --git a/helix-tui/src/widgets/paragraph.rs b/helix-tui/src/widgets/paragraph.rs index 4e8391621..a7bbbb70a 100644 --- a/helix-tui/src/widgets/paragraph.rs +++ b/helix-tui/src/widgets/paragraph.rs @@ -8,7 +8,7 @@ use crate::{ }, }; use helix_core::unicode::width::UnicodeWidthStr; -use helix_view::graphics::{Rect, Style}; +use helix_graphics::{Rect, Style}; use std::iter; fn get_line_offset(line_width: u16, text_area_width: u16, alignment: Alignment) -> u16 { @@ -27,7 +27,7 @@ fn get_line_offset(line_width: u16, text_area_width: u16, alignment: Alignment) /// # use helix_tui::text::{Text, Spans, Span}; /// # use helix_tui::widgets::{Block, Borders, Paragraph, Wrap}; /// # use helix_tui::layout::{Alignment}; -/// # use helix_view::graphics::{Style, Color, Modifier}; +/// # use helix_graphics::{Style, Color, Modifier}; /// let text = vec![ /// Spans::from(vec![ /// Span::raw("First"), diff --git a/helix-tui/src/widgets/table.rs b/helix-tui/src/widgets/table.rs index eb03704ea..2b5f3a188 100644 --- a/helix-tui/src/widgets/table.rs +++ b/helix-tui/src/widgets/table.rs @@ -10,7 +10,7 @@ use cassowary::{ {Expression, Solver}, }; use helix_core::unicode::width::UnicodeWidthStr; -use helix_view::graphics::{Rect, Style}; +use helix_graphics::{Rect, Style}; use std::collections::HashMap; /// A [`Cell`] contains the [`Text`] to be displayed in a [`Row`] of a [`Table`]. @@ -19,7 +19,7 @@ use std::collections::HashMap; /// ```rust /// # use helix_tui::widgets::Cell; /// # use helix_tui::text::{Span, Spans, Text}; -/// # use helix_view::graphics::{Style, Modifier}; +/// # use helix_graphics::{Style, Modifier}; /// Cell::from("simple string"); /// /// Cell::from(Span::from("span")); @@ -71,7 +71,7 @@ where /// But if you need a bit more control over individual cells, you can explicitly create [`Cell`]s: /// ```rust /// # use helix_tui::widgets::{Row, Cell}; -/// # use helix_view::graphics::{Style, Color}; +/// # use helix_graphics::{Style, Color}; /// Row::new(vec![ /// Cell::from("Cell1"), /// Cell::from("Cell2").style(Style::default().fg(Color::Yellow)), @@ -134,7 +134,7 @@ impl<'a> Row<'a> { /// ```rust /// # use helix_tui::widgets::{Block, Borders, Table, Row, Cell}; /// # use helix_tui::layout::Constraint; -/// # use helix_view::graphics::{Style, Color, Modifier}; +/// # use helix_graphics::{Style, Color, Modifier}; /// # use helix_tui::text::{Text, Spans, Span}; /// Table::new(vec![ /// // Row can be created from simple strings. diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 3074fb781..15478e81a 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -14,18 +14,20 @@ homepage = "https://helix-editor.com" lsp = ["helix-lsp", "tokio-runtime"] dap = ["helix-dap", "tokio-stream", "tokio-runtime"] tokio-runtime = ["tokio"] -term = ["crossterm"] +term = ["crossterm", "tui"] [dependencies] bitflags = "1.3" anyhow = "1" helix-core = { version = "0.6", path = "../helix-core" } +helix-graphics = { version = "0.6", path = "../helix-graphics" } helix-lsp = { version = "0.6", path = "../helix-lsp", optional = true } helix-dap = { version = "0.6", path = "../helix-dap", optional = true } tokio-stream = { version = "0.1", optional = true } tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"], optional = true } crossterm = { version = "0.23", optional = true } +tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = ["crossterm"], optional = true } # Conversion traits once_cell = "1.10" @@ -49,7 +51,3 @@ which = "4.2" [target.'cfg(windows)'.dependencies] clipboard-win = { version = "4.4", features = ["std"] } - -# TODO: graphics.rs tests rely on this, but we should remove that -# [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -# helix-tui = { path = "../helix-tui" } diff --git a/helix-term/src/compositor.rs b/helix-view/src/compositor.rs similarity index 97% rename from helix-term/src/compositor.rs rename to helix-view/src/compositor.rs index 12171d71f..e66a8d89d 100644 --- a/helix-term/src/compositor.rs +++ b/helix-view/src/compositor.rs @@ -1,8 +1,8 @@ // Each component declares it's own size constraints and gets fitted based on it's parent. // Q: how does this work with popups? // cursive does compositor.screen_mut().add_layer_at(pos::absolute(x, y), ) +use crate::graphics::{CursorKind, Rect}; use helix_core::Position; -use helix_view::graphics::{CursorKind, Rect}; pub type Callback = Box; @@ -13,15 +13,16 @@ pub enum EventResult { } use crate::job::Jobs; -use helix_view::Editor; +use crate::Editor; -pub use helix_view::input::Event; +pub use crate::input::Event; pub struct Context<'a> { pub editor: &'a mut Editor, pub jobs: &'a mut Jobs, } +#[cfg(feature = "term")] mod term { use super::*; pub use tui::buffer::Buffer as Surface; @@ -33,6 +34,7 @@ mod term { } } +#[cfg(feature = "term")] pub use term::*; pub trait Component: Any + AnyComponent { @@ -76,7 +78,8 @@ pub struct Compositor { layers: Vec>, area: Rect, - pub(crate) last_picker: Option>, + // TODO: remove pub + pub last_picker: Option>, } impl Compositor { diff --git a/helix-view/src/info.rs b/helix-view/src/info.rs index 3877df21a..545011f90 100644 --- a/helix-view/src/info.rs +++ b/helix-view/src/info.rs @@ -73,3 +73,47 @@ impl Info { infobox } } + +// term + +use crate::{ + compositor::{Component, RenderContext}, + graphics::{Margin, Rect}, +}; +use tui::widgets::{Block, Borders, Paragraph, Widget}; + +impl Component for Info { + fn render(&mut self, viewport: Rect, cx: &mut RenderContext<'_>) { + let text_style = cx.editor.theme.get("ui.text.info"); + let popup_style = cx.editor.theme.get("ui.popup.info"); + + // Calculate the area of the terminal to modify. Because we want to + // render at the bottom right, we use the viewport's width and height + // which evaluate to the most bottom right coordinate. + let width = self.width + 2 + 2; // +2 for border, +2 for margin + let height = self.height + 2; // +2 for border + let area = viewport.intersection(Rect::new( + viewport.width.saturating_sub(width), + viewport.height.saturating_sub(height + 2), // +2 for statusline + width, + height, + )); + cx.surface.clear_with(area, popup_style); + + let block = Block::default() + .title(self.title.as_str()) + .borders(Borders::ALL) + .border_style(popup_style); + + let margin = Margin { + vertical: 0, + horizontal: 1, + }; + let inner = block.inner(area).inner(&margin); + block.render(area, cx.surface); + + Paragraph::new(self.text.as_str()) + .style(text_style) + .render(inner, cx.surface); + } +} diff --git a/helix-term/src/job.rs b/helix-view/src/job.rs similarity index 99% rename from helix-term/src/job.rs rename to helix-view/src/job.rs index a6a770211..17fdc85fb 100644 --- a/helix-term/src/job.rs +++ b/helix-view/src/job.rs @@ -1,6 +1,5 @@ -use helix_view::Editor; - use crate::compositor::Compositor; +use crate::Editor; use futures_util::future::{self, BoxFuture, Future, FutureExt}; use futures_util::stream::{FuturesUnordered, StreamExt}; diff --git a/helix-view/src/lib.rs b/helix-view/src/lib.rs index 182c89c38..b85196504 100644 --- a/helix-view/src/lib.rs +++ b/helix-view/src/lib.rs @@ -6,10 +6,12 @@ pub mod backend { pub mod term; } pub mod clipboard; +pub mod compositor; pub mod document; pub mod editor; -pub mod graphics; +pub use helix_graphics as graphics; pub mod gutter; +pub mod job; pub mod handlers { #[cfg(feature = "dap")] pub mod dap;