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.
|
on the filesystem.
|
||||||
* `modelinefmt` _string_: A format string used to generate the mode line, that
|
* `modelinefmt` _string_: A format string used to generate the mode line, that
|
||||||
string is first expanded as a command line would be (expanding `%...{...}`
|
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
|
* `ui_options`: colon separated list of key=value pairs that are forwarded to
|
||||||
the user interface implementation. The NCurses UI support the following options:
|
the user interface implementation. The NCurses UI support the following options:
|
||||||
- `ncurses_set_title`: if `yes` or `true`, the terminal emulator title will
|
- `ncurses_set_title`: if `yes` or `true`, the terminal emulator title will
|
||||||
|
|
|
@ -137,7 +137,19 @@ Builtin options
|
||||||
*modelinefmt* 'string'::
|
*modelinefmt* 'string'::
|
||||||
A format string used to generate the mode line, that string is first
|
A format string used to generate the mode line, that string is first
|
||||||
expanded as a command line would be (expanding '%...{...}' strings),
|
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*::
|
*ui_options*::
|
||||||
colon separated list of key=value pairs that are forwarded to the user
|
colon separated list of key=value pairs that are forwarded to the user
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
#include "user_interface.hh"
|
#include "user_interface.hh"
|
||||||
#include "window.hh"
|
#include "window.hh"
|
||||||
|
#include "hash_map.hh"
|
||||||
|
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -117,15 +118,33 @@ DisplayCoord Client::dimensions() const
|
||||||
return m_ui->dimensions();
|
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 Client::generate_mode_line() const
|
||||||
{
|
{
|
||||||
DisplayLine modeline;
|
DisplayLine modeline;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const String& modelinefmt = context().options()["modelinefmt"].get<String>();
|
const String& modelinefmt = context().options()["modelinefmt"].get<String>();
|
||||||
|
HashMap<String, DisplayLine> atoms{{ "mode_info", context().client().input_handler().mode_line() },
|
||||||
modeline = parse_display_line(expand(modelinefmt, context(), ShellContext{},
|
{ "context_info", {generate_context_info(context()), get_face("Information")}}};
|
||||||
[](String s) { return escape(s, '{', '\\'); }));
|
auto expanded = expand(modelinefmt, context(), ShellContext{},
|
||||||
|
[](String s) { return escape(s, '{', '\\'); });
|
||||||
|
modeline = parse_display_line(expanded, atoms);
|
||||||
}
|
}
|
||||||
catch (runtime_error& err)
|
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") });
|
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;
|
return modeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ void DisplayBuffer::optimize()
|
||||||
line.optimize();
|
line.optimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayLine parse_display_line(StringView line)
|
DisplayLine parse_display_line(StringView line, const HashMap<String, DisplayLine>& builtins)
|
||||||
{
|
{
|
||||||
DisplayLine res;
|
DisplayLine res;
|
||||||
bool was_antislash = false;
|
bool was_antislash = false;
|
||||||
|
@ -312,7 +312,18 @@ DisplayLine parse_display_line(StringView line)
|
||||||
auto closing = std::find(it+1, end, '}');
|
auto closing = std::find(it+1, end, '}');
|
||||||
if (closing == end)
|
if (closing == end)
|
||||||
throw runtime_error("unclosed face definition");
|
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;
|
it = closing;
|
||||||
pos = closing + 1;
|
pos = closing + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "coord.hh"
|
#include "coord.hh"
|
||||||
#include "string.hh"
|
#include "string.hh"
|
||||||
#include "vector.hh"
|
#include "vector.hh"
|
||||||
|
#include "hash_map.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -143,7 +144,7 @@ private:
|
||||||
AtomList m_atoms;
|
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>
|
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"
|
" * The `identifier` face has been replaced with `variable`,\n"
|
||||||
" `function` and `module`, update your custom colorschemes\n"
|
" `function` and `module`, update your custom colorschemes\n"
|
||||||
" * BufNew and BufOpen hooks have been renamed to BufNewFile\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
|
struct startup_error : runtime_error
|
||||||
{
|
{
|
||||||
|
@ -154,7 +156,8 @@ void register_env_vars()
|
||||||
"window_height", false,
|
"window_height", false,
|
||||||
[](StringView name, const Context& context) -> String
|
[](StringView name, const Context& context) -> String
|
||||||
{ return to_string(context.window().dimensions().line); }
|
{ return to_string(context.window().dimensions().line); }
|
||||||
} };
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ShellManager& shell_manager = ShellManager::instance();
|
ShellManager& shell_manager = ShellManager::instance();
|
||||||
for (auto& env_var : env_vars)
|
for (auto& env_var : env_vars)
|
||||||
|
@ -306,7 +309,8 @@ void register_options()
|
||||||
" ncurses_wheel_down_button int\n",
|
" ncurses_wheel_down_button int\n",
|
||||||
UserInterface::Options{});
|
UserInterface::Options{});
|
||||||
reg.declare_option("modelinefmt", "format string used to generate the modeline",
|
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("debug", "various debug flags", DebugFlags::None);
|
||||||
reg.declare_option("readonly", "prevent buffers from being modified", false);
|
reg.declare_option("readonly", "prevent buffers from being modified", false);
|
||||||
reg.declare_option<String, check_extra_word_char>(
|
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": "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": "menu_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "info_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] }
|
{ "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": "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": "menu_hide", "params": [] }
|
||||||
{ "jsonrpc": "2.0", "method": "info_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] }
|
{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user