Сверхбыстрое копирование\вставка фрагментов кода

в 5:30, , рубрики: c++, code, copy, qt, Qt Software, Программирование, метки: , , ,

Постоянно программируя на C++/Qt, я заметил, что было бы удобнее хранить где-нибудь свои отрывки кода и иметь к ним быстрый доступ. Конечно же, я принялся искать и нашёл множество готовых программ-органайзеров и сайтов. Я перепробовал их, но меня всё это не устроило.

Хотелось именно быстрого доступа — а значит по глобальным хоткеям. Чтобы нажал — ввёл слова в поиск — получил код. Но такими функциями обладали всего две программы, а они были платными и не кроссплатформенными.

Поэтому я взялся написать свою программу на Qt. Она оказалась настолько удобной, что я уже не представляю свой кодинг без неё и конечно же решил её опубликовать — вдруг кому ещё пригодится? Под катом расскажу о проблемах и задачах, которые пришлось решить, выложу свой опыт, а также обзор самой программы и её исходного кода.
Сверхбыстрое копирование\вставка фрагментов кода

История разработки

Для начала я решил — программа должна быть, маленькой, удобной и шустрой. А значит — следует поместить программу в трее, чтобы не мешалась на панели задач. Благо что Qt предоставляет для этого удобное кроссплатформенное решение в виде класса QSystemTrayIcon. Также программа должна обязательно работать на глобальных хоткеях. Вот тут возникла проблема! Дело в том, что Qt, к сожалению, из коробки не поддерживает их. На то есть библиотека libqxt, которую я весьма успешно использовал почти год под Qt 4.8. Однако под Qt 5 её по неясной мне причине ещё нормально не доработали (на тот момент) и под Win7 она собираться ну никак не хотела — и я бросил эту затею. Вместо этого вставил самую капельку нативного кода — вызов winApi функции RegisterHotKey. Это единственная нативная вставка в программе — и я думаю что будет совсем легко доработать её под Linux или Mac.

Сами куски кода я решил сохранять в XML-базе данных. Может это и не лучшее решение, но оно пока вполне справляется с задачей. Да и вообще привык я к нему.

В качестве основы для редактора я взял, конечно же, QTextEdit. Тут меня ждал приятный сюрприз — код, скопированный из QtCreator — копируется как HTML с разметкой, а следовательно — с подсветкой синтаксиса. Тут же необходимость писать встроенную подсветку синтаксиса для C++Qt отпала сама по себе. QtCreator имеет очень крутую подсветку синтаксиса, особенно если её настроить под себя.
Сверхбыстрое копирование\вставка фрагментов кода
Далее, когда уже была возможность вставить в окошко код и он уходил в базу, а затем в файл xml, встал вопрос о том, как его удобно и быстро получить. Для этого я написал маленький поисковик, который ищет куски кода, где встречаются все слова, указанные через пробел. Пока его вполне хватает. В моей личной базе уже около 100 фрагментов кода и всё равно среди них я отлично ориентируюсь.

Также сделал кейворды. Ну как же без них? Поиск идёт не только по основному коду, но и по ним тоже. В кеях можно указать языки программирования, к которым относится данная паста, например «c++,qt» или «qml,js». Если в результате поиска появились фрагменты кода из нескольких языков, можно дифференцировать их, добавив ключевое слово-язык.

Дорабатывая программу, нарисовал в GIMPe логотип — фигурные скобочки. Просто и понятно.

Обзор программы

Можете скачать Windows-дистрибутив программы здесь или собрать её из исходников, скачав их с github. Только распаковывайте их не на рабочий стол, как это делают многие. Дистрибутив вместе со всеми dll весит 16 МБ в запакованном виде и 40 в распакованном — Qt5 значительно разжирел и даже простейшая программа требует тащить за собой целую массу библиотек. Но я думаю что это не проблема, тем более что оно никак не сказывается на скорости работы программы.

Распакуйте программу в любую папку на диске и запустите. Она создаст в своей папке файл конфигурации config.xml, а потом, при сохранении, чистую базу данных для вашего кода base.xml. Собственно как выглядит главное меню — вы можете увидеть на скрине в заголовке статьи. Интерфейс программы пока что весь на английском, чтобы не было проблем со сборкой на некоторых системах — сообщения и подписи пока-что в исходниках.

Добавление нового фрагмента кода осуществляется по глобальному хоткею ctrl+D, а поиск — по win + V. Вы можете бросить в меня камень за такие «глобальные» хоткеи, но эксперименты показали что они самые удобные. Да, возможно вы привыкли по ctrl+D отправлять код из QtCreator куда-либо. Если это так критично, можете зайти в конструктор класса CodePaster и поменять там хоткеи на те, которые вам угодны. В дальнейшем это можно будет сделать через GUI.

Продолжим. Допустим, вы написали какой-то удобный алгоритм, или освоили новую конструкцию языка, которую нет желания печатать каждый раз. Вы просто выделяете ваш блок кода в вашей любимой IDE (например в креэйторе) — и копируете как обычно через ctrl+C. Тут же будет удобно и совсем рядом — не отпуская ctrl — нажать на D. Вылезет окно поверх вашей IDE — и код уже сам прыгнет в него! Программа в автоматическом режиме читает буфер обмена, вставляя из него код. Ещё тут есть ещё 2 небольшие фичи — вставляется подпись перед кодом в виде комментария "//", а также у самого кода убираются лишние отступы. Т.е. если вы скопировали его из середины программы, то он сдвинется влево до упора.
Сверхбыстрое копирование\вставка фрагментов кода
Вы просто нажимаете «OK» — и ваш код уже в базе! Более того, она тут же сохранилась на жёсткий диск, чтобы не потерять данные в случае какого-либо сбоя.

Далее — когда вам захотелось быстро скопировать этот код — нажимаете win + ctrl. Почему именно его? Мне он кажется удобным вариантом и нигде не задействован. Вы увидите маленький поисковик по коду, и уже оттуда сможете скопировать нужные вам фрагменты. Что касается самого поисковика — то у каждого куска кода есть контекстное меню. Вы можете удалить его из базы, можете отредактировать, а можете посмотреть его свойства.
Сверхбыстрое копирование\вставка фрагментов кода
Сверхбыстрое копирование\вставка фрагментов кода
Как видите, фрагменты кода разделяются через "---", у каждого есть свой id, а также мелкие плюшки — программа запоминает дату добавления и сколько раз он был скопирован.

Пришлось немного потрудиться, чтобы сопоставить некоторый блок текста внутри QTextEdit некоторому объекту Code — при обновлении поиска формируется «карта» — лист из специальных объектов, каждый из которых хранит начальную и конечную позицию в QTextEdit и указатель на объект кода, который этой области соответствует.

Между прочим — прогу можно использовать не только для кода, а вообще для любого текста. Например я весьма успешно забил туда свои почтовые ящики и телефон, копирую их когда надо. Получается что-то типа блокнота с быстрым доступом и поиском.

Примеры

Приведём простой пример использования программы — если вам вдруг понадобилось кинуть в вашей программе мессаджбокс для отладки (именно его, а не вывод qDebug) — заранее подготовив код, вы просто набираете win + V и вбиваете «mes» — этого достаточно, чтобы найти нужный кусок кода и скопировать его. Вы потратите одно нажатие хоткеев, набор 3 символов, Enter (который в дальнейшем можно будет убрать), и выделение-копирование. А теперь дайте сравним — сколько времени вы потратите, чтобы скопировать его из того же ассистанта? Даже если он на глобальном хоткее — вам придётся через выделение или клавиш получить фокус для строки поиска, ввести туда «mess», выбрать нужный класс мышкой (!), промотать вниз до того места где есть пример (если он есть) и только тогда скопировать его. Это как минимум в 2 раза дольше. Qt Assistant — это просто идеальная документация, однако для копирования-вставки постоянно используемых кусков кода он не подходит.

Какие варианты вы ещё предложите? Заходить каждый раз на сайт pastebin и искать там? Это тоже лишние задержки. Вводить в гугле по 100 раз одни и те же запросы? А ведь большинство программистов, с которыми я общался на эту тему — так и делали — они каждый раз всё гуглили. Но ведь один раз нашёл — можно сохранить в какой-нибудь «кэш» для быстрого доступа, изменив если надо — и использовать на здоровье! Этим кэшем и должна быть программа, хорошо интегрированная с системой для большего удобства.

Приведём другой пример. Я часто сижу на форуме prog.org.ru и постоянно нахожу или получаю много хороших решений разных небольших задач. Например, как с помощью QSettings добавить программу в автозагрузку Windows. Или как динамически подгрузить ui-форму. Там целые алгоритмы. Каждый раз искать то нашёл один раз — это не комфортно. Хорошие и красивые решения приятно сохранять для себя для будущего использования.

Ещё один пример — я один раз сохранил код для bat-файла, который добавляет переменную в windows environment variables. Когда он бывает нужен — просто копирую его в командную строку вместо использования неудобного GUI.

Вы конечно также можете предложить сохранять фрагменты кода в файлы, однако как только встанет вопрос о быстром доступе и поиске, а также об удобной организации таких файлов — вы увидите, что это не самое лучшее решение. Большие куски кода — целые библиотеки и классы — конечно же стоит хранить именно так, но речь идёт о маленьких фрагментах, которые мы часто используем.

Если вы работаете сразу с несколькими языками программирования — преимущества использования такой программы станут ещё более существенными. Вы можете забыть как выглядит та или иная конструкция на определённом языке — и через поиск легко вспомнить.

Обзор исходного кода

Исходный код я писал жёстко по стандарту Qt Coding Style. Временами использовал конструкции С++11. Я думаю при его чтении проблем не возникнет. Все окна построены на основе виджетов, однако потом планирую перевести их на QML.

Вообще — не судите строго. Это мой первый публичный проект и я надеюсь что хоть кому-то пригодится если не прога, то те моменты, которые я изложил здесь. Если прога окажется реально полезной и вы плюсуете — то могу её доработать. В планах — сделать её ещё удобнее (идеи есть), подсветку синтаксиса для других языков и поддержку хоткеев для LinuxMac.

Также не исключаю, то что где-то в статье или в коде есть опечатки иили ошибки. Рад буду принять здавую критику.

Так что — жду ваших отзывов!

Автор: kciray

Источник

Поделиться

* - обязательные к заполнению поля