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
|
||||
//! keys come from [modalkit::env::vim::keybindings].
|
||||
use modalkit::{
|
||||
actions::{MacroAction, WindowAction},
|
||||
actions::{InsertTextAction, MacroAction, WindowAction},
|
||||
env::vim::keybindings::{InputStep, VimBindings},
|
||||
env::vim::VimMode,
|
||||
env::CommonKeyClass,
|
||||
key::TerminalKey,
|
||||
keybindings::{EdgeEvent, EdgeRepeat, InputBindings},
|
||||
prelude::Count,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
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 key_m_lc = "m".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 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::Normal, &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
|
||||
}
|
||||
|
||||
|
|
105
src/main.rs
105
src/main.rs
|
@ -48,6 +48,9 @@ use modalkit::crossterm::{
|
|||
EnableFocusChange,
|
||||
Event,
|
||||
KeyEventKind,
|
||||
KeyboardEnhancementFlags,
|
||||
PopKeyboardEnhancementFlags,
|
||||
PushKeyboardEnhancementFlags,
|
||||
},
|
||||
execute,
|
||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle},
|
||||
|
@ -250,16 +253,7 @@ impl Application {
|
|||
settings: ApplicationSettings,
|
||||
store: AsyncProgramStore,
|
||||
) -> IambResult<Application> {
|
||||
let mut stdout = 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 backend = CrosstermBackend::new(stdout());
|
||||
let terminal = Terminal::new(backend)?;
|
||||
|
||||
let mut bindings = crate::keybindings::setup_keybindings();
|
||||
|
@ -905,6 +899,70 @@ async fn login_normal(
|
|||
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<()> {
|
||||
// Get old keys the first time we run w/ the upgraded SDK.
|
||||
let import_keys = check_import_keys(&settings).await?;
|
||||
|
@ -938,27 +996,30 @@ async fn run(settings: ApplicationSettings) -> IambResult<()> {
|
|||
Ok(()) => (),
|
||||
}
|
||||
|
||||
fn restore_tty() {
|
||||
let _ = crossterm::terminal::disable_raw_mode();
|
||||
let _ = crossterm::execute!(stdout(), DisableBracketedPaste);
|
||||
let _ = crossterm::execute!(stdout(), DisableFocusChange);
|
||||
let _ = crossterm::execute!(stdout(), LeaveAlternateScreen);
|
||||
let _ = crossterm::execute!(stdout(), CursorShow);
|
||||
}
|
||||
// Set up the terminal for drawing, and cleanup properly on panics.
|
||||
let enable_enhanced_keys = match crossterm::terminal::supports_keyboard_enhancement() {
|
||||
Ok(supported) => supported,
|
||||
Err(e) => {
|
||||
tracing::warn!(err = %e,
|
||||
"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();
|
||||
std::panic::set_hook(Box::new(move |panic_info| {
|
||||
restore_tty();
|
||||
restore_tty(enable_enhanced_keys);
|
||||
orig_hook(panic_info);
|
||||
process::exit(1);
|
||||
}));
|
||||
|
||||
// And finally, start running the terminal UI.
|
||||
let mut application = Application::new(settings, store).await?;
|
||||
|
||||
// We can now run the application.
|
||||
application.run().await?;
|
||||
restore_tty();
|
||||
|
||||
// Clean up the terminal on exit.
|
||||
restore_tty(enable_enhanced_keys);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue