Skip to content

Commit

Permalink
Remove highlightinfo based smooth scrolling support
Browse files Browse the repository at this point in the history
  • Loading branch information
fredizzimo committed May 16, 2024
1 parent 2ded8e2 commit 0d68c14
Show file tree
Hide file tree
Showing 6 changed files with 8 additions and 171 deletions.
1 change: 1 addition & 0 deletions src/bridge/api_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ pub struct ApiInformation {
}

impl ApiInformation {
#[allow(dead_code)]
pub fn has_event(&self, event_name: &str) -> bool {
self.ui_events.iter().any(|event| event.name == event_name)
}
Expand Down
66 changes: 2 additions & 64 deletions src/bridge/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use rmpv::Value;
use skia_safe::Color4f;
use strum::AsRefStr;

use crate::editor::{
Colors, CursorMode, CursorShape, HighlightInfo, HighlightKind, Style, UnderlineStyle,
};
use crate::editor::{Colors, CursorMode, CursorShape, Style, UnderlineStyle};

#[derive(Clone, Debug)]
pub enum ParseError {
Expand Down Expand Up @@ -503,7 +501,7 @@ fn parse_default_colors(default_colors_arguments: Vec<Value>) -> Result<RedrawEv
})
}

fn parse_style(style_map: Value, info_array: Value) -> Result<Style> {
fn parse_style(style_map: Value, _info_array: Value) -> Result<Style> {
let attributes = parse_map(style_map)?;

let mut style = Style::new(Colors::new(None, None, None));
Expand Down Expand Up @@ -551,69 +549,9 @@ fn parse_style(style_map: Value, info_array: Value) -> Result<Style> {
}
}

style.infos = parse_array(info_array)?
.into_iter()
.map(parse_highlight_info)
.collect::<Result<Vec<_>>>()?;

Ok(style)
}

fn parse_highlight_info(info_map: Value) -> Result<HighlightInfo> {
let attributes = parse_map(info_map)?;

let mut kind = None;
let mut ui_name = None;
let mut hi_name = None;
let mut id = None;

for attribute in attributes {
if let (Value::String(name), value) = attribute {
match (name.as_str().unwrap(), value) {
("kind", value) => {
let kind_str = parse_string(value)?;
match kind_str.as_str() {
"ui" => kind = Some(HighlightKind::Ui),
"syntax" => kind = Some(HighlightKind::Syntax),
// The documentation says terminal but Neovim 0.9.4 sends term...
"terminal" | "term" => kind = Some(HighlightKind::Terminal),
_ => return Err(ParseError::Format("Invalid highlight kind".to_string())),
}
}
("ui_name", value) => ui_name = Some(parse_string(value)?),
("hi_name", value) => hi_name = Some(parse_string(value)?),
("id", value) => id = Some(parse_u64(value)?),
_ => debug!("Ignored highlight info attribute: {}", name),
}
} else {
return Err(ParseError::Format(
"Invalid highlight info format".to_string(),
));
}
}
let kind = kind.ok_or(ParseError::Format(
"kind field not found in highlight info".to_string(),
))?;
let ui_name = if kind == HighlightKind::Ui {
ui_name.ok_or(ParseError::Format(
"ui_name field not found in highlight info".to_string(),
))?
} else {
String::default()
};
// hi_name can actually be absent for terminal, even though the documentation indicates otherwise
let hi_name = hi_name.unwrap_or_default();
let id = id.ok_or(ParseError::Format(
"id field not found in highlight info".to_string(),
))?;
Ok(HighlightInfo {
kind,
ui_name,
hi_name,
id,
})
}

fn parse_hl_attr_define(hl_attr_define_arguments: Vec<Value>) -> Result<RedrawEvent> {
let [id, attributes, _terminal_attributes, infos] = extract_values(hl_attr_define_arguments)?;

Expand Down
3 changes: 0 additions & 3 deletions src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ async fn launch(handler: NeovimHandler, grid_size: Option<GridSize<u32>>) -> Res
SETTINGS.read_initial_values(&session.neovim).await?;

let mut options = UiAttachOptions::new();
if !api_information.has_event("win_viewport_margins") {
options.set_hlstate_external(true);
}
options.set_linegrid_external(true);
options.set_multigrid_external(!settings.no_multi_grid);
options.set_rgb(true);
Expand Down
2 changes: 1 addition & 1 deletion src/editor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::{cmd_line::CmdLineSettings, frame::Frame, settings::SETTINGS};

pub use cursor::{Cursor, CursorMode, CursorShape};
pub use draw_command_batcher::DrawCommandBatcher;
pub use style::{Colors, HighlightInfo, HighlightKind, Style, UnderlineStyle};
pub use style::{Colors, Style, UnderlineStyle};
pub use window::*;

const MODE_CMDLINE: u64 = 4;
Expand Down
17 changes: 0 additions & 17 deletions src/editor/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,6 @@ pub struct Style {
pub blend: u8,
#[new(default)]
pub underline: Option<UnderlineStyle>,
#[new(default)]
pub infos: Vec<HighlightInfo>,
}

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum HighlightKind {
Ui,
Syntax,
Terminal,
}

#[derive(Debug, Clone, PartialEq)]
pub struct HighlightInfo {
pub kind: HighlightKind,
pub ui_name: String,
pub hi_name: String,
pub id: u64,
}

impl Style {
Expand Down
90 changes: 4 additions & 86 deletions src/renderer/rendered_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ pub struct LineFragment {
pub struct ViewportMargins {
pub top: u64,
pub bottom: u64,
pub inferred: bool,
}

#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -71,7 +70,6 @@ struct Line {
line_fragments: Vec<LineFragment>,
background_picture: Option<Picture>,
foreground_picture: Option<Picture>,
is_inferred_border: bool,
blend: u8,
is_valid: bool,
}
Expand Down Expand Up @@ -141,11 +139,7 @@ impl RenderedWindow {
actual_lines: RingBuffer::new(grid_size.height as usize, None),
scrollback_lines: RingBuffer::new(2 * grid_size.height as usize, None),
scroll_delta: 0,
viewport_margins: ViewportMargins {
top: 0,
bottom: 0,
inferred: true,
},
viewport_margins: ViewportMargins { top: 0, bottom: 0 },

grid_start_position: grid_position.cast(),
grid_current_position: grid_position.cast(),
Expand Down Expand Up @@ -455,47 +449,14 @@ impl RenderedWindow {
} => {
tracy_zone!("draw_line_cmd", 0);

let mut line = Line {
let line = Line {
line_fragments,
background_picture: None,
foreground_picture: None,
is_inferred_border: false,
blend: 0,
is_valid: false,
};

if self.viewport_margins.inferred {
let check_border = |fragment: &LineFragment, check: &dyn Fn(&str) -> bool| {
fragment.style.as_ref().map_or(false, |style| {
style.infos.last().map_or(false, |info| {
// The specification seems to indicate that kind should be UI and
// then we only need to test ui_name. But at least for FloatTitle,
// that is not the case, the kind is set to syntax and hi_name is
// set.
check(&info.ui_name) || check(&info.hi_name)
})
})
};

let float_border =
|s: &str| matches!(s, "FloatBorder" | "FloatTitle" | "FloatFooter");
let winbar = |s: &str| matches!(s, "WinBar" | "WinBarNC");

// Lines with purly border highlight groups are considered borders.
line.is_inferred_border = line
.line_fragments
.iter()
.map(|fragment| check_border(fragment, &float_border))
.all(|v| v);

// And also lines with a winbar highlight anywhere
line.is_inferred_border |= line
.line_fragments
.iter()
.map(|fragment| check_border(fragment, &winbar))
.any(|v| v)
}

self.actual_lines[row] = Some(Rc::new(RefCell::new(line)));
}
WindowDrawCommand::Scroll {
Expand Down Expand Up @@ -543,47 +504,13 @@ impl RenderedWindow {
self.scroll_delta = scroll_delta.round() as isize;
}
WindowDrawCommand::ViewportMargins { top, bottom, .. } => {
self.viewport_margins = ViewportMargins {
top,
bottom,
inferred: false,
}
self.viewport_margins = ViewportMargins { top, bottom }
}
_ => {}
};
}

fn infer_viewport_margins(&mut self) {
if self.viewport_margins.inferred {
self.viewport_margins.top = self
.actual_lines
.iter()
.take_while(|line| {
if let Some(line) = line {
line.borrow().is_inferred_border
} else {
false
}
})
.count() as u64;
self.viewport_margins.bottom = (self.viewport_margins.top as usize
..self.actual_lines.len())
.rev()
.map(|i| self.actual_lines[i].as_ref())
.take_while(|line| {
if let Some(line) = line {
line.borrow().is_inferred_border
} else {
false
}
})
.count() as u64;
}
}

pub fn flush(&mut self, renderer_settings: &RendererSettings) {
self.infer_viewport_margins();

// If the borders are changed, reset the scrollback to only fit the inner view
let inner_range = self.viewport_margins.top as isize
..(self.actual_lines.len() - self.viewport_margins.bottom as usize) as isize;
Expand Down Expand Up @@ -641,19 +568,10 @@ impl RenderedWindow {
let actual_line_count = self.actual_lines.len() as isize;
let bottom_border_indices =
actual_line_count - self.viewport_margins.bottom as isize..actual_line_count;
let margins_inferred = self.viewport_margins.inferred;

top_border_indices
.chain(bottom_border_indices)
.filter_map(move |i| {
self.actual_lines[i].as_ref().and_then(|line| {
if !margins_inferred || line.borrow().is_inferred_border {
Some((i, line))
} else {
None
}
})
})
.filter_map(move |i| self.actual_lines[i].as_ref().map(|line| (i, line)))
}

// Iterates over the scrollable lines (excluding the viewport margins). Includes the index for
Expand Down

0 comments on commit 0d68c14

Please sign in to comment.