Skip to content

Commit

Permalink
chore: use a proper type for Vec<(Rc<Highlight>, Vec<String>)>
Browse files Browse the repository at this point in the history
  • Loading branch information
theHamsta committed Jan 6, 2023
1 parent af6d450 commit 525a309
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 50 deletions.
58 changes: 28 additions & 30 deletions src/cmd_line/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ use gtk::prelude::*;
use unicode_segmentation::UnicodeSegmentation;

use crate::cursor;
use crate::highlight::{Highlight, HighlightMap};
use crate::highlight::HighlightMap;
use crate::mode;
use crate::nvim::{self, *};
use crate::nvim_viewport::NvimViewport;
use crate::popup_menu;
use crate::render::{self, CellMetrics};
use crate::shell;
use crate::ui::UiMutex;
use crate::ui_model::ModelLayout;
use crate::ui_model::{HighlightedLine, HighlightedRange, ModelLayout};

use viewport::CmdlineViewport;

Expand Down Expand Up @@ -61,7 +61,7 @@ impl Level {
level
}

fn replace_line(&mut self, lines: Vec<Vec<(Rc<Highlight>, Vec<String>)>>, append: bool) {
fn replace_line(&mut self, lines: Vec<HighlightedLine>, append: bool) {
if append {
self.model_layout.layout_append(lines);
} else {
Expand Down Expand Up @@ -93,7 +93,7 @@ impl Level {
}

pub fn from_lines(
lines: Vec<Vec<(Rc<Highlight>, Vec<String>)>>,
lines: Vec<HighlightedLine>,
max_width: i32,
render_state: &shell::RenderState,
) -> Self {
Expand Down Expand Up @@ -129,19 +129,20 @@ impl Level {
}
}

type PromptLine = (Rc<Highlight>, Vec<String>);

fn prompt_lines(
firstc: &str,
prompt: &str,
indent: u64,
hl: &HighlightMap,
) -> (usize, Vec<PromptLine>) {
let prompt: Vec<PromptLine> = if !firstc.is_empty() {
) -> (usize, Vec<HighlightedRange>) {
let prompt: Vec<HighlightedRange> = if !firstc.is_empty() {
if firstc.len() >= indent as usize {
vec![(hl.default_hl(), vec![firstc.to_owned()])]
vec![HighlightedRange {
highlight: hl.default_hl(),
graphemes: vec![firstc.to_owned()],
}]
} else {
vec![(
vec![HighlightedRange::new(
hl.default_hl(),
iter::once(firstc.to_owned())
.chain((firstc.len()..indent as usize).map(|_| " ".to_owned()))
Expand All @@ -151,18 +152,19 @@ fn prompt_lines(
} else if !prompt.is_empty() {
prompt
.lines()
.map(|l| {
(
hl.default_hl(),
l.graphemes(true).map(|g| g.to_owned()).collect(),
)
.map(|l| HighlightedRange {
highlight: hl.default_hl(),
graphemes: l.graphemes(true).map(|g| g.to_owned()).collect(),
})
.collect()
} else {
vec![]
};

let prompt_offset = prompt.last().map(|l| l.1.len()).unwrap_or(0);
let prompt_offset = prompt
.last()
.map(|range| range.graphemes.len())
.unwrap_or(0);

(prompt_offset, prompt)
}
Expand Down Expand Up @@ -541,25 +543,23 @@ impl<'a> CmdLineContext<'a> {
}

struct LineContent {
lines: Vec<Vec<(Rc<Highlight>, Vec<String>)>>,
lines: Vec<HighlightedLine>,
prompt_offset: usize,
}

trait ToAttributedModelContent {
fn to_attributed_content(&self, hl: &HighlightMap) -> Vec<Vec<(Rc<Highlight>, Vec<String>)>>;
fn to_attributed_content(&self, hl: &HighlightMap) -> Vec<HighlightedLine>;
}

impl ToAttributedModelContent for Vec<Vec<(u64, String)>> {
fn to_attributed_content(&self, hl: &HighlightMap) -> Vec<Vec<(Rc<Highlight>, Vec<String>)>> {
fn to_attributed_content(&self, hl: &HighlightMap) -> Vec<HighlightedLine> {
self.iter()
.map(|line_chars| {
line_chars
.iter()
.map(|c| {
(
hl.get(c.0.into()),
c.1.graphemes(true).map(|g| g.to_owned()).collect(),
)
.map(|c| HighlightedRange {
highlight: hl.get(c.0.into()),
graphemes: c.1.graphemes(true).map(|g| g.to_owned()).collect(),
})
.collect()
})
Expand All @@ -568,14 +568,12 @@ impl ToAttributedModelContent for Vec<Vec<(u64, String)>> {
}

impl ToAttributedModelContent for Vec<(u64, String)> {
fn to_attributed_content(&self, hl: &HighlightMap) -> Vec<Vec<(Rc<Highlight>, Vec<String>)>> {
fn to_attributed_content(&self, hl: &HighlightMap) -> Vec<HighlightedLine> {
vec![self
.iter()
.map(|c| {
(
hl.get(c.0.into()),
c.1.graphemes(true).map(|g| g.to_owned()).collect(),
)
.map(|c| HighlightedRange {
highlight: hl.get(c.0.into()),
graphemes: c.1.graphemes(true).map(|g| g.to_owned()).collect(),
})
.collect()]
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui_model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod model_rect;
pub use self::cell::Cell;
pub use self::item::Item;
pub use self::line::{Line, StyledLine};
pub use self::model_layout::ModelLayout;
pub use self::model_layout::{HighlightedLine, HighlightedRange, ModelLayout};
pub use self::model_rect::ModelRect;

#[derive(Default)]
Expand Down
95 changes: 76 additions & 19 deletions src/ui_model/model_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,28 @@ use unicode_width::UnicodeWidthStr;
use crate::highlight::Highlight;
use crate::ui_model::UiModel;

#[derive(Clone)]
pub struct HighlightedRange {
pub highlight: Rc<Highlight>,
pub graphemes: Vec<String>,
}

impl HighlightedRange {
pub fn new(highlight: Rc<Highlight>, graphemes: Vec<String>) -> Self {
Self {
highlight,
graphemes,
}
}
}

pub type HighlightedLine = Vec<HighlightedRange>;

pub struct ModelLayout {
pub model: UiModel,
rows_filled: usize,
cols_filled: usize,
lines: Vec<Vec<(Rc<Highlight>, Vec<String>)>>,
lines: Vec<HighlightedLine>,
}

impl ModelLayout {
Expand All @@ -25,7 +42,7 @@ impl ModelLayout {
}
}

pub fn layout_append(&mut self, mut lines: Vec<Vec<(Rc<Highlight>, Vec<String>)>>) {
pub fn layout_append(&mut self, mut lines: Vec<HighlightedLine>) {
let rows_filled = self.rows_filled;
let take_from = self.lines.len();

Expand All @@ -34,7 +51,7 @@ impl ModelLayout {
self.layout_replace(rows_filled, take_from);
}

pub fn layout(&mut self, lines: Vec<Vec<(Rc<Highlight>, Vec<String>)>>) {
pub fn layout(&mut self, lines: Vec<HighlightedLine>) {
self.lines = lines;
self.layout_replace(0, 0);
}
Expand Down Expand Up @@ -85,18 +102,18 @@ impl ModelLayout {
}

fn insert_into_lines(&mut self, ch: String) {
let line = &mut self.lines[0];
let highlight_ranges = &mut self.lines[0];

let (_, cur_col) = self.model.get_real_cursor();

let mut col_idx = 0;
for &mut (_, ref mut chars) in line {
if cur_col < col_idx + chars.len() {
for range in highlight_ranges.iter_mut() {
if cur_col < col_idx + range.graphemes.len() {
let col_sub_idx = cur_col - col_idx;
chars.insert(col_sub_idx, ch);
range.graphemes.insert(col_sub_idx, ch);
break;
} else {
col_idx += chars.len();
col_idx += range.graphemes.len();
}
}
}
Expand All @@ -115,8 +132,12 @@ impl ModelLayout {
let mut max_col_idx = 0;
let mut col_idx = 0;
let mut row_idx = row_offset;
for content in lines {
for (hl, ch_list) in content {
for highlight_ranges in lines {
for HighlightedRange {
highlight: hl,
graphemes: ch_list,
} in highlight_ranges
{
for ch in ch_list {
let ch_width = max(1, ch.width());

Expand Down Expand Up @@ -156,11 +177,11 @@ impl ModelLayout {
}
}

fn count_lines(lines: &[Vec<(Rc<Highlight>, Vec<String>)>], max_columns: usize) -> usize {
fn count_lines(lines: &[HighlightedLine], max_columns: usize) -> usize {
let mut row_count = 0;

for line in lines {
let len: usize = line.iter().map(|c| c.1.len()).sum();
let len: usize = line.iter().map(|range| range.graphemes.len()).sum();
row_count += len / (max_columns + 1) + 1;
}

Expand All @@ -174,7 +195,10 @@ mod tests {

#[test]
fn test_count_lines() {
let lines = vec![vec![(Rc::new(Highlight::new()), vec!["a".to_owned(); 5])]];
let lines = vec![vec![HighlightedRange {
highlight: Rc::new(Highlight::new()),
graphemes: vec!["a".to_owned(); 5],
}]];

let rows = ModelLayout::count_lines(&lines, 4);
assert_eq!(2, rows);
Expand All @@ -183,7 +207,10 @@ mod tests {
#[test]
fn test_resize() {
let lines = vec![
vec![(Rc::new(Highlight::new()), vec!["a".to_owned(); 5])];
vec![HighlightedRange {
highlight: Rc::new(Highlight::new()),
graphemes: vec!["a".to_owned(); 5]
}];
ModelLayout::ROWS_STEP
];
let mut model = ModelLayout::new(5);
Expand All @@ -202,7 +229,13 @@ mod tests {

#[test]
fn test_cols_filled() {
let lines = vec![vec![(Rc::new(Highlight::new()), vec!["a".to_owned(); 3])]; 1];
let lines = vec![
vec![HighlightedRange::new(
Rc::new(Highlight::new()),
vec!["a".to_owned(); 3]
)];
1
];
let mut model = ModelLayout::new(5);

model.layout(lines);
Expand All @@ -212,7 +245,13 @@ mod tests {
let (cols, _) = model.size();
assert_eq!(4, cols); // size is 3 and 4 - is with cursor position

let lines = vec![vec![(Rc::new(Highlight::new()), vec!["a".to_owned(); 2])]; 1];
let lines = vec![
vec![HighlightedRange::new(
Rc::new(Highlight::new()),
vec!["a".to_owned(); 2]
)];
1
];

model.layout_append(lines);
model.set_cursor(2);
Expand All @@ -222,7 +261,13 @@ mod tests {

#[test]
fn test_insert_shift() {
let lines = vec![vec![(Rc::new(Highlight::new()), vec!["a".to_owned(); 3])]; 1];
let lines = vec![
vec![HighlightedRange::new(
Rc::new(Highlight::new()),
vec!["a".to_owned(); 3]
)];
1
];
let mut model = ModelLayout::new(5);
model.layout(lines);
model.set_cursor(1);
Expand All @@ -236,7 +281,13 @@ mod tests {

#[test]
fn test_insert_no_shift() {
let lines = vec![vec![(Rc::new(Highlight::new()), vec!["a".to_owned(); 3])]; 1];
let lines = vec![
vec![HighlightedRange::new(
Rc::new(Highlight::new()),
vec!["a".to_owned(); 3]
)];
1
];
let mut model = ModelLayout::new(5);
model.layout(lines);
model.set_cursor(1);
Expand All @@ -250,7 +301,13 @@ mod tests {

#[test]
fn test_double_width() {
let lines = vec![vec![(Rc::new(Highlight::new()), vec!["あ".to_owned(); 3])]; 1];
let lines = vec![
vec![HighlightedRange::new(
Rc::new(Highlight::new()),
vec!["あ".to_owned(); 3]
)];
1
];
let mut model = ModelLayout::new(7);
model.layout(lines);
model.set_cursor(1);
Expand Down

0 comments on commit 525a309

Please sign in to comment.