mirror of
https://github.com/mawww/kakoune.git
synced 2024-09-11 13:00:41 +03:00
Compare commits
9 Commits
196644e388
...
6e18812c2c
Author | SHA1 | Date | |
---|---|---|---|
|
6e18812c2c | ||
|
238e5e7659 | ||
|
560e3631ec | ||
|
6ed01f402b | ||
|
1b2100753e | ||
|
1a52006c3d | ||
|
2d9886afe7 | ||
|
a250b96c18 | ||
|
4dd9dbb3f8 |
@ -3,6 +3,7 @@
|
||||
|
||||
#include "safe_ptr.hh"
|
||||
#include "string.hh"
|
||||
#include "ranges.hh"
|
||||
#include "hash_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "assert.hh"
|
||||
|
||||
#include "backtrace.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "format.hh"
|
||||
#include "file.hh"
|
||||
#include "exception.hh"
|
||||
#include "debug.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "backtrace.hh"
|
||||
|
||||
#include "string.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
|
||||
#if defined(__GLIBC__) || defined(__APPLE__)
|
||||
# include <execinfo.h>
|
||||
|
@ -271,36 +271,6 @@ Buffer* create_fifo_buffer(String name, int fd, Buffer::Flags flags, bool scroll
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void write_to_debug_buffer(StringView str)
|
||||
{
|
||||
if (not BufferManager::has_instance())
|
||||
{
|
||||
write(2, str);
|
||||
write(2, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr StringView debug_buffer_name = "*debug*";
|
||||
// Try to ensure we keep an empty line at the end of the debug buffer
|
||||
// where the user can put its cursor to scroll with new messages
|
||||
const bool eol_back = not str.empty() and str.back() == '\n';
|
||||
if (Buffer* buffer = BufferManager::instance().get_buffer_ifp(debug_buffer_name))
|
||||
{
|
||||
buffer->flags() &= ~Buffer::Flags::ReadOnly;
|
||||
auto restore = on_scope_end([buffer] { buffer->flags() |= Buffer::Flags::ReadOnly; });
|
||||
|
||||
buffer->insert(buffer->back_coord(), eol_back ? str : str + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
String line = str + (eol_back ? "\n" : "\n\n");
|
||||
create_buffer_from_string(
|
||||
debug_buffer_name.str(), Buffer::Flags::NoUndo | Buffer::Flags::Debug | Buffer::Flags::ReadOnly,
|
||||
line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto to_string(Buffer::HistoryId id)
|
||||
{
|
||||
using Result = decltype(to_string(size_t{}));
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "context.hh"
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "file.hh"
|
||||
#include "remote.hh"
|
||||
#include "option.hh"
|
||||
@ -130,6 +131,7 @@ void Client::print_status(DisplayLine status_line)
|
||||
{
|
||||
m_status_line = std::move(status_line);
|
||||
m_ui_pending |= StatusLine;
|
||||
m_pending_clear &= ~PendingClear::StatusLine;
|
||||
}
|
||||
|
||||
|
||||
@ -144,7 +146,8 @@ String generate_context_info(const Context& context)
|
||||
if (context.buffer().is_modified())
|
||||
s += "[+]";
|
||||
if (context.client().input_handler().is_recording())
|
||||
s += format("[recording ({})]", context.client().input_handler().recording_reg());
|
||||
s += format("[recording ({}): {}]", context.client().input_handler().recording_reg(),
|
||||
context.client().input_handler().recorded_keys());
|
||||
if (context.hooks_disabled())
|
||||
s += "[no-hooks]";
|
||||
if (not(context.buffer().flags() & (Buffer::Flags::File | Buffer::Flags::Debug)))
|
||||
@ -467,6 +470,7 @@ void Client::info_show(DisplayLine title, DisplayLineList content, BufferCoord a
|
||||
m_info = Info{ std::move(title), std::move(content), anchor, {}, style };
|
||||
m_ui_pending |= InfoShow;
|
||||
m_ui_pending &= ~InfoHide;
|
||||
m_pending_clear &= ~PendingClear::Info;
|
||||
}
|
||||
|
||||
void Client::info_show(StringView title, StringView content, BufferCoord anchor, InfoStyle style)
|
||||
@ -490,4 +494,21 @@ void Client::info_hide(bool even_modal)
|
||||
m_ui_pending &= ~InfoShow;
|
||||
}
|
||||
|
||||
void Client::schedule_clear()
|
||||
{
|
||||
if (not (m_ui_pending & InfoShow))
|
||||
m_pending_clear |= PendingClear::Info;
|
||||
if (not (m_ui_pending & StatusLine))
|
||||
m_pending_clear |= PendingClear::StatusLine;
|
||||
}
|
||||
|
||||
void Client::clear_pending()
|
||||
{
|
||||
if (m_pending_clear & PendingClear::StatusLine)
|
||||
print_status({});
|
||||
if (m_pending_clear & PendingClear::Info)
|
||||
info_hide();
|
||||
m_pending_clear = PendingClear::None;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ public:
|
||||
|
||||
DisplayCoord dimensions() const;
|
||||
|
||||
void schedule_clear();
|
||||
void clear_pending();
|
||||
|
||||
void force_redraw(bool full = false);
|
||||
void redraw_ifn();
|
||||
|
||||
@ -111,6 +114,16 @@ private:
|
||||
};
|
||||
int m_ui_pending = 0;
|
||||
|
||||
enum class PendingClear
|
||||
{
|
||||
None = 0,
|
||||
Info = 0b01,
|
||||
StatusLine = 0b10
|
||||
};
|
||||
friend constexpr bool with_bit_ops(Meta::Type<PendingClear>) { return true; }
|
||||
PendingClear m_pending_clear = PendingClear::None;
|
||||
|
||||
|
||||
struct Menu
|
||||
{
|
||||
Vector<DisplayLine> items;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "exception.hh"
|
||||
#include "ranges.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -2,10 +2,11 @@
|
||||
|
||||
#include "alias_registry.hh"
|
||||
#include "assert.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "context.hh"
|
||||
#include "debug.hh"
|
||||
#include "flags.hh"
|
||||
#include "file.hh"
|
||||
#include "hook_manager.hh"
|
||||
#include "optional.hh"
|
||||
#include "option_types.hh"
|
||||
#include "profile.hh"
|
||||
@ -13,6 +14,7 @@
|
||||
#include "regex.hh"
|
||||
#include "register_manager.hh"
|
||||
#include "shell_manager.hh"
|
||||
#include "scope.hh"
|
||||
#include "utils.hh"
|
||||
#include "unit_tests.hh"
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "command_manager.hh"
|
||||
#include "completion.hh"
|
||||
#include "context.hh"
|
||||
#include "debug.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "face_registry.hh"
|
||||
#include "file.hh"
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "file.hh"
|
||||
#include "context.hh"
|
||||
#include "option_types.hh"
|
||||
#include "option_manager.hh"
|
||||
#include "regex.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -1,10 +1,8 @@
|
||||
#include "context.hh"
|
||||
|
||||
#include "alias_registry.hh"
|
||||
#include "client.hh"
|
||||
#include "face_registry.hh"
|
||||
#include "scope.hh"
|
||||
#include "buffer_manager.hh"
|
||||
#include "hook_manager.hh"
|
||||
#include "register_manager.hh"
|
||||
#include "window.hh"
|
||||
|
||||
@ -62,6 +60,12 @@ Scope& Context::scope(bool allow_local) const
|
||||
return GlobalScope::instance();
|
||||
}
|
||||
|
||||
OptionManager& Context::options() const { return scope().options(); }
|
||||
HookManager& Context::hooks() const { return scope().hooks(); }
|
||||
KeymapManager& Context::keymaps() const { return scope().keymaps(); }
|
||||
AliasRegistry& Context::aliases() const { return scope().aliases(); }
|
||||
FaceRegistry& Context::faces(bool allow_local) const { return scope(allow_local).faces(); }
|
||||
|
||||
void Context::set_client(Client& client)
|
||||
{
|
||||
kak_assert(not has_client());
|
||||
@ -82,6 +86,12 @@ void Context::print_status(DisplayLine status) const
|
||||
client().print_status(std::move(status));
|
||||
}
|
||||
|
||||
void Context::push_jump(bool force)
|
||||
{
|
||||
if (force or not (m_flags & Flags::Draft))
|
||||
m_jump_list.push(selections());
|
||||
}
|
||||
|
||||
void JumpList::push(SelectionList jump, Optional<size_t> index)
|
||||
{
|
||||
if (index)
|
||||
@ -428,4 +438,22 @@ void Context::set_name(String name) {
|
||||
String old_name = std::exchange(m_name, std::move(name));
|
||||
hooks().run_hook(Hook::ClientRenamed, format("{}:{}", old_name, m_name), *this);
|
||||
}
|
||||
|
||||
ScopedEdition::ScopedEdition(Context& context)
|
||||
: m_context{context},
|
||||
m_buffer{context.has_buffer() ? &context.buffer() : nullptr}
|
||||
{ if (m_buffer) m_context.begin_edition(); }
|
||||
|
||||
ScopedEdition::~ScopedEdition() { if (m_buffer) m_context.end_edition(); }
|
||||
|
||||
ScopedSelectionEdition::ScopedSelectionEdition(Context& context)
|
||||
: m_context{context},
|
||||
m_buffer{not (m_context.flags() & Context::Flags::Draft) and context.has_buffer() ? &context.buffer() : nullptr}
|
||||
{ if (m_buffer) m_context.m_selection_history.begin_edition(); }
|
||||
|
||||
ScopedSelectionEdition::ScopedSelectionEdition(ScopedSelectionEdition&& other) : m_context{other.m_context}, m_buffer{other.m_buffer}
|
||||
{ other.m_buffer = nullptr; }
|
||||
|
||||
ScopedSelectionEdition::~ScopedSelectionEdition() { if (m_buffer) m_context.m_selection_history.end_edition(); }
|
||||
|
||||
}
|
||||
|
@ -4,20 +4,26 @@
|
||||
#include "selection.hh"
|
||||
#include "optional.hh"
|
||||
#include "utils.hh"
|
||||
#include "flags.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class Context;
|
||||
class Window;
|
||||
class Buffer;
|
||||
class Client;
|
||||
class Scope;
|
||||
class InputHandler;
|
||||
class DisplayLine;
|
||||
class KeymapManager;
|
||||
|
||||
class AliasRegistry;
|
||||
class FaceRegistry;
|
||||
class OptionManager;
|
||||
class KeymapManager;
|
||||
class HookManager;
|
||||
|
||||
enum Direction { Backward = -1, Forward = 1 };
|
||||
|
||||
@ -104,11 +110,11 @@ public:
|
||||
Scope& scope(bool allow_local = true) const;
|
||||
Scope* local_scope() const { return m_local_scopes.empty() ? nullptr : m_local_scopes.back(); }
|
||||
|
||||
OptionManager& options() const { return scope().options(); }
|
||||
HookManager& hooks() const { return scope().hooks(); }
|
||||
KeymapManager& keymaps() const { return scope().keymaps(); }
|
||||
AliasRegistry& aliases() const { return scope().aliases(); }
|
||||
FaceRegistry& faces(bool allow_local = true) const { return scope(allow_local).faces(); }
|
||||
OptionManager& options() const;
|
||||
HookManager& hooks() const;
|
||||
KeymapManager& keymaps() const;
|
||||
AliasRegistry& aliases() const;
|
||||
FaceRegistry& faces(bool allow_local = true) const;
|
||||
|
||||
void print_status(DisplayLine status) const;
|
||||
|
||||
@ -132,11 +138,7 @@ public:
|
||||
Flags flags() const { return m_flags; }
|
||||
|
||||
JumpList& jump_list() { return m_jump_list; }
|
||||
void push_jump(bool force = false)
|
||||
{
|
||||
if (force or not (m_flags & Flags::Draft))
|
||||
m_jump_list.push(selections());
|
||||
}
|
||||
void push_jump(bool force = false);
|
||||
|
||||
template<typename Func>
|
||||
void set_last_select(Func&& last_select) { m_last_select = std::forward<Func>(last_select); }
|
||||
@ -215,12 +217,9 @@ private:
|
||||
|
||||
struct ScopedEdition
|
||||
{
|
||||
ScopedEdition(Context& context)
|
||||
: m_context{context},
|
||||
m_buffer{context.has_buffer() ? &context.buffer() : nullptr}
|
||||
{ if (m_buffer) m_context.begin_edition(); }
|
||||
|
||||
~ScopedEdition() { if (m_buffer) m_context.end_edition(); }
|
||||
ScopedEdition(Context& context);
|
||||
~ScopedEdition();
|
||||
ScopedEdition(const ScopedEdition&) = delete;
|
||||
|
||||
Context& context() const { return m_context; }
|
||||
private:
|
||||
@ -230,14 +229,10 @@ private:
|
||||
|
||||
struct ScopedSelectionEdition
|
||||
{
|
||||
ScopedSelectionEdition(Context& context)
|
||||
: m_context{context},
|
||||
m_buffer{not (m_context.flags() & Context::Flags::Draft) and context.has_buffer() ? &context.buffer() : nullptr}
|
||||
{ if (m_buffer) m_context.m_selection_history.begin_edition(); }
|
||||
ScopedSelectionEdition(ScopedSelectionEdition&& other) : m_context{other.m_context}, m_buffer{other.m_buffer}
|
||||
{ other.m_buffer = nullptr; }
|
||||
ScopedSelectionEdition(Context& context);
|
||||
ScopedSelectionEdition(ScopedSelectionEdition&& other);
|
||||
~ScopedSelectionEdition();
|
||||
|
||||
~ScopedSelectionEdition() { if (m_buffer) m_context.m_selection_history.end_edition(); }
|
||||
private:
|
||||
Context& m_context;
|
||||
SafePtr<Buffer> m_buffer;
|
||||
|
39
src/debug.cc
Normal file
39
src/debug.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include "debug.hh"
|
||||
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
void write_to_debug_buffer(StringView str)
|
||||
{
|
||||
if (not BufferManager::has_instance())
|
||||
{
|
||||
write(2, str);
|
||||
write(2, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr StringView debug_buffer_name = "*debug*";
|
||||
// Try to ensure we keep an empty line at the end of the debug buffer
|
||||
// where the user can put its cursor to scroll with new messages
|
||||
const bool eol_back = not str.empty() and str.back() == '\n';
|
||||
if (Buffer* buffer = BufferManager::instance().get_buffer_ifp(debug_buffer_name))
|
||||
{
|
||||
buffer->flags() &= ~Buffer::Flags::ReadOnly;
|
||||
auto restore = on_scope_end([buffer] { buffer->flags() |= Buffer::Flags::ReadOnly; });
|
||||
|
||||
buffer->insert(buffer->back_coord(), eol_back ? str : str + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
String line = str + (eol_back ? "\n" : "\n\n");
|
||||
create_buffer_from_string(
|
||||
debug_buffer_name.str(), Buffer::Flags::NoUndo | Buffer::Flags::Debug | Buffer::Flags::ReadOnly,
|
||||
line);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
40
src/debug.hh
Normal file
40
src/debug.hh
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef debug_hh_INCLUDED
|
||||
#define debug_hh_INCLUDED
|
||||
|
||||
#include "constexpr_utils.hh"
|
||||
#include "enum.hh"
|
||||
#include "flags.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class StringView;
|
||||
|
||||
enum class DebugFlags
|
||||
{
|
||||
None = 0,
|
||||
Hooks = 1 << 0,
|
||||
Shell = 1 << 1,
|
||||
Profile = 1 << 2,
|
||||
Keys = 1 << 3,
|
||||
Commands = 1 << 4,
|
||||
};
|
||||
|
||||
constexpr bool with_bit_ops(Meta::Type<DebugFlags>) { return true; }
|
||||
|
||||
constexpr auto enum_desc(Meta::Type<DebugFlags>)
|
||||
{
|
||||
return make_array<EnumDesc<DebugFlags>>({
|
||||
{ DebugFlags::Hooks, "hooks" },
|
||||
{ DebugFlags::Shell, "shell" },
|
||||
{ DebugFlags::Profile, "profile" },
|
||||
{ DebugFlags::Keys, "keys" },
|
||||
{ DebugFlags::Commands, "commands" },
|
||||
});
|
||||
}
|
||||
|
||||
void write_to_debug_buffer(StringView str);
|
||||
|
||||
}
|
||||
|
||||
#endif // debug_hh_INCLUDED
|
@ -7,6 +7,8 @@
|
||||
#include "string.hh"
|
||||
#include "vector.hh"
|
||||
#include "hash_map.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "exception.hh"
|
||||
#include "ranges.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "meta.hh"
|
||||
#include "string.hh"
|
||||
#include "units.hh"
|
||||
#include "constexpr_utils.hh"
|
||||
#include "vector.hh"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
180
src/format.cc
Normal file
180
src/format.cc
Normal file
@ -0,0 +1,180 @@
|
||||
#include "format.hh"
|
||||
|
||||
#include "exception.hh"
|
||||
#include "string_utils.hh"
|
||||
|
||||
#include <charconv>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
|
||||
template<size_t N>
|
||||
InplaceString<N> to_string_impl(auto val, auto format)
|
||||
{
|
||||
InplaceString<N> res;
|
||||
auto [end, errc] = std::to_chars(res.m_data, res.m_data + N, val, format);
|
||||
if (errc != std::errc{})
|
||||
throw runtime_error("to_string error");
|
||||
res.m_length = end - res.m_data;
|
||||
*end = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
InplaceString<N> to_string_impl(auto val)
|
||||
{
|
||||
return to_string_impl<N>(val, 10);
|
||||
}
|
||||
|
||||
InplaceString<15> to_string(int val)
|
||||
{
|
||||
return to_string_impl<15>(val);
|
||||
}
|
||||
|
||||
InplaceString<15> to_string(unsigned val)
|
||||
{
|
||||
return to_string_impl<15>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(long int val)
|
||||
{
|
||||
return to_string_impl<23>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(long long int val)
|
||||
{
|
||||
return to_string_impl<23>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(unsigned long val)
|
||||
{
|
||||
return to_string_impl<23>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(Hex val)
|
||||
{
|
||||
return to_string_impl<23>(val.val, 16);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(Grouped val)
|
||||
{
|
||||
auto ungrouped = to_string_impl<23>(val.val);
|
||||
|
||||
InplaceString<23> res;
|
||||
for (int pos = 0, len = ungrouped.m_length; pos != len; ++pos)
|
||||
{
|
||||
if (res.m_length and ((len - pos) % 3) == 0)
|
||||
res.m_data[res.m_length++] = ',';
|
||||
res.m_data[res.m_length++] = ungrouped.m_data[pos];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(float val)
|
||||
{
|
||||
#if defined(__cpp_lib_to_chars)
|
||||
return to_string_impl<23>(val, std::chars_format::general);
|
||||
#else
|
||||
InplaceString<23> res;
|
||||
res.m_length = snprintf(res.m_data, 23, "%f", val);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
InplaceString<7> to_string(Codepoint c)
|
||||
{
|
||||
InplaceString<7> res;
|
||||
char* ptr = res.m_data;
|
||||
utf8::dump(ptr, c);
|
||||
res.m_length = (int)(ptr - res.m_data);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename AppendFunc>
|
||||
void format_impl(StringView fmt, ArrayView<const StringView> params, AppendFunc append)
|
||||
{
|
||||
int implicitIndex = 0;
|
||||
for (auto it = fmt.begin(), end = fmt.end(); it != end;)
|
||||
{
|
||||
auto opening = std::find(it, end, '{');
|
||||
if (opening == end)
|
||||
{
|
||||
append(StringView{it, opening});
|
||||
break;
|
||||
}
|
||||
else if (opening != it and *(opening-1) == '\\')
|
||||
{
|
||||
append(StringView{it, opening-1});
|
||||
append('{');
|
||||
it = opening + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
append(StringView{it, opening});
|
||||
auto closing = std::find(opening, end, '}');
|
||||
if (closing == end)
|
||||
throw runtime_error("format string error, unclosed '{'");
|
||||
|
||||
auto format = std::find(opening+1, closing, ':');
|
||||
const int index = opening+1 == format ? implicitIndex : str_to_int({opening+1, format});
|
||||
|
||||
if (index >= params.size())
|
||||
throw runtime_error("format string parameter index too big");
|
||||
|
||||
if (format != closing)
|
||||
{
|
||||
char padding = ' ';
|
||||
if (*(++format) == '0')
|
||||
{
|
||||
padding = '0';
|
||||
++format;
|
||||
}
|
||||
for (ColumnCount width = str_to_int({format, closing}), len = params[index].column_length();
|
||||
width > len; --width)
|
||||
append(padding);
|
||||
}
|
||||
|
||||
append(params[index]);
|
||||
implicitIndex = index+1;
|
||||
it = closing+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
char* ptr = buffer.begin();
|
||||
const char* end = buffer.end();
|
||||
format_impl(fmt, params, [&](StringView s) mutable {
|
||||
for (auto c : s)
|
||||
{
|
||||
if (ptr == end)
|
||||
throw runtime_error("buffer is too small");
|
||||
*ptr++ = c;
|
||||
}
|
||||
});
|
||||
if (ptr == end)
|
||||
throw runtime_error("buffer is too small");
|
||||
*ptr = 0;
|
||||
|
||||
return { buffer.begin(), ptr };
|
||||
}
|
||||
|
||||
void format_with(FunctionRef<void (StringView)> append, StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
format_impl(fmt, params, append);
|
||||
}
|
||||
|
||||
String format(StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
ByteCount size = fmt.length();
|
||||
for (auto& s : params) size += s.length();
|
||||
String res;
|
||||
res.reserve(size);
|
||||
|
||||
format_impl(fmt, params, [&](StringView s) { res += s; });
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
81
src/format.hh
Normal file
81
src/format.hh
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef format_hh_INCLUDED
|
||||
#define format_hh_INCLUDED
|
||||
|
||||
#include "string.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
template<size_t N>
|
||||
struct InplaceString
|
||||
{
|
||||
static_assert(N < 256, "InplaceString cannot handle sizes >= 256");
|
||||
|
||||
constexpr operator StringView() const { return {m_data, ByteCount{m_length}}; }
|
||||
operator String() const { return {m_data, ByteCount{m_length}}; }
|
||||
|
||||
unsigned char m_length{};
|
||||
char m_data[N];
|
||||
};
|
||||
|
||||
struct Hex { size_t val; };
|
||||
constexpr Hex hex(size_t val) { return {val}; }
|
||||
|
||||
struct Grouped { size_t val; };
|
||||
constexpr Grouped grouped(size_t val) { return {val}; }
|
||||
|
||||
InplaceString<15> to_string(int val);
|
||||
InplaceString<15> to_string(unsigned val);
|
||||
InplaceString<23> to_string(long int val);
|
||||
InplaceString<23> to_string(unsigned long val);
|
||||
InplaceString<23> to_string(long long int val);
|
||||
InplaceString<23> to_string(Hex val);
|
||||
InplaceString<23> to_string(Grouped val);
|
||||
InplaceString<23> to_string(float val);
|
||||
InplaceString<7> to_string(Codepoint c);
|
||||
|
||||
template<typename RealType, typename ValueType>
|
||||
decltype(auto) to_string(const StronglyTypedNumber<RealType, ValueType>& val)
|
||||
{
|
||||
return to_string((ValueType)val);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename T> requires std::is_convertible_v<T, StringView>
|
||||
StringView format_param(const T& val) { return val; }
|
||||
|
||||
template<typename T> requires (not std::is_convertible_v<T, StringView>)
|
||||
decltype(auto) format_param(const T& val) { return to_string(val); }
|
||||
|
||||
}
|
||||
|
||||
String format(StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
String format(StringView fmt, Types&&... params)
|
||||
{
|
||||
return format(fmt, ArrayView<const StringView>{detail::format_param(std::forward<Types>(params))...});
|
||||
}
|
||||
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, Types&&... params)
|
||||
{
|
||||
return format_to(buffer, fmt, ArrayView<const StringView>{detail::format_param(std::forward<Types>(params))...});
|
||||
}
|
||||
|
||||
void format_with(FunctionRef<void (StringView)> append, StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
void format_with(FunctionRef<void (StringView)> append, StringView fmt, Types&&... params)
|
||||
{
|
||||
return format_with(append, fmt, ArrayView<const StringView>{detail::format_param(std::forward<Types>(params))...});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // format_hh_INCLUDED
|
@ -2,10 +2,12 @@
|
||||
|
||||
#include "clock.hh"
|
||||
#include "string.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "unit_tests.hh"
|
||||
#include "format.hh"
|
||||
#include "debug.hh"
|
||||
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "highlighter.hh"
|
||||
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include "coord.hh"
|
||||
#include "completion.hh"
|
||||
#include "display_buffer.hh"
|
||||
#include "exception.hh"
|
||||
#include "flags.hh"
|
||||
#include "range.hh"
|
||||
#include "hash_map.hh"
|
||||
#include "array_view.hh"
|
||||
#include "string.hh"
|
||||
@ -18,6 +18,9 @@ namespace Kakoune
|
||||
{
|
||||
|
||||
class Context;
|
||||
class DisplayBuffer;
|
||||
|
||||
using BufferRange = Range<BufferCoord>;
|
||||
|
||||
enum class HighlightPass
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "highlighter_group.hh"
|
||||
|
||||
#include "ranges.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "assert.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "changes.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "context.hh"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "hook_manager.hh"
|
||||
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "clock.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "context.hh"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "safe_ptr.hh"
|
||||
#include "meta.hh"
|
||||
#include "enum.hh"
|
||||
#include "constexpr_utils.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "input_handler.hh"
|
||||
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "client.hh"
|
||||
#include "event_manager.hh"
|
||||
@ -212,14 +212,6 @@ constexpr StringView register_doc =
|
||||
|
||||
class Normal : public InputMode
|
||||
{
|
||||
enum class PendingClear
|
||||
{
|
||||
None = 0,
|
||||
Info = 0b01,
|
||||
StatusLine = 0b10
|
||||
};
|
||||
friend constexpr bool with_bit_ops(Meta::Type<PendingClear>) { return true; }
|
||||
|
||||
public:
|
||||
Normal(InputHandler& input_handler, bool single_command = false)
|
||||
: InputMode(input_handler),
|
||||
@ -228,13 +220,7 @@ public:
|
||||
Timer::Callback{} : [this](Timer&) {
|
||||
RefPtr<InputMode> keep_alive{this}; // hook could trigger pop_mode()
|
||||
if (context().has_client())
|
||||
{
|
||||
if (m_pending_clear & PendingClear::StatusLine)
|
||||
context().client().print_status({});
|
||||
if (m_pending_clear & PendingClear::Info)
|
||||
context().client().info_hide();
|
||||
}
|
||||
m_pending_clear = PendingClear::None;
|
||||
context().client().clear_pending();
|
||||
|
||||
context().hooks().run_hook(Hook::NormalIdle, "", context());
|
||||
}},
|
||||
@ -381,8 +367,7 @@ public:
|
||||
if (enabled() and not transient) // The hook might have changed mode
|
||||
{
|
||||
if (should_clear and context().has_client())
|
||||
m_pending_clear = (context().client().info_pending() ? PendingClear::None : PendingClear::Info)
|
||||
| (context().client().status_line_pending() ? PendingClear::None : PendingClear::StatusLine);
|
||||
context().client().schedule_clear();
|
||||
m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context()));
|
||||
}
|
||||
}
|
||||
@ -416,7 +401,7 @@ public:
|
||||
if (not (context().flags() & Context::Flags::Draft))
|
||||
{
|
||||
if (context().has_client())
|
||||
m_pending_clear = PendingClear::Info | PendingClear::StatusLine;
|
||||
context().client().schedule_clear();
|
||||
m_idle_timer.set_next_date(Clock::now() + get_idle_timeout(context()));
|
||||
}
|
||||
}
|
||||
@ -434,7 +419,6 @@ private:
|
||||
Timer m_idle_timer;
|
||||
Timer m_fs_check_timer;
|
||||
MouseHandler m_mouse_handler;
|
||||
PendingClear m_pending_clear = PendingClear::None;
|
||||
|
||||
enum class State { Normal, SingleCommand, PopOnEnabled };
|
||||
State m_state;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "constexpr_utils.hh"
|
||||
#include "context.hh"
|
||||
#include "env_vars.hh"
|
||||
#include "enum.hh"
|
||||
#include "face.hh"
|
||||
#include "normal.hh"
|
||||
#include "optional.hh"
|
||||
@ -99,6 +100,7 @@ public:
|
||||
bool is_recording() const;
|
||||
void stop_recording();
|
||||
char recording_reg() const { return m_recording_reg; }
|
||||
StringView recorded_keys() const { return m_recorded_keys; }
|
||||
|
||||
void reset_normal_mode();
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "client.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "changes.hh"
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "hash_map.hh"
|
||||
#include "string.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "value.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "keys.hh"
|
||||
#include "ranges.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
|
||||
#include <cstdio>
|
||||
#include <utility>
|
||||
|
@ -3,7 +3,8 @@
|
||||
#include "array_view.hh"
|
||||
#include "assert.hh"
|
||||
#include "exception.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "unit_tests.hh"
|
||||
#include "utf8_iterator.hh"
|
||||
#include "utils.hh"
|
||||
#include "format.hh"
|
||||
#include "string_utils.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -1,12 +1,13 @@
|
||||
#include "assert.hh"
|
||||
#include "backtrace.hh"
|
||||
#include "buffer.hh"
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "buffer_manager.hh"
|
||||
#include "client_manager.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "commands.hh"
|
||||
#include "context.hh"
|
||||
#include "debug.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "face_registry.hh"
|
||||
#include "file.hh"
|
||||
|
@ -1,17 +1,12 @@
|
||||
#ifndef meta_hh_INCLUDED
|
||||
#define meta_hh_INCLUDED
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
inline namespace Meta
|
||||
namespace Kakoune::inline Meta
|
||||
{
|
||||
|
||||
struct AnyType{};
|
||||
template<typename T> struct Type : AnyType {};
|
||||
|
||||
template<typename T> using void_t = void;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // meta_hh_INCLUDED
|
||||
|
@ -1841,7 +1841,7 @@ SelectionList read_selections_from_register(char reg, const Context& context)
|
||||
const auto buffer_name = StringView{ content[0].begin (), end_content[1].begin () - 1 };
|
||||
Buffer& buffer = BufferManager::instance().get_buffer(buffer_name);
|
||||
|
||||
return selection_list_from_strings(buffer, ColumnType::Byte, content | skip(1), timestamp, main);
|
||||
return selection_list_from_strings(buffer, ColumnType::Byte, content.subrange(1), timestamp, main);
|
||||
}
|
||||
|
||||
enum class CombineOp
|
||||
|
@ -64,29 +64,6 @@ struct PrefixedList
|
||||
template<typename T>
|
||||
using TimestampedList = PrefixedList<size_t, T>;
|
||||
|
||||
enum class DebugFlags
|
||||
{
|
||||
None = 0,
|
||||
Hooks = 1 << 0,
|
||||
Shell = 1 << 1,
|
||||
Profile = 1 << 2,
|
||||
Keys = 1 << 3,
|
||||
Commands = 1 << 4,
|
||||
};
|
||||
|
||||
constexpr bool with_bit_ops(Meta::Type<DebugFlags>) { return true; }
|
||||
|
||||
constexpr auto enum_desc(Meta::Type<DebugFlags>)
|
||||
{
|
||||
return make_array<EnumDesc<DebugFlags>>({
|
||||
{ DebugFlags::Hooks, "hooks" },
|
||||
{ DebugFlags::Shell, "shell" },
|
||||
{ DebugFlags::Profile, "profile" },
|
||||
{ DebugFlags::Keys, "keys" },
|
||||
{ DebugFlags::Commands, "commands" },
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // option_hh_INCLUDED
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ranges.hh"
|
||||
#include "utils.hh"
|
||||
#include "vector.hh"
|
||||
#include "format.hh"
|
||||
#include "string_utils.hh"
|
||||
|
||||
#include <memory>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "option_types.hh"
|
||||
#include "debug.hh"
|
||||
#include "unit_tests.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include "flags.hh"
|
||||
#include "hash_map.hh"
|
||||
#include "option.hh"
|
||||
#include "ranges.hh"
|
||||
#include "string.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
#include "units.hh"
|
||||
|
||||
#include <tuple>
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "parameters_parser.hh"
|
||||
|
||||
#include "ranges.hh"
|
||||
#include "flags.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "optional.hh"
|
||||
#include "flags.hh"
|
||||
#include "string.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "option.hh"
|
||||
#include "clock.hh"
|
||||
#include "option_manager.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "unit_tests.hh"
|
||||
#include "utf8_iterator.hh"
|
||||
#include "optional.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -6,9 +6,10 @@
|
||||
#include "unit_tests.hh"
|
||||
#include "utf8.hh"
|
||||
#include "utf8_iterator.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
#include "vector.hh"
|
||||
#include "utils.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "utils.hh"
|
||||
|
||||
#include <bit>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
@ -210,11 +211,12 @@ constexpr bool is_direction(RegexMode mode)
|
||||
(mode & ~(RegexMode::Forward | RegexMode::Backward)) == RegexMode{0};
|
||||
}
|
||||
|
||||
template<typename It, typename=void>
|
||||
template<typename It>
|
||||
struct SentinelType { using Type = It; };
|
||||
|
||||
template<typename It>
|
||||
struct SentinelType<It, void_t<typename It::Sentinel>> { using Type = typename It::Sentinel; };
|
||||
requires requires { typename It::Sentinel; }
|
||||
struct SentinelType<It> { using Type = typename It::Sentinel; };
|
||||
|
||||
template<typename Iterator, RegexMode mode>
|
||||
requires (has_direction(mode))
|
||||
|
@ -3,11 +3,23 @@
|
||||
#include "assert.hh"
|
||||
#include "context.hh"
|
||||
#include "hash_map.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
#include "ranges.hh"
|
||||
#include "hook_manager.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
Register::RestoreInfo Register::save(const Context& context)
|
||||
{
|
||||
return get(context) | gather<RestoreInfo>();
|
||||
}
|
||||
|
||||
void Register::restore(Context& context, const RestoreInfo& info)
|
||||
{
|
||||
set(context, info, true);
|
||||
}
|
||||
|
||||
void StaticRegister::set(Context& context, ConstArrayView<String> values, bool)
|
||||
{
|
||||
m_content.assign(values.begin(), values.end());
|
||||
|
@ -24,8 +24,8 @@ public:
|
||||
virtual const String& get_main(const Context& context, size_t main_index) = 0;
|
||||
|
||||
using RestoreInfo = Vector<String, MemoryDomain::Registers>;
|
||||
RestoreInfo save(const Context& context) { return get(context) | gather<RestoreInfo>(); }
|
||||
void restore(Context& context, const RestoreInfo& info) { set(context, info, true); }
|
||||
RestoreInfo save(const Context& context);
|
||||
void restore(Context& context, const RestoreInfo& info);
|
||||
|
||||
NestedBool& modified_hook_disabled() { return m_disable_modified_hook; }
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "remote.hh"
|
||||
|
||||
#include "buffer_manager.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "client_manager.hh"
|
||||
#include "command_manager.hh"
|
||||
#include "display_buffer.hh"
|
||||
|
@ -7,6 +7,8 @@
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
SelectionList::~SelectionList() = default;
|
||||
|
||||
SelectionList::SelectionList(Buffer& buffer, Selection s, size_t timestamp)
|
||||
: m_selections({ std::move(s) }), m_buffer(&buffer), m_timestamp(timestamp)
|
||||
{
|
||||
@ -27,6 +29,11 @@ SelectionList::SelectionList(Buffer& buffer, Vector<Selection> list, size_t time
|
||||
SelectionList::SelectionList(Buffer& buffer, Vector<Selection> list)
|
||||
: SelectionList(buffer, std::move(list), buffer.timestamp()) {}
|
||||
|
||||
SelectionList::SelectionList(const SelectionList&) = default;
|
||||
SelectionList::SelectionList(SelectionList&&) = default;
|
||||
SelectionList& SelectionList::operator=(const SelectionList&) = default;
|
||||
SelectionList& SelectionList::operator=(SelectionList&&) = default;
|
||||
|
||||
void SelectionList::remove(size_t index)
|
||||
{
|
||||
m_selections.erase(begin() + index);
|
||||
@ -538,4 +545,31 @@ Selection selection_from_string(ColumnType column_type, const Buffer& buffer, St
|
||||
return Selection{anchor, cursor};
|
||||
}
|
||||
|
||||
SelectionList selection_list_from_strings(Buffer& buffer, ColumnType column_type, ConstArrayView<String> descs, size_t timestamp, size_t main, ColumnCount tabstop)
|
||||
{
|
||||
if ((column_type != ColumnType::Byte and timestamp != buffer.timestamp()) or timestamp > buffer.timestamp())
|
||||
throw runtime_error{format("invalid timestamp '{}'", timestamp)};
|
||||
|
||||
auto from_string = [&](StringView desc) {
|
||||
return selection_from_string(column_type, buffer, desc, tabstop);
|
||||
};
|
||||
|
||||
auto sels = descs | transform(from_string) | gather<Vector<Selection>>();
|
||||
if (sels.empty())
|
||||
throw runtime_error{"empty selection description"};
|
||||
if (main >= sels.size())
|
||||
throw runtime_error{"invalid main selection index"};
|
||||
|
||||
sort_selections(sels, main);
|
||||
merge_overlapping_selections(sels, main);
|
||||
if (timestamp < buffer.timestamp())
|
||||
update_selections(sels, main, buffer, timestamp);
|
||||
else
|
||||
clamp_selections(sels, buffer);
|
||||
|
||||
SelectionList res{buffer, std::move(sels)};
|
||||
res.set_main_index(main);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,21 @@
|
||||
#ifndef selection_hh_INCLUDED
|
||||
#define selection_hh_INCLUDED
|
||||
|
||||
#include "buffer.hh"
|
||||
#include "coord.hh"
|
||||
#include "range.hh"
|
||||
#include "safe_ptr.hh"
|
||||
#include "utils.hh"
|
||||
#include "string.hh"
|
||||
#include "vector.hh"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class Buffer;
|
||||
using BufferRange = Range<BufferCoord>;
|
||||
|
||||
using CaptureList = Vector<String, MemoryDomain::Selections>;
|
||||
|
||||
constexpr ColumnCount max_column{std::numeric_limits<int>::max()};
|
||||
@ -84,11 +92,18 @@ struct SelectionList
|
||||
{
|
||||
static constexpr MemoryDomain Domain = MemoryDomain::Selections;
|
||||
|
||||
~SelectionList();
|
||||
SelectionList(Buffer& buffer, Selection s);
|
||||
SelectionList(Buffer& buffer, Selection s, size_t timestamp);
|
||||
SelectionList(Buffer& buffer, Vector<Selection> s);
|
||||
SelectionList(Buffer& buffer, Vector<Selection> s, size_t timestamp);
|
||||
|
||||
SelectionList(const SelectionList&);
|
||||
SelectionList(SelectionList&&);
|
||||
|
||||
SelectionList& operator=(const SelectionList&);
|
||||
SelectionList& operator=(SelectionList&&);
|
||||
|
||||
void update(bool merge = true);
|
||||
void check_invariant() const;
|
||||
|
||||
@ -166,33 +181,7 @@ String selection_to_string(ColumnType column_type, const Buffer& buffer, const S
|
||||
|
||||
String selection_list_to_string(ColumnType column_type, const SelectionList& selections, ColumnCount tabstop = -1);
|
||||
|
||||
template<typename StringArray>
|
||||
SelectionList selection_list_from_strings(Buffer& buffer, ColumnType column_type, StringArray&& descs, size_t timestamp, size_t main, ColumnCount tabstop = -1)
|
||||
{
|
||||
if ((column_type != ColumnType::Byte and timestamp != buffer.timestamp()) or timestamp > buffer.timestamp())
|
||||
throw runtime_error{format("invalid timestamp '{}'", timestamp)};
|
||||
|
||||
auto from_string = [&](StringView desc) {
|
||||
return selection_from_string(column_type, buffer, desc, tabstop);
|
||||
};
|
||||
|
||||
auto sels = descs | transform(from_string) | gather<Vector<Selection>>();
|
||||
if (sels.empty())
|
||||
throw runtime_error{"empty selection description"};
|
||||
if (main >= sels.size())
|
||||
throw runtime_error{"invalid main selection index"};
|
||||
|
||||
sort_selections(sels, main);
|
||||
merge_overlapping_selections(sels, main);
|
||||
if (timestamp < buffer.timestamp())
|
||||
update_selections(sels, main, buffer, timestamp);
|
||||
else
|
||||
clamp_selections(sels, buffer);
|
||||
|
||||
SelectionList res{buffer, std::move(sels)};
|
||||
res.set_main_index(main);
|
||||
return res;
|
||||
}
|
||||
SelectionList selection_list_from_strings(Buffer& buffer, ColumnType column_type, ConstArrayView<String> descs, size_t timestamp, size_t main, ColumnCount tabstop = -1);
|
||||
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "meta.hh"
|
||||
#include "unicode.hh"
|
||||
#include "vector.hh"
|
||||
#include "constexpr_utils.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "shared_string.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "format.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "shell_manager.hh"
|
||||
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "client.hh"
|
||||
#include "clock.hh"
|
||||
#include "context.hh"
|
||||
|
@ -147,88 +147,6 @@ int str_to_int(StringView str)
|
||||
throw runtime_error{str + " is not a number"};
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
InplaceString<N> to_string_impl(auto val, auto format)
|
||||
{
|
||||
InplaceString<N> res;
|
||||
auto [end, errc] = std::to_chars(res.m_data, res.m_data + N, val, format);
|
||||
if (errc != std::errc{})
|
||||
throw runtime_error("to_string error");
|
||||
res.m_length = end - res.m_data;
|
||||
*end = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
InplaceString<N> to_string_impl(auto val)
|
||||
{
|
||||
return to_string_impl<N>(val, 10);
|
||||
}
|
||||
|
||||
InplaceString<15> to_string(int val)
|
||||
{
|
||||
return to_string_impl<15>(val);
|
||||
}
|
||||
|
||||
InplaceString<15> to_string(unsigned val)
|
||||
{
|
||||
return to_string_impl<15>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(long int val)
|
||||
{
|
||||
return to_string_impl<23>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(long long int val)
|
||||
{
|
||||
return to_string_impl<23>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(unsigned long val)
|
||||
{
|
||||
return to_string_impl<23>(val);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(Hex val)
|
||||
{
|
||||
return to_string_impl<23>(val.val, 16);
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(Grouped val)
|
||||
{
|
||||
auto ungrouped = to_string_impl<23>(val.val);
|
||||
|
||||
InplaceString<23> res;
|
||||
for (int pos = 0, len = ungrouped.m_length; pos != len; ++pos)
|
||||
{
|
||||
if (res.m_length and ((len - pos) % 3) == 0)
|
||||
res.m_data[res.m_length++] = ',';
|
||||
res.m_data[res.m_length++] = ungrouped.m_data[pos];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
InplaceString<23> to_string(float val)
|
||||
{
|
||||
#if defined(__cpp_lib_to_chars)
|
||||
return to_string_impl<23>(val, std::chars_format::general);
|
||||
#else
|
||||
InplaceString<23> res;
|
||||
res.m_length = snprintf(res.m_data, 23, "%f", val);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
InplaceString<7> to_string(Codepoint c)
|
||||
{
|
||||
InplaceString<7> res;
|
||||
char* ptr = res.m_data;
|
||||
utf8::dump(ptr, c);
|
||||
res.m_length = (int)(ptr - res.m_data);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool subsequence_match(StringView str, StringView subseq)
|
||||
{
|
||||
auto it = str.begin();
|
||||
@ -327,92 +245,6 @@ WrapView::Iterator& WrapView::Iterator::operator++()
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename AppendFunc>
|
||||
void format_impl(StringView fmt, ArrayView<const StringView> params, AppendFunc append)
|
||||
{
|
||||
int implicitIndex = 0;
|
||||
for (auto it = fmt.begin(), end = fmt.end(); it != end;)
|
||||
{
|
||||
auto opening = std::find(it, end, '{');
|
||||
if (opening == end)
|
||||
{
|
||||
append(StringView{it, opening});
|
||||
break;
|
||||
}
|
||||
else if (opening != it and *(opening-1) == '\\')
|
||||
{
|
||||
append(StringView{it, opening-1});
|
||||
append('{');
|
||||
it = opening + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
append(StringView{it, opening});
|
||||
auto closing = std::find(opening, end, '}');
|
||||
if (closing == end)
|
||||
throw runtime_error("format string error, unclosed '{'");
|
||||
|
||||
auto format = std::find(opening+1, closing, ':');
|
||||
const int index = opening+1 == format ? implicitIndex : str_to_int({opening+1, format});
|
||||
|
||||
if (index >= params.size())
|
||||
throw runtime_error("format string parameter index too big");
|
||||
|
||||
if (format != closing)
|
||||
{
|
||||
char padding = ' ';
|
||||
if (*(++format) == '0')
|
||||
{
|
||||
padding = '0';
|
||||
++format;
|
||||
}
|
||||
for (ColumnCount width = str_to_int({format, closing}), len = params[index].column_length();
|
||||
width > len; --width)
|
||||
append(padding);
|
||||
}
|
||||
|
||||
append(params[index]);
|
||||
implicitIndex = index+1;
|
||||
it = closing+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
char* ptr = buffer.begin();
|
||||
const char* end = buffer.end();
|
||||
format_impl(fmt, params, [&](StringView s) mutable {
|
||||
for (auto c : s)
|
||||
{
|
||||
if (ptr == end)
|
||||
throw runtime_error("buffer is too small");
|
||||
*ptr++ = c;
|
||||
}
|
||||
});
|
||||
if (ptr == end)
|
||||
throw runtime_error("buffer is too small");
|
||||
*ptr = 0;
|
||||
|
||||
return { buffer.begin(), ptr };
|
||||
}
|
||||
|
||||
void format_with(FunctionRef<void (StringView)> append, StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
format_impl(fmt, params, append);
|
||||
}
|
||||
|
||||
String format(StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
ByteCount size = fmt.length();
|
||||
for (auto& s : params) size += s.length();
|
||||
String res;
|
||||
res.reserve(size);
|
||||
|
||||
format_impl(fmt, params, [&](StringView s) { res += s; });
|
||||
return res;
|
||||
}
|
||||
|
||||
String double_up(StringView s, StringView characters)
|
||||
{
|
||||
String res;
|
||||
|
@ -4,9 +4,10 @@
|
||||
#include "string.hh"
|
||||
#include "enum.hh"
|
||||
#include "vector.hh"
|
||||
#include "ranges.hh"
|
||||
#include "optional.hh"
|
||||
#include "utils.hh"
|
||||
#include "format.hh"
|
||||
#include "ranges.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
@ -107,75 +108,6 @@ inline auto wrap_at(ColumnCount max_width)
|
||||
int str_to_int(StringView str); // throws on error
|
||||
Optional<int> str_to_int_ifp(StringView str);
|
||||
|
||||
template<size_t N>
|
||||
struct InplaceString
|
||||
{
|
||||
static_assert(N < 256, "InplaceString cannot handle sizes >= 256");
|
||||
|
||||
constexpr operator StringView() const { return {m_data, ByteCount{m_length}}; }
|
||||
operator String() const { return {m_data, ByteCount{m_length}}; }
|
||||
|
||||
unsigned char m_length{};
|
||||
char m_data[N];
|
||||
};
|
||||
|
||||
struct Hex { size_t val; };
|
||||
constexpr Hex hex(size_t val) { return {val}; }
|
||||
|
||||
struct Grouped { size_t val; };
|
||||
constexpr Grouped grouped(size_t val) { return {val}; }
|
||||
|
||||
InplaceString<15> to_string(int val);
|
||||
InplaceString<15> to_string(unsigned val);
|
||||
InplaceString<23> to_string(long int val);
|
||||
InplaceString<23> to_string(unsigned long val);
|
||||
InplaceString<23> to_string(long long int val);
|
||||
InplaceString<23> to_string(Hex val);
|
||||
InplaceString<23> to_string(Grouped val);
|
||||
InplaceString<23> to_string(float val);
|
||||
InplaceString<7> to_string(Codepoint c);
|
||||
|
||||
template<typename RealType, typename ValueType>
|
||||
decltype(auto) to_string(const StronglyTypedNumber<RealType, ValueType>& val)
|
||||
{
|
||||
return to_string((ValueType)val);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename T> requires std::is_convertible_v<T, StringView>
|
||||
StringView format_param(const T& val) { return val; }
|
||||
|
||||
template<typename T> requires (not std::is_convertible_v<T, StringView>)
|
||||
decltype(auto) format_param(const T& val) { return to_string(val); }
|
||||
|
||||
}
|
||||
|
||||
String format(StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
String format(StringView fmt, Types&&... params)
|
||||
{
|
||||
return format(fmt, ArrayView<const StringView>{detail::format_param(std::forward<Types>(params))...});
|
||||
}
|
||||
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, Types&&... params)
|
||||
{
|
||||
return format_to(buffer, fmt, ArrayView<const StringView>{detail::format_param(std::forward<Types>(params))...});
|
||||
}
|
||||
|
||||
void format_with(FunctionRef<void (StringView)> append, StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
void format_with(FunctionRef<void (StringView)> append, StringView fmt, Types&&... params)
|
||||
{
|
||||
return format_with(append, fmt, ArrayView<const StringView>{detail::format_param(std::forward<Types>(params))...});
|
||||
}
|
||||
|
||||
String double_up(StringView s, StringView characters);
|
||||
|
||||
inline String quote(StringView s)
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "file.hh"
|
||||
#include "keys.hh"
|
||||
#include "ranges.hh"
|
||||
#include "string_utils.hh"
|
||||
#include "format.hh"
|
||||
#include "diff.hh"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <cwchar>
|
||||
|
||||
#include "array_view.hh"
|
||||
#include "ranges.hh"
|
||||
#include "units.hh"
|
||||
|
||||
namespace Kakoune
|
||||
@ -75,8 +74,12 @@ enum WordType { Word, WORD };
|
||||
template<WordType word_type = Word>
|
||||
inline bool is_word(Codepoint c, ConstArrayView<Codepoint> extra_word_chars = {'_'}) noexcept
|
||||
{
|
||||
return (c < 128 ? is_basic_alpha(c) or is_basic_digit(c) : iswalnum((wchar_t)c)) or
|
||||
contains(extra_word_chars, c);
|
||||
if (c < 128 ? is_basic_alpha(c) or is_basic_digit(c) : iswalnum((wchar_t)c))
|
||||
return true;
|
||||
for (auto cp : extra_word_chars)
|
||||
if (c == cp)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -1,13 +1,15 @@
|
||||
#include "window.hh"
|
||||
|
||||
#include "assert.hh"
|
||||
#include "buffer.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "clock.hh"
|
||||
#include "context.hh"
|
||||
#include "highlighter.hh"
|
||||
#include "hook_manager.hh"
|
||||
#include "input_handler.hh"
|
||||
#include "client.hh"
|
||||
#include "buffer_utils.hh"
|
||||
#include "debug.hh"
|
||||
#include "option.hh"
|
||||
#include "option_types.hh"
|
||||
#include "profile.hh"
|
||||
|
@ -1,10 +1,8 @@
|
||||
ui_out -ignore 7
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'
|
||||
exec 5>fifo
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'
|
||||
|
||||
printf '* noeol' >&5
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " noeol\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -ignore 2
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " noeol\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
|
||||
exec 5>&-
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "*fifo* 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "[scratch]" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "*fifo* 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "[scratch]" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
|
@ -2,11 +2,11 @@ ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'
|
||||
exec 5>fifo
|
||||
|
||||
echo '* line1' >&5
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " line1\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " line1\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'
|
||||
|
||||
echo '* line2' >&5
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " line1\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "* line2\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "*" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " line1\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "* line2\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'
|
||||
|
||||
dd if=/dev/zero bs=2049 count=1 2>/dev/null | sed s/././g >&5
|
||||
|
@ -1,6 +1,4 @@
|
||||
ui_out -ignore 7
|
||||
ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ ":my-command " ] }'
|
||||
ui_out -ignore 6
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "menu_show", "params": [[[{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "aaa" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "bbb" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "ccc" }]], { "line": 0, "column": 0 }, { "fg": "white", "bg": "blue", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "white", "underline": "default", "attributes": [] }, "prompt"] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "menu_show", "params": [[[{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "aaa" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "bbb" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "ccc" }]], { "line": 0, "column": 0 }, { "fg": "white", "bg": "blue", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "white", "underline": "default", "attributes": [] }, "prompt"] }'
|
||||
ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "<s-tab><ret>" ] }'
|
||||
|
@ -1,15 +1,4 @@
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "0" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "02\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "03\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "04\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "05\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "06\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "07\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "08\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "09\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "10\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "11\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "12\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "13\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "14\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "15\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "16\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "17\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "18\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "19\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "20\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "21\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "22\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "23\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "24\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "out 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 0 }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "underline": "default", "attributes": [] }, "contents": "0" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "02\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "03\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "04\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "05\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "06\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "07\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "08\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "09\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "10\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "11\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "12\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "13\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "14\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "15\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "16\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "17\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "18\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "19\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "20\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "21\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "22\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "23\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "24\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'
|
||||
ui_in '{ "jsonrpc": "2.0", "method": "scroll", "params": [ 2 ] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "03\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "04\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "05\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "06\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "07\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "08\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "09\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "10\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "11\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "12\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "13\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "14\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "15\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "16\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "17\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "18\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "19\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "20\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "21\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "22\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "23\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "24\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "25\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "26\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 0 }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "out 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "underline": "default", "attributes": [] }, "contents": "" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 0 }] }'
|
||||
ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'
|
||||
ui_out -until '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "03\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "04\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "05\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "06\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "07\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "08\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "09\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "10\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "11\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "12\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "13\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "14\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "15\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "16\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "17\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "18\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "19\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "20\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "21\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "22\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "23\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "24\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "25\u000a" }], [{ "face": { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, "contents": "26\u000a" }]], { "fg": "default", "bg": "default", "underline": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "underline": "default", "attributes": [] }] }'
|
||||
|
Loading…
Reference in New Issue
Block a user