summaryrefslogtreecommitdiffstats
path: root/src/components/syntax_text.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/syntax_text.rs')
-rw-r--r--src/components/syntax_text.rs444
1 files changed, 222 insertions, 222 deletions
diff --git a/src/components/syntax_text.rs b/src/components/syntax_text.rs
index 73de6d7b..26d4eba2 100644
--- a/src/components/syntax_text.rs
+++ b/src/components/syntax_text.rs
@@ -1,21 +1,21 @@
use super::{
- CommandBlocking, CommandInfo, Component, DrawableComponent,
- EventState,
+ CommandBlocking, CommandInfo, Component, DrawableComponent,
+ EventState,
};
use crate::{
- keys::SharedKeyConfig,
- strings,
- ui::{
- self, common_nav, style::SharedTheme, AsyncSyntaxJob,
- ParagraphState, ScrollPos, StatefulParagraph,
- },
- AsyncAppNotification, AsyncNotification,
+ keys::SharedKeyConfig,
+ strings,
+ ui::{
+ self, common_nav, style::SharedTheme, AsyncSyntaxJob,
+ ParagraphState, ScrollPos, StatefulParagraph,
+ },
+ AsyncAppNotification, AsyncNotification,
};
use anyhow::Result;
use asyncgit::{
- asyncjob::AsyncSingleJob,
- sync::{self, TreeFile},
- CWD,
+ asyncjob::AsyncSingleJob,
+ sync::{self, TreeFile},
+ CWD,
};
use crossbeam_channel::Sender;
use crossterm::event::Event;
@@ -23,251 +23,251 @@ use filetreelist::MoveSelection;
use itertools::Either;
use std::{cell::Cell, convert::From, path::Path};
use tui::{
- backend::Backend,
- layout::Rect,
- text::Text,
- widgets::{Block, Borders, Wrap},
- Frame,
+ backend::Backend,
+ layout::Rect,
+ text::Text,
+ widgets::{Block, Borders, Wrap},
+ Frame,
};
pub struct SyntaxTextComponent {
- current_file: Option<(String, Either<ui::SyntaxText, String>)>,
- async_highlighting:
- AsyncSingleJob<AsyncSyntaxJob, AsyncAppNotification>,
- key_config: SharedKeyConfig,
- paragraph_state: Cell<ParagraphState>,
- focused: bool,
- theme: SharedTheme,
+ current_file: Option<(String, Either<ui::SyntaxText, String>)>,
+ async_highlighting:
+ AsyncSingleJob<AsyncSyntaxJob, AsyncAppNotification>,
+ key_config: SharedKeyConfig,
+ paragraph_state: Cell<ParagraphState>,
+ focused: bool,
+ theme: SharedTheme,
}
impl SyntaxTextComponent {
- ///
- pub fn new(
- sender: &Sender<AsyncAppNotification>,
- key_config: SharedKeyConfig,
- theme: SharedTheme,
- ) -> Self {
- Self {
- async_highlighting: AsyncSingleJob::new(
- sender.clone(),
- AsyncAppNotification::SyntaxHighlighting,
- ),
- current_file: None,
- paragraph_state: Cell::new(ParagraphState::default()),
- focused: false,
- key_config,
- theme,
- }
- }
+ ///
+ pub fn new(
+ sender: &Sender<AsyncAppNotification>,
+ key_config: SharedKeyConfig,
+ theme: SharedTheme,
+ ) -> Self {
+ Self {
+ async_highlighting: AsyncSingleJob::new(
+ sender.clone(),
+ AsyncAppNotification::SyntaxHighlighting,
+ ),
+ current_file: None,
+ paragraph_state: Cell::new(ParagraphState::default()),
+ focused: false,
+ key_config,
+ theme,
+ }
+ }
- ///
- pub fn update(&mut self, ev: AsyncNotification) {
- if matches!(
- ev,
- AsyncNotification::App(
- AsyncAppNotification::SyntaxHighlighting
- )
- ) {
- if let Some(job) = self.async_highlighting.take_last() {
- if let Some((path, content)) =
- self.current_file.as_mut()
- {
- if let Some(syntax) = job.result() {
- if syntax.path() == Path::new(path) {
- *content = Either::Left(syntax);
- }
- }
- }
- }
- }
- }
+ ///
+ pub fn update(&mut self, ev: AsyncNotification) {
+ if matches!(
+ ev,
+ AsyncNotification::App(
+ AsyncAppNotification::SyntaxHighlighting
+ )
+ ) {
+ if let Some(job) = self.async_highlighting.take_last() {
+ if let Some((path, content)) =
+ self.current_file.as_mut()
+ {
+ if let Some(syntax) = job.result() {
+ if syntax.path() == Path::new(path) {
+ *content = Either::Left(syntax);
+ }
+ }
+ }
+ }
+ }
+ }
- ///
- pub fn any_work_pending(&self) -> bool {
- self.async_highlighting.is_pending()
- }
+ ///
+ pub fn any_work_pending(&self) -> bool {
+ self.async_highlighting.is_pending()
+ }
- ///
- pub fn clear(&mut self) {
- self.current_file = None;
- }
+ ///
+ pub fn clear(&mut self) {
+ self.current_file = None;
+ }
- ///
- pub fn load_file(&mut self, path: String, item: &TreeFile) {
- let already_loaded = self
- .current_file
- .as_ref()
- .map(|(current_file, _)| current_file == &path)
- .unwrap_or_default();
+ ///
+ pub fn load_file(&mut self, path: String, item: &TreeFile) {
+ let already_loaded = self
+ .current_file
+ .as_ref()
+ .map(|(current_file, _)| current_file == &path)
+ .unwrap_or_default();
- if !already_loaded {
- //TODO: fetch file content async aswell
- match sync::tree_file_content(CWD, item) {
- Ok(content) => {
- self.async_highlighting.spawn(
- AsyncSyntaxJob::new(
- content.clone(),
- path.clone(),
- ),
- );
+ if !already_loaded {
+ //TODO: fetch file content async aswell
+ match sync::tree_file_content(CWD, item) {
+ Ok(content) => {
+ self.async_highlighting.spawn(
+ AsyncSyntaxJob::new(
+ content.clone(),
+ path.clone(),
+ ),
+ );
- self.current_file =
- Some((path, Either::Right(content)));
- }
- Err(e) => {
- self.current_file = Some((
- path,
- Either::Right(format!(
- "error loading file: {}",
- e
- )),
- ));
- }
- }
- }
- }
+ self.current_file =
+ Some((path, Either::Right(content)));
+ }
+ Err(e) => {
+ self.current_file = Some((
+ path,
+ Either::Right(format!(
+ "error loading file: {}",
+ e
+ )),
+ ));
+ }
+ }
+ }
+ }
- fn scroll(&self, nav: MoveSelection) -> bool {
- let state = self.paragraph_state.get();
+ fn scroll(&self, nav: MoveSelection) -> bool {
+ let state = self.paragraph_state.get();
- let new_scroll_pos = match nav {
- MoveSelection::Down => state.scroll().y.saturating_add(1),
- MoveSelection::Up => state.scroll().y.saturating_sub(1),
- MoveSelection::Top => 0,
- MoveSelection::End => state
- .lines()
- .saturating_sub(state.height().saturating_sub(2)),
- MoveSelection::PageUp => state
- .scroll()
- .y
- .saturating_sub(state.height().saturating_sub(2)),
- MoveSelection::PageDown => state
- .scroll()
- .y
- .saturating_add(state.height().saturating_sub(2)),
- _ => state.scroll().y,
- };
+ let new_scroll_pos = match nav {
+ MoveSelection::Down => state.scroll().y.saturating_add(1),
+ MoveSelection::Up => state.scroll().y.saturating_sub(1),
+ MoveSelection::Top => 0,
+ MoveSelection::End => state
+ .lines()
+ .saturating_sub(state.height().saturating_sub(2)),
+ MoveSelection::PageUp => state
+ .scroll()
+ .y
+ .saturating_sub(state.height().saturating_sub(2)),
+ MoveSelection::PageDown => state
+ .scroll()
+ .y
+ .saturating_add(state.height().saturating_sub(2)),
+ _ => state.scroll().y,
+ };
- self.set_scroll(new_scroll_pos)
- }
+ self.set_scroll(new_scroll_pos)
+ }
- fn set_scroll(&self, pos: u16) -> bool {
- let mut state = self.paragraph_state.get();
+ fn set_scroll(&self, pos: u16) -> bool {
+ let mut state = self.paragraph_state.get();
- let new_scroll_pos = pos.min(
- state
- .lines()
- .saturating_sub(state.height().saturating_sub(2)),
- );
+ let new_scroll_pos = pos.min(
+ state
+ .lines()
+ .saturating_sub(state.height().saturating_sub(2)),
+ );
- if new_scroll_pos == state.scroll().y {
- return false;
- }
+ if new_scroll_pos == state.scroll().y {
+ return false;
+ }
- state.set_scroll(ScrollPos {
- x: 0,
- y: new_scroll_pos,
- });
- self.paragraph_state.set(state);
+ state.set_scroll(ScrollPos {
+ x: 0,
+ y: new_scroll_pos,
+ });
+ self.paragraph_state.set(state);
- true
- }
+ true
+ }
}
impl DrawableComponent for SyntaxTextComponent {
- fn draw<B: Backend>(
- &self,
- f: &mut Frame<B>,
- area: Rect,
- ) -> Result<()> {
- let text = self.current_file.as_ref().map_or_else(
- || Text::from(""),
- |(_, content)| match content {
- Either::Left(syn) => syn.into(),
- Either::Right(s) => Text::from(s.as_str()),
- },
- );
+ fn draw<B: Backend>(
+ &self,
+ f: &mut Frame<B>,
+ area: Rect,
+ ) -> Result<()> {
+ let text = self.current_file.as_ref().map_or_else(
+ || Text::from(""),
+ |(_, content)| match content {
+ Either::Left(syn) => syn.into(),
+ Either::Right(s) => Text::from(s.as_str()),
+ },
+ );
- let content = StatefulParagraph::new(text)
- .wrap(Wrap { trim: false })
- .block(
- Block::default()
- .title(
- self.current_file
- .as_ref()
- .map(|(name, _)| name.clone())
- .unwrap_or_default(),
- )
- .borders(Borders::ALL)
- .border_style(self.theme.title(self.focused())),
- );
+ let content = StatefulParagraph::new(text)
+ .wrap(Wrap { trim: false })
+ .block(
+ Block::default()
+ .title(
+ self.current_file
+ .as_ref()
+ .map(|(name, _)| name.clone())
+ .unwrap_or_default(),
+ )
+ .borders(Borders::ALL)
+ .border_style(self.theme.title(self.focused())),
+ );
- let mut state = self.paragraph_state.get();
+ let mut state = self.paragraph_state.get();
- f.render_stateful_widget(content, area, &mut state);
+ f.render_stateful_widget(content, area, &mut state);
- self.paragraph_state.set(state);
+ self.paragraph_state.set(state);
- self.set_scroll(state.scroll().y);
+ self.set_scroll(state.scroll().y);
- if self.focused() {
- ui::draw_scrollbar(
- f,
- area,
- &self.theme,
- usize::from(state.lines().saturating_sub(
- state.height().saturating_sub(2),
- )),
- usize::from(state.scroll().y),
- );
- }
+ if self.focused() {
+ ui::draw_scrollbar(
+ f,
+ area,
+ &self.theme,
+ usize::from(state.lines().saturating_sub(
+ state.height().saturating_sub(2),
+ )),
+ usize::from(state.scroll().y),
+ );
+ }
- Ok(())
- }
+ Ok(())
+ }
}
impl Component for SyntaxTextComponent {
- fn commands(
- &self,
- out: &mut Vec<CommandInfo>,
- force_all: bool,
- ) -> CommandBlocking {
- if self.focused() || force_all {
- out.push(
- CommandInfo::new(
- strings::commands::scroll(&self.key_config),
- true,
- true,
- )
- .order(strings::order::NAV),
- );
- }
- CommandBlocking::PassingOn
- }
+ fn commands(
+ &self,
+ out: &mut Vec<CommandInfo>,
+ force_all: bool,
+ ) -> CommandBlocking {
+ if self.focused() || force_all {
+ out.push(
+ CommandInfo::new(
+ strings::commands::scroll(&self.key_config),
+ true,
+ true,
+ )
+ .order(strings::order::NAV),
+ );
+ }
+ CommandBlocking::PassingOn
+ }
- fn event(
- &mut self,
- event: crossterm::event::Event,
- ) -> Result<EventState> {
- if let Event::Key(key) = event {
- if let Some(nav) = common_nav(key, &self.key_config) {
- return Ok(self
- .scroll(nav)
- .then(|| EventState::Consumed)
- .unwrap_or(EventState::NotConsumed));
- }
- }
+ fn event(
+ &mut self,
+ event: crossterm::event::Event,
+ ) -> Result<EventState> {
+ if let Event::Key(key) = event {
+ if let Some(nav) = common_nav(key, &self.key_config) {
+ return Ok(self
+ .scroll(nav)
+ .then(|| EventState::Consumed)
+ .unwrap_or(EventState::NotConsumed));
+ }
+ }
- Ok(EventState::NotConsumed)
- }
+ Ok(EventState::NotConsumed)
+ }
- ///
- fn focused(&self) -> bool {
- self.focused
- }
+ ///
+ fn focused(&self) -> bool {
+ self.focused
+ }
- /// focus/unfocus this component depending on param
- fn focus(&mut self, focus: bool) {
- self.focused = focus;
- }
+ /// focus/unfocus this component depending on param
+ fn focus(&mut self, focus: bool) {
+ self.focused = focus;
+ }
}