Скрипт для Notepad++ на Python

Введение


Думаю, многим известен Notepad++ — удобная бесплатная утилита, выступающая в качестве «продвинутой» замены стандартному Блокноту Windows. Как и при работе в любом текстовом редакторе, в Notepad++ время от времени возникает необходимость автоматизировать какие-либо повторяющиеся действия, которые в силу сложности логики невозможно записать как макрос. К счастью, для решения этой задачи нет необходимости переключаться из Notepad++ в, например, Word, дабы воспользоваться встроенным в него VB.

Среди плагинов для Notepad++ существуют расширения, реализующие возможность написания скриптов для Notepad++ на разных языках, таких как JavaScript, Lua, PHP или Python. Именно на последнем я и решил остановиться для решения своей задачи.

Постановка задачи


Предположим, перед нами стоит следующая задача (взята из жизни).

1. В выделенном фрагменте текста (если ничего не выделено — то во всём документе):
  • пронумеровать символы '@', находящиеся в начале строки, заменив '@' на '@1', '@2' и т.д.;
  • удалить пустые (включая пробелы и табуляцию) строки, идущие подряд по две и более.
2. При запуске скрипта должен выдаваться запрос — с какого номера начинать нумерацию символов '@'. По умолчанию (по нажатию «Enter»), нумерация должна начинаться с 1. Если введено не числовое значение, окно запроса должно появляться вновь, до тех пор, пока не будет введено число.

3. Если в выделенном фрагменте текста (или во всём документе — в случае если нет выделения) отсутствует символ '@', должно выводиться соответствующее сообщение об ошибке.

4. Должна присутствовать возможность запуска скрипта:
  • по нажатию соответствующей кнопки на панели инструментов;
  • с помощью клавиатурного сочетания;
  • через контекстное меню правой кнопки мыши.

Решение


Для начала нам потребуется установить плагин для Notepad++ под названием Python Script. С его помощью можно производить любые операции с редактируемым текстом, открывать/закрывать файлы, переключать вкладки, выполнять команды меню Notepad++ и т.д. — одним словом, практически всё, что вообще можно сделать в Notepad++.

Далее, выбрав в меню Notepad++ Plugins->Python Script->New Script, создаём скрипт:

# -*- coding: utf-8 -*-

#Скрипт для Notepad++, удаляющий пустые строки и нумерующий символы "@", находящиеся в начале строки

# Получаем выделенный текст
text = editor.getSelText()
isSelection = True

# Если текст не выделен, то работаем со всем документом
if not text:
	isSelection = False
	text = editor.getText()

#Находим количество вхождений символа "@", находящегося в начале строки
import re
occurrencesCount = len(re.findall('^@', text, flags=re.MULTILINE))

# Если в тексте нет ни одного символа "@" в начале строки, выводим сообщение об ошибке
if occurrencesCount == 0:
	notepad.messageBox('В тексте должен присутствовать как минимум 1 символ "@" в начале строки', 'Неверный формат входных данных', MESSAGEBOXFLAGS.ICONEXCLAMATION)
	
# Если символ "@" присутствует, то
else:
	countStartFrom = ''
	# Выдаём запрос до тех пор, пока не будет введено число
	while not countStartFrom.isdigit():
		countStartFrom = notepad.prompt('Введите число, с которого должна начинаться нумерация вхождений в тексте символа "@":', 'Нумерация вхождений символа "@"', '1')
		if countStartFrom == None:
			break
	if countStartFrom != None:
		# Удаление пустых строк
		text = re.sub('\r\n\\s*\r\n', '\r\n', text)
		# Удаление пустой строки в конце и в начале файла/выделения
		text = re.sub('\r\n\s*$|^\s*\r\n', '', text, flags=re.MULTILINE)

		# Переводим countStartFrom из строки в целочисленный тип
		countStartFrom = int(countStartFrom)

		# Функция, возвращающая символ "@" с добавленным к нему и увеличенным номером
		def addNumber(matchobj):
			global countStartFrom
			countStartFrom += 1
			return '@'+str(countStartFrom-1)

		#Добавляем нумерацию ко всем символам "@", находящимся в начале строки
		text = re.sub('^@', addNumber, text, flags=re.MULTILINE)

		#Заменяем обработанной строкой выделение или весь документ
		if isSelection:
			editor.replaceSel(text)
		else:
			editor.setText(text)

Если мы назвали скрипт «Empty Lines And Count», то запустить его можно из меню Plugins->Python Script->Scripts->Empty Lines And Count. Чтобы добавить его кнопку на панель инструментов и сделать возможным запуск по клавиатурному сочетанию, в настройках плагина (Plugins->Python Script->Configuration) выбираем созданный нами скрипт и добавляем его в меню и на панель инструментов. Теперь после перезапуска Notepad++ соответствующая кнопка появится на панели инструментов.

Назначить скрипту сочетание клавиш можно в меню Settings->Shortcut mapper в разделе Plugin commands.

Чтобы добавить скрипт в контекстное меню Notepad++, нужно в xml-файл настроек (Settings->Edit Popup ContextMenu) добавить в нужном вам месте (например, перед первым элементом) следующие строчки:

<Item PluginEntryName="Python Script" PluginCommandItemName="Empty Lines And Count"  ItemNameAs="Удалить пустые строки и пронумеровать символы '@'"/>
<Item id="0"/>



Вот и всё. Теперь даже рутинные действия со сложной логикой можно выполнять одним кликом.

Полезные ссылки:
Метки:
Поделиться публикацией
Похожие публикации
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 22
  • +1
    мне в нем безумно не хватает нормального autocomplete как в microsoft expression.
    А так же автоформатирования, когда расставляются отступы и пробелы в зависимости от кода.
    • +1
      Я думаю, что как раз Вам показали сильный инструмент, который это докажет.
      Вот: npppythonscript.sourceforge.net/docs/latest/scintilla.html документация на автодополнение текста (найдите «Еditor.auto») и дополняйте себе сколько угодно!
      • 0
        Проще сменить редактор, чем все это туда запихивать самопальными макросами и плагинами.
        Пользуюсь им для быстрого редактирования чего-нибудь.
        • 0
          аналогично. Автокомплит там есть но не юзабельный. Автоформат тоже но через плагин и кривоватый какой-то.
      • –8
        Мы уже поняли что вы гик! В таком случае случае пользуетесь системами типа: Emacs и Vim. Например в емаксе это просто макрос, в возможно функция в пару строк.

        p.s. Вашу энергию — да в мирных целях!
        • +7
          Мне не нравится:
          — дефиниция функции в середине блока
          — импорт на 13той строке скрипта
          — незнаете о PEP 8
          — «Выдаём запрос до тех пор, пока не будет введено число», Что если случайно нажал?
          — не предкомпилированные регулярные выражения, по той причине, что новички прийдут да будут ваши компиляции регулярок использовать в цыклах.
          • +1
            Благодарю за замечания. Это мой дебют в Python.

            — «Выдаём запрос до тех пор, пока не будет введено число», Что если случайно нажал?

            В окне запроса есть кнопка «Отмена», в случае нажатия которой (countStartFrom == None) скрипт прекратит работу.
            • +1
              А можно про PEP8 и предкомпилированные регулярные выражения чуть подробней? Хочу использовать питон для автоматизации и только-только начинаю учить его, было бы интересно почитать о том, как надо правильно делать.
              Объявление функции и импорт в середине кода это не смертельно, но «не удобно и не принято», я так понимаю?
              • –2
                «Не питонично». У питонистов очень тонкий вкус на оформление кода.
                Вот то есть, если сам язык вынуждает писать (self) в каждом методе, это оки-доки, а вот если ты, паразитина, вместо under_score_style выбираешь camelCaseStyle, то на кол тебя.
                • +3
                  Извините пожалуйста, никто-же Java, PHP, C, C++ итд… не бьёт по голове, из-за того, что они используют фигурные скобки для отделения блоков вместо индентации, правда? Так пожалуйста не надо подъёбывать «не питонично».
                  «если сам язык вынуждает писать (self) в каждом методе» — Питон не скрывает то где у него находится указатель на инстанцию класса, а функция с первым параметром «self», это просто указатель на какую-то там живую инстанцию класса. В других языках этот self или this скрыты, и это тоже надо понимать.
                  • –4
                    Я прям обожаю злить питонщиков )))
                    По поводу «питонично» — вы же, питонщики, и придумали прилагательное pythonic.
                    А что до self'а — именно пейсателям на питоне всегда было сложно признать что их инструмент (как и все прочие) не совершенен и в нем некоторые вещи сделаны через жопу.
                    • +2
                      Троллинг?
                      Я не злюсь. И вы кстати сделаны хоть и не через жопу, но через письку на 100%! Так что не надо ругать, унижать и стебаться с других. И продолжать дискуссию на тему «стёб над питонистами» идите туда одкуда вы вылезли.
                      Кстати заметьте я ни разу не сказал чтолибо "(не)питонично"… Вы сами это значение сюда принесли и сами начали стёб. Когда речь пойдёт о Java, вы будете пиликать: «java way»? Задумайтесь что хорошего вы принесли в этот разговор. Ничего!
                • +3
                  1 — import this
                  2 — PEP8: www.python.org/dev/peps/pep-0008/ его прочитайте

                  3 — docs.python.org/library/re.html
                  3.1 — где-то в начале кода где нет никакой логики, никаких цыклов предкомпилируйте регуларное выражение
                  cmpld_reg = re.compile('^@', flags=re.MULTILINE)
                  3.2 — Потом где-то в коде где есть какая-то логика, можете использовать уже «приготовленное» регулярное выражение, не компилируя его 20 раз подряд.
                  cmpld_reg.sub(addNumber, text)
                  4 — Да, а также потому, что так к этой функции с другого конца «кода» нельзя приступить и использовать её ещё раз.
            • –11
              удобная бесплатная утилита, выступающая в качестве «продвинутой» замены стандартному Блокноту Windows

              удобная бесплатная утилита, выступающая в качестве продвинутой «замены стандартному Блокноту Windows»
              • 0
                Откровенно намекать в статье на ошибки. Вы явно не правы. В тысячный раз повторюсь, в личку…
              • 0
                Такой вот вопрос, не подскажете где можно найти уже готовые скрипты? и есть ли они вообще :)
                • 0
                  Думаю, вряд ли где-то есть готовые, во всяком случае, мне о таком неизвестно.
                • 0
                  Спасибо за хороший туториал. Как раз задавался вопросом написания скриптов для Notepad++, правда, на Lua. Теперь есть матермал для размышлений, спасибо. :)
                • +1
                  Чем только люди не маются, лишь бы не потратить полчаса на освоение VIM'а:))
                  • 0
                    написал скрипт на 4 строки, получаю выделенный текст и запускаю пункт меню через runPluginCommand.
                    скрипт добавил на тулбар и в меню, при вызове скрипта из меню Plugins->Python Script->Скрипт — все работает. а вот кнопка на тулбаре — мертва, не кликабельна ;(. что я делаю не так?
                    заранее спасибо)

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.