Don't visually freeze the UI on an onslaught of input.
This commit is contained in:
parent
d1de3aacb3
commit
6e8f132563
90
Cargo.lock
generated
90
Cargo.lock
generated
|
@ -10,6 +10,7 @@ dependencies = [
|
||||||
"gag",
|
"gag",
|
||||||
"ropey",
|
"ropey",
|
||||||
"smallvec 1.2.0",
|
"smallvec 1.2.0",
|
||||||
|
"time",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
@ -291,6 +292,35 @@ version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-hack"
|
||||||
|
version = "0.5.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
@ -356,6 +386,17 @@ dependencies = [
|
||||||
"smallvec 0.6.13",
|
"smallvec 0.6.13",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -410,6 +451,17 @@ version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
|
@ -433,6 +485,38 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcb8742444475438c500d017736dd7cf3d9c9dd1f0153cfa4af428692484e3ef"
|
||||||
|
dependencies = [
|
||||||
|
"rustversion",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ae9b6e9f095bc105e183e3cd493d72579be3181ad4004fceb01adbe9eecab2d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-hack",
|
||||||
|
"time-macros-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros-impl"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e987cfe0537f575b5fc99909de6185f6c19c3ad8889e2275e686a873d0869ba1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-hack",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -445,6 +529,12 @@ version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
|
@ -23,6 +23,7 @@ clap = "2"
|
||||||
smallvec = "1"
|
smallvec = "1"
|
||||||
crossterm = "0.14"
|
crossterm = "0.14"
|
||||||
gag = "0.1.10"
|
gag = "0.1.10"
|
||||||
|
time = "0.2"
|
||||||
|
|
||||||
# Local crate dependencies
|
# Local crate dependencies
|
||||||
[dependencies.backend]
|
[dependencies.backend]
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
editor::Editor,
|
editor::Editor,
|
||||||
formatter::{block_count, block_index_and_range, char_range_from_block_index, LineFormatter},
|
formatter::{block_count, block_index_and_range, char_range_from_block_index, LineFormatter},
|
||||||
string_utils::{line_ending_to_str, rope_slice_is_line_ending, LineEnding},
|
string_utils::{line_ending_to_str, rope_slice_is_line_ending, LineEnding},
|
||||||
utils::{digit_count, RopeGraphemes},
|
utils::{digit_count, RopeGraphemes, Timer},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
|
@ -24,6 +24,7 @@ use self::{
|
||||||
};
|
};
|
||||||
|
|
||||||
const EMPTY_MOD: KeyModifiers = KeyModifiers::empty();
|
const EMPTY_MOD: KeyModifiers = KeyModifiers::empty();
|
||||||
|
const UPDATE_TICK_MS: u64 = 10;
|
||||||
|
|
||||||
// Color theme.
|
// Color theme.
|
||||||
// Styles are (FG, BG).
|
// Styles are (FG, BG).
|
||||||
|
@ -80,6 +81,7 @@ const STYLE_INFO: Style = Style(
|
||||||
macro_rules! ui_loop {
|
macro_rules! ui_loop {
|
||||||
($term_ui:ident,draw $draw:block,key_press($key:ident) $key_press:block) => {
|
($term_ui:ident,draw $draw:block,key_press($key:ident) $key_press:block) => {
|
||||||
let mut stop = false;
|
let mut stop = false;
|
||||||
|
let mut timer = Timer::new();
|
||||||
|
|
||||||
// Draw the editor to screen for the first time
|
// Draw the editor to screen for the first time
|
||||||
{
|
{
|
||||||
|
@ -97,7 +99,7 @@ macro_rules! ui_loop {
|
||||||
// want to re-draw on e.g. async syntax highlighting updates, or
|
// want to re-draw on e.g. async syntax highlighting updates, or
|
||||||
// update based on a file being modified outside our process.
|
// update based on a file being modified outside our process.
|
||||||
loop {
|
loop {
|
||||||
if crossterm::event::poll(Duration::from_millis(5)).unwrap() {
|
if crossterm::event::poll(Duration::from_millis(UPDATE_TICK_MS)).unwrap() {
|
||||||
match crossterm::event::read().unwrap() {
|
match crossterm::event::read().unwrap() {
|
||||||
Event::Key($key) => {
|
Event::Key($key) => {
|
||||||
let (status, state_changed) = || -> (LoopStatus, bool) { $key_press }();
|
let (status, state_changed) = || -> (LoopStatus, bool) { $key_press }();
|
||||||
|
@ -120,6 +122,15 @@ macro_rules! ui_loop {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If too much time has passed since the last redraw,
|
||||||
|
// break so we can draw if needed. This keeps an onslaught
|
||||||
|
// of input (e.g. when pasting a large piece of text) from
|
||||||
|
// visually freezing the UI.
|
||||||
|
if timer.elapsed() >= UPDATE_TICK_MS {
|
||||||
|
timer.tick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
29
src/utils.rs
29
src/utils.rs
|
@ -1,4 +1,5 @@
|
||||||
use ropey::{iter::Chunks, str_utils::byte_to_char_idx, RopeSlice};
|
use ropey::{iter::Chunks, str_utils::byte_to_char_idx, RopeSlice};
|
||||||
|
use time::Instant;
|
||||||
use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};
|
use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
|
@ -190,6 +191,34 @@ impl<'a> Iterator for RopeGraphemes<'a> {
|
||||||
|
|
||||||
//=============================================================
|
//=============================================================
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Timer {
|
||||||
|
last_instant: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Timer {
|
||||||
|
pub fn new() -> Timer {
|
||||||
|
Timer {
|
||||||
|
last_instant: Instant::now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Marks a new tick time and returns the time elapsed in milliseconds since
|
||||||
|
/// the last call to tick().
|
||||||
|
pub fn tick(&mut self) -> u64 {
|
||||||
|
let n = self.elapsed();
|
||||||
|
self.last_instant = Instant::now();
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the time elapsed in milliseconds since the last call to tick().
|
||||||
|
pub fn elapsed(self) -> u64 {
|
||||||
|
self.last_instant.elapsed().whole_milliseconds() as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user