mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-19 21:29:52 -07:00
Allow typing newline with <S-Enter>
and enable keyboard enhancement protocol (#272)
This commit is contained in:
parent
7bc34c8145
commit
3971801aa3
2 changed files with 97 additions and 24 deletions
|
@ -3,13 +3,13 @@
|
||||||
//! The keybindings are set up here. We define some iamb-specific keybindings, but the default Vim
|
//! The keybindings are set up here. We define some iamb-specific keybindings, but the default Vim
|
||||||
//! keys come from [modalkit::env::vim::keybindings].
|
//! keys come from [modalkit::env::vim::keybindings].
|
||||||
use modalkit::{
|
use modalkit::{
|
||||||
actions::{MacroAction, WindowAction},
|
actions::{InsertTextAction, MacroAction, WindowAction},
|
||||||
env::vim::keybindings::{InputStep, VimBindings},
|
env::vim::keybindings::{InputStep, VimBindings},
|
||||||
env::vim::VimMode,
|
env::vim::VimMode,
|
||||||
env::CommonKeyClass,
|
env::CommonKeyClass,
|
||||||
key::TerminalKey,
|
key::TerminalKey,
|
||||||
keybindings::{EdgeEvent, EdgeRepeat, InputBindings},
|
keybindings::{EdgeEvent, EdgeRepeat, InputBindings},
|
||||||
prelude::Count,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::base::{IambAction, IambInfo, Keybindings, MATRIX_ID_WORD};
|
use crate::base::{IambAction, IambInfo, Keybindings, MATRIX_ID_WORD};
|
||||||
|
@ -36,6 +36,7 @@ pub fn setup_keybindings() -> Keybindings {
|
||||||
let ctrl_z = "<C-Z>".parse::<TerminalKey>().unwrap();
|
let ctrl_z = "<C-Z>".parse::<TerminalKey>().unwrap();
|
||||||
let key_m_lc = "m".parse::<TerminalKey>().unwrap();
|
let key_m_lc = "m".parse::<TerminalKey>().unwrap();
|
||||||
let key_z_lc = "z".parse::<TerminalKey>().unwrap();
|
let key_z_lc = "z".parse::<TerminalKey>().unwrap();
|
||||||
|
let shift_enter = "<S-Enter>".parse::<TerminalKey>().unwrap();
|
||||||
|
|
||||||
let cwz = vec![once(&ctrl_w), once(&key_z_lc)];
|
let cwz = vec![once(&ctrl_w), once(&key_z_lc)];
|
||||||
let cwcz = vec![once(&ctrl_w), once(&ctrl_z)];
|
let cwcz = vec![once(&ctrl_w), once(&ctrl_z)];
|
||||||
|
@ -57,6 +58,17 @@ pub fn setup_keybindings() -> Keybindings {
|
||||||
ism.add_mapping(VimMode::Visual, &cwm, &stoggle);
|
ism.add_mapping(VimMode::Visual, &cwm, &stoggle);
|
||||||
ism.add_mapping(VimMode::Normal, &cwcm, &stoggle);
|
ism.add_mapping(VimMode::Normal, &cwcm, &stoggle);
|
||||||
ism.add_mapping(VimMode::Visual, &cwcm, &stoggle);
|
ism.add_mapping(VimMode::Visual, &cwcm, &stoggle);
|
||||||
|
|
||||||
|
let shift_enter = vec![once(&shift_enter)];
|
||||||
|
let newline = IambStep::new().actions(vec![InsertTextAction::Type(
|
||||||
|
Char::Single('\n').into(),
|
||||||
|
MoveDir1D::Previous,
|
||||||
|
1.into(),
|
||||||
|
)
|
||||||
|
.into()]);
|
||||||
|
ism.add_mapping(VimMode::Insert, &cwm, &newline);
|
||||||
|
ism.add_mapping(VimMode::Insert, &shift_enter, &newline);
|
||||||
|
|
||||||
ism
|
ism
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
105
src/main.rs
105
src/main.rs
|
@ -48,6 +48,9 @@ use modalkit::crossterm::{
|
||||||
EnableFocusChange,
|
EnableFocusChange,
|
||||||
Event,
|
Event,
|
||||||
KeyEventKind,
|
KeyEventKind,
|
||||||
|
KeyboardEnhancementFlags,
|
||||||
|
PopKeyboardEnhancementFlags,
|
||||||
|
PushKeyboardEnhancementFlags,
|
||||||
},
|
},
|
||||||
execute,
|
execute,
|
||||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle},
|
terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle},
|
||||||
|
@ -250,16 +253,7 @@ impl Application {
|
||||||
settings: ApplicationSettings,
|
settings: ApplicationSettings,
|
||||||
store: AsyncProgramStore,
|
store: AsyncProgramStore,
|
||||||
) -> IambResult<Application> {
|
) -> IambResult<Application> {
|
||||||
let mut stdout = stdout();
|
let backend = CrosstermBackend::new(stdout());
|
||||||
crossterm::terminal::enable_raw_mode()?;
|
|
||||||
crossterm::execute!(stdout, EnterAlternateScreen)?;
|
|
||||||
crossterm::execute!(stdout, EnableBracketedPaste)?;
|
|
||||||
crossterm::execute!(stdout, EnableFocusChange)?;
|
|
||||||
|
|
||||||
let title = format!("iamb ({})", settings.profile.user_id);
|
|
||||||
crossterm::execute!(stdout, SetTitle(title))?;
|
|
||||||
|
|
||||||
let backend = CrosstermBackend::new(stdout);
|
|
||||||
let terminal = Terminal::new(backend)?;
|
let terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
let mut bindings = crate::keybindings::setup_keybindings();
|
let mut bindings = crate::keybindings::setup_keybindings();
|
||||||
|
@ -905,6 +899,70 @@ async fn login_normal(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EnableModifyOtherKeys;
|
||||||
|
struct DisableModifyOtherKeys;
|
||||||
|
|
||||||
|
impl crossterm::Command for EnableModifyOtherKeys {
|
||||||
|
fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(f, "\x1B[>4;2m")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crossterm::Command for DisableModifyOtherKeys {
|
||||||
|
fn write_ansi(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
|
||||||
|
write!(f, "\x1B[>4;0m")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn execute_winapi(&self) -> std::io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set up the terminal for drawing the TUI, and getting additional info.
|
||||||
|
fn setup_tty(title: &str, enable_enhanced_keys: bool) -> std::io::Result<()> {
|
||||||
|
let title = format!("iamb ({})", title);
|
||||||
|
|
||||||
|
// Enable raw mode and enter the alternate screen.
|
||||||
|
crossterm::terminal::enable_raw_mode()?;
|
||||||
|
crossterm::execute!(stdout(), EnterAlternateScreen)?;
|
||||||
|
|
||||||
|
if enable_enhanced_keys {
|
||||||
|
// Enable the Kitty keyboard enhancement protocol for improved keypresses.
|
||||||
|
crossterm::queue!(
|
||||||
|
stdout(),
|
||||||
|
PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES)
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
crossterm::queue!(stdout(), EnableModifyOtherKeys)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
crossterm::execute!(stdout(), EnableBracketedPaste, EnableFocusChange, SetTitle(title))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do our best to reverse what we did in setup_tty() when we exit or crash.
|
||||||
|
fn restore_tty(enable_enhanced_keys: bool) {
|
||||||
|
if enable_enhanced_keys {
|
||||||
|
let _ = crossterm::queue!(stdout(), PopKeyboardEnhancementFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = crossterm::execute!(
|
||||||
|
stdout(),
|
||||||
|
DisableModifyOtherKeys,
|
||||||
|
DisableBracketedPaste,
|
||||||
|
DisableFocusChange,
|
||||||
|
LeaveAlternateScreen,
|
||||||
|
CursorShow,
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = crossterm::terminal::disable_raw_mode();
|
||||||
|
}
|
||||||
|
|
||||||
async fn run(settings: ApplicationSettings) -> IambResult<()> {
|
async fn run(settings: ApplicationSettings) -> IambResult<()> {
|
||||||
// Get old keys the first time we run w/ the upgraded SDK.
|
// Get old keys the first time we run w/ the upgraded SDK.
|
||||||
let import_keys = check_import_keys(&settings).await?;
|
let import_keys = check_import_keys(&settings).await?;
|
||||||
|
@ -938,27 +996,30 @@ async fn run(settings: ApplicationSettings) -> IambResult<()> {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restore_tty() {
|
// Set up the terminal for drawing, and cleanup properly on panics.
|
||||||
let _ = crossterm::terminal::disable_raw_mode();
|
let enable_enhanced_keys = match crossterm::terminal::supports_keyboard_enhancement() {
|
||||||
let _ = crossterm::execute!(stdout(), DisableBracketedPaste);
|
Ok(supported) => supported,
|
||||||
let _ = crossterm::execute!(stdout(), DisableFocusChange);
|
Err(e) => {
|
||||||
let _ = crossterm::execute!(stdout(), LeaveAlternateScreen);
|
tracing::warn!(err = %e,
|
||||||
let _ = crossterm::execute!(stdout(), CursorShow);
|
"Failed to determine whether the terminal supports keyboard enhancements");
|
||||||
}
|
false
|
||||||
|
},
|
||||||
|
};
|
||||||
|
setup_tty(settings.profile.user_id.as_str(), enable_enhanced_keys)?;
|
||||||
|
|
||||||
// Make sure panics clean up the terminal properly.
|
|
||||||
let orig_hook = std::panic::take_hook();
|
let orig_hook = std::panic::take_hook();
|
||||||
std::panic::set_hook(Box::new(move |panic_info| {
|
std::panic::set_hook(Box::new(move |panic_info| {
|
||||||
restore_tty();
|
restore_tty(enable_enhanced_keys);
|
||||||
orig_hook(panic_info);
|
orig_hook(panic_info);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// And finally, start running the terminal UI.
|
||||||
let mut application = Application::new(settings, store).await?;
|
let mut application = Application::new(settings, store).await?;
|
||||||
|
|
||||||
// We can now run the application.
|
|
||||||
application.run().await?;
|
application.run().await?;
|
||||||
restore_tty();
|
|
||||||
|
// Clean up the terminal on exit.
|
||||||
|
restore_tty(enable_enhanced_keys);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue