Vim: самый эффективный способ проверить наличие шаблона при наведении курсора?

#regex #vim

#регулярное выражение #vim

Вопрос:

У меня проблема с сопоставлением текста в буферах Vim. У меня в тексте есть определенная форма дат, и мне часто нужно проверять, соответствует ли текст при наведении курсора шаблону дат.

Вот несколько примеров отформатированных дат, которым может предшествовать или следовать другой текст в той же строке:

 <2011-10-13 Wed>
[2011-10-13 Wed]
<2011-10-13 Wed  1>
[2011-10-13 Wed  1]
<2011-10-13 Wed 10:30>
[2011-10-13 Wed 10:30]
<2011-10-13 Wed 10:30-11:30>
[2011-10-13 Wed 10:30-11:30]
<2011-10-13 Wed 10:30  1w>
[2011-10-13 Wed 10:30  1w]
  

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

Есть комментарии по поводу того, какая функция наиболее эффективна для возврата даты под курсором (или пустой строки, если не в дате)? (Я бы опубликовал свой код, но пока воздержусь как (1) из-за смущения, так и (2) чтобы не загрязнять ваши умы предложением конкретного подхода к проблеме.)

Спасибо за любые советы.

Ответ №1:

 function! CheckDate(expr)
    let date_pattern = '[[<]'      " The first < or [
                .'d{4}-d{2}-d{2}' " YYYY-MM-DD
                .' (Mon|Tue|Wed|Thu|Fri|Sat|Sun)' " Week day
                .'( d{2}:d{2}(-d{2}:d{2})?)?'
                                    " Optional time or range
                .'(  dw?)?'   " Optional   digit with optional 'w'
                .'([]>])'     " The closing > or ]
    return match(a:expr, date_pattern) != -1
endfunction

function! IsOverDate()
    call setreg('a','')
    call setreg('b','')
    normal! "aya>
    let expr1 = getreg('a')
    normal! "bya]
    let expr2 = getreg('b')
    if CheckDate(expr1)
        return expr1
    elseif CheckDate(expr2)
        return expr2
    endif
    return ''
endfunction
  

Функция IsOverDate() очищает регистры a и b и сохраняет в соответствующих регистрах текст под курсором, который находится внутри < и > , < и > , и, и, и и, включая скобки. Затем он получает значение из регистров a и b и отправляет его в функцию CheckDate() , которая проверяет, соответствует ли выражение шаблону даты (я основывался на ваших примерах и сделал некоторые предположения для построения шаблона).

CheckDate() Функция возвращает true, только если выражение соответствует шаблону даты. Функция IsOverDate() возвращает дату под курсором (в скобках) или пустую строку, если курсор не находится над датой.

Надеюсь, это подходит.

Комментарии:

1. freitass — Спасибо, намного лучше, чем мой метод. Я думаю, что ключевая вещь, которая мне помогает, — это переход к регистру с помощью команд ya> или ya] . Я использовал более неуклюжий способ получения текста.

2. Добро пожаловать! Пожалуйста, «проверьте» ответ, чтобы выразить свою благодарность. Спасибо 😉

3. freitass — Спасибо, готово. Оказывается, я нашел второе место, где я сделал это в своем коде, которое было ближе к вашему методу. Я (по какой-то причине) использовал vi< and then "ay вместо прямого нажатия. Плюс изменение разделителей, как вы это делали (т. Е. ya< ), немного облегчает мне задачу, так что ваша помощь в наведении порядка приветствуется.

4. Включение скобок не было преднамеренным, просто вариант. Я рад, что у вас это сработало! =)