Проверьте, есть ли текущий активный визуальный выбор в Vim из функции, вызванной командой - PullRequest
7 голосов
/ 30 ноября 2010

Ситуация # 1: я только что выделил блок текста.Затем я набираю «: Command», которая вызывает некоторую функцию.

Ситуация # 2: Текущий визуальный выбор не выполняется (хотя я мог сделать такой выбор ранее в сеансе редактирования).Я набираю «: Command», которая вызывает (ту же самую) функцию.

Есть ли (надежный) способ отличить две вышеупомянутые ситуации от функции?Я пробовал mode(), но проблема в том, что в обоих случаях я нахожусь в командном режиме, хотя в первом случае я попал в командный режим из визуального режима, а во втором - из нормального режима.Может быть, путем проверки a:firstline / a:lastline / v:count?


Обновление - Пример использования: ":Sum".Если имеется текущий визуальный выбор, например, столбец чисел (выбор блока) или диапазон строк, содержащих только цифры, эта команда отобразит сумму чисел.В противном случае он ожидает список разделенных пробелами чисел в качестве аргументов и будет отображать сумму этих чисел.Базовая структура:

command! -nargs="*" -range Sum :call CalcSum(<f-args>)
function! CalcSum(...) range
   " 1. collect numbers from visual selection if there is a current active selection
   " 2. otherwise, if len(args) > 0, collect numbers from args
   " 3. other cases (i.e., no selection and no args or both selection and args) handled reasonably
   " 4. sum collection of numbers
   " 5. return/echo result
endfunction 

Шаги (2) - (5) просты.У меня проблемы с (1).Я использую маркеры "<"/">", чтобы воссоздать коллекцию чисел из визуального выбора.Но я хочу сделать это только , если есть визуальный выбор в настоящее время выделено / активно.

Возможно, вся моя логика неверна и есть лучший способ разработкиэто функциональность?

1 Ответ

6 голосов
/ 30 ноября 2010

Если вам нужно использовать команду, я вижу только способ проверки a:firstline / a:lastline:

" Assuming that you have passed -range=% when defining command
if a:firstline==1 && a:lastline==line('$')
    " Do something
endif

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

function DoCommand()
    if mode()!~#"^[vV\<C-v>]"
        " Do something. For example, set global variable (and unset it in :Command)
    endif
    return ':Command'
endfunction
noremap <expr> {lhs} DoCommand()

Обновление : Визуальный режим никогда активен в командном режиме.Никогда.Просто потому, что командный режим не визуальный режим.Использование отображений - единственный способ достичь того, чего вы хотите, и здесь есть два подхода: вы используете абсолютно одинаковое выражение expr для всех режимов и проверяете где-то в этом выражении mode(), или вы определяете различные отображения для разных режимов и используете эти различияфункция из какого режима она называется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...