Выбор hex-цвета в Vim (Color Picker)

19.10.2010

Сейчас будет немного магии Vim :) Это со стороны точно покажется магией, хотя и того хуже — ужасным красноглазием. Но я доволен, мне результат нравится.

Я долгое время мучался с CSS, копируя цветовые коды из стандартного окошка gcolor2 в буфер обмена, и потом вставляя в редактируемый документ. Это была одна из моих глупых привычек. Но сегодня мне, наконец, надоело.

Так выглядит популярная выбиралка цвета под Linux

Подходить к решению этой проблемы я пытался давно, но выяснялось, что в плагинах Vim для этой цели есть только варианты под Mac или под Linux, но основанные на пайтоновских скриптах, что мне почему-то как-то не нравится. Поэтому я сделал свой велосипед, может, кому-то тоже пригодится. По моему заказу сегодня фрилансер модифицировал исходники gcolor2, и теперь она пишет значение выбранного цвета в /tmp/hexcolor.

Как этим пользоваться?

Я просто запускаю gcolor2 на сеанс работы с CSS и пользуюсь настроенной клавиатурной последовательностью \h для вставки цветового кода. В режиме вставки эта последовательность вставляет код и помещает курсор после него, а в основном режиме \h меняет любое слово (или hex-цвет) под курсором на цветовой код. Написанное выше может показаться непонятным, но, поверьте, это очень удобно!

Если вам тоже нужная такая возможность, скачайте модифицированный gcolor2 (ссылки будут внизу) и добавьте в свой .vimrc несколько строчек.

Расшифровка магии

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

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

Цвет меняется для обычных и сокращённых цветовых кодов а также если курсор стоит в любом месте обычного слова (например, в слове black). В цветовых кодах курсор тоже может стоять где угодно! В начале (в т. ч. и на «решётке»), в конце, в середине. Так что по сути в этих двух строках настройки целые подпрограммки зашифрованы.

Если вам интересно разобраться, открывайте красивую картинку в отдельной вкладке, смотрите индексы по порядку и читайте…

Расшифровка Vim-магии

Основной режим

Сперва идёт ключевое слово nmap, которое обозначает, что последовательность предназначена для работы в основном режиме; потом <leader> — управляющий символ (обратный слеш по умолчанию); и буква — я выбрал h (от hex). Ну а дальше ровно по картинке.

Кстати, если вам действительно интересно разобраться, рекомендую пройти все команды вручную, в своём Vim. Тогда вы поймёте что к чему и запомните пару полезных команд подкоркой своего мозга.

  1. b2leb — на самом деле это целых четыре команды, они играют роль локатора. Именно благодаря этому сочетанию курсор ставится в начало слова, где бы он ни находился. Команда b ставит курсор на первый символ слова, 2l перемещает его на два символа вправо, e ставит курсор на последний символ, а b снова ставит в начало. Если считаете, что можете придумать комбинацию короче для всех случаев — попробуйте ;)
  2. mh — ставим закладку с именем h. Кстати, m от слова mark, это я как бы намекаю, что Vim на самом деле очень даже интуитивен, особенно когда уже проходит некоторое время и вы поняли основную концепцию. Некоторые команды (например f) я узнал без подсказок и чтения мануалов — просто нажал клавишу, предполагая действие. И попал в яблочко.
  3. :r/tmp/hexcolor<CR> — тоже несколько команд, двоеточие означает переход в командный режим, r[ead] читает файлик от gcolor2 и помещает его содержимое в документ после нажатия Enter (<CR>).
  4. 7x — вырезаем решётку и 6 символов кода. Предыдущая команда вывела код на новой строке и курсор поставила в её начале. Интересный момент, который не все знают: если мы удаляем (копируем, вырезаем) что-то, содержащее хотя бы одну строку, это помещается в регистр 0 (а далее смещается до 9 новыми аналогичными операциями), но если, как в этом случае, вырезается лишь несколько символов без знака перевода строки, то храниться оно будет в специальном регистре -. Здесь не ошибка, это правда просто дефис. Через два шага мы этот регистр используем.
  5. dd — удаляем строку, где был наш цветовой код. Впрочем, от неё только остался только символ перевода строки, на котором пару мгновений скучал курсор.
  6. `h — переходим к закладке h, которую поставили на втором шаге. Обратите внимание, это не кавычка, вернее, особая кавычка. Проще говоря, я не знаю как называется этот символ :) Но на русских клавиатурах он обычно там же, где буква «ё», слева вверху.
  7. h"-p — здесь две команды, h сдвигает курсор влево на один символ, а p (paste) вставляет содержимое регистра (того самого дефисного) после курсора. Доступ к этому регистру мы получили также, как к любым другим — через двойную кавычку.
  8. lde — после вставки курсор оказался на последнем символе цветового кода, поэтому сдвигаем его вправо на один символ (команда l) и удаляем (команда d) всё оставшееся до конца слова (команда e). До конца того слова, которое мы заменяем цветовым годом.
  9. b3h — две подготовительные к следующей операции команды: b ставит курсор на начало слова (код после решётки), а 3h сдвигает его на три символа влево. Кстати, вот сейчас написал это и понял, что правильней было сделать проще, вместо двух команд только одну — 8h. Сдвиг влево нужен, чтобы освободить плацдарм для замены…
  10. :silent! s/##/#<CR> — переходим в командный режим (двоеточие) и меняем две решётки на одну. Ведь у нас осталась одна решётка от того кода, который у нас был сразу в тексте. А если меняем не hex-цвет, а просто слово? Для этого у нас silent с восклицательным знаком, чтобы команда замены не предупреждала нас красненько о том, что не нашла двух решёток.
  11. `he — снова переходим к закладке и после ставим курсор на конец слова (цветового кода) командой e. Это необходимо, если предыдущий шаг выполнился, произошла замена решёток. Тогда курсор оказывается в начале строки.

Вот и всё. Сложно? Да, кажется, что сложно. Но этот алгоритм отрабатывает мгновенно, просто по нажатию последовательности двух клавиш, при этом я совершенно не беспокоюсь о том, что может что-то пойти не так — где бы курсор не стоял, замена произойдёт как надо.

Режим вставки

Почти то же самое, с некоторыми нюансами. Расписывать также подробно как с нормальным режимом не буду, особенно аналогичные участки. Настройка в .vimrc начинается с ключевого слова imap, означающего, что дальнейшая последовательность будет работать только в режиме вставки (insert). Далее, собственно, два символа — \h (обратный слеш и h, также, как в нормальном режиме), пробел и команды, назначенные на это сочетание…

  1. TAG — пишем метку, с ней работать удобней. Это просто три набранных буквы. Скажу честно, не знаю, почему без метки не получилось сделать отработку сочетания, если его нажать в начале строки. Вряд ли такой случай понадобится, но хотел сделать универсальное решение.
  2. <ESC> — просто эмуляция нажатия клавиши Escape для перехода в нормальный режим.
  3. FT — ищем назад (команда F) начало метки и ставим курсор на этот символ. Напомню, что если бы искать нужно было вперёд, команда была бы f, и так со многими командами Vim. Искать вперёд и ставить курсор перед найденным символом — t, то же, но обратно — T. Удобнейшие команды! Кстати, последний поиск команд f, F, t и T можно получить через точку с запятой (команда ;).
  4. mh — ставим закладку h, также как в настройке замены цвета. Кстати, это минус моего решения — т. к. можно забыть о том, что закладка (метка) h используется в подстановках цвета и поставить её в редактируемом тексте, а после цветовой подстановки она перепишется. Но это маловероятная мелочь, да и ущерб от неё почти нулевой. Однако, если желаете, попробуйте в качестве разминки переписать алгоритм без использования закладок, или чтобы существующие закладки гарантированно не переписывались ;)
  5. :r/tmp/hexcolor<CR> — про это уже рассказывал выше, теперь чтение внешнего файла должно быть для вас очевидной операцией.
  6. 7x — вырезаем hex-код,
  7. dd — и удаляем пустую строку.
  8. `he — переходим к метке (помните TAG?) и ставим курсор на крайний конечный символ (это будет G).
  9. "-p — вставляем после метки наш цветовой код.
  10. FT — снова ищем начало метки и ставим курсор на первый символ в слове TAG.
  11. dw — удаляем всю метку. Здесь команда удаления d комбинируется с командой w, означающей слово (word). Фактически мы сказали Виму: «удали всё слово». Вот он TAG и удалил. До решётки, потому что решётка — разделительный символ.
  12. ea — снова две команды. Команда e перемещает курсор на конечный символ «слова» (это уже как раз наш вставленный код цвета), после чего команда a переводит редактор в режим вставки, при этом курсор смещается вправо.

Уфф! Рассказать это было раз в двадцать дольше, чем сделать и тщательно протестировать. Надеюсь, старался не зря и кому-то мои труды пригодятся.

Скачать мою версию gcolor2

За фрилансером пришлось переделывать, кстати, был баг. Частая ситуация, к сожалению — человек делает работу как попало и пропадает. Ну ничего, я справился :)

Вы можете скачать исходники или уже скомпилированный пакет для Slackware. Пакет, естественно, должен встать как влитой не только в Slackware, но и в совместимые со Слакой дистрибутивы типа Zenwalk, MOPS, Slax, Salix OS и т. п.

Напоминаю, что моя версия отличается от оригинальной gcolor2 только тем, что пишет значение выбранного цвета в текстовый файлик /tmp/hexcolor. Пишет во время выполнения, то есть можно держать цветовыбиралку открытой.

Комментарии

  1. # tulvit

    Как все сложно=) Точнее, как много букв в мануале по простой вставке кода цвета. Я решительно не понимаю Vim и вообще целесообразность его использования, ИМХО стремиться надо к использованию НетБеанс или Эклипс.

    PS
    Сейчас юзаю Geany, в нем вставка кода цвета автоматическая по дефолту.

  2. # Тормоз

    Я тоже раньше Geany пользовался. Он вообще, даже рядом с Vim не валялся, просто сравнивать нечего.

  3. # Тормоз

    Кстати, это нифига не мануал по вставке цвета. Это просто дополнительный ликбез по командам, сам лучше запомнил и людям помог.

    Мануал очень прост: скачал gcolor2, поставил, добавил две строчки в .vimrc. Всё. Можно пользоваться.

  4. # tulvit

    Надо бы как-нибудь Vim попробовать, чтобы хоть как-то обоснованно его критиковать =) Сейчас пользователи Vim-a мне больше сектантов напоминают.

    И вот такой еще вопрос – можно ли получить представление о Vim-е, пользуясь его дефолтными настройками без всяких дополнений? Или wow-эффект (типа «Как же я раньше его не использовал?!!111») достигнется только после недели курения мануалов и глобальной настройки всего и вся?

  5. # Тормоз

    Если просто «попробовать», то для критики у тебя мало оснований будет :) А если попробуешь всерьез, то вообще вряд ли критиковать захочешь.

    WOW-эффект у меня был на пустом свежем Vim в процессе прохождения vimtutor. Так что можешь попробовать получить этот эффектик уже прямо сейчас, в ближайшие полчаса.

  6. # tulvit

    Не-не-не, только не сегодня и не в ближайшее время, кодить надо, а к новому инструменту еще привыкать придется, как нибудь потом.

    А Vim вообще не противопоказан любителям красивых интерфейсов? Ну то есть чтобы кнопочки были, вкладки, разные менюшки и т. д.

  7. # Тормоз

    Противопоказан, наверно. Хотя, вроде в gVim есть это всё, но не знаю, не пользовался. Нафиг эти менюшечки-кнопочки? Если с мышкой собираешься изучать Vim, то лучше даже не начинать.

  8. # Тормоз

    У Vim прозрачный интерфейс, то есть его можно сказать и нет. Только ты и код.

  9. # tulvit

    Нафиг эти менюшечки-кнопочки?

    Привычка, наверно. В общем, надо бы попробовать, хотя бы «для галочки», а там может и подсяду. Хотя я всегда видел в качестве замены Geany в будущем либо Эклипс, либо НетБеанс, установлены оба, но дружба с ними у меня все как-то не завязывается, слишком уж они монстроподобны.

  10. # Тормоз

    Блин, ты на комменты потратил уже минут 20 или больше, а ведь наверняка не на один мой блог прокрастинируешь ;) За это время можно было пройти vimtutor. Попробуй. Всё равно не работаешь.

  11. # tulvit

    Я просто сильно уставший, только что флудить сил хватает =)

  12. # Тормоз

    Эх, сплошные отмазки у человека. Чего в жизни успеешь? :)

    Я вот сейчас закрываю комменты окончательно и отправляюсь программировать. И делать мне это в таком редакторе просто приятно.

  13. # samlowry

    tulvit, ёп, vimtutor — это типа игры, это не сурьёзный квест на выживание.

    Тормоз, об аглицком, кстати: как это ты осилил vimtutor? :) Или перевод брал? :)

  14. # Тормоз

    У меня русский vimtutor был :) Это сейчас у меня аглицкая локаль стоит, а в те времена (кстати, скоро год) было многое иначе.

    Так ты, значит, тоже учишься, присматриваешься к Виму? Как тебе вообще подход? Как процесс обучения идёт?

  15. # Тормоз

    Кстати, английскую локаль поставил, потому что русские маны часто или сильно устаревшие, или просто коряво переведены. Ну их нафиг. А ещё при русской локали в некоторых программах вылезают древние артефакты, когда почти не знали про UTF-8…

  16. # samlowry

    Да нет, всё никак не сяду. Тока тутора прошёл штук 10-20 заданий, да 3-4 статьи прочитал, чтобы понять, шо це таке.

    Главное — понял, в чём телега VIM-а. Мне он напоминает отличия цифровых данных от аналоговых: у первых мы напрямую обращаемся к чему угодно, у вторых — должны перематывать туда-сюда. Или высокоуровневые языки от низко.

    И, есесна, как педанту, любящему оптимальность, хочется освоить.

    Но текущие задачи у меня — начать проекты, понять, чё вообще делать и что с этого будет. Редактирование тут не при чём.

  17. # Тормоз

    Сперва не понял сравнение с «цифрой» и языками, но потом дошло. Именно так!

  18. # Ал: 

    Сперва не понял сравнение с «цифрой» и языками, но потом дошло. Именно так!

    А я до сих пор не понял. Можно подробнее сравнение расшифровать?

  19. # samlowry

    Ал: в обычных редакторах дан ограниченный набор действий: шаг курсора во все стороны, хом/енд вверх и бока, пейдж ап/даун. Переход на слово по одному алго. Зажим шифта для выделения. 3 команды работы с буфером обмена. ВСЁ!

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

  20. # Ал: 

    2samlowry
    Спасибо, более менее дошло :)

  21. # Clr

    Добавлю каплю холивара. :)

    На мой взгляд, скрипты для вима выглядят как brainf*ck. Ну неужели нельзя было сделать для программирования редактора нормальный язык вместо магических последовательностей управляющих символов?

    Собственно, мне основная идея этого редактора не ясна. С одной стороны, он перерос изначальное «простой переносимый на любое железо консольный редактор». С другой стороны, раз существует такой замечательный программируемый редактор emacs, то насиловать vim зубодробительными макросами смысла тоже нет. :)

  22. # Тормоз

    Эти последовательности выглядят магическими только для сторонних неосиливших наблюдателей. Для меня они прозрачны и полны смысла.

    Однако, насколько я знаю, плагины под Vim можно писать на любом языке.

  23. # Clr

    Проблема в том, что «стороннему неосилившему наблюдателю», в общем-то, нет резона изучать еще один узкоспециализированный ЯП, который нигде больше не пригодится. Тем более, если это write-only язык.

    Если под плагинами понимается то, как плагины сделаны в большинстве «расширяемых» приложений, то это костыль. Должно быть ядро, реализующее базовые абстракции предметной области и полноценный язык типа лиспа или, как минимум, питона или руби, для обвешивания этого ядра любой автоматизацией, какая только придёт в голову. Обычно же делают закрытое решение, а потом в нём сверлят отверстия, чтобы высунуть наружу API.

    Мне это напоминает, как я недавно при помощи shell, sed, awk и такой-то матери пытался реализовать выдирание фрагментов текста из нескольких файлов, несложную их обработку и подстановку в шаблон. После получаса курения гугла и манов плюнул, взял ruby и решил задачу 6-ю простыми строчками кода. Потому что полноценный язык с хорошей библиотекой — это гораздо более мощное средство, чем набор отдельных решений «на все случаи жизни». :)

    И мне любопытство не даёт покоя… :) Не могли бы вы объяснить магию последовательности b2leb? Почему одной только b не достаточно?

  24. # Тормоз

    Если сторонний наблюдатель не видит для себя резона, ну так пусть не изучает. Это как раз совсем не проблема, а если проблема — то непонятно, чья она? :)

    Пример с Ruby тоже не показательный, я вообще не понимаю, причем здесь сравнение текстового редактора с языком программирования? Не станет же этот пресловутый сторонний наблюдатель все задачи редактирования текста делать через Ruby? То-то же.

    Не могли бы вы объяснить магию последовательности b2leb? Почему одной только b не достаточно?

    Потому что нам необходимо одинаково хорошо справляться как с цветами вида #ccc и #123456, так и с ключевыми словами типа black, blue, green и т. п. Решётка — это разделительный символ, поэтому если курсор находится после неё, нажатие b не поставит его на решётку.

    P.S. Ко мне на «ты» лучше.

  25. # Тормоз

    Ой, немножко неправильно объяснил :) В данной ситуации локатор решает как раз обратную задачу: чтобы курсор ставился в начало слова или цифровой последовательности даже в случае, если изначально он стоял на решётке.

  26. # Clr

    Ясно, спасибо.

    Пример с ruby — это такая своеобразная аналогия в сравнении идеологии sed vs ruby и vim vs emacs. :) В первом случае у нас «набор команд для 95% случаев, а покурив траву и изрядно изматерившись, можно придумать, как сделать оставшиеся 5%». Во втором случае — годный тьюринг-полный язык, дающий возможность прямо объяснить машине, что нам от неё надо.

Комментирование этой статьи закрыто.

Интересное Покупки ТехникаРазное Отдых Статьи Строительство Услуги Общество Хобби Культура Советы Уют