summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-04-12 10:39:17 +0100
committerMaxime Coste <mawww@kakoune.org>2017-04-12 10:39:17 +0100
commit91bfd714e4be3484e04eaadc5bbe630861fff652 (patch)
treed8b2eb554c7feaf44545d650351480b468f4886d
parent80dd9ec4cb68669df4688c621486a27dd9b33548 (diff)
Place hardware terminal cursor at the current main cursor/prompt cursor position
Fixes #1318 Also fixes https://gitlab.com/gnachman/iterm2/issues/5408
-rw-r--r--src/client.cc3
-rw-r--r--src/input_handler.cc22
-rw-r--r--src/input_handler.hh3
-rw-r--r--src/json_ui.cc15
-rw-r--r--src/json_ui.hh2
-rw-r--r--src/main.cc1
-rw-r--r--src/ncurses_ui.cc14
-rw-r--r--src/ncurses_ui.hh9
-rw-r--r--src/remote.cc18
-rw-r--r--src/user_interface.hh8
10 files changed, 94 insertions, 1 deletions
diff --git a/src/client.cc b/src/client.cc
index 3ce8436d..d41a1ba9 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -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;
}
diff --git a/src/input_handler.cc b/src/input_handler.cc
index 4edce81c..b378b871 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -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
diff --git a/src/input_handler.hh b/src/input_handler.hh
index 2962ac12..17c655d9 100644
--- a/src/input_handler.hh
+++ b/src/input_handler.hh
@@ -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
{
diff --git a/src/json_ui.cc b/src/json_ui.cc
index 8a436513..e907be24 100644
--- a/src/json_ui.cc
+++ b/src/json_ui.cc
@@ -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);
diff --git a/src/json_ui.hh b/src/json_ui.hh
index 1b35538f..ad887561 100644
--- a/src/json_ui.hh
+++ b/src/json_ui.hh
@@ -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;
diff --git a/src/main.cc b/src/main.cc
index b8f27622..24f1ae4b 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -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 {}
diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc
index 991cb79b..2e2cb5ad 100644
--- a/src/ncurses_ui.cc
+++ b/src/ncurses_ui.cc
@@ -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)
diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh
index 02270a8d..35889193 100644
--- a/src/ncurses_ui.hh
+++ b/src/ncurses_ui.hh
@@ -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;
diff --git a/src/remote.cc b/src/remote.cc
index 721c4759..bb577aa2 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -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;
diff --git a/src/user_interface.hh b/src/user_interface.hh
index b202f188..d8139336 100644
--- a/src/user_interface.hh
+++ b/src/user_interface.hh
@@ -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;