Repository: zellij-org/zellij
File: zellij-server/src/screen.rs (Rust)

Code before:
                if let Some(client_active_tab) = self.tabs.get_mut(&client_previous_tab) {
                    self.active_tab_indices
                        .insert(client_id, client_previous_tab);
                    client_active_tab.add_client(client_id, Some(client_mode_info));
                    continue;
                }
            }
            self.active_tab_indices.insert(client_id, first_tab_index);
            self.tabs
                .get_mut(&first_tab_index)
                .unwrap()
                .add_client(client_id, Some(client_mode_info));
        }
    }
    fn move_clients_between_tabs(
        &mut self,
        source_tab_index: usize,
        destination_tab_index: usize,
        clients_to_move: Option<Vec<ClientId>>,
    ) -> Result<()> {
        // None ==> move all clients
        let drained_clients = self
            .get_indexed_tab_mut(source_tab_index)
            .map(|t| t.drain_connected_clients(clients_to_move));
        if let Some(client_mode_info_in_source_tab) = drained_clients {
            let destination_tab = self.get_indexed_tab_mut(destination_tab_index).context("failed to get destination tab by index: {destination_tab_index}")?;
            destination_tab.add_multiple_clients(client_mode_info_in_source_tab);
            destination_tab.update_input_modes();
            destination_tab.set_force_render();
            destination_tab.visible(true);
        }
        Ok(())
    }
    fn update_client_tab_focus(&mut self, client_id: ClientId, new_tab_index: usize) {
        match self.active_tab_indices.remove(&client_id) {
            Some(old_active_index) => {
                self.active_tab_indices.insert(client_id, new_tab_index);
                let client_tab_history = self.tab_history.entry(client_id).or_insert_with(Vec::new);
                client_tab_history.retain(|&e| e != new_tab_index);
                client_tab_history.push(old_active_index);
            },
            None => {
                self.active_tab_indices.insert(client_id, new_tab_index);
            },
        }
    }

    /// A helper function to switch to a new tab at specified position.
    fn switch_active_tab(&mut self, new_tab_pos: usize, client_id: ClientId) -> Result<()> {
        let err_context = || {
            format!(

Review comment (bug):
Unfortunately this doesn't work, because [`context` takes a static argument][1] and doesn't perform string interpolation. You have to `with_context(format!(...))` here, too. I admit I only learned this recently, too, so forgive me if I got it wrong somewhere in the code here (And feel free to fix it, if you want to).

Also I think we should add another error context after this one, maybe something like: `failed to move clients from tab {} to tab {}`. That way we know what it was trying to do when it "failed to get destination tab...". What do you think?

[1]: https://docs.rs/anyhow/latest/anyhow/trait.Context.html#tymethod.context

Code after:
                if let Some(client_active_tab) = self.tabs.get_mut(&client_previous_tab) {
                    self.active_tab_indices
                        .insert(client_id, client_previous_tab);
                    client_active_tab.add_client(client_id, Some(client_mode_info));
                    continue;
                }
            }
            self.active_tab_indices.insert(client_id, first_tab_index);
            self.tabs
                .get_mut(&first_tab_index)
                .unwrap()
                .add_client(client_id, Some(client_mode_info));
        }
    }
    fn move_clients_between_tabs(
        &mut self,
        source_tab_index: usize,
        destination_tab_index: usize,
        clients_to_move: Option<Vec<ClientId>>,
    ) -> Result<()> {
        let err_context = || {
            format!(
                "failed to move clients from tab {source_tab_index} to tab {destination_tab_index}"
            )
        };

        // None ==> move all clients
        let drained_clients = self
            .get_indexed_tab_mut(source_tab_index)
            .map(|t| t.drain_connected_clients(clients_to_move));
        if let Some(client_mode_info_in_source_tab) = drained_clients {
            let destination_tab = self
                .get_indexed_tab_mut(destination_tab_index)
                .context("failed to get destination tab by index")
                .with_context(err_context)?;
            destination_tab.add_multiple_clients(client_mode_info_in_source_tab);
            destination_tab.update_input_modes();
            destination_tab.set_force_render();
            destination_tab.visible(true);
        }
        Ok(())
    }
    fn update_client_tab_focus(&mut self, client_id: ClientId, new_tab_index: usize) {
        match self.active_tab_indices.remove(&client_id) {
            Some(old_active_index) => {
                self.active_tab_indices.insert(client_id, new_tab_index);
                let client_tab_history = self.tab_history.entry(client_id).or_insert_with(Vec::new);
                client_tab_history.retain(|&e| e != new_tab_index);
                client_tab_history.push(old_active_index);
            },
            None => {