Skip to main content

line_editor/
history.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use bstr::BString;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub(crate) enum HistoryDir {
9    Prev,
10    Next,
11}
12
13/// Manages input history for the line editor.
14#[derive(Debug, Clone)]
15pub struct History {
16    entries: Vec<BString>,
17    max_len: usize,
18}
19
20impl History {
21    /// Creates a new history buffer with the specified maximum length.
22    pub fn new(max_len: usize) -> Self {
23        Self { entries: Vec::new(), max_len }
24    }
25
26    /// Adds a new line to history, returning `true` if added (deduplicating adjacent
27    /// identical entries).
28    pub fn add(&mut self, line: impl Into<BString>) -> bool {
29        if self.max_len == 0 {
30            return false;
31        }
32        let line_bstring = line.into();
33        if let Some(last) = self.entries.last() {
34            if last == &line_bstring {
35                return false;
36            }
37        }
38        if self.entries.len() >= self.max_len {
39            self.entries.remove(0);
40        }
41        self.entries.push(line_bstring);
42        true
43    }
44
45    /// Returns a slice of all stored history entries.
46    pub fn entries(&self) -> &[BString] {
47        &self.entries
48    }
49
50    /// Returns the number of stored history entries.
51    pub fn len(&self) -> usize {
52        self.entries.len()
53    }
54
55    /// Returns `true` if the history buffer is empty.
56    pub fn is_empty(&self) -> bool {
57        self.entries.is_empty()
58    }
59
60    /// Clears all entries from the history buffer.
61    pub fn clear(&mut self) {
62        self.entries.clear();
63    }
64
65    /// Sets the maximum number of history entries allowed, evicting oldest entries if needed.
66    pub fn set_max_len(&mut self, max_len: usize) {
67        self.max_len = max_len;
68        while self.entries.len() > self.max_len {
69            self.entries.remove(0);
70        }
71    }
72
73    /// Returns the maximum number of history entries allowed.
74    pub fn max_len(&self) -> usize {
75        self.max_len
76    }
77
78    /// Returns an entry at the given index, if present.
79    pub fn get(&self, index: usize) -> Option<&BString> {
80        self.entries.get(index)
81    }
82}