| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include "lumacs/buffer_manager.hpp"
- #include "lumacs/editor_core.hpp" // For EditorCore access
- #include <algorithm>
- #include <iostream> // TODO: Replace with proper logging
- namespace lumacs {
- BufferManager::BufferManager(EditorCore& core) : core_(core) {
- }
- std::shared_ptr<Buffer> BufferManager::create_buffer_no_window(std::string name) {
- // Check if a buffer with this name already exists
- auto existing_buf = get_buffer_by_name(name);
- if (existing_buf) {
- return existing_buf;
- }
- auto new_buf = std::make_shared<Buffer>(std::move(name));
- buffers_.push_back(new_buf);
- return new_buf;
- }
- void BufferManager::new_buffer(std::string name) {
- auto new_buf = create_buffer_no_window(std::move(name));
-
- // Set this new buffer in the active window
- if (core_.active_window()) {
- core_.active_window()->set_buffer(new_buf);
- } else {
- // This case should ideally not happen if EditorCore initializes properly
- // For robustness, create a default window if none exists
- std::cerr << "[ERROR] No active window to set new buffer. This should not happen." << std::endl;
- }
- core_.emit_event(EditorEvent::BufferModified);
- core_.emit_event(EditorEvent::CursorMoved);
- core_.emit_event(EditorEvent::ViewportChanged);
- }
- bool BufferManager::load_file(const std::filesystem::path& path) {
- std::filesystem::path abs_path = std::filesystem::absolute(path);
- // Check if already open
- for (const auto& buf : buffers_) {
- if (buf->file_path() && std::filesystem::equivalent(*buf->file_path(), abs_path)) {
- if (core_.active_window()) {
- core_.active_window()->set_buffer(buf);
- }
- core_.emit_event(EditorEvent::BufferModified);
- core_.emit_event(EditorEvent::CursorMoved);
- core_.emit_event(EditorEvent::ViewportChanged);
- return true;
- }
- }
- auto new_buffer_opt = Buffer::from_file(abs_path);
- if (!new_buffer_opt) {
- return false;
- }
-
- auto new_buffer = std::make_shared<Buffer>(std::move(*new_buffer_opt));
- buffers_.push_back(new_buffer);
- if (core_.active_window()) {
- core_.active_window()->set_buffer(new_buffer);
- }
- core_.emit_event(EditorEvent::BufferModified);
- core_.emit_event(EditorEvent::CursorMoved);
- core_.emit_event(EditorEvent::ViewportChanged);
- return true;
- }
- bool BufferManager::switch_buffer_in_window(const std::string& name) {
- auto buf = get_buffer_by_name(name);
- if (!buf) {
- return false;
- }
- if (core_.active_window()) {
- core_.active_window()->set_buffer(buf);
- }
- core_.emit_event(EditorEvent::BufferModified);
- core_.emit_event(EditorEvent::CursorMoved);
- core_.emit_event(EditorEvent::ViewportChanged);
- return true;
- }
- bool BufferManager::close_buffer(const std::string& name) {
- auto buf_to_close = get_buffer_by_name(name);
- if (!buf_to_close) {
- return false;
- }
- // Cannot close buffer if it's the only one
- if (buffers_.size() <= 1) {
- core_.set_message("Cannot close last buffer");
- return false;
- }
- // Check if buffer is displayed in any window and switch it
- std::vector<std::shared_ptr<Window>> windows;
- // Need a way for BufferManager to access all windows.
- // EditorCore should provide this functionality.
- core_.collect_windows(core_.root_layout().get(), windows); // Assuming EditorCore has this helper
- for (const auto& win : windows) {
- if (win->buffer_ptr() == buf_to_close) {
- // Find another buffer to switch to
- auto other_buf_it = std::find_if(buffers_.begin(), buffers_.end(),
- [&](const std::shared_ptr<Buffer>& b) { return b != buf_to_close; });
- if (other_buf_it != buffers_.end()) {
- win->set_buffer(*other_buf_it);
- } else {
- // This scenario should be prevented by the buffers_.size() <= 1 check
- std::cerr << "[ERROR] No other buffer found to switch to after closing." << std::endl;
- return false;
- }
- }
- }
- // Remove buffer from list
- buffers_.remove(buf_to_close);
- core_.emit_event(EditorEvent::BufferModified);
- core_.emit_event(EditorEvent::CursorMoved);
- core_.emit_event(EditorEvent::ViewportChanged);
- return true;
- }
- std::shared_ptr<Buffer> BufferManager::active_buffer() {
- if (core_.active_window()) {
- return core_.active_window()->buffer_ptr();
- }
- return nullptr; // Should not happen in a well-initialized editor
- }
- std::shared_ptr<Buffer> BufferManager::get_buffer_by_name(const std::string& name) const {
- for (const auto& buf : buffers_) {
- if (buf->name() == name) {
- return buf;
- }
- }
- return nullptr;
- }
- std::vector<std::string> BufferManager::get_buffer_names() const {
- std::vector<std::string> names;
- names.reserve(buffers_.size());
- for (const auto& buf : buffers_) {
- names.push_back(buf->name());
- }
- return names;
- }
- std::vector<BufferManager::BufferInfo> BufferManager::get_all_buffer_info() const {
- std::vector<BufferInfo> info;
- info.reserve(buffers_.size());
- for (const auto& buf : buffers_) {
- BufferInfo bi;
- bi.name = buf->name();
- bi.size = buf->line_count();
- bi.modified = buf->is_modified();
- bi.mode = "fundamental-mode"; // TODO: Get actual mode from buffer
- bi.filepath = buf->file_path();
- info.push_back(bi);
- }
- return info;
- }
- } // namespace lumacs
|