mirror of
https://github.com/mawww/kakoune.git
synced 2024-11-27 12:16:22 +03:00
Increase modelinefmt configuration power
This commit is contained in:
parent
b9317ba38c
commit
5a403a9611
@ -970,7 +970,10 @@ Some options are built in Kakoune, and can be used to control it's behaviour:
|
||||
on the filesystem.
|
||||
* `modelinefmt` _string_: A format string used to generate the mode line, that
|
||||
string is first expanded as a command line would be (expanding `%...{...}`
|
||||
strings), then markup tags are applied (see <<Markup strings>>).
|
||||
strings), then markup tags are applied (see <<Markup strings>>). Two special
|
||||
atom are available as markup: `{{mode_info}}` with information about the current
|
||||
mode (example `insert 3 sel`), and `{{context_info}}` with information such as
|
||||
if the file has been modified (with `[+]`), or if it is new (with `[new file]`).
|
||||
* `ui_options`: colon separated list of key=value pairs that are forwarded to
|
||||
the user interface implementation. The NCurses UI support the following options:
|
||||
- `ncurses_set_title`: if `yes` or `true`, the terminal emulator title will
|
||||
|
@ -137,7 +137,19 @@ Builtin options
|
||||
*modelinefmt* 'string'::
|
||||
A format string used to generate the mode line, that string is first
|
||||
expanded as a command line would be (expanding '%...{...}' strings),
|
||||
then markup tags are applied (c.f. the 'Expansions' documentation page)
|
||||
then markup tags are applied (c.f. the 'Expansions' documentation page.)
|
||||
Two special atoms are available as markup:
|
||||
|
||||
*`{{mode_info}}`*:::
|
||||
Information about the current mode, such as `insert 3 sel` or
|
||||
`prompt`. The faces used are StatusLineMode, StatusLineInfo,
|
||||
and StatusLineValue.
|
||||
|
||||
*`{{context_info}}`*:::
|
||||
Information such as `[+][recording (@)][no-hooks][new file][fifo]`,
|
||||
in face Information.
|
||||
|
||||
The default value is '%val{bufname} %val{cursor_line}:%val{cursor_char_column} {{context_info}} {{mode_info}} - %val{client}@[%val{session}]'
|
||||
|
||||
*ui_options*::
|
||||
colon separated list of key=value pairs that are forwarded to the user
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "event_manager.hh"
|
||||
#include "user_interface.hh"
|
||||
#include "window.hh"
|
||||
#include "hash_map.hh"
|
||||
|
||||
#include <csignal>
|
||||
#include <unistd.h>
|
||||
@ -117,15 +118,33 @@ DisplayCoord Client::dimensions() const
|
||||
return m_ui->dimensions();
|
||||
}
|
||||
|
||||
String generate_context_info(const Context& context)
|
||||
{
|
||||
String s = "";
|
||||
if (context.buffer().is_modified())
|
||||
s += "[+]";
|
||||
if (context.client().input_handler().is_recording())
|
||||
s += format("[recording ({})]", context.client().input_handler().recording_reg());
|
||||
if (context.buffer().flags() & Buffer::Flags::New)
|
||||
s += "[new file]";
|
||||
if (context.hooks_disabled())
|
||||
s += "[no-hooks]";
|
||||
if (context.buffer().flags() & Buffer::Flags::Fifo)
|
||||
s += "[fifo]";
|
||||
return s;
|
||||
}
|
||||
|
||||
DisplayLine Client::generate_mode_line() const
|
||||
{
|
||||
DisplayLine modeline;
|
||||
try
|
||||
{
|
||||
const String& modelinefmt = context().options()["modelinefmt"].get<String>();
|
||||
|
||||
modeline = parse_display_line(expand(modelinefmt, context(), ShellContext{},
|
||||
[](String s) { return escape(s, '{', '\\'); }));
|
||||
HashMap<String, DisplayLine> atoms{{ "mode_info", context().client().input_handler().mode_line() },
|
||||
{ "context_info", {generate_context_info(context()), get_face("Information")}}};
|
||||
auto expanded = expand(modelinefmt, context(), ShellContext{},
|
||||
[](String s) { return escape(s, '{', '\\'); });
|
||||
modeline = parse_display_line(expanded, atoms);
|
||||
}
|
||||
catch (runtime_error& err)
|
||||
{
|
||||
@ -133,23 +152,6 @@ DisplayLine Client::generate_mode_line() const
|
||||
modeline.push_back({ "modelinefmt error, see *debug* buffer", get_face("Error") });
|
||||
}
|
||||
|
||||
Face info_face = get_face("Information");
|
||||
|
||||
if (context().buffer().is_modified())
|
||||
modeline.push_back({ "[+]", info_face });
|
||||
if (m_input_handler.is_recording())
|
||||
modeline.push_back({ format("[recording ({})]", m_input_handler.recording_reg()), info_face });
|
||||
if (context().buffer().flags() & Buffer::Flags::New)
|
||||
modeline.push_back({ "[new file]", info_face });
|
||||
if (context().hooks_disabled())
|
||||
modeline.push_back({ "[no-hooks]", info_face });
|
||||
if (context().buffer().flags() & Buffer::Flags::Fifo)
|
||||
modeline.push_back({ "[fifo]", info_face });
|
||||
modeline.push_back({ " " });
|
||||
for (auto& atom : m_input_handler.mode_line())
|
||||
modeline.push_back(std::move(atom));
|
||||
modeline.push_back({ format(" - {}@[{}]", context().name(), Server::instance().session()) });
|
||||
|
||||
return modeline;
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ void DisplayBuffer::optimize()
|
||||
line.optimize();
|
||||
}
|
||||
|
||||
DisplayLine parse_display_line(StringView line)
|
||||
DisplayLine parse_display_line(StringView line, const HashMap<String, DisplayLine>& builtins)
|
||||
{
|
||||
DisplayLine res;
|
||||
bool was_antislash = false;
|
||||
@ -312,7 +312,18 @@ DisplayLine parse_display_line(StringView line)
|
||||
auto closing = std::find(it+1, end, '}');
|
||||
if (closing == end)
|
||||
throw runtime_error("unclosed face definition");
|
||||
face = get_face({it+1, closing});
|
||||
if (*(it+1) == '{' and closing+1 != end and *(closing+1) == '}')
|
||||
{
|
||||
auto builtin_it = builtins.find(StringView{it+2, closing});
|
||||
if (builtin_it == builtins.end())
|
||||
throw runtime_error(format("undefined atom {}", StringView{it+2, closing}));
|
||||
for (auto& atom : builtin_it->value)
|
||||
res.push_back(atom);
|
||||
// closing is now at the first char of "}}", advance it to the second
|
||||
++closing;
|
||||
}
|
||||
else
|
||||
face = get_face({it+1, closing});
|
||||
it = closing;
|
||||
pos = closing + 1;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "coord.hh"
|
||||
#include "string.hh"
|
||||
#include "vector.hh"
|
||||
#include "hash_map.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
@ -143,7 +144,7 @@ private:
|
||||
AtomList m_atoms;
|
||||
};
|
||||
|
||||
DisplayLine parse_display_line(StringView line);
|
||||
DisplayLine parse_display_line(StringView line, const HashMap<String, DisplayLine>& builtins = {});
|
||||
|
||||
class DisplayBuffer : public UseMemoryDomain<MemoryDomain::Display>
|
||||
{
|
||||
|
10
src/main.cc
10
src/main.cc
@ -43,7 +43,9 @@ static const char* startup_info =
|
||||
" * The `identifier` face has been replaced with `variable`,\n"
|
||||
" `function` and `module`, update your custom colorschemes\n"
|
||||
" * BufNew and BufOpen hooks have been renamed to BufNewFile\n"
|
||||
" and BufOpenFile.\n";
|
||||
" and BufOpenFile.\n"
|
||||
" * The status line can be further customized.\n"
|
||||
" See `help options modelinefmt`.\n";
|
||||
|
||||
struct startup_error : runtime_error
|
||||
{
|
||||
@ -154,7 +156,8 @@ void register_env_vars()
|
||||
"window_height", false,
|
||||
[](StringView name, const Context& context) -> String
|
||||
{ return to_string(context.window().dimensions().line); }
|
||||
} };
|
||||
}
|
||||
};
|
||||
|
||||
ShellManager& shell_manager = ShellManager::instance();
|
||||
for (auto& env_var : env_vars)
|
||||
@ -306,7 +309,8 @@ void register_options()
|
||||
" ncurses_wheel_down_button int\n",
|
||||
UserInterface::Options{});
|
||||
reg.declare_option("modelinefmt", "format string used to generate the modeline",
|
||||
"%val{bufname} %val{cursor_line}:%val{cursor_char_column} "_str);
|
||||
"%val{bufname} %val{cursor_line}:%val{cursor_char_column} {{context_info}} {{mode_info}} - %val{client}@[%val{session}]"_str);
|
||||
|
||||
reg.declare_option("debug", "various debug flags", DebugFlags::None);
|
||||
reg.declare_option("readonly", "prevent buffers from being modified", false);
|
||||
reg.declare_option<String, check_extra_word_char>(
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "\"" }, { "face": { "fg": "green", "bg": "default", "attributes": [] }, "contents": "abcdefgh\"" }, { "face": { "fg": "yellow", "bg": "default", "attributes": [] }, "contents": " hehe " }, { "face": { "fg": "red", "bg": "default", "attributes": [] }, "contents": "${ youhou{hihi} }" }, { "face": { "fg": "yellow", "bg": "default", "attributes": [] }, "contents": "\u000a" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
||||
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
||||
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:1 " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - unnamed0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - unnamed0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||
{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "red", "bg": "default", "attributes": [] }, "contents": "“" }, { "face": { "fg": "white", "bg": "blue", "attributes": [] }, "contents": "We" }, { "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "ought to scrape this planet clean of every living thing on it," }, { "face": { "fg": "red", "bg": "default", "attributes": [] }, "contents": "”" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "\u000a" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
|
||||
{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
|
||||
{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
|
||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:4 " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - unnamed0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||
{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:4 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - unnamed0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
|
||||
{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }
|
||||
|
Loading…
Reference in New Issue
Block a user