Initial support for user configurable modeline with the modelinefmt option

modelinefmt is first sent through a command line expander (so %sh{...},
%val{...} et al. are expanded), then through markup expand (so that
{face} are interpreted as well)
This commit is contained in:
Maxime Coste 2015-09-19 12:43:39 +01:00
parent 6bc5f8c3a3
commit f59108072f
3 changed files with 29 additions and 16 deletions

View File

@ -3,10 +3,12 @@
#include "face_registry.hh" #include "face_registry.hh"
#include "context.hh" #include "context.hh"
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh"
#include "user_interface.hh" #include "user_interface.hh"
#include "file.hh" #include "file.hh"
#include "remote.hh" #include "remote.hh"
#include "client_manager.hh" #include "client_manager.hh"
#include "command_manager.hh"
#include "event_manager.hh" #include "event_manager.hh"
#include "window.hh" #include "window.hh"
@ -97,30 +99,39 @@ void Client::print_status(DisplayLine status_line)
DisplayLine Client::generate_mode_line() const DisplayLine Client::generate_mode_line() const
{ {
auto pos = context().selections().main().cursor(); Face status_face = get_face("StatusLine");
auto col = context().buffer()[pos.line].char_count_to(pos.column);
DisplayLine modeline;
try
{
const String& modelinefmt = context().options()["modelinefmt"].get<String>();
modeline = parse_display_line(expand(modelinefmt, context()), status_face);
}
catch (runtime_error& err)
{
write_to_debug_buffer(format("Error while parsing modelinefmt: {}", err.what()));
modeline.push_back({ "modelinefmt error, see *debug* buffer", get_face("Error") });
}
DisplayLine status;
Face info_face = get_face("Information"); Face info_face = get_face("Information");
status.push_back({ context().buffer().display_name() });
status.push_back({ format(" {}:{} ", pos.line+1, col+1) });
if (context().buffer().is_modified()) if (context().buffer().is_modified())
status.push_back({ "[+]", info_face }); modeline.push_back({ "[+]", info_face });
if (m_input_handler.is_recording()) if (m_input_handler.is_recording())
status.push_back({ format("[recording ({})]", m_input_handler.recording_reg()), info_face }); modeline.push_back({ format("[recording ({})]", m_input_handler.recording_reg()), info_face });
if (context().buffer().flags() & Buffer::Flags::New) if (context().buffer().flags() & Buffer::Flags::New)
status.push_back({ "[new file]", info_face }); modeline.push_back({ "[new file]", info_face });
if (context().user_hooks_disabled()) if (context().user_hooks_disabled())
status.push_back({ "[no-hooks]", info_face }); modeline.push_back({ "[no-hooks]", info_face });
if (context().buffer().flags() & Buffer::Flags::Fifo) if (context().buffer().flags() & Buffer::Flags::Fifo)
status.push_back({ "[fifo]", info_face }); modeline.push_back({ "[fifo]", info_face });
status.push_back({ " " }); modeline.push_back({ " " });
for (auto& atom : m_input_handler.mode_line()) for (auto& atom : m_input_handler.mode_line())
status.push_back(std::move(atom)); modeline.push_back(std::move(atom));
status.push_back({ format(" - {}@[{}]", context().name(), Server::instance().session()) }); modeline.push_back({ format(" - {}@[{}]", context().name(), Server::instance().session()) });
return status; return modeline;
} }
void Client::change_buffer(Buffer& buffer) void Client::change_buffer(Buffer& buffer)

View File

@ -104,8 +104,8 @@ private:
}; };
String expand(StringView str, const Context& context, String expand(StringView str, const Context& context,
ConstArrayView<String> shell_params, ConstArrayView<String> shell_params = {},
const EnvVarMap& env_vars); const EnvVarMap& env_vars = EnvVarMap{});
} }

View File

@ -229,6 +229,8 @@ void register_options()
"colon separated list of <key>=<value> options that are" "colon separated list of <key>=<value> options that are"
"passed to and interpreted by the user interface", "passed to and interpreted by the user interface",
UserInterface::Options{}); UserInterface::Options{});
reg.declare_option("modelinefmt", "format string used to generate the modeline",
"%val{bufname} %val{cursor_line}:%val{cursor_char_column} "_str);
} }
std::unique_ptr<UserInterface> create_local_ui(bool dummy_ui) std::unique_ptr<UserInterface> create_local_ui(bool dummy_ui)