Skip to content
ismay edited this page Apr 19, 2024 · 8 revisions

%opt{modelinefmt} is used to set what info are displayed in the right part of the status line.

By default it has the following value: %val{bufname} %val{cursor_line}:%val{cursor_char_column} {{context_info}} {{mode_info}} - %val{client}@[%val{session}]

The {{context_info}} placeholder displays hard-coded info:

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.hooks_disabled())
        s += "[no-hooks]";
    if (not(context.buffer().flags() & (Buffer::Flags::File | Buffer::Flags::Debug)))
        s += "[scratch]";
    if (context.buffer().flags() & Buffer::Flags::New)
        s += "[new file]";
    if (context.buffer().flags() & Buffer::Flags::Fifo)
        s += "[fifo]";
    if (context.buffer().flags() & Buffer::Flags::Debug)
        s += "[debug]";
    return s;
}

The {{mode_info}} placeholder also displays hard-coded info, depending of the current mode:

DisplayLine mode_line() const override
{
    AtomList atoms;
    auto num_sel = context().selections().size();
    auto main_index = context().selections().main_index();
    if (num_sel == 1)
        atoms.emplace_back(format("{} sel", num_sel), context().faces()["StatusLineInfo"]);
    else
        atoms.emplace_back(format("{} sels ({})", num_sel, main_index + 1), context().faces()["StatusLineInfo"]);

    if (m_params.count != 0)
    {
        atoms.emplace_back(" param=", context().faces()["StatusLineInfo"]);
        atoms.emplace_back(to_string(m_params.count), context().faces()["StatusLineValue"]);
    }
    if (m_params.reg)
    {
        atoms.emplace_back(" reg=", context().faces()["StatusLineInfo"]);
        atoms.emplace_back(StringView(m_params.reg).str(), context().faces()["StatusLineValue"]);
    }
    return atoms;
}

Examples

Here's some simple things you might want to include in your status line.

The current date and time

The modeline is regularly updated, so:

set global modelinefmt '%sh{date}'

will display the current date with elapsing seconds.

Codepoint of the character under the cursor

Many Unicode characters are quite similar, and it can be difficult to tell at a glance whether the character you're looking at is (say) U+0027 APOSTROPHE or U+2019 RIGHT SINGLE QUOTE. If you display the codepoint of the character under the cursor in the status bar, even if you don't recognise the specific code-point, at least you've got a specific value you can look up.

set global modelinefmt 'U+%sh{printf "%04x" "$kak_cursor_char_value"}'

An alternative available as a command could be:

# char command, like :char from helix.
define-command char %{
    echo %sh{
        ch=$(printf "\\$(printf '%03o' "$kak_cursor_char_value")")
        printf '"%s" (U+%04X) Dec %d Hex %02X\n' "$ch" "$kak_cursor_char_value" "$kak_cursor_char_value" "$kak_cursor_char_value"
    }
}

How many buffers are currently open:

set-option -add global modelinefmt '%sh{printf "﬘->%s"  $(printf %s\\n $kak_buflist |wc -w) }'

$kak_buflist is a string with all the buffers separated by spaces. wc -w will count these. Usually starts with 2, as *debug* buffer also listed in $kak_buflist.

Cursor position as a percentage of the whole file

To show the relative position of the cursor in percent using wc:

decl str modeline_pos_percent

hook global WinCreate .* %{
    hook window NormalIdle .* %{ %sh{
        if [ -f "${kak_buffile}" ]; then
            echo "set window modeline_pos_percent '$(($kak_cursor_line * 100 / $(wc -l < $kak_buffile)))'"
        else
            echo "
                eval -save-regs 'm' %{
                    exec -draft '%<a-s>:reg m %reg{#}<ret>'
                    set window modeline_pos_percent %sh{echo \$((\$kak_cursor_line * 100 / \$kak_reg_m))}
                }
            "
        fi
    } }
}

Git branch integration

Here's an example on how to add more info to the modeline, like the current git branch.

##
## git-branch.kak by lenormf
## Store the current git branch that contains the buffer
##

declare-option -docstring "name of the git branch holding the current buffer" \
    str modeline_git_branch

hook global WinCreate .* %{
    hook window NormalIdle .* %{ evaluate-commands %sh{
        branch=$(cd "$(dirname "${kak_buffile}")" && git rev-parse --abbrev-ref HEAD 2>/dev/null)
        if [ -n "${branch}" ]; then
            printf 'set window modeline_git_branch %%{%s}' "${branch}"
        fi
    } }
}

The git-branch.kak file is from lenormf here. You can use option in your modelinefmt with something like the following hook

hook global WinCreate .* %{ evaluate-commands %sh{
    is_work_tree=$(cd "$(dirname "${kak_buffile}")" && git rev-parse --is-inside-work-tree 2>/dev/null)
    if [ "${is_work_tree}" = 'true' ]; then
        printf 'set-option window modelinefmt %%{%s}' " %opt{modeline_git_branch} ${kak_opt_modelinefmt}"
    fi 
}}

You can use this strategy to add many different custom modules to your modelinefmt easily.

Clone this wiki locally