1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-12 21:30:45 +03:00

Add cursor and pane position info to wezterm cli list data

This is included only in the json output mode.

Note that this does not and cannot include positioning information known
only to the GUI, as there may not be a GUI. That means that window
position, tab bar and padding data are not known and not able to be
returned via this interface.

```
; wezterm cli list --format json
[
  {
    "window_id": 0,
    "tab_id": 0,
    "pane_id": 0,
    "workspace": "default",
    "size": {
      "rows": 24,
      "cols": 80,
      "pixel_width": 1040,
      "pixel_height": 672,
      "dpi": 124
    },
    "title": "wezterm cli list --format json -- wez@foo:~",
    "cwd": "file://foo/home/wez/",
    "cursor_x": 0,
    "cursor_y": 2,
    "cursor_shape": "Default",
    "cursor_visibility": "Visible",
    "left_col": 0,
    "top_row": 0
  }
]
```

refs: #2319
This commit is contained in:
Wez Furlong 2022-07-31 11:58:40 -07:00
parent aed0e3ebf8
commit 0d51a9c444
3 changed files with 67 additions and 11 deletions

View File

@ -416,7 +416,7 @@ macro_rules! pdu {
/// The overall version of the codec.
/// This must be bumped when backwards incompatible changes
/// are made to the types and protocol.
pub const CODEC_VERSION: usize = 27;
pub const CODEC_VERSION: usize = 28;
// Defines the Pdu enum.
// Each struct has an explicit identifying number.

View File

@ -1,5 +1,6 @@
use crate::domain::DomainId;
use crate::pane::*;
use crate::renderable::StableCursorPosition;
use crate::{Mux, WindowId};
use bintree::PathBranch;
use config::configuration;
@ -10,7 +11,7 @@ use std::cell::{RefCell, RefMut};
use std::convert::TryInto;
use std::rc::Rc;
use url::Url;
use wezterm_term::TerminalSize;
use wezterm_term::{StableRowIndex, TerminalSize};
pub type Tree = bintree::Tree<Rc<dyn Pane>, SplitDirectionAndSize>;
pub type Cursor = bintree::Cursor<Rc<dyn Pane>, SplitDirectionAndSize>;
@ -194,21 +195,42 @@ fn pane_tree(
active: Option<&Rc<dyn Pane>>,
zoomed: Option<&Rc<dyn Pane>>,
workspace: &str,
left_col: usize,
top_row: usize,
) -> PaneNode {
match tree {
Tree::Empty => PaneNode::Empty,
Tree::Node { left, right, data } => PaneNode::Split {
left: Box::new(pane_tree(
&*left, tab_id, window_id, active, zoomed, workspace,
)),
right: Box::new(pane_tree(
&*right, tab_id, window_id, active, zoomed, workspace,
)),
node: data.unwrap(),
},
Tree::Node { left, right, data } => {
let data = data.unwrap();
PaneNode::Split {
left: Box::new(pane_tree(
&*left, tab_id, window_id, active, zoomed, workspace, left_col, top_row,
)),
right: Box::new(pane_tree(
&*right,
tab_id,
window_id,
active,
zoomed,
workspace,
if data.direction == SplitDirection::Vertical {
left_col
} else {
left_col + data.left_of_second()
},
if data.direction == SplitDirection::Horizontal {
top_row
} else {
top_row + data.top_of_second()
},
)),
node: data,
}
}
Tree::Leaf(pane) => {
let dims = pane.get_dimensions();
let working_dir = pane.get_current_working_dir();
let cursor_pos = pane.get_cursor_position();
PaneNode::Leaf(PaneEntry {
window_id,
@ -226,6 +248,10 @@ fn pane_tree(
},
working_dir: working_dir.map(Into::into),
workspace: workspace.to_string(),
cursor_pos,
physical_top: dims.physical_top,
left_col,
top_row,
})
}
}
@ -567,6 +593,8 @@ impl Tab {
active.as_ref(),
zoomed.as_ref(),
&workspace,
0,
0,
)
} else {
PaneNode::Empty
@ -1862,6 +1890,10 @@ pub struct PaneEntry {
pub is_active_pane: bool,
pub is_zoomed_pane: bool,
pub workspace: String,
pub cursor_pos: StableCursorPosition,
pub physical_top: StableRowIndex,
pub top_row: usize,
pub left_col: usize,
}
#[derive(Deserialize, Clone, Serialize, PartialEq, Debug)]

View File

@ -575,10 +575,14 @@ async fn resolve_pane_id(client: &Client, pane_id: Option<PaneId>) -> anyhow::Re
struct CliListResultPtySize {
rows: usize,
cols: usize,
/// Pixel width of the pane, if known (can be zero)
pixel_width: usize,
/// Pixel height of the pane, if known (can be zero)
pixel_height: usize,
/// dpi of the pane, if known (can be zero)
dpi: u32,
}
// This will be serialized to JSON via the 'List' command.
// As such it is intended to be a stable output format,
// Thus we need to be careful about both the fields and their types,
@ -592,6 +596,16 @@ struct CliListResultItem {
size: CliListResultPtySize,
title: String,
cwd: String,
/// Cursor x coordinate from top left of non-scrollback pane area
cursor_x: usize,
/// Cursor y coordinate from top left of non-scrollback pane area
cursor_y: usize,
cursor_shape: termwiz::surface::CursorShape,
cursor_visibility: termwiz::surface::CursorVisibility,
/// Number of cols from the left of the tab area to the left of this pane
left_col: usize,
/// Number of rows from the top of the tab area to the top of this pane
top_row: usize,
}
impl From<mux::tab::PaneEntry> for CliListResultItem {
@ -603,6 +617,10 @@ impl From<mux::tab::PaneEntry> for CliListResultItem {
workspace,
title,
working_dir,
cursor_pos,
physical_top,
left_col,
top_row,
size:
TerminalSize {
rows,
@ -632,6 +650,12 @@ impl From<mux::tab::PaneEntry> for CliListResultItem {
.map(|url| url.url.as_str())
.unwrap_or("")
.to_string(),
cursor_x: cursor_pos.x,
cursor_y: cursor_pos.y.saturating_sub(physical_top) as usize,
cursor_shape: cursor_pos.shape,
cursor_visibility: cursor_pos.visibility,
left_col,
top_row,
}
}
}