Автоматическое рубиновое складывание в vim - PullRequest
12 голосов
/ 29 сентября 2011

Есть ли способ настроить vim на автоматическое сворачивание исходных файлов ruby, но только на уровне метода, независимо от того, на каком уровне они определены?

Таким образом, он сложится, когда у меня будет:

class MyClass
  def method
    ...
  end
end

но также когда у меня есть:

module FirstModule
  module SecondModule
    class MyClass
      def method
        ...
      end
    end
  end
end

Я экспериментировал с foldmethod = синтаксисом и различными уровнями сгиба, но он не учитывает глубину, где метод определен.

Кроме того, я не хочу, чтобы внутри метода складывалось ничего (если блоки, каждый блок и т. Д.).

Я думаю, что foldmethod = expr был бы моим лучшим выбором, но мне не удалось выяснить, как работают выражения сгиба, и помощь в vim не очень показательна.

Ответы [ 5 ]

11 голосов
/ 03 октября 2011

Ваша догадка об использовании метода expr, я полагаю, была правильной!

Вы можете использовать синтаксическую структуру файла для проверки собственного свертывания в стиле syntax.Следующее в моем .vimrc произвело ожидаемое поведение:

function! RubyMethodFold(line)
  let line_is_method_or_end = synIDattr(synID(a:line,1,0), 'name') == 'rubyMethodBlock'
  let line_is_def = getline(a:line) =~ '\s*def '
  return line_is_method_or_end || line_is_def
endfunction

set foldexpr=RubyMethodFold(v:lnum)

Некоторые предостережения:

Я не уверен, должен ли окончательный аргумент synID быть 0 или 1.Это аргумент, который определяет, получите ли вы информацию о синтаксисе для самого верхнего прозрачного или непрозрачного элемента в указанном местоположении.Когда нет прозрачного элемента, аргумент не действует.В тривиальном примере, который я пробовал, это не вызывало никаких проблем, но могло бы.

Стоит также отметить, что регулярное выражение line_is_def, вероятно, слишком мягкое.В этой ситуации может быть лучше вернуть -1, поэтому строка, соответствующая регулярному выражению, сворачивается только тогда, когда она находится рядом с блоком свернутых методов.Также может сработать более ограничительное регулярное выражение.

Если вы чувствуете себя странно, вы можете расширить это и вернуть отдельные уровни сгиба для элементов rubyClass и rubyModule.

Если вырешите пойти по этому пути, в моем .vimrc есть несколько полезных пользовательских функций для интроспекции элементов синтаксиса и подсветки.Они наиболее удобны, когда сопоставлены с клавишами для быстрого использования, например:

nnoremap g<C-h> :echo GetSynInfo()<CR>

Пожалуйста, дайте мне знать, если это сработает для вас!Это было весело, чтобы выяснить.Кроме того, несмотря на то, что :help 'foldexpr' не содержит много деталей, :help 'fold-expr' гораздо полезнее и даже содержит несколько примеров в верхней части.

4 голосов
/ 04 августа 2013

Внесены изменения в решение Макса Кантора, мой работает отлично, он сворачивает блоки методов определения (включая ключевое слово end) и документацию (= начало = конец) независимо от того, где он находится (в классе или с отступом)

function! RubyMethodFold(line)
  let stack = synstack(a:line, (match(getline(a:line), '^\s*\zs'))+1)

  for synid in stack
    if GetSynString(GetSynDict(synid)) ==? "rubyMethodBlock" || GetSynString(GetSynDict(synid)) ==? "rubyDefine" || GetSynString(GetSynDict(synid)) ==? "rubyDocumentation"
      return 1
    endif
  endfor

  return 0
endfunction

set foldexpr=RubyMethodFold(v:lnum)

set foldmethod=expr

Спасибо Максу Кантору за его вспомогательные методы для вывода информации о синтаксисе.

Позвольте мне объяснить эту строку построчно:

Самой важной строкой будет вторая строкагде он получает стеки разного уровня синтаксического элемента в строке.Так что если у вас есть строка типа def methodname с пробелами или символами табуляции перед ней, она всегда будет получать стек с первым непустым символом.Проблема с решением Макса Кантора состоит в том, что его код будет распечатывать только самый низкий синтаксический элемент, найденный в первом столбце строки, поэтому он всегда будет возвращать что-то случайное, такие элементы, как «rubyContant», которые нас не волнуют.

Таким образом, используя match(getline(a:line), '^\s*\zs'), мы можем переместить наш курсор к столбцу первого непустого символа, чтобы мы могли получить более точную картину стеков.+1, потому что match проиндексирован нулями.

А затем все остальное похоже на метод GetSynInfo, где мы перебираем стек и сопоставляем нужные элементы и возвращаем 1, так что они все находятся на одном уровне сгибаи 0 для остальных.

И это все, рабочая складывающаяся функция expr, которая будет складывать только методы определения ruby:)

Наслаждайтесь и хорошего дня!

4 голосов
/ 26 июля 2013

Возможно, вам повезет больше, особенно если у вас уже есть подсветка синтаксиса:

Это будет в вашей ~ / .vimrc

"" Enable folding based on syntax rules
set foldmethod=syntax

"" Adjust the highlighting
highlight Folded guibg=grey guifg=blue

"" Map folding to Spacebar
nnoremap  za

Это также отличный VIMcast наскладной: http://vimcasts.org/episodes/how-to-fold/

2 голосов
/ 24 ноября 2014

Я сделал vim-ruby-fold плагин для простого метода складывания в ruby. Я надеюсь, что это помогает людям.

1 голос
/ 01 октября 2011

Возможно, вам удастся найти решение, которое также складывается внутри метода, с помощью команды zO. zO будет рекурсивно открывать сгиб, поэтому, если вы используете его вместо zo, это будет так, как если бы внутри метода не сложилось ничего. Вы также можете переназначить zo на zO, если чувствуете себя бледно.

...