autoload/display.vim

Don’t limit ourselves to plain ASCII encoding:

scriptencoding utf-8

Enforce vim script implementation to reduce ambiguities and improve robustness:

scriptversion 4
add_line_highlight() None

Highlight line.

highlight link LineHighlightPrefix Search
highlight link LineHighlightText Visual
function! display#add_line_highlight() abort
    if !exists('w:line_highlights')
        let w:line_highlights = []
    endif
    if getline('.')[0] =~# '\s'
        let w:line_highlights += [
        \   matchadd('LineHighlightPrefix',
        \            printf('\%%%dl^\s\+', line('.')), 1'000),
        \ ]
    endif
    let w:line_highlights += [
    \   matchadd('LineHighlightText',
    \            printf('\%%%dl^\s*\zs.*$', line('.')), 1'000),
    \ ]
endfunction
clear_line_highlights() None

Clear highlights created by add_line_highlight()

function! display#clear_line_highlights() abort
    for l:id in w:line_highlights
        call matchdelete(l:id)
    endfor
    unlet w:line_highlights
endfunction
command_balloon(cmd: str) List[str]

A helper for simple 'balloonexpr' usage that simply calls an external command.

Parameters

cmd – If string contains %s then it will be replaced with v:beval_text, else v:beval_text is appended

Returns

Command output.

function! display#command_balloon(cmd) abort
    const l:cmd = stridx(a:cmd, '%s') == -1 ? a:cmd .. ' %s' : a:cmd
    return printf(l:cmd, shellescape(v:beval_text))->systemlist()
endfunction
conceal_toggle() None

Toggle conceal on and off.

function! display#conceal_toggle() abort
    if &conceallevel == 0 && get(w:, 'orig_conceallevel')
        let &conceallevel = w:orig_conceallevel
        unlet w:orig_conceallevel
    else
        let w:orig_conceallevel = &conceallevel
        set conceallevel=0
    endif
endfunction
cursor_ping() None

Ping the cursor position.

function! display#cursor_ping() abort
    const [l:cursorline, l:cursorcolumn] = [&cursorline, &cursorcolumn]
    for _ in range(5)
        set cursorline! cursorcolumn!
        redraw
        sleep 15m
    endfor
    let [&cursorline, &cursorcolumn] = [l:cursorline, l:cursorcolumn]
endfunction
fold_text() str

Custom foldtext formatting.

function! s:shorten(text, line_str) abort
    let l:text = a:text
    " Non-getline() text length
    const l:base = 19
    const l:text_width = winwidth(0) - v:foldlevel - len(a:line_str) - l:base
    if strlen(l:text) > l:text_width
        let l:text = l:text[:l:text_width] .. '…'
    endif
    return l:text
endfunction

function! display#fold_text() abort
    return foldtext()->substitute(
    \   '^+-\(-\+\)\s*\(\d\+\) lines: \(.*\)',
    \   {m -> printf('%s %s▼ %d lines', repeat('─', v:foldlevel),
    \                <SID>shorten(m[3], m[2]), m[2])},
    \   ''
    \ )
endfunction

Note

Parsing foldtext() may be brittle, but manual creation is loads of work; whitespace, 'commentstring' RegEx escaping(C for example), 'foldlevel', no scanf(), &c.

get_highlight_group(mark: Optional[str] = '.') List[Dict[str, str]]

Find syntax highlighting in use at the given location.

Parameters

mark – Location to display highlighting information for

Returns

All highlighting rules active at location

function! display#get_highlight_group(mark = '.') abort
    const [l:lnum, l:col] = getpos(a:mark)[1:2]

    const s:synname = {synid -> synIDattr(synid, 'name')}

    let l:groups = []
    for l:id in synstack(l:lnum, l:col)
        let l:groups += [#{
        \   hi: s:synname(l:id),
        \   gr: s:synname(synIDtrans(l:id)),
        \ }]
    endfor
    return l:groups
endfunction
readable_path(filename: str) str

Format filename for user display.

The assumption here is that any file that is within a project need only be specified as such, whereas all other files should show their complete path.

Parameters

filename – Filename to operate on

Returns

Relative filename or full path

function! display#readable_path(filename) abort
    return fnamemodify(a:filename, ':~:.')
endfunction
split_to_right() None

Issue a “shift to right” for a window.

There is an attempt made to ignore this directive when a portrait display can be detected.

function! display#split_to_right() abort
    if has('vertsplit')
        if !exists('g:display_portrait')
            if executable('xdotool')
                silent const [s:width, s:height] =
                \   system('xdotool getdisplaygeometry')->split()->map(
                \       {_, s -> str2nr(s)}
                \   )
                let g:display_portrait = s:width < s:height
            else
                let g:display_portrait = v:none
            endif
        endif
        if g:display_portrait == v:false && winnr('$') > 1
            wincmd L
        endif
    endif
endfunction