Выделить блок кода под курсором? - PullRequest
2 голосов
/ 18 ноября 2009

Я ищу способ выделить блок кода, находящийся в данный момент под курсором в обычном режиме.

Это будет работать примерно так же, как параметры конфигурации set showmatch, но обнаружение и выделение будут охватывать весь блок.

Есть ли способ реализовать эту функцию с помощью параметров конфигурации или (желательно существующих) сценариев?

1 Ответ

1 голос
/ 18 ноября 2009

Краткий ответ: нет.

Длинный ответ: есть способы достичь этого, но вам придется пожертвовать множеством других довольно важных функций выделения.

Конечно, нет способа сделать это с простой опцией. Проблема, с которой вы можете столкнуться, состоит в том, что Vim не допускает перекрывающихся областей, поэтому если у вас установлен rainbow.vim или что-то еще, что делает область в области вашего блока, она теряется. Также сложно (хотя я бы приветствовал любые исправления) иметь несколько выделенных групп, так что одна устанавливает цвет фона, а другая - основной. Это очень ограниченно, как вы увидите.

Однако, если хотите поиграть, продолжайте читать.

Я предполагаю, что вы используете код C в том же стиле кодирования, что и я, но это легко можно изменить ...

Вот простая функция, которая должна помочь показать вам, что с этим связано:

function! HighlightBlock()
    " Search backwards and forwards for an opening and closing brace
    " at the start of the line (change this according to your coding
    " style or how you define a block).
    let startmatch = search('^{', 'bcnW')
    let endmatch = search('^}', 'cnW')

    " Search in the other direction for each to catch the situation
    " where we're in between blocks.
    let checkstart = search('^{', 'cnW')
    let checkend = search('^}', 'bcnW')

    " Clear BlockRegion if it exists already (requires Vim 7 probably)
    try
        syn clear BlockRegion
    catch
    endtry

    " If we're not in a block, give up
    if ((startmatch < checkstart) && (endmatch > checkstart))
                \ || ((startmatch < checkend) && (endmatch > checkend))
                \ || (startmatch == 0)
                \ || (endmatch == 0)
        return
    endif

    " Create a new syntax region called "BlockRegion" that starts
    " on the specific lines found above (see :help \%l for more 
    " information).
    exec 'syn region BlockRegion'
                \ 'start=' . '"\%' . startmatch . 'l"'
                \ 'end='   . '"\%' . (endmatch+1)   . 'l"'

    " Add "contains=ALL" onto the end for a different way of 
    " highlighting, but it's not much better...

    " Define the colours - not an ideal place to do this,
    " but good for an example
    if &background == 'light'
        hi default BlockRegion guibg='#AAAAAA'
    else
        hi default BlockRegion guibg='#333333'
    endif

endfunction

Чтобы использовать функцию, найдите ее откуда-то, а затем создайте autocmd, чтобы вызывать ее всякий раз, когда что-то меняется, например,

au CursorMoved *.c call HighlightBlock()

Ниже приведены некоторые автокоманды, которые вы можете рассмотреть:

:help CursorHold
:help CursorHoldI
:help CursorMoved
:help CursorMovedI
...