Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/pages/faces.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ the user interface:
*BufferPadding*::
Face applied on the *~* characters that follow the last line of a buffer.

*ScrollBarGutter*::
Face applied on the scroll bar's gutter.

*ScrollBarHandle*::
Face applied on the scroll bar's handle.

=== Built-in highlighter faces

The following faces are used by built-in highlighters if enabled.
Expand Down
3 changes: 3 additions & 0 deletions doc/pages/options.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ are exclusively available to built-in options.
set the maximum allowable width of an info box. set to zero for
no limit.

*terminal_status_bar*:::
if *yes* or *true* a scroll bar will be displayed.

*terminal_cursor_native*:::
if *yes* or *true*, use native terminal cursor visibility control
instead of Kakoune's cursor management (defaults to *false*)
Expand Down
15 changes: 14 additions & 1 deletion src/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,20 @@ void Client::redraw_ifn()
{
auto& display_buffer = window.update_display_buffer(context());
auto cursor_pos = window.display_coord(context().selections().main().cursor()).value_or(DisplayCoord{});
m_ui->draw(display_buffer, cursor_pos, faces["Default"], faces["BufferPadding"]);
auto selections = context().selections();
auto sel = selections.begin();
Vector<LineCount> selection_lines;
selection_lines.reserve(selections.size());
std::generate_n(std::back_inserter(selection_lines), selections.size(), [&sel] { return (sel++)->min().line; });
m_ui->draw(display_buffer,
cursor_pos,
{display_buffer.range().begin.line, display_buffer.range().end.line},
context().buffer().line_count(),
selection_lines,
faces["Default"],
faces["BufferPadding"],
faces["ScrollBarGutter"],
faces["ScrollBarHandle"]);
}

const bool update_menu_anchor = (m_ui_pending & Draw) and not (m_ui_pending & MenuHide) and
Expand Down
2 changes: 2 additions & 0 deletions src/face_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ FaceRegistry::FaceRegistry()
{ "BufferPadding", {Face{ Color::Blue, Color::Default }} },
{ "Whitespace", {Face{ Color::Default, Color::Default, Attribute::FinalFg }} },
{ "WhitespaceIndent", {Face{}, "Whitespace"} },
{ "ScrollBarGutter", {Face{ Color::Blue, Color::Default }} },
{ "ScrollBarHandle", {Face{ Color::Blue, Color::Default, Attribute::Reverse }} },
}
{}

Expand Down
23 changes: 20 additions & 3 deletions src/json_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,27 @@ JsonUI::JsonUI()
set_signal_handler(SIGINT, SIG_DFL);
}

void JsonUI::draw(const DisplayBuffer& display_buffer, DisplayCoord cursor_pos,
const Face& default_face, const Face& padding_face)
void JsonUI::draw(const DisplayBuffer& display_buffer,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face)
{
rpc_call("draw", display_buffer.lines(), cursor_pos, default_face, padding_face);
rpc_call("draw",
display_buffer.lines(),
cursor_pos,
range.begin,
range.end,
buffer_line_count,
selection_lines,
default_face,
padding_face,
scroll_bar_gutter_face,
scroll_bar_handle_face);
}

void JsonUI::draw_status(const DisplayLine& prompt,
Expand Down
9 changes: 7 additions & 2 deletions src/json_ui.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ public:
bool is_ok() const override { return m_stdin_watcher.fd() != -1; }

void draw(const DisplayBuffer& display_buffer,
DisplayCoord cursor_pos,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& buffer_padding) override;
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face) override;

void draw_status(const DisplayLine& prompt,
const DisplayLine& content,
Expand Down
11 changes: 10 additions & 1 deletion src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ void register_options()
" terminal_shift_function_key int\n"
" terminal_padding_char codepoint\n"
" terminal_padding_fill bool\n"
" terminal_scroll_bar bool\n"
" terminal_cursor_native bool\n"
" terminal_info_max_width int\n",
UserInterface::Options{});
Expand Down Expand Up @@ -582,7 +583,15 @@ UniquePtr<UserInterface> make_ui(UIType ui_type)
void info_show(const DisplayLine&, const DisplayLineList&, DisplayCoord, Face, InfoStyle) override {}
void info_hide() override {}

void draw(const DisplayBuffer&, DisplayCoord, const Face&, const Face&) override {}
void draw(const DisplayBuffer& display_buffer,
const DisplayCoord,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face) override {}
void draw_status(const DisplayLine&, const DisplayLine&, const ColumnCount, const DisplayLine&, const Face&) override {}
DisplayCoord dimensions() override { return {24,80}; }
void refresh(bool) override {}
Expand Down
20 changes: 15 additions & 5 deletions src/remote.cc
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,14 @@ class RemoteUI : public UserInterface
void info_hide() override;

void draw(const DisplayBuffer& display_buffer,
DisplayCoord cursor_pos,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face) override;
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face) override;

void draw_status(const DisplayLine& prompt,
const DisplayLine& content,
Expand Down Expand Up @@ -563,11 +568,16 @@ void RemoteUI::info_hide()
}

void RemoteUI::draw(const DisplayBuffer& display_buffer,
DisplayCoord cursor_pos,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face)
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face)
{
send_message(MessageType::Draw, display_buffer, cursor_pos, default_face, padding_face);
send_message(MessageType::Draw, display_buffer, cursor_pos, range, buffer_line_count, selection_lines, default_face, padding_face, scroll_bar_gutter_face, scroll_bar_handle_face);
}

void RemoteUI::draw_status(const DisplayLine& prompt,
Expand Down
69 changes: 64 additions & 5 deletions src/terminal_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -557,12 +557,27 @@ void TerminalUI::refresh(bool force)
m_dirty = false;
}

template<typename T>
T scale_to(T val, Range<T> from, Range<T> to)
{
T from_size = from.end - from.begin + 1;
T to_size = to.end - to.begin + 1;

return ((val - from.begin) * to_size + from_size / 2) / from_size + to.begin;
}

static const DisplayLine empty_line = { String(" "), {} };


void TerminalUI::draw(const DisplayBuffer& display_buffer,
DisplayCoord cursor_pos,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face)
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face)
{
check_resize();

Expand All @@ -576,9 +591,40 @@ void TerminalUI::draw(const DisplayBuffer& display_buffer,

DisplayAtom padding{String{m_padding_char, m_padding_fill ? dim.column : 1}};

const auto padding_lines = (dim.line + line_offset) - line_index;
while (line_index < dim.line + line_offset)
m_window.draw(line_index++, padding, face);

if (m_scroll_bar)
{
Range<LineCount> gutter_range = {0_line, dim.line - 1};
Range<LineCount> buffer_range = {0_line, buffer_line_count - 1 + dim.line - 1};

std::fill(m_scroll_bar_scratch.begin(), m_scroll_bar_scratch.end(), 0);

for (const LineCount selection_line : selection_lines)
m_scroll_bar_scratch[(int) scale_to(selection_line, buffer_range, gutter_range)]++;

const auto visible_lines = range.end - range.begin + padding_lines;
const auto mark_height = scale_to(visible_lines, buffer_range, gutter_range);

const auto mark_begin = scale_to(range.begin, buffer_range, gutter_range);
const auto mark_end = mark_begin + mark_height;

for (auto line = 0_line; line < dim.line; ++line) {
const bool is_mark = line >= mark_begin and line <= mark_end;
String selections;
switch (m_scroll_bar_scratch[(int)line]) {
case 0: selections = " "; break;
case 1: selections = "-"; break;
case 2: selections = "="; break;
default: selections = "≡"; break;
}

m_window.draw({line + line_offset, m_window.size.column - 1}, DisplayAtom(selections), is_mark ? scroll_bar_handle_face : scroll_bar_gutter_face);
}
}

m_cursor_pos = cursor_pos;

m_dirty = true;
Expand All @@ -605,12 +651,13 @@ void TerminalUI::draw_status(const DisplayLine& prompt,
m_window.draw(status_line_pos, prompt.atoms(), default_face);
m_window.draw(DisplayCoord{status_line_pos, prompt.length()}, trimmed_content.atoms(), default_face);

const auto scroll_bar_gutter = m_scroll_bar ? 1 : 0;
const auto mode_len = mode_line.length();
m_status_len = prompt.length() + trimmed_content.length();
const auto remaining = m_dimensions.column - m_status_len;
if (mode_len < remaining)
{
ColumnCount col = m_dimensions.column - mode_len;
ColumnCount col = m_dimensions.column - mode_len + scroll_bar_gutter;
m_window.draw({status_line_pos, col}, mode_line.atoms(), default_face);
}
else if (remaining > 2)
Expand All @@ -620,7 +667,7 @@ void TerminalUI::draw_status(const DisplayLine& prompt,
trimmed_mode_line.insert(trimmed_mode_line.begin(), { "…", {} });
kak_assert(trimmed_mode_line.length() == remaining - 1);

ColumnCount col = m_dimensions.column - remaining + 1;
ColumnCount col = m_dimensions.column - remaining + 1 + scroll_bar_gutter;
m_window.draw({status_line_pos, col}, trimmed_mode_line.atoms(), default_face);
}

Expand Down Expand Up @@ -675,6 +722,11 @@ void TerminalUI::check_resize(bool force)

m_dimensions = terminal_size - 1_line;

if (m_scroll_bar) {
m_dimensions -= {0_line, 1_col};
m_scroll_bar_scratch.resize((size_t)m_dimensions.line);
}

// if (char* csr = tigetstr((char*)"csr"))
// putp(tparm(csr, 0, ws.ws_row));

Expand Down Expand Up @@ -1593,7 +1645,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);

bool new_cursor_native = find("terminal_cursor_native").map(to_bool).value_or(false);
if (new_cursor_native != m_cursor_native)
{
Expand All @@ -1602,6 +1654,13 @@ void TerminalUI::set_ui_options(const Options& options)
}

m_info_max_width = find("terminal_info_max_width").map(str_to_int_ifp).value_or(0);

bool new_scroll_bar = find("terminal_scroll_bar").map(to_bool).value_or(false);

if (m_scroll_bar != new_scroll_bar) {
m_scroll_bar = new_scroll_bar;
check_resize(true);
}
}

}
12 changes: 10 additions & 2 deletions src/terminal_ui.hh
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ public:
bool is_ok() const override { return (bool)m_window; }

void draw(const DisplayBuffer& display_buffer,
DisplayCoord cursor_pos,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face) override;
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face) override;

void draw_status(const DisplayLine& prompt,
const DisplayLine& content,
Expand Down Expand Up @@ -167,6 +172,9 @@ private:
bool m_padding_fill = false;
bool m_cursor_native = false;

bool m_scroll_bar = false;
Vector<char> m_scroll_bar_scratch;

bool m_dirty = false;

bool m_resize_pending = false;
Expand Down
16 changes: 13 additions & 3 deletions src/user_interface.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
#define user_interface_hh_INCLUDED

#include "array_view.hh"
#include "hash_map.hh"
#include "function.hh"
#include "hash_map.hh"
#include "range.hh"
#include "selection.hh"
#include "units.hh"

#include <functional>

namespace Kakoune
{
Expand Down Expand Up @@ -58,9 +63,14 @@ public:
virtual void info_hide() = 0;

virtual void draw(const DisplayBuffer& display_buffer,
DisplayCoord cursor_pos,
const DisplayCoord cursor_pos,
const Range<LineCount> range,
const LineCount buffer_line_count,
const Vector<LineCount> selection_lines,
const Face& default_face,
const Face& padding_face) = 0;
const Face& padding_face,
const Face& scroll_bar_gutter_face,
const Face& scroll_bar_handle_face) = 0;

virtual void draw_status(const DisplayLine& prompt,
const DisplayLine& content,
Expand Down
Loading