Cursor shape can now be configured. (#269)

This commit is contained in:
Xithrius 2022-12-14 09:09:21 -08:00 committed by GitHub
parent b9515f41cc
commit b9a9988a96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 6 deletions

View File

@ -51,3 +51,5 @@ badges = true
theme = "dark"
# If the user's name appears in chat, highlight it.
username_highlight = true
# The shape of the cursor, block (default), underscore, or line.
cursor_shape = "block"

View File

@ -105,6 +105,8 @@ pub struct FrontendConfig {
pub username_highlight: bool,
/// If there should be state tabs shown on the bottom of the terminal.
pub state_tabs: bool,
/// The shape of the cursor in insert boxes.
pub cursor_shape: CursorType,
}
impl Default for TwitchConfig {
@ -144,6 +146,7 @@ impl Default for FrontendConfig {
theme: Theme::Dark,
username_highlight: true,
state_tabs: false,
cursor_shape: CursorType::default(),
}
}
}
@ -174,6 +177,32 @@ impl FromStr for Alignment {
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum CursorType {
Line,
Block,
UnderScore,
}
impl FromStr for CursorType {
type Err = Error;
fn from_str(s: &str) -> Result<CursorType, Self::Err> {
match s {
"line" => Ok(CursorType::Line),
"underscore" => Ok(CursorType::UnderScore),
_ => Ok(CursorType::Block),
}
}
}
impl Default for CursorType {
fn default() -> Self {
Self::Block
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "lowercase")]
pub enum Palette {

View File

@ -1,12 +1,15 @@
use std::{
fmt,
io::{stdout, Stdout},
time::Duration,
};
use crossterm::{
cursor::{CursorShape, SetCursorShape},
event::{DisableMouseCapture, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
Command,
};
use log::{debug, info};
use tokio::sync::mpsc::{Receiver, Sender};
@ -15,7 +18,7 @@ use tui::{backend::CrosstermBackend, Terminal};
use crate::{
handlers::{
app::{App, State},
config::CompleteConfig,
config::{CompleteConfig, CursorType},
data::{Data, DataBuilder, PayLoad},
user_input::{
events::{Config, Events, Key},
@ -26,17 +29,45 @@ use crate::{
ui::draw_ui,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ResetCursorShape;
impl Command for ResetCursorShape {
/// Fs escape sequence RIS for full reset
/// <https://en.wikipedia.org/wiki/ANSI_escape_code#Fs_Escape_sequences/>
fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result {
f.write_str("\x1Bc")
}
#[cfg(windows)]
fn execute_winapi(&self) -> Result<(), std::io::Error> {
Ok(())
}
}
fn reset_terminal() {
disable_raw_mode().unwrap();
execute!(stdout(), LeaveAlternateScreen).unwrap();
execute!(stdout(), LeaveAlternateScreen, ResetCursorShape).unwrap();
}
fn init_terminal() -> Terminal<CrosstermBackend<Stdout>> {
fn init_terminal(cursor_shape: CursorType) -> Terminal<CrosstermBackend<Stdout>> {
enable_raw_mode().unwrap();
let cursor_type = match cursor_shape {
CursorType::Line => CursorShape::Line,
CursorType::UnderScore => CursorShape::UnderScore,
CursorType::Block => CursorShape::Block,
};
let mut stdout = stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture).unwrap();
execute!(
stdout,
EnterAlternateScreen,
EnableMouseCapture,
SetCursorShape(cursor_type),
)
.unwrap();
let backend = CrosstermBackend::new(stdout);
@ -49,7 +80,7 @@ fn quit_terminal(mut terminal: Terminal<CrosstermBackend<Stdout>>) {
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
DisableMouseCapture,
)
.unwrap();
@ -79,7 +110,7 @@ pub async fn ui_driver(
})
.await;
let mut terminal = init_terminal();
let mut terminal = init_terminal(config.frontend.cursor_shape.clone());
terminal.clear().unwrap();