Shaper fully working and cached to preserve performance to some extent

macos-click-through
keith 5 years ago
parent 4a685942a9
commit 8b633986de

133
Cargo.lock generated

@ -5,6 +5,14 @@ name = "adler32"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ahash"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aho-corasick"
version = "0.7.6"
@ -112,6 +120,14 @@ name = "byteorder"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "c2-chacha"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "calloop"
version = "0.4.4"
@ -186,6 +202,24 @@ dependencies = [
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "const-random-macro"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation"
version = "0.6.4"
@ -348,11 +382,30 @@ name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "getrandom"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hashbrown"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heck"
version = "0.3.1"
@ -455,6 +508,14 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lru"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
@ -550,6 +611,7 @@ version = "0.1.0"
dependencies = [
"derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"neovim-lib 0.6.0 (git+https://github.com/daa84/neovim-lib)",
"rmpv 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"skulpin 0.3.0",
@ -683,6 +745,21 @@ name = "pkg-config"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro-hack"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
@ -720,6 +797,43 @@ dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "raw-window-handle"
version = "0.3.3"
@ -1062,6 +1176,11 @@ dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasi"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wayland-client"
version = "0.23.6"
@ -1238,6 +1357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
"checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3"
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
"checksum andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e"
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
@ -1251,6 +1371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
"checksum calloop 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160"
"checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8"
"checksum cexpr 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
@ -1259,6 +1380,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400"
"checksum const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b641a8c9867e341f3295564203b1c250eb8ce6cb6126e007941f78c4d2ed7fe"
"checksum const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c750ec12b83377637110d5a57f5ae08e895b06c4b16e2bdbf1a94ef717428c59"
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
@ -1277,7 +1400,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6c346c299e3fe8ef94dc10c2c0253d858a69aac1245157a3bf4125915d528caf"
@ -1292,6 +1417,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9"
"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237"
"checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
@ -1316,11 +1442,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
@ -1363,6 +1495,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
"checksum wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda"
"checksum wayland-commons 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb"
"checksum wayland-protocols 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9"

@ -5,6 +5,7 @@ authors = ["keith <keith@the-simmons.net>"]
edition = "2018"
[dependencies]
lru = "0.4.3"
skulpin = { path = "c:/dev/Projects/skulpin" }
derive-new = "0.5"
env_logger = "0.7.1"

@ -66,8 +66,7 @@ pub type GridCell = Option<(char, Style)>;
#[derive(new, Debug, Clone)]
pub struct DrawCommand {
pub text: String,
pub row: u64,
pub col_start: u64,
pub grid_position: (u64, u64),
pub style: Style
}
@ -90,7 +89,6 @@ impl CursorType {
}
pub struct Editor {
pub nvim: Neovim,
pub grid: Vec<Vec<GridCell>>,
pub cursor_pos: (u64, u64),
pub cursor_type: CursorType,
@ -104,9 +102,8 @@ pub struct Editor {
}
impl Editor {
pub fn new(nvim: Neovim, width: u64, height: u64) -> Editor {
pub fn new(width: u64, height: u64) -> Editor {
let mut editor = Editor {
nvim,
grid: Vec::new(),
cursor_pos: (0, 0),
cursor_type: CursorType::Block,
@ -160,7 +157,7 @@ impl Editor {
match command {
Some(command) => command.text.push(character.clone()),
None => {
command.replace(DrawCommand::new(character.to_string(), row_index, col_index, style));
command.replace(DrawCommand::new(character.to_string(), (col_index, row_index), style));
}
}
}
@ -222,7 +219,6 @@ impl Editor {
}
pub fn resize(&mut self, new_width: u64, new_height: u64) {
self.nvim.ui_try_resize(new_width as i64, new_height as i64).expect("Resize failed");
self.size = (new_width, new_height);
}

@ -150,6 +150,16 @@ fn parse_mode_change(mode_change_arguments: Vec<Value>) -> Result<RedrawEvent> {
}
}
fn parse_grid_resize(grid_resize_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [grid_id, width, height] = grid_resize_arguments.as_slice() {
Ok(RedrawEvent::Resize {
grid: parse_u64(&grid_id)?, width: parse_u64(&width)?, height: parse_u64(&height)?
})
} else {
Err(EventParseError::InvalidEventFormat)
}
}
fn parse_default_colors(default_colors_arguments: Vec<Value>) -> Result<RedrawEvent> {
if let [
foreground, background, special, _term_foreground, _term_background
@ -247,7 +257,7 @@ fn parse_grid_scroll(grid_scroll_arguments: Vec<Value>) -> Result<RedrawEvent> {
}
pub fn parse_redraw_event(event_value: Value) -> Result<Vec<RedrawEvent>> {
let mut event_contents = parse_array(&event_value)?.to_vec();
let event_contents = parse_array(&event_value)?.to_vec();
let name_value = event_contents.get(0).ok_or(EventParseError::InvalidEventFormat)?;
let event_name = parse_string(&name_value)?;
let events = event_contents;
@ -263,6 +273,7 @@ pub fn parse_redraw_event(event_value: Value) -> Result<Vec<RedrawEvent>> {
"mode_change" => Some(parse_mode_change(event_parameters)?),
"busy_start" => Some(RedrawEvent::BusyStart),
"busy_stop" => Some(RedrawEvent::BusyStop),
"grid_resize" => Some(parse_grid_resize(event_parameters)?),
"default_colors_set" => Some(parse_default_colors(event_parameters)?),
"hl_attr_define" => Some(parse_hl_attr_define(event_parameters)?),
"grid_line" => Some(parse_grid_line(event_parameters)?),

@ -1,5 +1,3 @@
use std::fmt;
use skulpin::winit::event::{KeyboardInput, ElementState, ModifiersState, VirtualKeyCode};
fn parse_keycode(keycode: VirtualKeyCode) -> Option<(String, bool)> {
@ -126,7 +124,7 @@ fn append_modifiers(modifiers: ModifiersState, keycode_text: String, special: bo
"/" => "?".to_string(),
other => {
special = true;
format!("S-{}", result)
format!("S-{}", other)
}
};
}

@ -5,8 +5,7 @@ mod events;
mod window;
mod keybindings;
#[macro_use]
extern crate derive_new;
#[macro_use] extern crate derive_new;
use std::panic;
use std::process::{Command, Stdio, exit};
@ -69,12 +68,12 @@ fn main() {
options.set_rgb(true);
nvim.ui_attach(INITIAL_WIDTH as i64, INITIAL_HEIGHT as i64, &options).unwrap();
let editor = Arc::new(Mutex::new(Editor::new(nvim, INITIAL_WIDTH, INITIAL_HEIGHT)));
let editor = Arc::new(Mutex::new(Editor::new(INITIAL_WIDTH, INITIAL_HEIGHT)));
let nvim_editor = editor.clone();
thread::spawn(move || {
nvim_event_loop(receiver, &nvim_editor);
});
ui_loop(editor);
ui_loop(editor, nvim, (INITIAL_WIDTH, INITIAL_HEIGHT));
}

@ -1,125 +1,189 @@
use std::borrow::Cow;
use std::sync::{Arc, Mutex};
use std::any::Any;
use std::time::{Duration, Instant};
use skulpin::{CoordinateSystem, CoordinateSystemHelper, RendererBuilder};
use skulpin::skia_safe::{Canvas, colors, Color4f, Font, FontStyle, Point, Paint, Rect, Shaper, Typeface};
use skulpin::skia_safe::paint::Style;
use skulpin::skia_safe::matrix::ScaleToFit;
use lru::LruCache;
use skulpin::{CoordinateSystem, RendererBuilder};
use skulpin::skia_safe::{Canvas, colors, Font, FontStyle, Paint, Point, Rect, Shaper, TextBlob, Typeface};
use skulpin::skia_safe::icu;
use skulpin::winit::dpi::{LogicalSize, LogicalPosition};
use skulpin::winit::event::{ElementState, Event, MouseScrollDelta, KeyboardInput, VirtualKeyCode, WindowEvent};
use skulpin::winit::dpi::LogicalSize;
use skulpin::winit::event::{ElementState, Event, MouseScrollDelta, WindowEvent};
use skulpin::winit::event_loop::{ControlFlow, EventLoop};
use skulpin::winit::window::WindowBuilder;
use neovim_lib::NeovimApi;
use neovim_lib::{Neovim, NeovimApi};
use crate::editor::{DrawCommand, Editor, Colors, CursorType};
use crate::editor::{Editor, CursorType, Style, Colors};
use crate::keybindings::construct_keybinding_string;
const FONT_NAME: &str = "Delugia Nerd Font";
const FONT_SIZE: f32 = 14.0;
fn draw(
editor: &Arc<Mutex<Editor>>,
canvas: &mut Canvas,
cursor_pos: &mut (f32, f32),
shaper: &Shaper,
paint: &mut Paint,
font: &Font,
struct CachingShaper {
shaper: Shaper,
cache: LruCache<String, TextBlob>
}
impl CachingShaper {
pub fn new() -> CachingShaper {
CachingShaper {
shaper: Shaper::new(None),
cache: LruCache::new(1000)
}
}
pub fn shape(&self, text: &str, font: &Font) -> TextBlob {
let (blob, _) = self.shaper.shape_text_blob(text, font, true, 1000.0, Point::default()).unwrap();
blob
}
pub fn shape_cached(&mut self, text: String, font: &Font) -> &TextBlob {
if !self.cache.contains(&text) {
self.cache.put(text.clone(), self.shape(&text, &font));
}
self.cache.get(&text).unwrap()
}
}
struct Renderer {
editor: Arc<Mutex<Editor>>,
paint: Paint,
font: Font,
shaper: CachingShaper,
font_width: f32,
font_height: f32
) {
let (draw_commands, default_colors, cursor_grid_pos, cursor_type, cursor_foreground, cursor_background, cursor_enabled) = {
let editor = editor.lock().unwrap();
(
editor.build_draw_commands().clone(),
editor.default_colors.clone(),
editor.cursor_pos.clone(),
editor.cursor_type.clone(),
editor.cursor_foreground(),
editor.cursor_background(),
editor.cursor_enabled
)
};
canvas.clear(default_colors.background.clone().unwrap().to_color());
for command in draw_commands {
let x = command.col_start as f32 * font_width;
let y = command.row as f32 * font_height + font_height - font_height * 0.2;
let top = y - font_height * 0.8;
let width = command.text.chars().count() as f32 * font_width;
let height = font_height;
font_height: f32,
cursor_pos: (f32, f32),
previous_frame_instant: Instant
}
impl Renderer {
pub fn new(editor: Arc<Mutex<Editor>>) -> Renderer {
let paint = Paint::new(colors::WHITE, None);
let typeface = Typeface::new(FONT_NAME, FontStyle::default()).expect("Could not load font file.");
let font = Font::from_typeface(typeface, FONT_SIZE);
let shaper = CachingShaper::new();
let (_, bounds) = font.measure_str("0", Some(&paint));
let font_width = bounds.width();
let (_, metrics) = font.metrics();
let font_height = metrics.descent - metrics.ascent; // bounds.height() * 1.68;
let cursor_pos = (0.0, 0.0);
let previous_frame_instant = Instant::now();
Renderer { editor, paint, font, shaper, font_width, font_height, cursor_pos, previous_frame_instant }
}
fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) {
let (grid_x, grid_y) = grid_pos;
let x = grid_x as f32 * self.font_width;
let y = grid_y as f32 * self.font_height + self.font_height - self.font_height * 0.2;
let top = y - self.font_height * 0.8;
let width = text.chars().count() as f32 * self.font_width;
let height = self.font_height;
let region = Rect::new(x, top, x + width, top + height);
paint.set_color(command.style.background(&default_colors).to_color());
canvas.draw_rect(region, &paint);
self.paint.set_color(style.background(default_colors).to_color());
canvas.draw_rect(region, &self.paint);
if command.style.underline || command.style.undercurl {
let (_, metrics) = font.metrics();
let width = command.text.chars().count() as f32 * font_width;
if style.underline || style.undercurl {
let (_, metrics) = self.font.metrics();
let width = text.chars().count() as f32 * self.font_width;
let underline_position = metrics.underline_position().unwrap();
paint.set_color(command.style.special(&default_colors).to_color());
canvas.draw_line((x, y + underline_position), (x + width, y + underline_position), &paint);
self.paint.set_color(style.special(&default_colors).to_color());
canvas.draw_line((x, y + underline_position), (x + width, y + underline_position), &self.paint);
}
paint.set_color(command.style.foreground(&default_colors).to_color());
let text = command.text.trim_end();
canvas.draw_str(text, (x, y), &font, &paint);
// if text.len() > 0 {
// if let Some((blob, _)) = shaper.shape_text_blob(&text, font, false, 10000.0, Point::default()) {
// canvas.draw_text_blob(&blob, (x, top), &paint);
// }
// }
self.paint.set_color(style.foreground(&default_colors).to_color());
let text = text.trim_end();
//canvas.draw_str(text, (x, y), &font, &paint);
if text.len() > 0 {
let reference;
let blob = if update_cache {
self.shaper.shape_cached(text.to_string(), &self.font)
} else {
reference = self.shaper.shape(text, &self.font);
&reference
};
canvas.draw_text_blob(blob, (x, top), &self.paint);
}
}
let (cursor_grid_x, cursor_grid_y) = cursor_grid_pos;
let target_cursor_x = cursor_grid_x as f32 * font_width;
let target_cursor_y = cursor_grid_y as f32 * font_height;
let (previous_cursor_x, previous_cursor_y) = cursor_pos;
pub fn draw(&mut self, canvas: &mut Canvas) {
let (draw_commands, default_colors, cursor_grid_pos, cursor_type, cursor_foreground, cursor_background, cursor_enabled) = {
let editor = self.editor.lock().unwrap();
(
editor.build_draw_commands().clone(),
editor.default_colors.clone(),
editor.cursor_pos.clone(),
editor.cursor_type.clone(),
editor.cursor_foreground(),
editor.cursor_background(),
editor.cursor_enabled
)
};
let cursor_x = (target_cursor_x - *previous_cursor_x) * 0.5 + *previous_cursor_x;
let cursor_y = (target_cursor_y - *previous_cursor_y) * 0.5 + *previous_cursor_y;
canvas.clear(default_colors.background.clone().unwrap().to_color());
*cursor_pos = (cursor_x, cursor_y);
if cursor_enabled {
let cursor_width = match cursor_type {
CursorType::Vertical => font_width / 8.0,
CursorType::Horizontal | CursorType::Block => font_width
};
let cursor_height = match cursor_type {
CursorType::Horizontal => font_width / 8.0,
CursorType::Vertical | CursorType::Block => font_height
};
let cursor = Rect::new(cursor_x, cursor_y, cursor_x + cursor_width, cursor_y + cursor_height);
paint.set_color(cursor_background.to_color());
canvas.draw_rect(cursor, &paint);
if let CursorType::Block = cursor_type {
paint.set_color(cursor_foreground.to_color());
let editor = editor.lock().unwrap();
let character = editor.grid[cursor_grid_y as usize][cursor_grid_x as usize].clone()
.map(|(character, _)| character)
.unwrap_or(' ');
let text_y = cursor_y + font_height - font_height * 0.2;
canvas.draw_str(character.to_string(), (cursor_x, text_y), &font, &paint);
for command in draw_commands {
self.draw_text(canvas, &command.text, command.grid_position, &command.style, &default_colors, true);
}
}
}
pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
let shaper = Shaper::new(None);
let typeface = Typeface::new(FONT_NAME, FontStyle::default()).expect("Could not load font file.");
let font = Font::from_typeface(typeface, FONT_SIZE);
let mut paint = Paint::new(colors::WHITE, None);
let (cursor_grid_x, cursor_grid_y) = cursor_grid_pos;
let target_cursor_x = cursor_grid_x as f32 * self.font_width;
let target_cursor_y = cursor_grid_y as f32 * self.font_height;
let (previous_cursor_x, previous_cursor_y) = self.cursor_pos;
let cursor_x = (target_cursor_x - previous_cursor_x) * 0.5 + previous_cursor_x;
let cursor_y = (target_cursor_y - previous_cursor_y) * 0.5 + previous_cursor_y;
let (width, bounds) = font.measure_str("0", Some(&paint));
let font_width = width;
let font_height = bounds.height() * 1.68;
self.cursor_pos = (cursor_x, cursor_y);
if cursor_enabled {
let cursor_width = match cursor_type {
CursorType::Vertical => self.font_width / 8.0,
CursorType::Horizontal | CursorType::Block => self.font_width
};
let cursor_height = match cursor_type {
CursorType::Horizontal => self.font_width / 8.0,
CursorType::Vertical | CursorType::Block => self.font_height
};
let cursor = Rect::new(cursor_x, cursor_y, cursor_x + cursor_width, cursor_y + cursor_height);
self.paint.set_color(cursor_background.to_color());
canvas.draw_rect(cursor, &self.paint);
if let CursorType::Block = cursor_type {
self.paint.set_color(cursor_foreground.to_color());
let editor = self.editor.lock().unwrap();
let character = editor.grid[cursor_grid_y as usize][cursor_grid_x as usize].clone()
.map(|(character, _)| character)
.unwrap_or(' ');
let text_y = cursor_y + self.font_height - self.font_height * 0.2;
canvas.draw_text_blob(
self.shaper.shape_cached(character.to_string(), &self.font),
(cursor_x, text_y), &self.paint);
}
}
}
}
pub fn ui_loop(editor: Arc<Mutex<Editor>>, nvim: Neovim, initial_size: (u64, u64)) {
let mut nvim = nvim;
let mut renderer = Renderer::new(editor);
let event_loop = EventLoop::<()>::with_user_event();
let logical_size = LogicalSize::new((100.0 * font_width) as f64, (50.0 * font_height) as f64);
let (width, height) = initial_size;
let logical_size = LogicalSize::new(
(width as f32 * renderer.font_width) as f64,
// Add 1.0 here to make sure resizing horizontally doesn't change the grid height
(height as f32 * renderer.font_height + 1.0) as f64
);
let window = WindowBuilder::new()
.with_title("Neovide")
@ -127,13 +191,11 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
.build(&event_loop)
.expect("Failed to create window");
let mut renderer = RendererBuilder::new()
let mut skulpin_renderer = RendererBuilder::new()
.coordinate_system(CoordinateSystem::Logical)
.prefer_mailbox_present_mode()
.build(&window)
.expect("Failed to create renderer");
let mut cursor_pos = (0.0, 0.0);
let mut mouse_down = false;
let mut mouse_pos = (0, 0);
@ -151,10 +213,9 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
..
} => {
if new_size.width > 0.0 && new_size.height > 0.0 {
editor.lock().unwrap().resize(
(new_size.width as f32 / font_width) as u64,
(new_size.height as f32 / font_height) as u64
)
let new_width = (new_size.width as f32 / renderer.font_width) as u64;
let new_height = (new_size.height as f32 / renderer.font_height) as u64;
nvim.ui_try_resize(new_width as i64, new_height as i64).expect("Resize failed");
}
},
@ -166,7 +227,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
..
} => {
if let Some(string) = construct_keybinding_string(input) {
editor.lock().unwrap().nvim.input(&string).expect("Input call failed...");
nvim.input(&string).expect("Input call failed...");
}
},
@ -177,11 +238,11 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
},
..
} => {
let grid_x = (position.x as f32 / font_width) as i64;
let grid_y = (position.y as f32 / font_height) as i64;
let grid_x = (position.x as f32 / renderer.font_width) as i64;
let grid_y = (position.y as f32 / renderer.font_height) as i64;
mouse_pos = (grid_x, grid_y);
if mouse_down {
editor.lock().unwrap().nvim.input_mouse("left", "drag", "", 0, grid_y, grid_x);
nvim.input_mouse("left", "drag", "", 0, grid_y, grid_x).expect("Could not send mouse input");
}
}
@ -203,7 +264,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
}
};
let (grid_x, grid_y) = mouse_pos;
editor.lock().unwrap().nvim.input_mouse("left", input_type, "", 0, grid_y, grid_x);
nvim.input_mouse("left", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input");
}
Event::WindowEvent {
@ -219,7 +280,7 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
"down"
};
let (grid_x, grid_y) = mouse_pos;
editor.lock().unwrap().nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x);
nvim.input_mouse("wheel", input_type, "", 0, grid_y, grid_x).expect("Could not send mouse input");
}
Event::EventsCleared => {
@ -230,8 +291,8 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>) {
event: WindowEvent::RedrawRequested,
..
} => {
if let Err(e) = renderer.draw(&window, |canvas, _coordinate_system_helper| {
draw(&editor, canvas, &mut cursor_pos, &shaper, &mut paint, &font, font_width, font_height);
if let Err(e) = skulpin_renderer.draw(&window, |canvas, _coordinate_system_helper| {
renderer.draw(canvas);
}) {
println!("Error during draw: {:?}", e);
*control_flow = ControlFlow::Exit

Loading…
Cancel
Save