Rust终端工具Wezterm输入处理库wezterm-input-types的使用,解析与扩展终端输入事件类型

Rust终端工具Wezterm输入处理库wezterm-input-types的使用,解析与扩展终端输入事件类型

安装

在项目目录中运行以下Cargo命令:

cargo add wezterm-input-types

或者在Cargo.toml中添加以下行:

wezterm-input-types = "0.1.0"

基本使用

wezterm-input-types库提供了处理终端输入事件的功能。以下是一个基本使用示例:

use wezterm_input_types::{KeyCode, KeyModifiers, MouseEvent};

fn handle_key_event(key: KeyCode, mods: KeyModifiers) {
    match key {
        KeyCode::Char(c) => println!("Pressed character: {} with modifiers {:?}", c, mods),
        KeyCode::Enter => println!("Pressed Enter"),
        _ => println!("Other key: {:?}", key),
    }
}

fn handle_mouse_event(event: MouseEvent) {
    println!("Mouse event: {:?}", event);
}

fn main() {
    // 模拟键盘输入
    handle_key_event(KeyCode::Char('a'), KeyModifiers::NONE);
    handle_key_event(KeyCode::Enter, KeyModifiers::SHIFT);
    
    // 模拟鼠标输入
    handle_mouse_event(MouseEvent {
        x: 100,
        y: 200,
        button: 1,
        modifiers: KeyModifiers::CTRL,
    });
}

完整示例

以下是一个更完整的示例,展示了如何解析和扩展终端输入事件:

use wezterm_input_types::{
    KeyCode, KeyModifiers, MouseButton, MouseEvent, InputEvent, InputParser
};

struct CustomInputHandler;

impl CustomInputHandler {
    fn handle_event(&mut self, event: InputEvent) {
        match event {
            InputEvent::Key(key_event) => {
                println!("Key event: {:?}", key_event);
                self.handle_key(key_event.key, key_event.mods);
            }
            InputEvent::Mouse(mouse_event) => {
                println!("Mouse event: {:?}", mouse_event);
                self.handle_mouse(mouse_event);
            }
            InputEvent::Paste(text) => {
                println!("Pasted text: {}", text);
            }
            _ => println!("Other input event: {:?}", event),
        }
    }

    fn handle_key(&self, key: KeyCode, mods: KeyModifiers) {
        // 自定义键盘处理逻辑
        match (key, mods) {
            (KeyCode::Char('c'), KeyModifiers::CTRL) => {
                println!("Ctrl+C pressed - handling custom behavior");
            }
            (KeyCode::F(n), _) => {
                println!("Function key F{} pressed", n);
            }
            _ => println!("Regular key: {:?} with mods {:?}", key, mods),
        }
    }

    fn handle_mouse(&self, event: MouseEvent) {
        // 自定义鼠标处理逻辑
        let button = match event.button {
            MouseButton::Left => "left",
            MouseButton::Right => "right",
            MouseButton::Middle => "middle",
            MouseButton::None => "none",
            _ => "other",
        };

        println!(
            "Mouse at ({}, {}), button: {}, mods: {:?}",
            event.x, event.y, button, event.modifiers
        );
    }
}

fn main() {
    let mut handler = CustomInputHandler;
    let mut parser = InputParser::new();

    // 模拟输入数据流
    let input_data = b"\x1b[32;100;200M"; // 模拟鼠标点击事件

    for byte in input_data {
        if let Some(event) = parser.advance(&[*byte]) {
            handler.handle_event(event);
        }
    }
}

扩展输入事件类型

您可以通过实现自定义的输入事件类型来扩展功能:

use wezterm_input_types::{InputEvent, KeyCode, KeyModifiers};

#[derive(Debug)]
enum CustomInputEvent {
    Standard(InputEvent),
    CustomGesture(String),
}

struct ExtendedInputHandler;

impl ExtendedInputHandler {
    fn handle_custom_event(&self, event: CustomInputEvent) {
        match event {
            CustomInputEvent::Standard(std_event) => {
                println!("Standard event: {:?}", std_event);
            }
            CustomInputEvent::CustomGesture(gesture) => {
                println!("Custom gesture detected: {}", gesture);
                self.handle_gesture(gesture);
            }
        }
    }

    fn handle_gesture(&self, gesture: String) {
        match gesture.as_str() {
            "swipe-left" => println!("Handling swipe left gesture"),
            "swipe-right" => println!("Handling swipe right gesture"),
            _ => println!("Unknown gesture: {}", gesture),
        }
    }
}

fn create_custom_events() -> Vec<CustomInputEvent> {
    vec![
        CustomInputEvent::Standard(InputEvent::Key(
            KeyCode::Char('a').with_modifiers(KeyModifiers::NONE)
        )),
        CustomInputEvent::CustomGesture("swipe-left".to_string()),
    ]
}

fn main() {
    let handler = ExtendedInputHandler;
    let events = create_custom_events();

    for event in events {
        handler.handle_custom_event(event);
    }
}

这个库是Wezterm终端模拟器的一部分,专门用于处理终端输入事件。它提供了强大的功能来解析和响应各种键盘和鼠标事件,并可以轻松扩展以支持自定义输入类型。


1 回复

wezterm-input-types: Rust终端工具Wezterm的输入处理库

概述

wezterm-input-types是Wezterm终端模拟器的一个核心输入处理库,专门用于解析和扩展终端输入事件类型。它提供了强大的功能来处理各种键盘、鼠标和其他输入设备产生的事件,是构建自定义终端输入处理逻辑的基础。

主要功能

  • 标准键盘事件处理
  • 鼠标事件处理
  • 自定义输入事件定义
  • 输入事件序列化/反序列化
  • 输入修饰键状态跟踪

完整示例代码

下面是一个结合键盘、鼠标处理和自定义事件的完整示例:

use wezterm_input_types::{
    InputEvent, KeyCode, KeyModifiers, KeyboardInput, MouseButton, MouseEvent
};
use serde_json;

// 自定义终端事件处理器
struct TerminalEventHandler;

impl TerminalEventHandler {
    // 处理所有输入事件
    fn handle_event(&self, event: InputEvent) {
        match event {
            InputEvent::Keyboard(key_event) => self.handle_keyboard(key_event),
            InputEvent::Mouse(mouse_event) => self.handle_mouse(mouse_event),
            InputEvent::Resize { cols, rows } => {
                println!("Terminal resized to {}x{}", cols, rows);
            },
            _ => println!("Received unhandled event type"),
        }
    }

    // 处理键盘事件
    fn handle_keyboard(&self, input: KeyboardInput) {
        match (input.key, input.mods) {
            (KeyCode::Char('c'), KeyModifiers::CTRL) => {
                println!("Ctrl+C pressed - exiting");
                std::process::exit(0);
            },
            (KeyCode::Char('s'), KeyModifiers::CTRL) => {
                println!("Ctrl+S pressed - saving session");
            },
            (KeyCode::Function(n), _) => {
                println!("F{} key pressed", n);
            },
            (KeyCode::Char(c), mods) => {
                println!("Char '{}' pressed with modifiers {:?}", c, mods);
            },
            _ => println!("Unhandled key combination"),
        }
    }

    // 处理鼠标事件
    fn handle_mouse(&self, event: MouseEvent) {
        match event.button {
            MouseButton::Left => {
                println!("Left click at ({}, {})", event.coords.x, event.coords.y);
            },
            MouseButton::Right => {
                println!("Right click at ({}, {})", event.coords.x, event.coords.y);
            },
            MouseButton::Middle => {
                println!("Middle click at ({}, {})", event.coords.x, event.coords.y);
            },
            MouseButton::WheelUp => println!("Mouse wheel scrolled up"),
            MouseButton::WheelDown => println!("Mouse wheel scrolled down"),
            _ => {}
        }
    }
}

// 自定义事件扩展示例
enum ExtendedEvent {
    CustomCommand(String),
    TerminalBell,
}

impl Into<InputEvent> for ExtendedEvent {
    fn into(self) -> InputEvent {
        match self {
            ExtendedEvent::CustomCommand(cmd) => {
                // 转换为键盘输入事件
                InputEvent::Keyboard(KeyboardInput {
                    key: KeyCode::Char(' '),
                    mods: KeyModifiers::NONE,
                })
            },
            ExtendedEvent::TerminalBell => {
                // 转换为自定义事件
                InputEvent::None
            }
        }
    }
}

fn main() {
    let handler = TerminalEventHandler;
    
    // 示例键盘事件
    let ctrl_c = InputEvent::Keyboard(KeyboardInput {
        key: KeyCode::Char('c'),
        mods: KeyModifiers::CTRL,
    });
    
    // 示例鼠标事件
    let mouse_click = InputEvent::Mouse(MouseEvent {
        button: MouseButton::Left,
        coords: (100, 200).into(),
    });
    
    // 处理示例事件
    handler.handle_event(ctrl_c);
    handler.handle_event(mouse_click);
    
    // 序列化示例
    let event = InputEvent::Keyboard(KeyboardInput {
        key: KeyCode::Char('a'),
        mods: KeyModifiers::SHIFT,
    });
    
    let serialized = serde_json::to_string(&event).unwrap();
    println!("Serialized event: {}", serialized);
    
    // 自定义事件处理
    let custom_event = ExtendedEvent::CustomCommand("test".to_string());
    let input_event: InputEvent = custom_event.into();
    handler.handle_event(input_event);
}

注意事项

  1. wezterm-input-types通常与wezterm-terminalwezterm-client一起使用
  2. 输入事件处理应考虑跨平台差异
  3. 某些特殊键组合可能在不同操作系统上有不同表现
  4. 实际使用时需要处理错误情况,如序列化/反序列化失败
  5. 自定义事件需要确保与现有事件类型不冲突

通过这个完整的示例,开发者可以了解如何:

  • 处理键盘和鼠标输入
  • 扩展自定义事件类型
  • 序列化和反序列化输入事件
  • 构建完整的终端输入处理逻辑
回到顶部