killing buffers
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
enter_command_mode = [":", "ctrl+;"]
|
||||
next_buffer = ["ctrl+l"]
|
||||
previous_buffer = ["ctrl+h"]
|
||||
close_buffer = ["ctrl+k"]
|
||||
|
||||
[keybindings.general]
|
||||
move_up = ["k", "Up"]
|
||||
|
||||
@@ -161,6 +161,7 @@ impl EventHandler {
|
||||
return Ok(EventOutcome::Ok(message));
|
||||
}
|
||||
|
||||
|
||||
if !matches!(current_mode, AppMode::Edit | AppMode::Command) {
|
||||
if let Some(action) = config.get_action_for_key_in_mode(
|
||||
&config.keybindings.global, key_code, modifiers
|
||||
@@ -176,6 +177,10 @@ impl EventHandler {
|
||||
return Ok(EventOutcome::Ok("Switched to previous buffer".to_string()));
|
||||
}
|
||||
}
|
||||
"close_buffer" => {
|
||||
let message = buffer_state.close_buffer_with_intro_fallback();
|
||||
return Ok(EventOutcome::Ok(message));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// src/state/app/buffer.rs
|
||||
|
||||
/// Represents the distinct views or "buffers" the user can navigate.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum AppView {
|
||||
Intro,
|
||||
@@ -14,7 +13,6 @@ pub enum AppView {
|
||||
}
|
||||
|
||||
impl AppView {
|
||||
/// Returns the display name for the view.
|
||||
pub fn display_name(&self) -> &str {
|
||||
match self {
|
||||
AppView::Intro => "Intro",
|
||||
@@ -29,7 +27,6 @@ impl AppView {
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds the state related to buffer management (navigation history).
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BufferState {
|
||||
pub history: Vec<AppView>,
|
||||
@@ -39,23 +36,17 @@ pub struct BufferState {
|
||||
impl Default for BufferState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
history: vec![AppView::Intro], // Start with Intro view
|
||||
history: vec![AppView::Intro],
|
||||
active_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BufferState {
|
||||
/// Updates the buffer history and active index.
|
||||
/// If the view already exists, it sets it as active.
|
||||
/// Otherwise, it adds the new view and makes it active.
|
||||
pub fn update_history(&mut self, view: AppView) {
|
||||
let existing_pos = self.history.iter().position(|v| v == &view);
|
||||
|
||||
match existing_pos {
|
||||
Some(pos) => {
|
||||
self.active_index = pos;
|
||||
}
|
||||
Some(pos) => self.active_index = pos,
|
||||
None => {
|
||||
self.history.push(view.clone());
|
||||
self.active_index = self.history.len() - 1;
|
||||
@@ -63,34 +54,51 @@ impl BufferState {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the currently active view.
|
||||
pub fn get_active_view(&self) -> Option<&AppView> {
|
||||
self.history.get(self.active_index)
|
||||
}
|
||||
|
||||
/// Removes the currently active buffer from the history, unless it's the Intro buffer.
|
||||
/// Sets the new active buffer to the one preceding the closed one.
|
||||
/// # Returns
|
||||
/// * `true` if a non-Intro buffer was closed.
|
||||
/// * `false` if the active buffer was Intro or only Intro remained.
|
||||
pub fn close_active_buffer(&mut self) -> bool {
|
||||
let current_index = self.active_index;
|
||||
if self.history.is_empty() {
|
||||
self.history.push(AppView::Intro);
|
||||
self.active_index = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rule 1: Cannot close Intro buffer.
|
||||
let current_index = self.active_index;
|
||||
if matches!(self.history.get(current_index), Some(AppView::Intro)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rule 2: Cannot close if only Intro would remain (or already remains).
|
||||
// This check implicitly covers the case where len <= 1.
|
||||
if self.history.len() <= 1 {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.history.remove(current_index);
|
||||
self.active_index = current_index.saturating_sub(1).min(self.history.len() - 1);
|
||||
|
||||
if self.history.is_empty() {
|
||||
self.history.push(AppView::Intro);
|
||||
self.active_index = 0;
|
||||
} else if self.active_index >= self.history.len() {
|
||||
self.active_index = self.history.len() - 1;
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn close_buffer_with_intro_fallback(&mut self) -> String {
|
||||
let current_view_cloned = self.get_active_view().cloned();
|
||||
if let Some(AppView::Intro) = current_view_cloned {
|
||||
return "Cannot close intro buffer".to_string();
|
||||
}
|
||||
|
||||
let closed_name = current_view_cloned
|
||||
.as_ref()
|
||||
.map(|v| v.display_name().to_string())
|
||||
.unwrap_or_else(|| "Unknown".to_string());
|
||||
|
||||
if self.close_active_buffer() {
|
||||
if self.history.len() == 1 && matches!(self.history.get(0), Some(AppView::Intro)) {
|
||||
format!("Closed '{}' - returned to intro", closed_name)
|
||||
} else {
|
||||
format!("Closed '{}'", closed_name)
|
||||
}
|
||||
} else {
|
||||
format!("Cannot close buffer: {}", closed_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user