-
Notifications
You must be signed in to change notification settings - Fork 57
/
grid.rs
151 lines (123 loc) · 3.38 KB
/
grid.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
use std::ops::{Index, IndexMut};
use std::rc::Rc;
use fnv::FnvHashMap;
use neovim_lib::Value;
use crate::highlight::{Highlight, HighlightMap};
use crate::ui_model::{ModelRect, ModelRectVec, UiModel};
const DEFAULT_GRID: u64 = 1;
pub struct GridMap {
grids: FnvHashMap<u64, Grid>,
}
impl Index<u64> for GridMap {
type Output = Grid;
fn index(&self, idx: u64) -> &Grid {
&self.grids[&idx]
}
}
impl IndexMut<u64> for GridMap {
fn index_mut(&mut self, idx: u64) -> &mut Grid {
self.grids.get_mut(&idx).unwrap()
}
}
impl GridMap {
pub fn new() -> Self {
GridMap {
grids: FnvHashMap::default(),
}
}
pub fn current(&self) -> Option<&Grid> {
self.grids.get(&DEFAULT_GRID)
}
pub fn current_model_mut(&mut self) -> Option<&mut UiModel> {
self.grids.get_mut(&DEFAULT_GRID).map(|g| &mut g.model)
}
pub fn current_model(&self) -> Option<&UiModel> {
self.grids.get(&DEFAULT_GRID).map(|g| &g.model)
}
pub fn get_or_create(&mut self, idx: u64) -> &mut Grid {
if self.grids.contains_key(&idx) {
return self.grids.get_mut(&idx).unwrap();
}
self.grids.insert(idx, Grid::new());
self.grids.get_mut(&idx).unwrap()
}
pub fn destroy(&mut self, idx: u64) {
self.grids.remove(&idx);
}
pub fn clear_glyphs(&mut self) {
for grid in self.grids.values_mut() {
grid.model.clear_glyphs();
}
}
}
pub struct Grid {
model: UiModel,
}
impl Grid {
pub fn new() -> Self {
Grid {
model: UiModel::empty(),
}
}
pub fn get_cursor(&self) -> (usize, usize) {
self.model.get_cursor()
}
pub fn cur_point(&self) -> ModelRect {
self.model.cur_point()
}
pub fn resize(&mut self, columns: u64, rows: u64) {
if self.model.columns != columns as usize || self.model.rows != rows as usize {
self.model = UiModel::new(rows, columns);
}
}
pub fn cursor_goto(&mut self, row: usize, col: usize) -> ModelRectVec {
self.model.set_cursor(row, col)
}
pub fn clear(&mut self, default_hl: &Rc<Highlight>) {
self.model.clear(default_hl);
}
pub fn line(
&mut self,
row: usize,
col_start: usize,
cells: Vec<Vec<Value>>,
highlights: &HighlightMap,
) -> ModelRect {
let mut hl_id = None;
let mut col_end = col_start;
for cell in cells {
let ch = cell.get(0).unwrap().as_str().unwrap_or("");
hl_id = cell.get(1).and_then(|h| h.as_u64()).or(hl_id);
let repeat = cell.get(2).and_then(|r| r.as_u64()).unwrap_or(1) as usize;
self.model.put(
row,
col_end,
ch,
ch.is_empty(),
repeat,
highlights.get(hl_id),
);
col_end += repeat;
}
ModelRect::new(row, row, col_start, col_end - 1)
}
pub fn scroll(
&mut self,
top: u64,
bot: u64,
left: u64,
right: u64,
rows: i64,
_: i64,
default_hl: &Rc<Highlight>,
) -> ModelRect {
self.model.scroll(
top as i64,
bot as i64 - 1,
left as usize,
right as usize - 1,
rows,
default_hl,
)
}
}