Skip to content

Commit

Permalink
Redo sticky note configuration, improve the caching
Browse files Browse the repository at this point in the history
Derive Default from macro
  • Loading branch information
SoraTenshi committed Mar 2, 2023
1 parent 4693a8f commit 2e6c02b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
43 changes: 26 additions & 17 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,10 @@ impl EditorView {
Box::new(highlights)
};

self.sticky_nodes = Self::calculate_sticky_nodes(&self.sticky_nodes, doc, view, &config);
if config.sticky_context.enable {
self.sticky_nodes =
Self::calculate_sticky_nodes(&self.sticky_nodes, doc, view, &config);
}

if is_focused {
let cursor = doc
Expand Down Expand Up @@ -221,7 +224,7 @@ impl EditorView {
&mut translated_positions,
);

if config.sticky_context {
if config.sticky_context.enable {
Self::render_sticky_context(
doc,
view,
Expand Down Expand Up @@ -735,6 +738,7 @@ impl EditorView {
}

/// Render the sticky context
#[allow(clippy::too_many_arguments)]
pub fn render_sticky_context(
doc: &Document,
view: &View,
Expand Down Expand Up @@ -765,13 +769,14 @@ impl EditorView {
surface.clear_with(context_area, context_style);

if let Some(indicator) = node.indicator.as_deref() {
// set the indicator
surface.set_string(context_area.x, context_area.y, indicator, indicator_style);
continue;
}

let line_num_anchor = text.line_to_char(node.line_nr);

// get all highlights from the latest points
// get all highlights from the latest point
let highlights = Self::doc_syntax_highlights(doc, line_num_anchor, 1, theme);

let mut renderer = TextRenderer::new(
Expand Down Expand Up @@ -807,9 +812,6 @@ impl EditorView {
view: &View,
config: &helix_view::editor::Config,
) -> Option<Vec<StickyNode>> {
if !config.sticky_context {
return None;
}
let syntax = doc.syntax()?;
let tree = syntax.tree();
let text = doc.text().slice(..);
Expand All @@ -821,15 +823,6 @@ impl EditorView {
let top_first_byte =
text.line_to_byte(anchor_line + nodes.as_deref().map_or(0, |v| v.len()));

if let Some(nodes) = nodes {
if nodes
.iter()
.any(|node| node.top_first_byte == top_first_byte)
{
return Some(nodes.to_vec());
}
}

let visual_cursor_pos = view
.screen_coords_at_pos(doc, text, cursor_line)
.unwrap_or_default()
Expand All @@ -839,6 +832,14 @@ impl EditorView {
return None;
}

if let Some(nodes) = nodes {
if nodes.iter().any(|node| {
node.top_first_byte == top_first_byte && (visual_cursor_pos as usize) >= nodes.len()
}) {
return Some(nodes.to_vec());
}
}

let context_nodes = doc
.language_config()
.and_then(|lc| lc.sticky_context_nodes.as_ref());
Expand Down Expand Up @@ -885,11 +886,19 @@ impl EditorView {
return None;
}

let max_lines = config.sticky_context.max_lines;
let max_nodes_amount = if max_lines == 0 {
viewport.height as usize / 3
} else {
max_lines.min(viewport.height) as usize
};

// we render from top most (last in the list)
context = context
.into_iter()
.rev()
.take(viewport.height as usize / 3) // only take the nodes until 1 / 3 of the viewport is reached
// only take the nodes until 1 / 3 of the viewport is reached or the maximum amount of sticky nodes .take(viewport.height as usize / 3)
.take(max_nodes_amount)
.enumerate()
.take_while(|(i, _)| *i + 1 != visual_cursor_pos as usize) // also only nodes that don't overlap with the visual cursor position
.map(|(i, node)| {
Expand All @@ -899,7 +908,7 @@ impl EditorView {
})
.collect();

if config.sticky_context_indicator {
if config.sticky_context.indicator {
let mut str = String::new();
let message = "┤Sticky Context├";
let side_placeholder = (viewport.width as usize)
Expand Down
23 changes: 18 additions & 5 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,26 @@ pub struct Config {
/// Whether to color modes with different colors. Defaults to `false`.
pub color_modes: bool,
pub soft_wrap: SoftWrap,
/// Contextual information on top of the viewport
pub sticky_context: StickyContextConfig,
}

/// Display context of current top view if it is outside the view.
pub sticky_context: bool,
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
pub struct StickyContextConfig {
/// Display context of current top view if it is outside the view. Default to off
pub enable: bool,

/// Display an indicator whether to indicate if the sticky context is active
pub sticky_context_indicator: bool,
/// Eventually making this a string so that it is configurable.
pub indicator: bool,

/// The max amount of lines to be displayed. (including indicator!)
/// The viewport is taken into account when changing this value.
/// So if the configured amount is more than the viewport height.
///
/// Default: 0, which means that it is a fixed size based on the viewport
pub max_lines: u16,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -778,8 +792,7 @@ impl Default for Config {
indent_guides: IndentGuidesConfig::default(),
color_modes: false,
soft_wrap: SoftWrap::default(),
sticky_context: false,
sticky_context_indicator: false,
sticky_context: StickyContextConfig::default(),
}
}
}
Expand Down

0 comments on commit 2e6c02b

Please sign in to comment.