From 5c371208692df2727d02a37646b7829f011680a8 Mon Sep 17 00:00:00 2001 From: JJ Date: Tue, 31 Oct 2023 17:37:26 -0700 Subject: Add file explorer and tree helper ref: https://github.com/helix-editor/helix/issues/200 ref: https://github.com/helix-editor/helix/pull/2377 ref: https://github.com/helix-editor/helix/pull/5566 ref: https://github.com/helix-editor/helix/pull/5768 Co-authored-by: cossonleo Co-authored-by: wongjiahau --- helix-view/src/editor.rs | 39 +++++++++++++++++++++++++++++++++++++++ helix-view/src/graphics.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) (limited to 'helix-view') diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 7af28ccc..f285aa99 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -210,6 +210,30 @@ impl Default for FilePickerConfig { } } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case", default, deny_unknown_fields)] +pub struct ExplorerConfig { + pub position: ExplorerPosition, + /// explorer column width + pub column_width: usize, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum ExplorerPosition { + Left, + Right, +} + +impl Default for ExplorerConfig { + fn default() -> Self { + Self { + position: ExplorerPosition::Left, + column_width: 36, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "kebab-case", default, deny_unknown_fields)] pub struct Config { @@ -280,6 +304,8 @@ pub struct Config { pub bufferline: BufferLine, /// Vertical indent width guides. pub indent_guides: IndentGuidesConfig, + /// Explorer configuration. + pub explorer: ExplorerConfig, /// Whether to color modes with different colors. Defaults to `false`. pub color_modes: bool, pub soft_wrap: SoftWrap, @@ -835,6 +861,7 @@ impl Default for Config { whitespace: WhitespaceConfig::default(), bufferline: BufferLine::default(), indent_guides: IndentGuidesConfig::default(), + explorer: ExplorerConfig::default(), color_modes: false, soft_wrap: SoftWrap { enable: Some(false), @@ -1011,6 +1038,18 @@ pub enum CloseError { SaveError(anyhow::Error), } +impl From for anyhow::Error { + fn from(error: CloseError) -> Self { + match error { + CloseError::DoesNotExist => anyhow::anyhow!("Document doesn't exist"), + CloseError::BufferModified(error) => { + anyhow::anyhow!(format!("Buffer modified: '{error}'")) + } + CloseError::SaveError(error) => anyhow::anyhow!(format!("Save error: {error}")), + } + } +} + impl Editor { pub fn new( mut area: Rect, diff --git a/helix-view/src/graphics.rs b/helix-view/src/graphics.rs index 046db86a..fbfde635 100644 --- a/helix-view/src/graphics.rs +++ b/helix-view/src/graphics.rs @@ -248,6 +248,34 @@ impl Rect { && self.y < other.y + other.height && self.y + self.height > other.y } + + /// Returns a smaller `Rect` with a margin of 5% on each side, and an additional 2 rows at the bottom + pub fn overlaid(self) -> Rect { + self.clip_bottom(2).clip_relative(90, 90) + } + + /// Returns a smaller `Rect` with width and height clipped to the given `percent_horizontal` + /// and `percent_vertical`. + /// + /// Value of `percent_horizontal` and `percent_vertical` is from 0 to 100. + pub fn clip_relative(self, percent_horizontal: u8, percent_vertical: u8) -> Rect { + fn mul_and_cast(size: u16, factor: u8) -> u16 { + ((size as u32) * (factor as u32) / 100).try_into().unwrap() + } + + let inner_w = mul_and_cast(self.width, percent_horizontal); + let inner_h = mul_and_cast(self.height, percent_vertical); + + let offset_x = self.width.saturating_sub(inner_w) / 2; + let offset_y = self.height.saturating_sub(inner_h) / 2; + + Rect { + x: self.x + offset_x, + y: self.y + offset_y, + width: inner_w, + height: inner_h, + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -- cgit v1.2.3-70-g09d2