Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add pane names #928

Merged
merged 6 commits into from
Dec 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion default-plugins/status-bar/src/first_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ pub fn ctrl_keys(help: &ModeInfo, max_len: usize, separator: &str) -> LinePart {
colored_elements,
separator,
),
InputMode::Pane => key_indicators(
InputMode::Pane | InputMode::RenamePane => key_indicators(
max_len,
&[
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
Expand Down
3 changes: 2 additions & 1 deletion src/tests/e2e/remote_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ fn read_from_channel(
let last_snapshot = last_snapshot.clone();
let cursor_coordinates = cursor_coordinates.clone();
let mut vte_parser = vte::Parser::new();
let mut terminal_output = TerminalPane::new(0, *pane_geom, Palette::default(), 0); // 0 is the pane index
let mut terminal_output =
TerminalPane::new(0, *pane_geom, Palette::default(), 0, String::new()); // 0 is the pane index
let mut retries_left = 3;
move || {
let mut should_sleep = false;
Expand Down
2 changes: 1 addition & 1 deletion zellij-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub fn start_client(
client_attributes,
Box::new(opts),
Box::new(config_options.clone()),
layout.unwrap(),
Box::new(layout.unwrap()),
Some(config.plugins.clone()),
)
}
Expand Down
4 changes: 2 additions & 2 deletions zellij-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub enum ServerInstruction {
ClientAttributes,
Box<CliArgs>,
Box<Options>,
LayoutFromYaml,
Box<LayoutFromYaml>,
ClientId,
Option<PluginsConfig>,
),
Expand Down Expand Up @@ -531,7 +531,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
pub struct SessionOptions {
pub opts: Box<CliArgs>,
pub config_options: Box<Options>,
pub layout: LayoutFromYaml,
pub layout: Box<LayoutFromYaml>,
pub plugins: Option<PluginsConfig>,
}

Expand Down
38 changes: 35 additions & 3 deletions zellij-server/src/panes/plugin_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::ClientId;
use zellij_utils::pane_size::Offset;
use zellij_utils::position::Position;
use zellij_utils::shared::ansi_len;
use zellij_utils::zellij_tile::prelude::{Event, Mouse, PaletteColor};
use zellij_utils::zellij_tile::prelude::{Event, InputMode, Mouse, PaletteColor};
use zellij_utils::{
channels::SenderWithContext,
pane_size::{Dimension, PaneGeom},
Expand All @@ -28,6 +28,7 @@ pub(crate) struct PluginPane {
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
pub active_at: Instant,
pub pane_title: String,
pub pane_name: String,
frame: bool,
borderless: bool,
}
Expand All @@ -38,6 +39,7 @@ impl PluginPane {
position_and_size: PaneGeom,
send_plugin_instructions: SenderWithContext<PluginInstruction>,
title: String,
pane_name: String,
) -> Self {
Self {
pid,
Expand All @@ -51,6 +53,7 @@ impl PluginPane {
content_offset: Offset::default(),
pane_title: title,
borderless: false,
pane_name,
}
}
}
Expand Down Expand Up @@ -209,14 +212,29 @@ impl Pane for PluginPane {
None
}
}
fn render_frame(&mut self, _client_id: ClientId, frame_params: FrameParams) -> Option<String> {
fn render_frame(
&mut self,
_client_id: ClientId,
frame_params: FrameParams,
input_mode: InputMode,
) -> Option<String> {
// FIXME: This is a hack that assumes all fixed-size panes are borderless. This
// will eventually need fixing!
if self.frame && !(self.geom.rows.is_fixed() || self.geom.cols.is_fixed()) {
let pane_title = if self.pane_name.is_empty()
&& input_mode == InputMode::RenamePane
&& frame_params.is_main_client
{
String::from("Enter name...")
} else if self.pane_name.is_empty() {
self.pane_title.clone()
} else {
self.pane_name.clone()
};
let frame = PaneFrame::new(
self.current_geom().into(),
(0, 0), // scroll position
self.pane_title.clone(),
pane_title,
frame_params,
);
Some(frame.render())
Expand All @@ -231,6 +249,20 @@ impl Pane for PluginPane {
) -> Option<String> {
None
}
fn update_name(&mut self, name: &str) {
match name {
"\0" => {
self.pane_name = String::new();
}
"\u{007F}" | "\u{0008}" => {
//delete and backspace keys
self.pane_name.pop();
}
c => {
self.pane_name.push_str(c);
}
}
}
fn pid(&self) -> PaneId {
PaneId::Plugin(self.pid)
}
Expand Down
44 changes: 38 additions & 6 deletions zellij-server/src/panes/terminal_pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use zellij_utils::{
pane_size::{Dimension, PaneGeom},
position::Position,
vte,
zellij_tile::data::{Palette, PaletteColor},
zellij_tile::data::{InputMode, Palette, PaletteColor},
};

pub const SELECTION_SCROLL_INTERVAL_MS: u64 = 10;
Expand All @@ -44,6 +44,7 @@ pub struct TerminalPane {
selection_scrolled_at: time::Instant,
content_offset: Offset,
pane_title: String,
pane_name: String,
frame: HashMap<ClientId, PaneFrame>,
borderless: bool,
fake_cursor_locations: HashSet<(usize, usize)>, // (x, y) - these hold a record of previous fake cursors which we need to clear on render
Expand Down Expand Up @@ -278,16 +279,31 @@ impl Pane for TerminalPane {
None
}
}
fn render_frame(&mut self, client_id: ClientId, frame_params: FrameParams) -> Option<String> {
fn render_frame(
&mut self,
client_id: ClientId,
frame_params: FrameParams,
input_mode: InputMode,
) -> Option<String> {
// TODO: remove the cursor stuff from here
let mut vte_output = None;
let frame = PaneFrame::new(
self.current_geom().into(),
self.grid.scrollback_position_and_length(),
let pane_title = if self.pane_name.is_empty()
&& input_mode == InputMode::RenamePane
&& frame_params.is_main_client
{
String::from("Enter name...")
} else if self.pane_name.is_empty() {
self.grid
.title
.clone()
.unwrap_or_else(|| self.pane_title.clone()),
.unwrap_or_else(|| self.pane_title.clone())
} else {
self.pane_name.clone()
};
let frame = PaneFrame::new(
self.current_geom().into(),
self.grid.scrollback_position_and_length(),
pane_title,
frame_params,
);
match self.frame.get(&client_id) {
Expand Down Expand Up @@ -336,6 +352,20 @@ impl Pane for TerminalPane {
}
vte_output
}
fn update_name(&mut self, name: &str) {
match name {
"\0" => {
self.pane_name = String::new();
}
"\u{007F}" | "\u{0008}" => {
//delete and backspace keys
self.pane_name.pop();
}
c => {
self.pane_name.push_str(c);
}
}
}
fn pid(&self) -> PaneId {
PaneId::Terminal(self.pid)
}
Expand Down Expand Up @@ -475,6 +505,7 @@ impl TerminalPane {
position_and_size: PaneGeom,
palette: Palette,
pane_index: usize,
pane_name: String,
) -> TerminalPane {
let initial_pane_title = format!("Pane #{}", pane_index);
let grid = Grid::new(
Expand All @@ -495,6 +526,7 @@ impl TerminalPane {
colors: palette,
selection_scrolled_at: time::Instant::now(),
pane_title: initial_pane_title,
pane_name,
borderless: false,
fake_cursor_locations: HashSet::new(),
}
Expand Down
2 changes: 1 addition & 1 deletion zellij-server/src/panes/unit/terminal_pane_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn scrolling_inside_a_pane() {

let pid = 1;
let palette = Palette::default();
let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0); // 0 is the pane index
let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0, String::new()); // 0 is the pane index
let mut text_to_fill_pane = String::new();
for i in 0..30 {
writeln!(&mut text_to_fill_pane, "\rline {}", i + 1).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion zellij-server/src/pty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub(crate) struct Pty {

use std::convert::TryFrom;

pub(crate) fn pty_thread_main(mut pty: Pty, layout: LayoutFromYaml) {
pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<LayoutFromYaml>) {
loop {
let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel");
err_ctx.add_call(ContextType::Pty((&event).into()));
Expand Down
6 changes: 6 additions & 0 deletions zellij-server/src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ fn route_action(
};
session.senders.send_to_pty(pty_instr).unwrap();
}
Action::PaneNameInput(c) => {
session
.senders
.send_to_screen(ScreenInstruction::UpdatePaneName(c, client_id))
.unwrap();
}
Action::Run(command) => {
let run_cmd = Some(TerminalAction::RunCommand(command.clone().into()));
let pty_instr = match command.direction {
Expand Down
10 changes: 10 additions & 0 deletions zellij-server/src/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub enum ScreenInstruction {
TogglePaneFrames,
SetSelectable(PaneId, bool, usize),
ClosePane(PaneId, Option<ClientId>),
UpdatePaneName(Vec<u8>, ClientId),
NewTab(Layout, Vec<RawFd>, ClientId),
SwitchTabNext(ClientId),
SwitchTabPrev(ClientId),
Expand Down Expand Up @@ -140,6 +141,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::TogglePaneFrames => ScreenContext::TogglePaneFrames,
ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable,
ScreenInstruction::ClosePane(..) => ScreenContext::ClosePane,
ScreenInstruction::UpdatePaneName(..) => ScreenContext::UpdatePaneName,
ScreenInstruction::NewTab(..) => ScreenContext::NewTab,
ScreenInstruction::SwitchTabNext(..) => ScreenContext::SwitchTabNext,
ScreenInstruction::SwitchTabPrev(..) => ScreenContext::SwitchTabPrev,
Expand Down Expand Up @@ -975,6 +977,14 @@ pub(crate) fn screen_thread_main(
}
screen.update_tabs();
}
ScreenInstruction::UpdatePaneName(c, client_id) => {
screen
.get_active_tab_mut(client_id)
.unwrap()
.update_active_pane_name(c, client_id);

screen.render();
}
ScreenInstruction::ToggleActiveTerminalFullscreen(client_id) => {
screen
.get_active_tab_mut(client_id)
Expand Down
36 changes: 32 additions & 4 deletions zellij-server/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ use std::time::Instant;
use std::{
cmp::Reverse,
collections::{BTreeMap, HashMap, HashSet},
str,
};
use zellij_tile::data::{Event, ModeInfo, Palette, PaletteColor};
use zellij_tile::data::{Event, InputMode, ModeInfo, Palette, PaletteColor};
use zellij_utils::{
input::{
layout::{Direction, Layout, Run},
Expand Down Expand Up @@ -181,12 +182,18 @@ pub trait Pane {
fn selectable(&self) -> bool;
fn set_selectable(&mut self, selectable: bool);
fn render(&mut self, client_id: Option<ClientId>) -> Option<String>;
fn render_frame(&mut self, client_id: ClientId, frame_params: FrameParams) -> Option<String>;
fn render_frame(
&mut self,
client_id: ClientId,
frame_params: FrameParams,
input_mode: InputMode,
) -> Option<String>;
fn render_fake_cursor(
&mut self,
cursor_color: PaletteColor,
text_color: PaletteColor,
) -> Option<String>;
fn update_name(&mut self, name: &str);
fn pid(&self) -> PaneId;
fn reduce_height(&mut self, percent: f64);
fn increase_height(&mut self, percent: f64);
Expand Down Expand Up @@ -400,6 +407,7 @@ impl Tab {
*position_and_size,
self.senders.to_plugin.as_ref().unwrap().clone(),
pane_title,
layout.pane_name.clone().unwrap_or_default(),
);
new_plugin.set_borderless(layout.borderless);
self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin));
Expand All @@ -412,6 +420,7 @@ impl Tab {
*position_and_size,
self.colors,
next_terminal_position,
layout.pane_name.clone().unwrap_or_default(),
);
new_pane.set_borderless(layout.borderless);
self.panes
Expand Down Expand Up @@ -588,6 +597,7 @@ impl Tab {
bottom_winsize,
self.colors,
next_terminal_position,
String::new(),
);
terminal_to_split.set_geom(top_winsize);
self.panes.insert(pid, Box::new(new_terminal));
Expand All @@ -604,6 +614,7 @@ impl Tab {
right_winsize,
self.colors,
next_terminal_position,
String::new(),
);
terminal_to_split.set_geom(left_winsize);
self.panes.insert(pid, Box::new(new_terminal));
Expand Down Expand Up @@ -647,6 +658,7 @@ impl Tab {
bottom_winsize,
self.colors,
next_terminal_position,
String::new(),
);
active_pane.set_geom(top_winsize);
self.panes.insert(pid, Box::new(new_terminal));
Expand Down Expand Up @@ -684,8 +696,13 @@ impl Tab {
}
let terminal_ws = active_pane.position_and_size();
if let Some((left_winsize, right_winsize)) = split(Direction::Vertical, &terminal_ws) {
let new_terminal =
TerminalPane::new(term_pid, right_winsize, self.colors, next_terminal_position);
let new_terminal = TerminalPane::new(
term_pid,
right_winsize,
self.colors,
next_terminal_position,
String::new(),
);
active_pane.set_geom(left_winsize);
self.panes.insert(pid, Box::new(new_terminal));
}
Expand Down Expand Up @@ -3451,6 +3468,17 @@ impl Tab {
.unwrap();
}
}

pub fn update_active_pane_name(&mut self, buf: Vec<u8>, client_id: ClientId) {
if let Some(active_terminal_id) = self.get_active_terminal_id(client_id) {
let s = str::from_utf8(&buf).unwrap();
let active_terminal = self
.panes
.get_mut(&PaneId::Terminal(active_terminal_id))
.unwrap();
active_terminal.update_name(s);
}
}
}

#[allow(clippy::borrowed_box)]
Expand Down
2 changes: 1 addition & 1 deletion zellij-server/src/ui/pane_contents_and_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<'a> PaneContentsAndUi<'a> {
other_cursors_exist_in_session: self.multiple_users_exist_in_session,
}
};
if let Some(vte_output) = self.pane.render_frame(client_id, frame_params) {
if let Some(vte_output) = self.pane.render_frame(client_id, frame_params, client_mode) {
// FIXME: Use Termion for cursor and style clearing?
self.output.push_to_client(
client_id,
Expand Down
Loading