Более эффективные движения, редактирующие файлы Python в VIM - PullRequest
46 голосов
/ 22 мая 2009

Имеется файл python, в котором повторяется бесконечно:

def myFunction(a, b, c):
    if a:
        print b
    elif c:
        print 'hello'

Я бы хотел переместиться и отредактировать этот файл, используя знакомые движения vim. Например, используя (,), [[,]], {,} или удаляя / дергая / меняя текст с помощью таких команд, как di}.

В других языках (таких как C ++, Java, C # и т. Д.) У вас есть множество фигурных скобок, поэтому с помощью такого движения, как di} можно легко найти соответствующую фигурную скобку и воздействовать на этот блок. И на самом деле, если я нахожусь на символе 'b' в приведенном выше тексте и делаю di) в vim, он успешно удаляет текст между двумя паренами.

Проблема в том, что Python обнаруживает блоки кода, я думаю. Использование (,), [[,]], {или} в качестве движений в значительной степени делает одно и то же, приводя вас к началу (выше или на линии def) или к концу (после последней строки функции) функция. И, насколько я знаю, нет никакого способа легко сказать vim «выбрать все для этого блока отступов». В приведенном выше примере я хотел бы быть в 'i' строки if, набрать di} и удалить весь блок if (до конца этой конкретной функции).

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

Ответы [ 4 ]

25 голосов
/ 02 февраля 2015

Отображение квадратных скобок [[, ]], [m, ]m и аналогичные

$VIMRUNTIME/ftplugin/python.vim сейчас (2018) перераспределяет все встроенные отображения, задокументированные в :h ]] и :h ]m для языка Python. Отображения:

]] Jump forward to begin of next toplevel
[[ Jump backwards to begin of current toplevel (if already there, previous toplevel)
]m Jump forward to begin of next method/scope
[m Jump backwords to begin of previous method/scope

][ Jump forward to end of current toplevel
[] Jump backward to end of previous of toplevel
]M Jump forward to end of current method/scope
[M Jump backward to end of previous method/scope

Следующий пример исходного кода с комментариями иллюстрирует различные сопоставления

class Mapping:                              # [[[[
    def __init__(self, iterable):
        pass

    def update(self, iterable):
        pass

    __update = update                       # []

class Reverse:                              # [[ or [m[m
    def __init__(self, data):               # [m
        self.data = data
        self.index = len(data)              # [M

    def __iter__(self):                     # <--- CURSOR
        return self                         # ]M

    def __next__(self):                     # ]m
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]        # ][

class MappingSubclass(Mapping):             # ]] or ]m]m

    def update(self, keys, values):
        pass

Отображения были добавлены и улучшены в коммитах abd468ed0 (2016-09-08), 01164a6546b4 (2017-11-02) и 7f2e9d7c9cd (2017-11-11).

Если у вас еще нет новой версии этого файла, вы можете скачать ее и поместить в ~/.vim/ftplugin/python.vim. Эта папка имеет приоритет перед $VIMRUNTIME/ftplugin.

До того, как эти сопоставления были добавлены в $VIMRUNTIME, существовал плагин python-mode, который обеспечивает [[, ]], [M и ]M. Кроме того, python-mode также определяет текстовые объекты aC, iC, aM и iM:

Плагин Python-mode

Этот плагин vim предоставляет движения, аналогичные встроенным:

2.4 Vim motion ~
                                                                *pymode-motion*

Support Vim motion (See |operator|) for python objects (such as functions,
class and methods).

`C` — means class
`M` — means method or function
                                                            *pymode-motion-keys*

==========  ============================
Key         Command (modes)
==========  ============================
[[          Jump to previous class or function (normal, visual, operator)
]]          Jump to next class or function  (normal, visual, operator)
[M          Jump to previous class or method (normal, visual, operator)
]M          Jump to next class or method (normal, visual, operator)
aC          Select a class. Ex: vaC, daC, yaC, caC (normal, operator)
iC          Select inner class. Ex: viC, diC, yiC, ciC (normal, operator)
aM          Select a function or method. Ex: vaM, daM, yaM, caM (normal, operator)
iM          Select inner func. or method. Ex: viM, diM, yiM, ciM (normal, operator)
==========  ============================

Плагин Pythonsense

Этот плагин обеспечивает аналогичные движения, но немного изменен:

Стандартные движения класса "Vim" ("]", "[[" и т. Д.) Vim 8.0 находят блоки, начинающиеся с первого столбца, независимо от того, являются ли они классовыми или функциональными блоками, в то время как его метод Движения / function ("[m", "] m" и т. д.) находят все блоки в любом отступе независимо от того, являются ли они классовыми или функциональными блоками. Напротив, движения класса "Pythonsense" работают над нахождением всех и только определений классов, независимо от их уровня отступа, в то время как его движения метода / функции работают с поиском всех и только определений методов / функций, независимо от их уровня отступа.

Все подробности и примеры приведены на https://github.com/jeetsukumaran/vim-pythonsense#stock-vim-vs-pythonsense-motions. Кроме того, этот плагин определяет текстовые объекты ic/ac (класс), if/af (функция), id/ad (строка документации).

Для обсуждения текстовых объектов для Python см. Какой самый быстрый способ выбрать функцию Python через VIM? .

20 голосов
/ 08 сентября 2009

python.vim

Упрощает навигацию по блокам кода Python.

Ярлыки:

  • ]t - Перейти к началу блока
  • ]e - Перейти к концу блока
  • ]v - Блок выбора (режим визуальной линии)
  • ]< - Сдвиг блока влево
  • ]> - Сдвиг блока вправо
  • ]# - Выбор комментариев
  • ]u - Раскомментировать выбор
  • ]c - Выбрать текущий / предыдущий класс
  • ]d - выбор текущей / предыдущей функции
  • ]<up> - Перейти к предыдущей строке с таким же / более низким отступом
  • ]<down> - Перейти к следующей строке с таким же / более низким отступом

python_match.vim

расширяется %:

  • % - перебрать, если / elif / else, попытаться / исключить / перехватить, для / продолжить / прервать
  • g% - двигаться против %
  • [% - перейти к началу текущего кодового блока
  • ]% - перейти в конец текущего блока кода

Все вышеперечисленные движения работают в обычном, визуальном и операторском режимах, поэтому:

  • d]% - удалить до конца текущего блока
  • v]%d - следует сделать то же самое, пройдя в визуальном режиме, чтобы Вы можете видеть, что удаляется
  • V]%d - выше, но с выбором строки
6 голосов
/ 22 мая 2009

Очень легко перемещать блоки с отступом, когда у вас есть set foldmethod=indent. Например, если вы находитесь в строке def main(): в следующем фрагменте кода:

def main():
+-- 35 lines: gps.init()-----------------------------------------------------

if __name__ == "__main__": main()

затем dj принимает всю основную функцию и может быть вставлена ​​в другом месте.

0 голосов
/ 18 августа 2015

Чтобы обратиться к вашему последнему абзацу, следующий скрипт определяет новый текстовый объект «отступ», с которым вы можете выполнять действия. Например, d i i удаляет все отступы на том же уровне, что и строка, на которой находится курсор.

Для получения дополнительной информации см. Документацию плагина: http://www.vim.org/scripts/script.php?script_id=3037

...