Place hardware terminal cursor at the current main cursor/prompt cursor position
Fixes #1318 Also fixes https://gitlab.com/gnachman/iterm2/issues/5408
This commit is contained in:
parent
80dd9ec4cb
commit
91bfd714e4
|
@ -246,6 +246,9 @@ void Client::redraw_ifn()
|
|||
if (m_ui_pending & StatusLine)
|
||||
m_ui->draw_status(m_status_line, m_mode_line, get_face("StatusLine"));
|
||||
|
||||
auto cursor = m_input_handler.get_cursor_info();
|
||||
m_ui->set_cursor(cursor.first, cursor.second);
|
||||
|
||||
m_ui->refresh(m_ui_pending | Refresh);
|
||||
m_ui_pending = 0;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,12 @@ public:
|
|||
|
||||
virtual KeymapMode keymap_mode() const = 0;
|
||||
|
||||
virtual std::pair<CursorMode, DisplayCoord> get_cursor_info() const
|
||||
{
|
||||
DisplayCoord coord = context().window().display_position(context().selections().main().cursor());
|
||||
return {CursorMode::Buffer, coord};
|
||||
}
|
||||
|
||||
using Insertion = InputHandler::Insertion;
|
||||
Insertion& last_insert() { return m_input_handler.m_last_insert; }
|
||||
|
||||
|
@ -467,6 +473,11 @@ public:
|
|||
const String& line() const { return m_line; }
|
||||
CharCount cursor_pos() const { return m_cursor_pos; }
|
||||
|
||||
ColumnCount cursor_display_column() const
|
||||
{
|
||||
return m_line.substr(m_display_pos, m_cursor_pos).column_length();
|
||||
}
|
||||
|
||||
DisplayLine build_display_line(ColumnCount in_width)
|
||||
{
|
||||
auto cleanup = [](StringView str) {
|
||||
|
@ -873,6 +884,12 @@ public:
|
|||
|
||||
KeymapMode keymap_mode() const override { return KeymapMode::Prompt; }
|
||||
|
||||
std::pair<CursorMode, DisplayCoord> get_cursor_info() const override
|
||||
{
|
||||
DisplayCoord coord{0_line, m_prompt.column_length() + m_line_editor.cursor_display_column()};
|
||||
return { CursorMode::Prompt, coord };
|
||||
}
|
||||
|
||||
private:
|
||||
void refresh_completions(CompletionFlags flags)
|
||||
{
|
||||
|
@ -1521,6 +1538,11 @@ DisplayLine InputHandler::mode_line() const
|
|||
return current_mode().mode_line();
|
||||
}
|
||||
|
||||
std::pair<CursorMode, DisplayCoord> InputHandler::get_cursor_info() const
|
||||
{
|
||||
return current_mode().get_cursor_info();
|
||||
}
|
||||
|
||||
bool show_auto_info_ifn(StringView title, StringView info, AutoInfo mask, const Context& context)
|
||||
{
|
||||
if (not (context.options()["autoinfo"].get<AutoInfo>() & mask) or
|
||||
|
|
|
@ -43,6 +43,7 @@ using KeyCallback = std::function<void (Key, Context&)>;
|
|||
class InputMode;
|
||||
enum class InsertMode : unsigned;
|
||||
enum class KeymapMode : char;
|
||||
enum class CursorMode;
|
||||
|
||||
class InputHandler : public SafeCountable
|
||||
{
|
||||
|
@ -91,6 +92,8 @@ public:
|
|||
|
||||
DisplayLine mode_line() const;
|
||||
|
||||
std::pair<CursorMode, DisplayCoord> get_cursor_info() const;
|
||||
|
||||
// Force an input handler into normal mode temporarily
|
||||
struct ScopedForceNormal
|
||||
{
|
||||
|
|
|
@ -135,6 +135,16 @@ String to_json(InfoStyle style)
|
|||
return "";
|
||||
}
|
||||
|
||||
String to_json(CursorMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case CursorMode::Prompt: return R"("prompt")";
|
||||
case CursorMode::Buffer: return R"("buffer")";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
String concat()
|
||||
{
|
||||
return "";
|
||||
|
@ -209,6 +219,11 @@ void JsonUI::info_hide()
|
|||
rpc_call("info_hide");
|
||||
}
|
||||
|
||||
void JsonUI::set_cursor(CursorMode mode, DisplayCoord coord)
|
||||
{
|
||||
rpc_call("set_cursor", mode, coord);
|
||||
}
|
||||
|
||||
void JsonUI::refresh(bool force)
|
||||
{
|
||||
rpc_call("refresh", force);
|
||||
|
|
|
@ -38,6 +38,8 @@ public:
|
|||
InfoStyle style) override;
|
||||
void info_hide() override;
|
||||
|
||||
void set_cursor(CursorMode mode, DisplayCoord coord) override;
|
||||
|
||||
void refresh(bool force) override;
|
||||
|
||||
DisplayCoord dimensions() override;
|
||||
|
|
|
@ -356,6 +356,7 @@ std::unique_ptr<UserInterface> make_ui(UIType ui_type)
|
|||
void draw(const DisplayBuffer&, const Face&, const Face&) override {}
|
||||
void draw_status(const DisplayLine&, const DisplayLine&, const Face&) override {}
|
||||
DisplayCoord dimensions() override { return {24,80}; }
|
||||
void set_cursor(CursorMode, DisplayCoord) override {}
|
||||
void refresh(bool) override {}
|
||||
void set_on_key(OnKeyCallback) override {}
|
||||
void set_ui_options(const Options&) override {}
|
||||
|
|
|
@ -312,11 +312,25 @@ void NCursesUI::redraw()
|
|||
{
|
||||
pnoutrefresh(m_window, 0, 0, 0, 0,
|
||||
(int)m_dimensions.line + 1, (int)m_dimensions.column);
|
||||
|
||||
m_menu.refresh();
|
||||
m_info.refresh();
|
||||
|
||||
if (m_cursor.mode == CursorMode::Prompt)
|
||||
wmove(newscr, m_status_on_top ? 0 : (int)m_dimensions.line + 1,
|
||||
(int)m_cursor.coord.column);
|
||||
else
|
||||
wmove(newscr, (int)m_cursor.coord.line + (m_status_on_top ? 1 : 0),
|
||||
(int)m_cursor.coord.column);
|
||||
|
||||
doupdate();
|
||||
}
|
||||
|
||||
void NCursesUI::set_cursor(CursorMode mode, DisplayCoord coord)
|
||||
{
|
||||
m_cursor = Cursor{ mode, coord };
|
||||
}
|
||||
|
||||
void NCursesUI::refresh(bool force)
|
||||
{
|
||||
if (force)
|
||||
|
|
|
@ -43,8 +43,9 @@ public:
|
|||
InfoStyle style) override;
|
||||
void info_hide() override;
|
||||
|
||||
void refresh(bool force) override;
|
||||
void set_cursor(CursorMode mode, DisplayCoord coord) override;
|
||||
|
||||
void refresh(bool force) override;
|
||||
|
||||
DisplayCoord dimensions() override;
|
||||
void set_on_key(OnKeyCallback callback) override;
|
||||
|
@ -121,6 +122,12 @@ private:
|
|||
InfoStyle style;
|
||||
} m_info;
|
||||
|
||||
struct Cursor
|
||||
{
|
||||
CursorMode mode;
|
||||
DisplayCoord coord;
|
||||
} m_cursor;
|
||||
|
||||
FDWatcher m_stdin_watcher;
|
||||
OnKeyCallback m_on_key;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ enum class MessageType : char
|
|||
InfoHide,
|
||||
Draw,
|
||||
DrawStatus,
|
||||
SetCursor,
|
||||
Refresh,
|
||||
SetOptions,
|
||||
Key
|
||||
|
@ -335,6 +336,8 @@ public:
|
|||
const DisplayLine& mode_line,
|
||||
const Face& default_face) override;
|
||||
|
||||
void set_cursor(CursorMode mode, DisplayCoord coord) override;
|
||||
|
||||
void refresh(bool force) override;
|
||||
|
||||
DisplayCoord dimensions() override { return m_dimensions; }
|
||||
|
@ -483,6 +486,14 @@ void RemoteUI::draw_status(const DisplayLine& status_line,
|
|||
m_socket_watcher.events() |= FdEvents::Write;
|
||||
}
|
||||
|
||||
void RemoteUI::set_cursor(CursorMode mode, DisplayCoord coord)
|
||||
{
|
||||
MsgWriter msg{m_send_buffer, MessageType::SetCursor};
|
||||
msg.write(mode);
|
||||
msg.write(coord);
|
||||
m_socket_watcher.events() |= FdEvents::Write;
|
||||
}
|
||||
|
||||
void RemoteUI::refresh(bool force)
|
||||
{
|
||||
MsgWriter msg{m_send_buffer, MessageType::Refresh};
|
||||
|
@ -611,6 +622,13 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
|
|||
m_ui->draw_status(status_line, mode_line, default_face);
|
||||
break;
|
||||
}
|
||||
case MessageType::SetCursor:
|
||||
{
|
||||
auto mode = reader.read<CursorMode>();
|
||||
auto coord = reader.read<DisplayCoord>();
|
||||
m_ui->set_cursor(mode, coord);
|
||||
break;
|
||||
}
|
||||
case MessageType::Refresh:
|
||||
m_ui->refresh(reader.read<bool>());
|
||||
break;
|
||||
|
|
|
@ -34,6 +34,12 @@ enum class InfoStyle
|
|||
|
||||
enum class EventMode;
|
||||
|
||||
enum class CursorMode
|
||||
{
|
||||
Prompt,
|
||||
Buffer,
|
||||
};
|
||||
|
||||
using OnKeyCallback = std::function<void(Key key)>;
|
||||
|
||||
class UserInterface
|
||||
|
@ -62,6 +68,8 @@ public:
|
|||
|
||||
virtual DisplayCoord dimensions() = 0;
|
||||
|
||||
virtual void set_cursor(CursorMode mode, DisplayCoord coord) = 0;
|
||||
|
||||
virtual void refresh(bool force) = 0;
|
||||
|
||||
virtual void set_on_key(OnKeyCallback callback) = 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user