1+ #pragma once
2+
3+ #include < filesystem>
4+ #include < optional>
5+ #include < deque>
6+
7+ namespace NuiFileExplorer
8+ {
9+ class PathHistory
10+ {
11+ public:
12+ PathHistory () = default ;
13+
14+ // / Record a new navigation. Call this whenever the user explicitly
15+ // / navigates somewhere (path bar Enter, suggestion click, directory
16+ // / double-click, etc.). Do NOT call when moving through history itself.
17+ void push (std::filesystem::path path)
18+ {
19+ // No-op if we're already sitting on this path.
20+ if (!history_.empty () && history_[cursor_] == path)
21+ return ;
22+
23+ // Drop everything after the cursor (forward stack).
24+ if (cursor_ + 1 < history_.size ())
25+ history_.erase (history_.begin () + static_cast <std::ptrdiff_t >(cursor_) + 1 , history_.end ());
26+
27+ history_.push_back (std::move (path));
28+ cursor_ = history_.size () - 1 ;
29+
30+ // Evict the oldest entry if we exceed the cap. cursor_ is always at
31+ // the end after a push, so decrementing it by one corrects for the
32+ // removed front element.
33+ if (history_.size () > maxSize)
34+ {
35+ history_.pop_front ();
36+ --cursor_;
37+ }
38+ }
39+
40+ // / Move one step back. Returns the path to navigate to, or nullopt if
41+ // / already at the beginning of the history.
42+ std::optional<std::filesystem::path> back ()
43+ {
44+ if (!canGoBack ())
45+ return std::nullopt ;
46+ --cursor_;
47+ return history_[cursor_];
48+ }
49+
50+ // / Move one step forward. Returns the path to navigate to, or nullopt if
51+ // / already at the most recent entry.
52+ std::optional<std::filesystem::path> forward ()
53+ {
54+ if (!canGoForward ())
55+ return std::nullopt ;
56+ ++cursor_;
57+ return history_[cursor_];
58+ }
59+
60+ bool canGoBack () const
61+ {
62+ return !history_.empty () && cursor_ > 0 ;
63+ }
64+ bool canGoForward () const
65+ {
66+ return !history_.empty () && cursor_ + 1 < history_.size ();
67+ }
68+
69+ // / The path currently shown (i.e. the entry at the cursor).
70+ std::optional<std::filesystem::path> current () const
71+ {
72+ if (history_.empty ())
73+ return std::nullopt ;
74+ return history_[cursor_];
75+ }
76+
77+ private:
78+ static constexpr std::size_t maxSize = 100 ;
79+
80+ std::deque<std::filesystem::path> history_{};
81+ std::size_t cursor_{0 };
82+ };
83+ }
0 commit comments