summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/highlighters.cc10
-rw-r--r--src/main.cc1
-rw-r--r--src/terminal_ui.cc39
-rw-r--r--src/terminal_ui.hh5
4 files changed, 51 insertions, 4 deletions
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 25f93245..6ae0a57b 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -16,6 +16,7 @@
#include "regex.hh"
#include "register_manager.hh"
#include "string.hh"
+#include "terminal_ui.hh"
#include "utf8.hh"
#include "utf8_iterator.hh"
#include "window.hh"
@@ -1290,11 +1291,20 @@ void highlight_selections(HighlightContext context, DisplayBuffer& display_buffe
highlight_range(display_buffer, begin, end, false,
apply_face(sel_faces[primary ? 0 : 1]));
}
+ // Check if we should skip drawing the primary cursor (for terminal cursor native mode)
+ const bool skip_primary_cursor = TerminalUI::has_instance() &&
+ TerminalUI::instance().is_cursor_native();
+
for (size_t i = 0; i < selections.size(); ++i)
{
auto& sel = selections[i];
const BufferCoord coord = sel.cursor();
const bool primary = (i == selections.main_index());
+
+ // Skip drawing primary cursor if terminal_cursor_native is enabled
+ if (primary && skip_primary_cursor)
+ continue;
+
const bool eol = buffer[coord.line].length() - 1 == coord.column;
highlight_range(display_buffer, coord, buffer.char_next(coord), false,
apply_face(sel_faces[2 + (eol ? 2 : 0) + (primary ? 0 : 1)]));
diff --git a/src/main.cc b/src/main.cc
index bf382dd2..09101341 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -604,6 +604,7 @@ void register_options()
" terminal_shift_function_key int\n"
" terminal_padding_char codepoint\n"
" terminal_padding_fill bool\n"
+ " terminal_cursor_native bool\n"
" terminal_info_max_width int\n",
UserInterface::Options{});
reg.declare_option("modelinefmt", "format string used to generate the modeline",
diff --git a/src/terminal_ui.cc b/src/terminal_ui.cc
index 672626e4..de332677 100644
--- a/src/terminal_ui.cc
+++ b/src/terminal_ui.cc
@@ -538,10 +538,30 @@ void TerminalUI::redraw(bool force)
auto set_cursor_pos = [&](DisplayCoord c) {
format_with(writer, "\033[{};{}H", (int)c.line + 1, (int)c.column + 1);
};
+
+ DisplayCoord target_pos;
if (m_cursor.mode == CursorMode::Prompt)
- set_cursor_pos({m_status_on_top ? 0 : m_dimensions.line, m_cursor.coord.column});
+ target_pos = {m_status_on_top ? 0 : m_dimensions.line, m_cursor.coord.column};
else
- set_cursor_pos(m_cursor.coord + content_line_offset());
+ target_pos = m_cursor.coord + content_line_offset();
+
+ if (m_terminal_cursor_native)
+ {
+ // Always position cursor in native mode to ensure it's correct after screen updates
+ set_cursor_pos(target_pos);
+
+ // Only send show cursor command when cursor changes or on force refresh
+ if (m_cursor.mode != m_prev_cursor.mode || m_cursor.coord != m_prev_cursor.coord || force)
+ {
+ format_with(writer, "\033[?25h"); // ensure cursor is visible
+ m_prev_cursor = m_cursor;
+ }
+ }
+ else
+ {
+ // Always position cursor (original behavior)
+ set_cursor_pos(target_pos);
+ }
}
void TerminalUI::set_cursor(CursorMode mode, DisplayCoord coord)
@@ -1484,13 +1504,17 @@ void TerminalUI::set_resize_pending()
void TerminalUI::setup_terminal()
{
+ const char* cursor_cmd = instance().m_terminal_cursor_native ? "\033[?25h" : "\033[?25l";
+
write(STDOUT_FILENO,
"\033[?1049h" // enable alternative screen buffer
"\033[?1004h" // enable focus notify
"\033[>4;1m" // request CSI u style key reporting
"\033[>5u" // kitty progressive enhancement - report shifted key codes
"\033[22t" // save the current window title
- "\033[?25l" // hide cursor
+ );
+ write(STDOUT_FILENO, cursor_cmd); // show or hide cursor based on mode
+ write(STDOUT_FILENO,
"\033=" // set application keypad mode, so the keypad keys send unique codes
"\033[?2004h" // force enable bracketed-paste events
);
@@ -1500,7 +1524,13 @@ void TerminalUI::restore_terminal()
{
write(STDOUT_FILENO,
"\033>"
- "\033[?25h"
+ );
+
+ // Only restore cursor visibility if it was hidden (non-native mode)
+ if (not instance().m_terminal_cursor_native)
+ write(STDOUT_FILENO, "\033[?25h");
+
+ write(STDOUT_FILENO,
"\033[23t"
"\033[<u"
"\033[>4;0m"
@@ -1574,6 +1604,7 @@ void TerminalUI::set_ui_options(const Options& options)
m_padding_char = find("terminal_padding_char").map([](StringView s) { return s.column_length() < 1 ? ' ' : s[0_char]; }).value_or(Codepoint{'~'});
m_padding_fill = find("terminal_padding_fill").map(to_bool).value_or(false);
+ m_terminal_cursor_native = find("terminal_cursor_native").map(to_bool).value_or(false);
m_info_max_width = find("terminal_info_max_width").map(str_to_int_ifp).value_or(0);
}
diff --git a/src/terminal_ui.hh b/src/terminal_ui.hh
index 02085532..6ad78bf9 100644
--- a/src/terminal_ui.hh
+++ b/src/terminal_ui.hh
@@ -61,6 +61,8 @@ public:
static void restore_terminal();
void suspend();
+
+ bool is_cursor_native() const { return m_terminal_cursor_native; }
struct Rect
{
@@ -134,6 +136,8 @@ private:
CursorMode mode;
DisplayCoord coord;
} m_cursor;
+
+ struct Cursor m_prev_cursor;
FDWatcher m_stdin_watcher;
OnKeyCallback m_on_key;
@@ -167,6 +171,7 @@ private:
Codepoint m_padding_char = '~';
bool m_padding_fill = false;
+ bool m_terminal_cursor_native = false;
bool m_dirty = false;