diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-08-02 00:36:10 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-08-02 00:36:10 +0200 |
| commit | fe0938b1de0c46fc2afcaa3dcd6a0f4ec870d21a (patch) | |
| tree | 8db7509894842395cfb309f00c41b7f4d173888c | |
| parent | 1e1eb95926f556e666bc20355327abd24d264858 (diff) | |
add state which is shared with the lua environment
| -rw-r--r-- | src/app.rs | 8 | ||||
| -rw-r--r-- | src/config/mod.rs | 5 | ||||
| -rw-r--r-- | src/config/theme/sheetview.rs | 5 | ||||
| -rw-r--r-- | src/cursor.rs (renamed from src/widgets/luaeditor/cursor.rs) | 7 | ||||
| -rw-r--r-- | src/lua/evalsto.rs (renamed from src/config/evalsto.rs) | 16 | ||||
| -rw-r--r-- | src/lua/mod.rs | 33 | ||||
| -rw-r--r-- | src/lua/runtime.rs | 9 | ||||
| -rw-r--r-- | src/main.rs | 2 | ||||
| -rw-r--r-- | src/sheet/cell.rs | 10 | ||||
| -rw-r--r-- | src/sheet/mod.rs | 16 | ||||
| -rw-r--r-- | src/sheet/register.rs | 33 | ||||
| -rw-r--r-- | src/state/mod.rs | 36 | ||||
| -rw-r--r-- | src/state/sheetview.rs | 97 | ||||
| -rw-r--r-- | src/widgets/luaeditor/buffer.rs | 6 | ||||
| -rw-r--r-- | src/widgets/luaeditor/mod.rs | 3 | ||||
| -rw-r--r-- | src/widgets/sheetview/mod.rs | 141 |
16 files changed, 316 insertions, 111 deletions
@@ -1,10 +1,7 @@ use std::{io, time::Duration}; use crate::{ - config, lua, - sheet::register::Register, - tui, - widgets::{logview::LogView, sheetview::SheetView}, + config, lua, sheet::register::Register, state::GlobalState, tui, widgets::{logview::LogView, sheetview::SheetView} }; use ratatui::{ @@ -22,7 +19,8 @@ pub struct App { impl App { pub fn new() -> Self { let sheet_id = Register::create(10, 50); - let view = SheetView::new(sheet_id); + GlobalState::instance_mut().sheetview.set_active_sheet(Some(sheet_id)); + let view = SheetView::new(); Self { exit: false, diff --git a/src/config/mod.rs b/src/config/mod.rs index c5131a6..b01be62 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -4,9 +4,8 @@ use mlua::{UserData, UserDataFields}; use self::theme::Theme; -pub mod theme; pub mod constants; -pub mod evalsto; +pub mod theme; #[derive(Debug, Default)] pub struct GlobalConfig { @@ -17,7 +16,7 @@ static GLOBAL_CONFIG: RwLock<GlobalConfig> = RwLock::new(GlobalConfig::new()); const DUMMY_CONFIG: GlobalConfig = GlobalConfig::new(); impl GlobalConfig { - pub const fn new() -> Self { + const fn new() -> Self { Self { theme: Theme::new(), } diff --git a/src/config/theme/sheetview.rs b/src/config/theme/sheetview.rs index edc7cc3..bcd53e1 100644 --- a/src/config/theme/sheetview.rs +++ b/src/config/theme/sheetview.rs @@ -1,10 +1,7 @@ use mlua::UserData; use ratatui::style::Color; -use crate::{ - config::{evalsto::EvalTo, GlobalConfig}, - sheet::cell::CellRef, -}; +use crate::{config::GlobalConfig, lua::evalsto::EvalTo, sheet::cell::CellRef}; use super::style::Style; diff --git a/src/widgets/luaeditor/cursor.rs b/src/cursor.rs index e051231..ad6703e 100644 --- a/src/widgets/luaeditor/cursor.rs +++ b/src/cursor.rs @@ -9,6 +9,7 @@ pub enum CursorMove { Begin, End, Jump((usize, usize)), + Relative((isize, isize)), } #[derive(Default, Debug, Clone)] @@ -20,7 +21,7 @@ pub struct Cursor { } impl Cursor { - pub fn new() -> Self { + pub const fn new() -> Self { Self { x: 0, y: 0, @@ -75,6 +76,10 @@ impl Cursor { CursorMove::Jump((x, y)) => { self.x = x as isize; self.y = y as isize; + }, + CursorMove::Relative((x, y)) => { + self.x += x; + self.y += y; } }; } diff --git a/src/config/evalsto.rs b/src/lua/evalsto.rs index eae9b2d..6d8ab29 100644 --- a/src/config/evalsto.rs +++ b/src/lua/evalsto.rs @@ -1,10 +1,10 @@ -use std::{marker::PhantomData, sync::Arc}; +use std::{fmt, marker::PhantomData, sync::Arc}; use mlua::{FromLua, IntoLua, Lua, Result, Value}; use crate::lua::ownedfunction::OwnedFunction; -#[derive(Clone, Debug)] +#[derive(Clone)] pub enum EvalTo<T, A> { Function(Arc<OwnedFunction>, PhantomData<A>), Value(T), @@ -71,3 +71,15 @@ where Self::Value(T::default()) } } + +impl<T, A> fmt::Debug for EvalTo<T, A> +where + T: fmt::Debug +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + EvalTo::Function(_, _) => write!(f, "function"), + EvalTo::Value(v) => v.fmt(f), + } + } +} diff --git a/src/lua/mod.rs b/src/lua/mod.rs index 7388890..fe3555e 100644 --- a/src/lua/mod.rs +++ b/src/lua/mod.rs @@ -1,5 +1,4 @@ use std::{ - borrow::Borrow, path::Path, sync::{Mutex, MutexGuard}, }; @@ -7,8 +6,9 @@ use std::{ use lazy_static::lazy_static; use mlua::prelude::*; -use crate::{config::GlobalConfig, sheet::cell::CellRef}; +use crate::{config::{theme::{sheetview::SheetViewTheme, Theme}, GlobalConfig}, sheet::cell::CellRef, state::{sheetview::SheetViewState, GlobalState}}; +pub mod evalsto; pub mod iobuffer; pub mod ownedfunction; pub mod runtime; @@ -32,18 +32,33 @@ lazy_static! { }; } +macro_rules! ud_is_type { + ($writer:ident, $ud:ident, $f:ty => $fe:expr $(, $($r:ty => $e:expr),+)? $(,)?) => { + if $ud.is::<$f>() { + $writer.write(format!("{:#?}", $fe)) + } $($( else if $ud.is::<$r>() { + $writer.write(format!("{:#?}", $e)) + })*)? else { + $writer.write(format!("{:#?}", $ud)); + } + }; +} + fn print(_: &Lua, args: LuaMultiValue) -> LuaResult<()> { let mut writer = iobuffer::iobuffer().write().unwrap(); for (i, arg) in args.iter().enumerate() { if let Some(ud) = arg.as_userdata() { - if ud.is::<CellRef>() { - writer.write(ud.borrow::<CellRef>().unwrap().value().to_string()); - } else if ud.is::<GlobalConfig>() { - writer.write(format!("{:#?}", GlobalConfig::instance().borrow())) - } else { - writer.write(format!("{:#?}", ud)); - } + ud_is_type!( + writer, + ud, + CellRef => ud.borrow::<CellRef>(), + GlobalConfig => GlobalConfig::instance(), + Theme => GlobalConfig::instance().theme, + SheetViewTheme => GlobalConfig::instance().theme.sheetview, + GlobalState => GlobalState::instance(), + SheetViewState => GlobalState::instance().sheetview, + ); } else { writer.write(format!("{:#?}", arg)); } diff --git a/src/lua/runtime.rs b/src/lua/runtime.rs index dfb37e6..4e8c52b 100644 --- a/src/lua/runtime.rs +++ b/src/lua/runtime.rs @@ -3,17 +3,20 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::{ config::{self, GlobalConfig}, - sheet::register::Register, + sheet::register::Register, state::GlobalState, }; pub fn neosheet(lua: &Lua) -> Result<()> { let exports = lua.create_table()?; exports - .set("sheets", lua.create_proxy::<Register>()?) + .set("sheets", lua.create_userdata(Register)?) .unwrap(); exports - .set("config", lua.create_userdata(GlobalConfig::new())?) + .set("config", lua.create_userdata(GlobalConfig::default())?) + .unwrap(); + exports + .set("state", lua.create_userdata(GlobalState::default())?) .unwrap(); lua.globals() diff --git a/src/main.rs b/src/main.rs index 776489f..9228eaf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,8 @@ pub mod tui; pub mod widgets; pub mod lua; pub mod config; +pub mod state; +pub mod cursor; fn run() -> io::Result<()> { let mut terminal = tui::init()?; diff --git a/src/sheet/cell.rs b/src/sheet/cell.rs index 3b18bde..b46b7d4 100644 --- a/src/sheet/cell.rs +++ b/src/sheet/cell.rs @@ -85,7 +85,7 @@ pub struct CellRef { row: usize, column: usize, sheet_id: SheetId, - cell: Cell, + value: Cell, } impl CellRef { @@ -98,7 +98,7 @@ impl CellRef { sheet_id, row, column, - cell + value: cell } } @@ -109,18 +109,18 @@ impl CellRef { sheet_id, row, column, - cell: cell.clone(), + value: cell.clone(), }) }) .unwrap_or(None) } pub fn value(&self) -> Cell { - self.cell.clone() + self.value.clone() } pub fn set_value(&mut self, cell: Cell) { - self.cell = cell.clone(); + self.value = cell.clone(); Register::get(self.sheet_id) .unwrap() .write() diff --git a/src/sheet/mod.rs b/src/sheet/mod.rs index f67d55e..501b71e 100644 --- a/src/sheet/mod.rs +++ b/src/sheet/mod.rs @@ -90,7 +90,7 @@ impl Clone for Sheet { } } -struct SheetLuaRef { +pub struct SheetLuaRef { id: SheetId, } @@ -98,6 +98,10 @@ impl SheetLuaRef { pub fn new(id: SheetId) -> Self { Self { id } } + + pub fn id(&self) -> SheetId { + self.id + } } impl LuaUserData for SheetLuaRef { @@ -122,3 +126,13 @@ impl LuaUserData for SheetLuaRef { }) } } + +impl<'lua> FromLua<'lua> for SheetLuaRef { + fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> { + if let Some(ud) = value.as_userdata() { + ud.take() + } else { + Err(LuaError::runtime("failed to parse sheet")) + } + } +} diff --git a/src/sheet/register.rs b/src/sheet/register.rs index 4fca3a3..039c6f0 100644 --- a/src/sheet/register.rs +++ b/src/sheet/register.rs @@ -1,8 +1,8 @@ use std::sync::{Arc, RwLock}; -use mlua::{UserData, Value}; +use mlua::{Table, UserData, Value}; -use super::{Sheet, SheetLuaRef}; +use super::{cell::Cell, Sheet, SheetLuaRef}; static REGISTER: RwLock<Vec<Arc<RwLock<Sheet>>>> = RwLock::new(Vec::new()); @@ -21,6 +21,31 @@ impl Register { id } + pub fn create_from_table(table: Table) -> mlua::Result<SheetId> { + let mut register = REGISTER.write().unwrap(); + let id = register.len(); + + let height = table.len()? as usize; + let mut width: usize = 0; + + for column in table.clone().pairs::<usize, Table>() { + width = width.max(column?.1.len()? as usize) + } + + let mut sheet = Sheet::new(width, height, id); + + for row_res in table.pairs::<usize, Table>() { + let (row, c) = row_res?; + for column_res in c.pairs::<usize, Cell>() { + let (column, cell) = column_res?; + sheet.set_cell(row, column, cell) + } + } + + register.push(Arc::new(RwLock::new(sheet))); + Ok(id) + } + pub fn get(id: SheetId) -> Option<Arc<RwLock<Sheet>>> { let register = REGISTER.read().unwrap(); @@ -34,8 +59,8 @@ impl Register { impl UserData for Register { fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_function_mut("create", |lua, (width, height): (usize, usize)| { - let id = Register::create(width, height); + methods.add_function_mut("create", |lua, table: Table| { + let id = Register::create_from_table(table)?; let luaref = SheetLuaRef::new(id); if let Ok(ud) = lua.create_userdata(luaref) { Ok(Value::UserData(ud)) diff --git a/src/state/mod.rs b/src/state/mod.rs new file mode 100644 index 0000000..5efd770 --- /dev/null +++ b/src/state/mod.rs @@ -0,0 +1,36 @@ +use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; + +use mlua::{UserData, UserDataFields}; + + +pub mod sheetview; + +#[derive(Debug, Default)] +pub struct GlobalState { + pub sheetview: sheetview::SheetViewState, +} + +static GLOBAL_STATE: RwLock<GlobalState> = RwLock::new(GlobalState::new()); +const DUMMY_STATE: GlobalState = GlobalState::new(); + +impl GlobalState { + const fn new() -> Self { + Self { + sheetview: sheetview::SheetViewState::new() + } + } + + pub fn instance() -> RwLockReadGuard<'static, Self> { + GLOBAL_STATE.read().unwrap() + } + + pub fn instance_mut() -> RwLockWriteGuard<'static, Self> { + GLOBAL_STATE.write().unwrap() + } +} + +impl UserData for GlobalState { + fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_function_get("sheetview", |_, _| Ok(DUMMY_STATE.sheetview)) + } +} diff --git a/src/state/sheetview.rs b/src/state/sheetview.rs new file mode 100644 index 0000000..8108a1d --- /dev/null +++ b/src/state/sheetview.rs @@ -0,0 +1,97 @@ +use std::sync::{Arc, RwLock}; + +use mlua::{IntoLua, UserData, Value}; + +use super::GlobalState; +use crate::{ + cursor::{Cursor, CursorMove}, + sheet::{ + register::{Register, SheetId}, + Sheet, SheetLuaRef, + }, +}; + +#[derive(Default, Debug)] +pub struct SheetViewState { + pub cursor: Cursor, + active_sheet: Option<SheetId>, +} + +impl SheetViewState { + pub const fn new() -> Self { + Self { + cursor: Cursor::new(), + active_sheet: None, + } + } + + pub fn set_active_sheet(&mut self, sheet: Option<SheetId>) { + if let Some(id) = sheet { + if let Some(lock) = Register::get(id) { + let sheet = lock.read().unwrap(); + self.cursor.set_x_max(sheet.width()); + self.cursor.set_y_max(sheet.height()); + } + } + + self.active_sheet = sheet + } + + pub fn active_sheet(&self) -> Option<Arc<RwLock<Sheet>>> { + if let Some(id) = self.active_sheet { + Register::get(id) + } else { + None + } + } +} + +macro_rules! cfg { + () => { + GlobalState::instance().sheetview + }; +} + +macro_rules! cfg_mut { + () => { + GlobalState::instance_mut().sheetview + }; +} + +impl UserData for SheetViewState { + fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_function_get("active", |lua, _| { + if let Some(id) = cfg!().active_sheet { + SheetLuaRef::new(id).into_lua(lua) + } else { + Ok(Value::Nil) + } + }); + + fields.add_field_function_set("active", |_, _, sheet: Option<SheetLuaRef>| { + if let Some(r) = sheet { + cfg_mut!().active_sheet = Some(r.id()) + } else { + cfg_mut!().active_sheet = None + } + + Ok(()) + }); + + fields.add_field_function_get("cursor", |lua, _| { + let table = lua.create_table()?; + table.set("row", cfg!().cursor.y())?; + table.set("column", cfg!().cursor.x())?; + Ok(table) + }) + } + + fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_function("move_cursor", |_, (row, column): (usize, usize)| { + cfg_mut!() + .cursor + .move_checked(CursorMove::Jump((row, column))); + Ok(()) + }) + } +} diff --git a/src/widgets/luaeditor/buffer.rs b/src/widgets/luaeditor/buffer.rs index 1af0c08..1427bdb 100644 --- a/src/widgets/luaeditor/buffer.rs +++ b/src/widgets/luaeditor/buffer.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use super::cursor::{Cursor, CursorMove}; +use crate::cursor::{Cursor, CursorMove}; #[derive(Default, Debug, Clone)] pub struct Buffer { @@ -17,8 +17,7 @@ impl Buffer { } fn refresh_line_max(&mut self) { - self.cursor - .set_x_max(self.lines[self.cursor.y()].len()) + self.cursor.set_x_max(self.lines[self.cursor.y()].len()) } fn refresh_buffer_max(&mut self) { @@ -143,6 +142,7 @@ impl Buffer { | CursorMove::Down(_) | CursorMove::Top | CursorMove::Bottom + | CursorMove::Relative(_) | CursorMove::Jump(_) => { self.cursor.move_checked(m); self.cursor.set_x_max(self.current_line().len()); diff --git a/src/widgets/luaeditor/mod.rs b/src/widgets/luaeditor/mod.rs index 939a65f..6fc8436 100644 --- a/src/widgets/luaeditor/mod.rs +++ b/src/widgets/luaeditor/mod.rs @@ -6,14 +6,13 @@ use ratatui::{ }; pub mod buffer; -pub mod cursor; pub mod theme; pub mod treesitter; use buffer::Buffer; use tree_sitter_highlight::HighlightConfiguration; -use self::cursor::CursorMove; +use crate::cursor::CursorMove; use super::statusbar::StatusBar; diff --git a/src/widgets/sheetview/mod.rs b/src/widgets/sheetview/mod.rs index f81edab..4ae37f0 100644 --- a/src/widgets/sheetview/mod.rs +++ b/src/widgets/sheetview/mod.rs @@ -10,13 +10,14 @@ use ratatui::{ use crate::{ config::GlobalConfig, + cursor::CursorMove, lua, sheet::{ cell::Cell, eval::EvalFunction, - register::{Register, SheetId}, Sheet, }, + state::GlobalState, }; use super::{luaeditor::LuaEditor, statusbar::StatusBar}; @@ -39,8 +40,6 @@ enum SheetViewMode { #[derive(Default)] pub struct SheetView { bar: StatusBar, - sheet: SheetId, - cursor: (u16, u16), scroll: (u16, u16), selection_anchor: Option<(u16, u16)>, mode: SheetViewMode, @@ -48,7 +47,7 @@ pub struct SheetView { } impl SheetView { - pub fn new(sheet: SheetId) -> Self { + pub fn new() -> Self { Self { bar: StatusBar::new() .left(" NORMAL ") @@ -56,8 +55,6 @@ impl SheetView { .middle("Sheet") .right("") .right_style(Style::default().on_red()), - sheet, - cursor: (0, 0), scroll: (0, 0), mode: SheetViewMode::Normal, selection_anchor: None, @@ -65,21 +62,12 @@ impl SheetView { } } - pub fn sheet(mut self, sheet: SheetId) -> Self { - self.sheet = sheet; - self - } - - pub fn move_cursor_by(&mut self, delta: (i32, i32)) { - let lock = Register::get(self.sheet).unwrap(); - let sheet = lock.read().unwrap(); - - self.cursor.0 = ((self.cursor.0 as i32) + delta.0) - .max(0) - .min(sheet.height() as i32 - 1) as u16; - self.cursor.1 = ((self.cursor.1 as i32) + delta.1) - .max(0) - .min(sheet.width() as i32 - 1) as u16; + pub fn move_cursor_by(&mut self, delta: (isize, isize)) { + let mut state = GlobalState::instance_mut(); + state + .sheetview + .cursor + .move_checked(CursorMove::Relative(delta)); } pub fn selection(&self) -> Vec<(u16, u16)> { @@ -108,17 +96,19 @@ impl SheetView { } fn selection_range(&self) -> Option<((u16, u16), (u16, u16))> { + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; if let Some(selection) = self.selection_anchor { - let row = if selection.0 > self.cursor.0 { - (self.cursor.0, selection.0) + let row = if selection.0 as usize > cursor.y() { + (cursor.y() as u16, selection.0) } else { - (selection.0, self.cursor.0) + (selection.0, cursor.y() as u16) }; - let column = if selection.1 > self.cursor.1 { - (self.cursor.1, selection.1) + let column = if selection.1 as usize > cursor.x() { + (cursor.x() as u16, selection.1) } else { - (selection.1, self.cursor.1) + (selection.1, cursor.x() as u16) }; Some((row, column)) @@ -133,7 +123,9 @@ impl SheetView { if handle.is_finished() { match handle.join().unwrap() { Ok(sheet) => { - Register::get(self.sheet) + GlobalState::instance() + .sheetview + .active_sheet() .unwrap() .write() .unwrap() @@ -151,12 +143,14 @@ impl SheetView { pub fn handle_key_event(&mut self, event: KeyEvent) { match &self.mode { SheetViewMode::Normal => match event.code { - KeyCode::Char('j') => self.move_cursor_by((1, 0)), - KeyCode::Char('k') => self.move_cursor_by((-1, 0)), - KeyCode::Char('h') => self.move_cursor_by((0, -1)), - KeyCode::Char('l') => self.move_cursor_by((0, 1)), + KeyCode::Char('j') => self.move_cursor_by((0, 1)), + KeyCode::Char('k') => self.move_cursor_by((0, -1)), + KeyCode::Char('h') => self.move_cursor_by((-1, 0)), + KeyCode::Char('l') => self.move_cursor_by((1, 0)), KeyCode::Char('v') => { - self.selection_anchor = Some(self.cursor); + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; + self.selection_anchor = Some((cursor.y() as u16, cursor.x() as u16)); self.mode = SheetViewMode::Visual } KeyCode::Char('s') => { @@ -175,13 +169,16 @@ impl SheetView { }, SheetViewMode::Insert => match event.code { KeyCode::Enter => { - let lock = Register::get(self.sheet).unwrap(); + let lock = GlobalState::instance().sheetview.active_sheet().unwrap(); let mut sheet = lock.write().unwrap(); + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; + if self.selection_anchor.is_some() { self.selection().iter().map(|(r, c)| (*r, *c)).collect() } else { - vec![self.cursor] + vec![(cursor.y() as u16, cursor.x() as u16)] } .into_iter() .for_each(|(r, c)| { @@ -212,10 +209,10 @@ impl SheetView { _ => self.bar.handle_keyevent(event), }, SheetViewMode::Visual => match event.code { - KeyCode::Char('j') => self.move_cursor_by((1, 0)), - KeyCode::Char('k') => self.move_cursor_by((-1, 0)), - KeyCode::Char('h') => self.move_cursor_by((0, -1)), - KeyCode::Char('l') => self.move_cursor_by((0, 1)), + KeyCode::Char('j') => self.move_cursor_by((0, 1)), + KeyCode::Char('k') => self.move_cursor_by((0, -1)), + KeyCode::Char('h') => self.move_cursor_by((-1, 0)), + KeyCode::Char('l') => self.move_cursor_by((1, 0)), KeyCode::Esc | KeyCode::Char('v') => { self.selection_anchor = None; self.mode = SheetViewMode::Normal; @@ -265,7 +262,7 @@ impl SheetView { let script = self.editor.text(); let (width, height) = { - let lock = Register::get(self.sheet).unwrap(); + let lock = GlobalState::instance().sheetview.active_sheet().unwrap(); let sheet = lock.read().unwrap(); (sheet.width(), sheet.height()) }; @@ -287,7 +284,9 @@ impl SheetView { } self.mode = SheetViewMode::Processing(Some( - Register::get(self.sheet) + GlobalState::instance() + .sheetview + .active_sheet() .unwrap() .eval_function(script, cells), )); @@ -383,9 +382,12 @@ impl Widget for &mut SheetView { ); { - let lock = Register::get(self.sheet).unwrap(); + let lock = GlobalState::instance().sheetview.active_sheet().unwrap(); let sheet = lock.read().unwrap(); + let state = GlobalState::instance(); + let cursor = &state.sheetview.cursor; + let mut sheet_area_inner = self.bar.area(sheet_area); if self.is_editor_visible() { @@ -397,16 +399,16 @@ impl Widget for &mut SheetView { .width() .min((sheet_area_inner.width / DEFAULT_COLUMN_WIDTH) as usize); - if self.cursor.0 >= viewport_rows as u16 + self.scroll.0 { - self.scroll.0 = self.cursor.0 - viewport_rows as u16 + 1; - } else if self.cursor.0 < self.scroll.0 { - self.scroll.0 = self.cursor.0; + if cursor.y() >= viewport_rows + self.scroll.0 as usize { + self.scroll.0 = (cursor.y() - viewport_rows) as u16 + 1; + } else if cursor.y() < self.scroll.0 as usize { + self.scroll.0 = cursor.y() as u16; } - if self.cursor.1 >= viewport_columns as u16 + self.scroll.1 { - self.scroll.1 = self.cursor.1 - viewport_columns as u16 + 1; - } else if self.cursor.1 < self.scroll.1 { - self.scroll.1 = self.cursor.1; + if cursor.x() >= viewport_columns + self.scroll.1 as usize { + self.scroll.1 = (cursor.x() - viewport_columns) as u16 + 1; + } else if cursor.x() < self.scroll.1 as usize { + self.scroll.1 = cursor.x() as u16; } for row in 0..viewport_rows as u16 { @@ -417,25 +419,26 @@ impl Widget for &mut SheetView { { let cell = cell_ref.value().to_string() + " "; - let line = if (cell_pos_y, cell_pos_x) == self.cursor { - theme - .cursor - .get(cell_ref, &lua::get()) - .unwrap_or_default() - .apply(cell.to_line()) - } else if self.is_in_selection(cell_pos_y, cell_pos_x) { - theme - .selection - .get(cell_ref, &lua::get()) - .unwrap_or_default() - .apply(cell.to_line()) - } else { - theme - .cell - .get(cell_ref, &lua::get()) - .unwrap_or_default() - .apply(cell.to_line()) - }; + let line = + if (cell_pos_y, cell_pos_x) == (cursor.y() as u16, cursor.x() as u16) { + theme + .cursor + .get(cell_ref, &lua::get()) + .unwrap_or_default() + .apply(cell.to_line()) + } else if self.is_in_selection(cell_pos_y, cell_pos_x) { + theme + .selection + .get(cell_ref, &lua::get()) + .unwrap_or_default() + .apply(cell.to_line()) + } else { + theme + .cell + .get(cell_ref, &lua::get()) + .unwrap_or_default() + .apply(cell.to_line()) + }; let rect = Rect::new( sheet_area_inner.x + column * DEFAULT_COLUMN_WIDTH, |