Поиск по этому блогу

вторник, 20 апреля 2010 г.

Yaml-формат и GEdit

Хозяйке на заметку

Я пишу в основном под PHP Symfony Framework, поэтому часто сталкиваюсь с редактированием YAML-файлов.
Окончательно переполз под Ubuntu и с удивлением обнаружил что боковая панель (File Browser) в GEdit не показывает в списке файлов и каталогов текстовые файлы *.yml, а так же отсутствует подсветка синтаксиса для данного типа файлов.
Как выяснилось это происходит из-за того что база MIME-типов считает что файлы формат YAML не является текстовыми файлами, а умный GEdit отображает лишь текстовые файлы в своей боковой панели.
Итак, что же делать? Добавим новый MIME-тип:
1) Создадим файлик x-yaml.xml со следующим содержанием:
<?xml version="1.0" encoding="utf-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="text/x-yaml">
<comment>YAML document</comment>
<comment xml:lang="ru">Документ - YAML</comment>
<comment xml:lang="en_GB">YAML document</comment>
<acronym>YAML</acronym>
<sub-class-of type="text/plain"/>
<glob pattern="*.yml"/>
<glob pattern="*.yaml"/>
<expanded-acronym>Yaml Aint Markup Language</expanded-acronym>
</mime-type>
</mime-info>
2) Положим его в /usr/share/mime/packages
3) Выполним sudo update-mime-database /usr/share/mime для обновления
Готово, теперь GEdit прекрасно показывает и открывает YAML-фалики.
Но что это? GEdit теперь видит, открывает, но не знает как раскрасить этот формат файла и не имеет соответствующего файла расцветки.
Что делать? Создаем свой файл "расцветки":
4) Создадим файлик yaml.lang с нижеследующим содержанием:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Masood Behabadi <m.behabadi AT gmail DOT com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<language id="yaml" _name="YAML" version="2.0" _section="Others">
<metadata>
<property name="globs">*.yaml;*.yml;</property>
<property name="line-comment-start">#</property>
</metadata>
<styles>
<style id="scalar" _name="Block literal" map-to="def:string"/>
<style id="comment" _name="Comment" map-to="def:comment"/>
<style id="string" _name="String" map-to="def:string"/>
<style id="anchor" _name="Anchor" map-to="def:identifier"/>
<style id="tag" _name="Tag" map-to="def:preprocessor"/>
<style id="alias" _name="Alias" map-to="def:type"/>
<style id="map-key" _name="Map key" map-to="def:keyword"/>
<style id="directive" _name="Directive" map-to="def:shebang"/>
<style id="null" _name="Null" map-to="def:special-constant"/>
<style id="bool" _name="Boolean" map-to="def:boolean"/>
<style id="int" _name="Integer" map-to="def:decimal"/>
<style id="float" _name="Floating point" map-to="def:floating-point"/>
</styles>
<definitions>
<define-regex id="ischar">[^-\?:,\[\]\{\}#&amp;*!|&gt;'"%@\s]</define-regex>

<define-regex id="lschar">[\s\[\{,]</define-regex>
<define-regex id="rschar">[\s\]\},]</define-regex>
<context id="scalar">
<start>(?&lt;=^|\s)[|&gt;]$</start>
<include>
<context end-parent="true" style-ref="scalar">
<start>^(?'indent'\s+)</start>
<end>^(?!\%{indent@start})</end>
</context>
<context end-parent="true">
<match>(?=.)</match>
</context>
</include>
</context>
<context id="alias" style-ref="alias">
<match>(?&lt;=^|\s)\*\%{ischar}+(?=$|\s)</match>
</context>
<context id="tag" style-ref="tag">
<match>(?&lt;=^|\s)!(?:\%{ischar}*)?!?\%{ischar}+(?=$|\s)</match>
</context>

<context id="anchor" style-ref="anchor">
<match>(?&lt;=^|\s)&amp;\%{ischar}+(?=$|\s)</match>
</context>
<context id="string" end-at-line-end="true" style-ref="string">
<start>(?&lt;=^|\%{lschar})(?'q'["'])</start>
<end>[^\\]\%{q@start}</end>
</context>
<context id="unquoted-string" end-at-line-end="true" style-ref="string">
<start>(?=\%{ischar}|[:-\?\]\}]\S)</start>
<end>(?=:\s|:$|\s#)</end>
</context>
<context id="inline-unquoted" end-at-line-end="true" style-ref="string">
<start>(?=\%{ischar}|-\S)</start>
<end>(?=[:,?\[\{\]\}]|\s#)</end>
</context>
<context id="null" style-ref="null">
<match>(?:null)(?=\s*$|\s+#)</match>
</context>
<context id="inline-null" style-ref="null">
<match>(?:null)(?=\s*[:,?\[\{\]\}]|\s+#)</match>
</context>

<context id="bool" style-ref="bool">
<match>(?:true|false)(?=\s*$|\s+#)</match>
</context>
<context id="inline-bool" style-ref="bool">
<match>(?:true|false)(?=\s*[:,?\[\{\]\}]|\s+#)</match>
</context>

<context id="inline-int" style-ref="int">
<match>-?(?:0|[1-9][0-9]*)(?=\s*[:,?\[\{\]\}]|\s+#)</match>
</context>
<context id="int" style-ref="int">
<match>-?(?:0|[1-9][0-9]*)(?=\s*$|\s+#)</match>
</context>

<context id="inline-float" style-ref="float">
<match>-?(?:0|[1-9][0-9]*)(?:[.][0-9]*)?(?:[eE][-+]?[0-9]+)?(?=\s*[:,?\[\{\]\}]|\s+#)</match>
</context>
<context id="float" style-ref="float">
<match>-?(?:0|[1-9][0-9]*)(?:[.][0-9]*)?(?:[eE][-+]?[0-9]+)?(?=\s*$|\s+#)</match>
</context>
<context id="comment" style-ref="comment">
<match>(?&lt;=^|\s)#.*$</match>
</context>
<context id="inline-sequence">
<start>(?&lt;=^|\s)\[</start>
<include>
<context ref="scalar"/>
<context ref="inline-sequence"/>
<context ref="inline-map"/>
<context ref="comment"/>
<context ref="alias"/>
<context ref="tag"/>
<context ref="anchor"/>
<context ref="string"/>
<context ref="inline-null"/>
<context ref="inline-bool"/>
<context ref="inline-int"/>
<context ref="inline-float"/>
<context ref="inline-unquoted"/>
<context end-parent="true">
<match>\]</match>
</context>
</include>
</context>
<context id="inline-map">
<start>(?&lt;=^|\s)\{</start>
<include>
<context ref="scalar"/>
<context ref="inline-sequence"/>
<context ref="inline-map"/>
<context ref="comment"/>
<context ref="alias"/>
<context ref="tag"/>
<context ref="anchor"/>
<context ref="string"/>
<context ref="inline-null"/>
<context ref="inline-bool"/>
<context ref="inline-int"/>
<context ref="inline-float"/>
<context ref="inline-unquoted"/>
<context end-parent="true">
<match>\}</match>
</context>
</include>
</context>
<context id="map">
<match>(?&lt;=^|\s)((?:[^:]|:(?=\S))+)(?::\s|:$)</match>
<include>
<context sub-pattern="1" style-ref="map-key"/>
</include>
</context>
<context id="sequence">
<match>^\s*-\s+</match>
</context>
<context id="document" style-ref="comment">
<match>^(?:-{3}|[.]{3})(?:\s|$)</match>
</context>
<context id="directive" style-ref="directive">
<match>^%\%{ischar}(?:\%{ischar}|\s)*</match>
</context>
<context id="yaml">
<include>
<context ref="directive"/>
<context ref="document"/>
<context ref="scalar"/>
<context ref="sequence"/>
<context ref="inline-sequence"/>
<context ref="inline-map"/>
<context ref="comment"/>
<context ref="null"/>
<context ref="bool"/>
<context ref="int"/>
<context ref="float"/>
<context ref="alias"/>
<context ref="tag"/>
<context ref="anchor"/>
<context ref="map"/>
<context ref="string"/>
<context ref="unquoted-string"/>
</include>
</context>

</definitions>

</language>
5) Положим его в /usr/share/gtksourceview-2.0/language-specs
Ву-а-ля. Миссия выполнена. Мы подружили GEDIT и YAML.
Теперь мы можем полноценно работать с документами в этом формате.