Support empty file-backed buffers.

This commit is contained in:
2025-11-29 18:03:29 -08:00
parent 69e7959fa4
commit 548d760df5
6 changed files with 72 additions and 59 deletions

23
.idea/workspace.xml generated
View File

@@ -32,29 +32,10 @@
</component>
<component name="ChangeListManager">
<list default="true" id="e1fe3ab0-3650-4fca-8664-a247d5dfa457" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/Command.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Command.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Frontend.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/GUIFrontend.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/GUIFrontend.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/GUIInputHandler.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/GUIInputHandler.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/GUIRenderer.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/GUIRenderer.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/InputHandler.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/ROADMAP.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Renderer.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/TerminalFrontend.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/TerminalFrontend.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/TerminalInputHandler.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/TerminalInputHandler.h" afterDir="false" />
<change afterPath="$PROJECT_DIR$/TerminalRenderer.cpp" afterDir="false" />
<change afterPath="$PROJECT_DIR$/TerminalRenderer.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.junie/guidelines.md" beforeDir="false" afterPath="$PROJECT_DIR$/.junie/guidelines.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/CMakeLists.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/GUIRenderer.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/GUIRenderer.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/cmake/packaging.cmake" beforeDir="false" afterPath="$PROJECT_DIR$/cmake/packaging.cmake" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/main.cpp" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@@ -142,7 +123,7 @@
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1764457173148</updated>
<workItem from="1764457174208" duration="9070000" />
<workItem from="1764457174208" duration="9674000" />
</task>
<servers />
</component>

View File

@@ -2,6 +2,7 @@
#include <fstream>
#include <sstream>
#include <filesystem>
Buffer::Buffer() = default;
@@ -17,11 +18,29 @@ Buffer::Buffer(const std::string &path)
bool
Buffer::OpenFromFile(const std::string &path, std::string &err)
{
std::ifstream in(path, std::ios::in | std::ios::binary);
if (!in) {
err = "Failed to open file: " + path;
return false;
}
// If the file doesn't exist, initialize an empty, non-file-backed buffer
// with the provided filename. Do not touch the filesystem until Save/SaveAs.
if (!std::filesystem::exists(path)) {
rows_.clear();
nrows_ = 0;
filename_ = path;
is_file_backed_ = false;
dirty_ = false;
// Reset cursor/viewport state
curx_ = cury_ = rx_ = 0;
rowoffs_ = coloffs_ = 0;
mark_set_ = false;
mark_curx_ = mark_cury_ = 0;
return true;
}
std::ifstream in(path, std::ios::in | std::ios::binary);
if (!in) {
err = "Failed to open file: " + path;
return false;
}
rows_.clear();
std::string line;

View File

@@ -44,7 +44,7 @@ endif ()
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
set(SOURCES
set(COMMON_SOURCES
GapBuffer.cpp
PieceTable.cpp
Buffer.cpp
@@ -55,7 +55,7 @@ set(SOURCES
TerminalFrontend.cpp
)
set(HEADERS
set(COMMON_HEADERS
GapBuffer.h
PieceTable.h
Buffer.h
@@ -70,10 +70,11 @@ set(HEADERS
TerminalFrontend.h
)
# kte (terminal-first) executable
add_executable(kte
main.cpp
${SOURCES}
${HEADERS}
${COMMON_SOURCES}
${COMMON_HEADERS}
)
if (KTE_USE_PIECE_TABLE)
@@ -83,6 +84,7 @@ endif ()
target_link_libraries(kte ${CURSES_LIBRARIES})
if (${BUILD_GUI})
# Add GUI support to kte so it can be started with -g
target_sources(kte PRIVATE
GUIRenderer.cpp
GUIRenderer.h
@@ -92,4 +94,18 @@ if (${BUILD_GUI})
GUIFrontend.h)
target_compile_definitions(kte PRIVATE KTE_BUILD_GUI=1)
target_link_libraries(kte imgui)
# kge (GUI-first) executable
add_executable(kge
main.cpp
${COMMON_SOURCES}
${COMMON_HEADERS}
GUIRenderer.cpp
GUIRenderer.h
GUIInputHandler.cpp
GUIInputHandler.h
GUIFrontend.cpp
GUIFrontend.h)
target_compile_definitions(kge PRIVATE KTE_BUILD_GUI=1 KTE_DEFAULT_GUI=1)
target_link_libraries(kge ${CURSES_LIBRARIES} imgui)
endif ()

View File

@@ -7,7 +7,25 @@
void GUIRenderer::Draw(const Editor &ed)
{
ImGui::Begin("kte");
// Make the editor window occupy the entire GUI container/viewport
ImGuiViewport* vp = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(vp->Pos);
ImGui::SetNextWindowSize(vp->Size);
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoBringToFrontOnFocus
| ImGuiWindowFlags_NoNavFocus;
// Reduce padding so the buffer content uses the whole area
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(6.f, 6.f));
ImGui::Begin("kte", nullptr, flags);
const Buffer *buf = ed.CurrentBuffer();
if (!buf) {
@@ -34,4 +52,5 @@ void GUIRenderer::Draw(const Editor &ed)
}
ImGui::End();
ImGui::PopStyleVar(3);
}

View File

@@ -180,32 +180,6 @@ Run:
./cmake-build-debug/kte [files]
```
CLI usage
---------
```
kte [OPTIONS] [files]
Options:
-g, --gui Use GUI frontend (if built)
-t, --term Use terminal (ncurses) frontend [default]
-h, --help Show help and exit
-V, --version Show version and exit
```
Examples:
```
# Terminal (default)
kte foo.txt bar.txt
# Explicit terminal
kte -t foo.txt
# GUI (requires building with -DBUILD_GUI=ON and GUI deps installed)
kte --gui foo.txt
```
GUI build example
-----------------

View File

@@ -90,8 +90,12 @@ main(int argc, const char *argv[])
} else if (req_term) {
use_gui = false;
} else {
// Default to terminal
use_gui = false;
// Default depends on build target: kge defaults to GUI, kte to terminal
#if defined(KTE_DEFAULT_GUI)
use_gui = true;
#else
use_gui = false;
#endif
}
#endif