Files
kte/TerminalRenderer.h
T
Claude 93901928da Force a UTF-8 ctype, stable buffer ids, redraw after deferred opens
- main: when the environment's locale is not UTF-8 (LANG unset, C/POSIX),
  switch LC_CTYPE to a UTF-8 locale so ncurses delivers and draws
  multibyte characters instead of dropping them.
- Buffer::Id(): a process-unique id that survives moves and is fresh for
  copies. The terminal renderer's skip and cursor caches and the reload
  confirmation now key on it rather than the buffer's address, which is
  reused after a buffer is closed.
- The reload confirmation is cancelled by any other command, like the
  quit confirmation.
- TerminalFrontend redraws when a deferred open starts a prompt or sets a
  status (e.g. the swap recovery question), not only when a buffer opens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
2026-09-24 09:16:04 -07:00

45 lines
1.2 KiB
C++

/*
* TerminalRenderer - ncurses-based renderer for terminal mode
*/
#pragma once
#include <vector>
#include <cstdint>
#include <cstddef>
#include "Renderer.h"
class TerminalRenderer final : public Renderer {
public:
TerminalRenderer();
~TerminalRenderer() override;
void Draw(Editor &ed) override;
private:
// Where a row's visible part starts (the draw loop's skip up to the
// horizontal scroll offset), cached per screen row. Scanning a very long
// line from column 0 on every frame made each redraw O(line length).
struct SkipCache {
std::uint64_t buf_id = 0; // Buffer::Id(); addresses get reused
std::uint64_t version = 0;
std::size_t row = 0;
std::size_t coloffs = 0;
std::size_t src = 0; // byte offset where drawing resumes
std::size_t col = 0; // render column at that offset
bool valid = false;
};
std::vector<SkipCache> skip_cache_;
// Render column of the cursor, cached the same way.
struct CursorCache {
std::uint64_t buf_id = 0; // Buffer::Id(); addresses get reused
std::uint64_t version = 0;
std::size_t row = 0;
std::size_t cx = 0;
std::size_t rx = 0;
bool valid = false;
} cursor_cache_;
};