diff --git a/src/client.cc b/src/client.cc index 38cc7d89..fa7b6d38 100644 --- a/src/client.cc +++ b/src/client.cc @@ -3,10 +3,12 @@ #include "face_registry.hh" #include "context.hh" #include "buffer_manager.hh" +#include "buffer_utils.hh" #include "user_interface.hh" #include "file.hh" #include "remote.hh" #include "client_manager.hh" +#include "command_manager.hh" #include "event_manager.hh" #include "window.hh" @@ -97,30 +99,39 @@ void Client::print_status(DisplayLine status_line) DisplayLine Client::generate_mode_line() const { - auto pos = context().selections().main().cursor(); - auto col = context().buffer()[pos.line].char_count_to(pos.column); + Face status_face = get_face("StatusLine"); + + DisplayLine modeline; + try + { + const String& modelinefmt = context().options()["modelinefmt"].get(); + + 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"); - status.push_back({ context().buffer().display_name() }); - status.push_back({ format(" {}:{} ", pos.line+1, col+1) }); if (context().buffer().is_modified()) - status.push_back({ "[+]", info_face }); + modeline.push_back({ "[+]", info_face }); 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) - status.push_back({ "[new file]", info_face }); + modeline.push_back({ "[new file]", info_face }); 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) - status.push_back({ "[fifo]", info_face }); - status.push_back({ " " }); + modeline.push_back({ "[fifo]", info_face }); + modeline.push_back({ " " }); for (auto& atom : m_input_handler.mode_line()) - status.push_back(std::move(atom)); - status.push_back({ format(" - {}@[{}]", context().name(), Server::instance().session()) }); + modeline.push_back(std::move(atom)); + modeline.push_back({ format(" - {}@[{}]", context().name(), Server::instance().session()) }); - return status; + return modeline; } void Client::change_buffer(Buffer& buffer) diff --git a/src/command_manager.hh b/src/command_manager.hh index ee71ea2b..9592bce6 100644 --- a/src/command_manager.hh +++ b/src/command_manager.hh @@ -104,8 +104,8 @@ private: }; String expand(StringView str, const Context& context, - ConstArrayView shell_params, - const EnvVarMap& env_vars); + ConstArrayView shell_params = {}, + const EnvVarMap& env_vars = EnvVarMap{}); } diff --git a/src/main.cc b/src/main.cc index 938097ce..2582a294 100644 --- a/src/main.cc +++ b/src/main.cc @@ -229,6 +229,8 @@ void register_options() "colon separated list of = options that are" "passed to and interpreted by the user interface", 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 create_local_ui(bool dummy_ui)