#include "lumacs/buffer_manager.hpp" #include "lumacs/editor_core.hpp" // For EditorCore access #include #include // TODO: Replace with proper logging namespace lumacs { BufferManager::BufferManager(EditorCore& core) : core_(core) { } std::shared_ptr 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(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(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> 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& 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 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 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 BufferManager::get_buffer_names() const { std::vector names; names.reserve(buffers_.size()); for (const auto& buf : buffers_) { names.push_back(buf->name()); } return names; } std::vector BufferManager::get_all_buffer_info() const { std::vector 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