diff options
Diffstat (limited to 'plugins/snippets')
48 files changed, 12583 insertions, 0 deletions
diff --git a/plugins/snippets/data/c.xml b/plugins/snippets/data/c.xml new file mode 100644 index 0000000..f46ceed --- /dev/null +++ b/plugins/snippets/data/c.xml @@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="C"> + <snippet id="gpl"> + <text><![CDATA[/* + * ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]} + * This file is part of ${2:<program name>} + * + * Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4: +import pwd, os +try: + return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0] +except KeyError: + return '<author\>' > + * + * ${2} 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 2 of the License, or + * (at your option) any later version. + * + * ${2} 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 ${2}. If not, see <http://www.gnu.org/licenses/>. + */ + +$0]]></text> + <tag>gpl</tag> + <description>GPL License</description> + </snippet> + <snippet id="lgpl"> + <text><![CDATA[/* + * ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]} + * This file is part of ${2:<library name>} + * + * Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4: +import pwd, os +try: + return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0] +except KeyError: + return '<author\>' > + * + * ${2} is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * ${2} 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ${2}. If not, see <http://www.gnu.org/licenses/>. + */ + +$0]]></text> + <tag>lgpl</tag> + <description>LGPL License</description> + </snippet> + <snippet id="do"> + <text><![CDATA[do +{ + $0 +} while ($1);]]></text> + <tag>do</tag> + <description>do .. while</description> + </snippet> + <snippet id="for"> + <text><![CDATA[for (${1:i} = ${2:0}; ${1:i} < ${3:count}; ${1:i} += ${4:1}) +{ + $0 +}]]></text> + <tag>for</tag> + <description>for loop</description> + </snippet> + <snippet id="while"> + <text><![CDATA[while (${1:condition}) +{ + $0 +}]]></text> + <tag>while</tag> + <description>while loop</description> + </snippet> + <snippet id="if"> + <text><![CDATA[if (${1:condition}) +{ + $0 +}]]></text> + <tag>if</tag> + <description>if</description> + </snippet> + <snippet id="elif"> + <text><![CDATA[else if (${1:condition}) +{ + $0 +}]]></text> + <tag>elif</tag> + <description>else if</description> + </snippet> + <snippet id="else"> + <text><![CDATA[else +{ + $0 +}]]></text> + <tag>else</tag> + <description>else</description> + </snippet> + <snippet id="Inc"> + <text><![CDATA[#include <${1:file}.h> +$0]]></text> + <tag>Inc</tag> + <description>#include <..></description> + </snippet> + <snippet id="inc"> + <text><![CDATA[#include "${1:file}.h" +$0]]></text> + <tag>inc</tag> + <description>#include ".."</description> + </snippet> + <snippet id="main"> + <text><![CDATA[int +main (int argc, char *argv[]) +{ + $0 + return 0; +}]]></text> + <tag>main</tag> + <description>main</description> + </snippet> + <snippet id="struct"> + <text><![CDATA[struct ${1:name} +{ + ${0:/* data */} +};]]></text> + <tag>struct</tag> + <description>struct</description> + </snippet> + <snippet id="endif"> + <text><![CDATA[#endif +$0]]></text> + <description>#endif</description> + <accelerator><![CDATA[<Control><Alt>period]]></accelerator> + </snippet> + <snippet id="td"> + <text><![CDATA[typedef ${1:newtype} ${2:type}; +$0]]></text> + <tag>td</tag> + <description>typedef</description> + </snippet> + <snippet id="gobject"> + <text><![CDATA[#include "$1.h" +$< +global camel_str,low_str, type_str, is_str, up_str +components = $1.split('-') +low_str = '_'.join(components).lower() +up_str = '_'.join(components).upper() +type_str = '_'.join([components[0], 'TYPE'] + components[1:]).upper() +is_str = '_'.join([components[0], 'IS'] + components[1:]).upper() +camel_str = '' + +for t in components: + camel_str += t.capitalize() +> + +typedef struct _$<[1]: return camel_str >Private +{ +} $<[1]: return camel_str >Private; + +G_DEFINE_TYPE_WITH_PRIVATE ($<[1]: return camel_str >, $<[1]: return low_str >, ${2:G_TYPE_OBJECT}) + +static void +$<[1]: return low_str>_finalize (GObject *object) +{ + G_OBJECT_CLASS ($<[1]: return low_str >_parent_class)->finalize (object); +} + +static void +$<[1]: return low_str >_class_init ($<[1]: return camel_str >Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = $<[1]: return low_str >_finalize; +} + +static void +$<[1]: return low_str >_init ($<[1]: return camel_str> *self) +{ +} + +$<[1]: return camel_str > * +$<[1]: return low_str >_new () +{ + return g_object_new ($<[1]: return type_str >, NULL); +}]]></text> + <tag>gobject</tag> + <description>GObject template</description> + </snippet> + <snippet id="ginterface"> + <text><![CDATA[#include "$1.h" +$< +global camel_str,low_str,up_str +components = $1.split('-') +low_str = '_'.join(components).lower() +up_str = '_'.join(components).upper() +camel_str = '' + +for t in components: + camel_str += t.capitalize() +> +G_DEFINE_INTERFACE ($<[1]: return camel_str >, $<[1]: return low_str >, ${2:G_TYPE_OBJECT}) + +/* Default implementation */ +static const gchar * +$<[1]: return low_str>_example_method_default ($<[1]: return camel_str > *self) +{ + g_return_val_if_reached (NULL); +} + +static void +$<[1]: return low_str>_init ($<[1]: return camel_str >Iface *iface) +{ + static gboolean initialized = FALSE; + + iface->example_method = $<[1]: return low_str>_example_method_default; + + if (!initialized) + { + initialized = TRUE; + } +} + +/* + * This is an method example for an interface + */ +const gchar * +$<[1]: return low_str>_example_method ($<[1]: return camel_str > *self) +{ + g_return_val_if_fail ($<[1]: return up_str> (self), NULL); + return $<[1]: return up_str>_GET_INTERFACE (self)->example_method (self); +}]]></text> + <tag>ginterface</tag> + <description>GObject interface</description> + </snippet> + <snippet> + <text><![CDATA[#include "$1.h" +$< +global camel_str,low_str, type_str, is_str, up_str +components = $1.split('-') +low_str = '_'.join(components).lower() +up_str = '_'.join(components).upper() +type_str = '_'.join([components[0], 'TYPE'] + components[1:]).upper() +camel_str = '' + +for t in components: + camel_str += t.capitalize() +> + +struct _$<[1]: return camel_str > +{ +}; + +G_DEFINE_BOXED_TYPE ($<[1]: return camel_str >, $<[1]: return low_str >, $<[1]: return low_str >_${2:copy}, $<[1]: return low_str >_${3:free}) + +$<[1]: return camel_str > * +$<[1]: return low_str >_${2:copy} ($<[1]: return camel_str > *${4:boxed_name}) +{ + +} + +void +$<[1]: return low_str >_${3:free} ($<[1]: return camel_str > *${4:boxed_name}) +{ + +}]]></text> + <tag>gboxed</tag> + <description>GBoxed template</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/chdr.xml b/plugins/snippets/data/chdr.xml new file mode 100644 index 0000000..2ce94d7 --- /dev/null +++ b/plugins/snippets/data/chdr.xml @@ -0,0 +1,258 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="chdr"> + <snippet id="once"> + <text><![CDATA[#ifndef ${1:NAME}_H +#define $1_H + +$0 + +#endif /* $1_H */ +]]></text> + <description>Header Include-Guard</description> + <tag>once</tag> + </snippet> + <snippet id="inc"> + <text><![CDATA[#include "${1:file}" +$0]]></text> + <description>#include ".."</description> + <tag>inc</tag> + </snippet> + <snippet id="Inc"> + <text><![CDATA[#include <${1:file}> +$0]]></text> + <description>#include <..></description> + <tag>Inc</tag> + </snippet> + <snippet id="namespace"> + <text><![CDATA[namespace ${1:ns} +{ + $0 +}; +]]></text> + <description>namespace ..</description> + <tag>namespace</tag> + </snippet> + <snippet id="gpl"> + <text><![CDATA[/* + * ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]} + * This file is part of ${2:<program name>} + * + * Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4: +import pwd, os +try: + return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0] +except KeyError: + return '<author\>' > + * + * ${2} 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 2 of the License, or + * (at your option) any later version. + * + * ${2} 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 ${2}. If not, see <http://www.gnu.org/licenses/>. + */ + +$0]]></text> + <tag>gpl</tag> + <description>GPL License</description> + </snippet> + <snippet id="lgpl"> + <text><![CDATA[/* + * ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]} + * This file is part of ${2:<library name>} + * + * Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4: +import pwd, os +try: + return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0] +except KeyError: + return '<author\>' > + * + * ${2} is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * ${2} 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ${2}. If not, see <http://www.gnu.org/licenses/>. + */ + +$0]]></text> + <tag>lgpl</tag> + <description>LGPL License</description> + </snippet> + <snippet id="td"> + <text><![CDATA[typedef ${1:newtype} ${2:type}; +$0]]></text> + <tag>td</tag> + <description>typedef</description> + </snippet> + <snippet id="class"> + <text><![CDATA[class ${1:name} +{ + public: + ${1:name} (${2:arguments}); + virtual ~${1:name} (); + + private: + ${0:/* data */} +};]]></text> + <description>class ..</description> + <tag>class</tag> + </snippet> + <snippet id="struct"> + <text><![CDATA[struct ${1:name} +{ + ${0:/* data */} +};]]></text> + <tag>struct</tag> + <description>struct</description> + </snippet> + <snippet id="template"> + <text><![CDATA[template <typename ${1:_InputIter}>]]></text> + <description>template <typename ..></description> + <tag>template</tag> + </snippet> + <snippet id="gobject"> + <text><![CDATA[#ifndef ${1:NAME}_H +#define $1_H +$< +global camel_str, module, name, type_str +components = $1.split('_') +module = components[0].upper() +name = '_'.join(components[1:]).upper() +type_str = '_'.join([components[0], 'TYPE'] + components[1:]).upper() +camel_str = '' + +for t in components: + camel_str += t.capitalize() +> +#include <${2:glib-object.h}> + +G_BEGIN_DECLS + +#define $<[1]: return type_str > ($<[1]: return $1.lower() >_get_type ()) +G_DECLARE_DERIVABLE_TYPE ($<[1]: return camel_str >, $<[1]: return $1.lower() >, $<[1]: return module >, $<[1]: return name >, ${3:GObject}) + +struct _$<[1]: return camel_str >Class +{ + $3Class parent_class; +}; + +$<[1]: return camel_str > *$< return $1.lower()>_new (void); + +$0 +G_END_DECLS + +#endif /* $1_H */]]></text> + <tag>gobject</tag> + <description>GObject template</description> + </snippet> + <snippet id="ginterface"> + <text><![CDATA[#ifndef ${1:NAME}_H +#define $1_H + +#include <${2:glib-object.h}> + +G_BEGIN_DECLS + +$< +global camel_str +components = $1.split('_') +type_str = '_'.join([components[0], 'TYPE'] + components[1:]) +is_str = '_'.join([components[0], 'IS'] + components[1:]) +camel_str = '' + +for t in components: + camel_str += t.capitalize() + +items = [ \ +['#define ' + type_str, '(' + $1.lower() + '_get_type ())'], \ +['#define ' + $1 + '(obj)', '(G_TYPE_CHECK_INSTANCE_CAST ((obj), ' + type_str + ', ' + camel_str + '))'], \ +['#define ' + is_str + '(obj)', '(G_TYPE_CHECK_INSTANCE_TYPE ((obj), ' + type_str + '))'], \ +['#define ' + $1 + '_GET_INTERFACE(obj)', '(G_TYPE_INSTANCE_GET_INTERFACE ((obj), ' + type_str + ', ' + camel_str + 'Iface))'] +] + +return align(items) > + +$<[1]: +items = [ \ +['typedef struct _' + camel_str, camel_str + ';'], \ +['typedef struct _' + camel_str + 'Iface', camel_str + 'Iface;'], \ +] + +return align(items) > + +struct _$<[1]: return camel_str >Iface +{ + ${7:GTypeInterface} parent; + + const gchar * (*example_method) ($<[1]: return camel_str > *self); +}; + +GType $< return $1.lower() + '_get_type' > (void) G_GNUC_CONST; + +const gchar *$< return $1.lower()>_example_method ($<[1]: return camel_str > *self); +$0 +G_END_DECLS + +#endif /* $1_H */]]></text> + <tag>ginterface</tag> + <description>GObject interface</description> + </snippet> + <snippet> + <text><![CDATA[#ifndef ${1:NAME}_H +#define $1_H + +#include <${2:glib-object.h}> + +G_BEGIN_DECLS + +$< +global camel_str +components = $1.split('_') +type_str = '_'.join([components[0], 'TYPE'] + components[1:]) +is_str = '_'.join([components[0], 'IS'] + components[1:]) +camel_str = '' + +for t in components: + camel_str += t.capitalize() + +items = [ \ +['#define ' + type_str, '(' + $1.lower() + '_get_type ())'], \ +['#define ' + $1 + '(obj)', '((' + camel_str + ' *)obj)'], \ +['#define ' + $1 + '_CONST(obj)', '((' + camel_str + ' const *)obj)'], \ +] + +return align(items) > + +$<[1]: +items = [ \ +['typedef struct _' + camel_str, camel_str + ';'], \ +] + +return align(items) > + +GType $< return $1.lower() + '_get_type' > (void) G_GNUC_CONST; +$<[1]: return camel_str > *$< return $1.lower()>_${3:copy} ($<[1]: return camel_str > *${4:boxed_name}); +void $< return $1.lower()>_${5:free} ($<[1]: return camel_str > *${4:boxed_name}); + +$0 +G_END_DECLS + +#endif /* $1_H */]]></text> + <tag>gboxed</tag> + <description>GBoxed template</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/cpp.xml b/plugins/snippets/data/cpp.xml new file mode 100644 index 0000000..1d4c31c --- /dev/null +++ b/plugins/snippets/data/cpp.xml @@ -0,0 +1,180 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="cpp"> + <snippet id="main"> + <text><![CDATA[int main (int argc, char const* argv[]) +{ + $0 + return 0; +}]]></text> + <description>main</description> + <tag>main</tag> + </snippet> + <snippet id="for"> + <text><![CDATA[for (${1:unsigned int} ${2:i} = ${3:0}; ${2:i} < ${4:count}; ${2:i} += ${5:1}) +{ + $0 +}]]></text> + <description>for loop</description> + <tag>for</tag> + </snippet> + <snippet id="beginend"> + <text><![CDATA[${1:v}.begin(), ${1:v}.end()]]></text> + <description>$1.begin</description> + <tag>beginend</tag> + </snippet> + <snippet id="do"> + <text><![CDATA[do +{ + $0 +} while ($1 );]]></text> + <description>do .. while</description> + <tag>do</tag> + </snippet> + <snippet id="endif"> + <text><![CDATA[#endif +$0]]></text> + <accelerator><![CDATA[<Control><Alt>period]]></accelerator> + <description>#endif</description> + </snippet> + <snippet id="if"> + <text><![CDATA[if (${1:condition}) +{ + $0 +}]]></text> + <description>if ..</description> + <tag>if</tag> + </snippet> + <snippet id="inc"> + <text><![CDATA[#include "${1:file}" +$0]]></text> + <description>#include ".."</description> + <tag>inc</tag> + </snippet> + <snippet id="Inc"> + <text><![CDATA[#include <${1:file}> +$0]]></text> + <description>#include <..></description> + <tag>Inc</tag> + </snippet> + <snippet id="namespace"> + <text><![CDATA[namespace ${1:ns} +{ + $0 +}; +]]></text> + <description>namespace ..</description> + <tag>namespace</tag> + </snippet> + <snippet id="readfile"> + <text><![CDATA[std::vector<uint8_t> v; +if (FILE* fp = fopen (${1:"filename"}, "r")) +{ + uint8_t buf[1024]; + while (size_t len = fread (buf, 1, sizeof (buf), fp)) + v.insert (v.end(), buf, buf + len); + fclose(fp); +} +$0]]></text> + <description>Read File Into Vector</description> + <tag>readfile</tag> + </snippet> + <snippet id="map"> + <text><![CDATA[std::map<${1:key}, ${2:value}> ${3:map}; +$0]]></text> + <description>std::map</description> + <tag>map</tag> + </snippet> + <snippet id="vector"> + <text><![CDATA[std::vector<${1:char}> ${2:v}; +$0]]></text> + <description>std::vector</description> + <tag>vector</tag> + </snippet> + <snippet id="struct"> + <text><![CDATA[struct ${1:name} +{ + ${0:/* data */} +};]]></text> + <description>struct ..</description> + <tag>struct</tag> + </snippet> + <snippet id="template"> + <text><![CDATA[template <typename ${1:_InputIter}>]]></text> + <description>template <typename ..></description> + <tag>template</tag> + </snippet> + <snippet id="gpl"> + <text><![CDATA[/* + * ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]} + * This file is part of ${2:<program name>} + * + * Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4: +import pwd, os +try: + return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0] +except KeyError: + return '<author\>' > + * + * ${2} 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 2 of the License, or + * (at your option) any later version. + * + * ${2} 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 ${2}. If not, see <http://www.gnu.org/licenses/>. + */ + + $0]]></text> + <tag>gpl</tag> + <description>GPL License</description> + </snippet> + <snippet id="lgpl"> + <text><![CDATA[/* + * ${1:[$GEDIT_CURRENT_DOCUMENT_NAME,<filename>]} + * This file is part of ${2:<library name>} + * + * Copyright (C) $<3: import datetime; return str(datetime.date.today().year)> - $<4: +import pwd, os +try: + return pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0] +except KeyError: + return '<author\>' > + * + * ${2} is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * ${2} 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with ${2}. If not, see <http://www.gnu.org/licenses/>. + */ + + $0]]></text> + <tag>lgpl</tag> + <description>LGPL License</description> + </snippet> + <snippet id="td"> + <text><![CDATA[typedef ${1:newtype} ${2:type}; +$0]]></text> + <tag>td</tag> + <description>typedef</description> + </snippet> + <snippet id="while"> + <text><![CDATA[while ($1) +{ + $0 +}]]></text> + <tag>while</tag> + <description>while</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/css.xml b/plugins/snippets/data/css.xml new file mode 100644 index 0000000..babca91 --- /dev/null +++ b/plugins/snippets/data/css.xml @@ -0,0 +1,557 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="CSS"> + <snippet id="background"> + <text><![CDATA[background-attachment: ${1:scroll/fixed}; +$0]]></text> + <description>background-attachment: scroll/fixed</description> + <tag>background</tag> + </snippet> + <snippet id="background-1"> + <text><![CDATA[background-color: #${1:DDD}; +$0]]></text> + <description>background-color: color-hex</description> + <tag>background</tag> + </snippet> + <snippet id="background-2"> + <text><![CDATA[background-color: ${1:red}; +$0]]></text> + <description>background-color: color-name</description> + <tag>background</tag> + </snippet> + <snippet id="background-3"> + <text><![CDATA[background-color: rgb(${1:255},${2:255},${3:255}); +$0]]></text> + <description>background-color: color-rgb</description> + <tag>background</tag> + </snippet> + <snippet id="background-4"> + <text><![CDATA[background: #${1:DDD} url($2) ${3:repeat/repeat-x/repeat-y/no-repeat} ${4:scroll/fixed} ${5:top letft/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos}; +$0]]></text> + <description>background: color image repeat attachment position</description> + <tag>background</tag> + </snippet> + <snippet id="background-5"> + <text><![CDATA[background-color: transparent; +$0]]></text> + <description>background-color: transparent</description> + <tag>background</tag> + </snippet> + <snippet id="background-6"> + <text><![CDATA[background-image: none; +$0]]></text> + <description>background-image: none</description> + <tag>background</tag> + </snippet> + <snippet id="background-7"> + <text><![CDATA[background-image: url($1); +$0]]></text> + <description>background-image: url</description> + <tag>background</tag> + </snippet> + <snippet id="background-8"> + <text><![CDATA[background-position: ${1:top letft/top center/top right/center left/center center/center right/bottom left/bottom center/bottom right/x-% y-%/x-pos y-pos}; +$0]]></text> + <description>background-position: position</description> + <tag>background</tag> + </snippet> + <snippet id="background-9"> + <text><![CDATA[background-repeat: ${1:repeat/repeat-x/repeat-y/no-repeat}; +$0]]></text> + <description>background-repeat: r/r-x/r-y/n-r</description> + <tag>background</tag> + </snippet> + <snippet id="border"> + <text><![CDATA[border-bottom-color: #${1:999}; +$0]]></text> + <description>border-bottom-color: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-1"> + <text><![CDATA[border-bottom: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-bottom: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-2"> + <text><![CDATA[border-bottom-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset}; +$0]]></text> + <description>border-bottom-style: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-3"> + <text><![CDATA[border-bottom-width: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-bottom-width: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-4"> + <text><![CDATA[border-color: ${1:999}; +$0]]></text> + <description>border-color: color</description> + <tag>border</tag> + </snippet> + <snippet id="border-5"> + <text><![CDATA[border-right-color: #${1:999}; +$0]]></text> + <description>border-left-color: color</description> + <tag>border</tag> + </snippet> + <snippet id="border-6"> + <text><![CDATA[border-left: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-left: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-7"> + <text><![CDATA[border-left-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset}; +$0]]></text> + <description>border-left-style: style</description> + <tag>border</tag> + </snippet> + <snippet id="border-8"> + <text><![CDATA[border-left-width: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-left-width: size</description> + <tag>border</tag> + </snippet> + <snippet id="border-9"> + <text><![CDATA[border-right-color: #${1:999}; +$0]]></text> + <description>border-right-color: color</description> + <tag>border</tag> + </snippet> + <snippet id="border-10"> + <text><![CDATA[border-right: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-right: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-11"> + <text><![CDATA[border-right-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset}; +$0]]></text> + <description>border-right-style: style</description> + <tag>border</tag> + </snippet> + <snippet id="border-12"> + <text><![CDATA[border-right-width: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-right-width: size</description> + <tag>border</tag> + </snippet> + <snippet id="border-13"> + <text><![CDATA[border: ${1:1px} ${2:solid} #${3:999}; +$0]]></text> + <description>border: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-14"> + <text><![CDATA[border-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset}; +$0]]></text> + <description>border-style: style</description> + <tag>border</tag> + </snippet> + <snippet id="border-15"> + <text><![CDATA[border-top-color: #${1:999}; +$0]]></text> + <description>border-top-color: color</description> + <tag>border</tag> + </snippet> + <snippet id="border-16"> + <text><![CDATA[border-top: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-top: size style color</description> + <tag>border</tag> + </snippet> + <snippet id="border-17"> + <text><![CDATA[border-top-style: ${1:none/hidden/dotted/dashed/solid/double/groove/ridge/inset/outset}; +$0]]></text> + <description>border-top-style: style</description> + <tag>border</tag> + </snippet> + <snippet id="border-18"> + <text><![CDATA[border-top-width: ${1:1}px ${2:solid} #${3:999}; +$0]]></text> + <description>border-top-width: size</description> + <tag>border</tag> + </snippet> + <snippet id="border-19"> + <text><![CDATA[border-color: ${1:1px}; +$0]]></text> + <description>border-width: width</description> + <tag>border</tag> + </snippet> + <snippet id="clear"> + <text><![CDATA[clear: ${1:left/right/both/none}; +$0]]></text> + <description>clear: value</description> + <tag>clear</tag> + </snippet> + <snippet id="color"> + <text><![CDATA[color: #${1:DDD}; +$0]]></text> + <description>color: color-hex</description> + <tag>color</tag> + </snippet> + <snippet id="color-1"> + <text><![CDATA[color: ${1:red}; +$0]]></text> + <description>color: color-name</description> + <tag>color</tag> + </snippet> + <snippet id="color-2"> + <text><![CDATA[color: rgb(${1:255},${2:255},${3:255}); +$0]]></text> + <description>color: color-rgb</description> + <tag>color</tag> + </snippet> + <snippet id="cursor"> + <text><![CDATA[cursor: {$1:default/auto/crosshair/pointer/move/*-resize/text/wait/help}; +$0]]></text> + <description>cursor: type</description> + <tag>cursor</tag> + </snippet> + <snippet id="clear-1"> + <text><![CDATA[cursor: url($1); +$0]]></text> + <description>cursor: url</description> + <tag>clear</tag> + </snippet> + <snippet id="direction"> + <text><![CDATA[direction: ${1:ltr|rtl}; +$0]]></text> + <description>direction: ltr|rtl</description> + <tag>direction</tag> + </snippet> + <snippet id="display"> + <text><![CDATA[display: block; +$0]]></text> + <description>display: block</description> + <tag>display</tag> + </snippet> + <snippet id="display-1"> + <text><![CDATA[display: ${1:none/inline/block/list-item/run-in/compact/marker}; +$0]]></text> + <description>display: common-types</description> + <tag>display</tag> + </snippet> + <snippet id="display-2"> + <text><![CDATA[display: inline; +$0]]></text> + <description>display: inline</description> + <tag>display</tag> + </snippet> + <snippet id="display-3"> + <text><![CDATA[display: ${1:table/inline-table/table-row-group/table-header-group/table-footer-group/table-row/table-column-group/table-column/table-cell/table-caption}; +$0]]></text> + <description>display: table-types</description> + <tag>display</tag> + </snippet> + <snippet id="float"> + <text><![CDATA[float: ${1:left/right/none}; +$0]]></text> + <description>float: left/right/none</description> + <tag>float</tag> + </snippet> + <snippet id="font"> + <text><![CDATA[font-family: ${1:Arial, "MS Trebuchet"}, ${2:sans-}serif; +$0]]></text> + <description>font-family: family</description> + <tag>font</tag> + </snippet> + <snippet id="font-1"> + <text><![CDATA[font: ${1:75%} ${2:"Lucida Grande", "Trebuchet MS", Verdana,} ${3:sans-}serif; +$0]]></text> + <description>font: size font</description> + <tag>font</tag> + </snippet> + <snippet id="font-2"> + <text><![CDATA[font-size: ${1:100%}; +$0]]></text> + <description>font-size: size</description> + <tag>font</tag> + </snippet> + <snippet id="font-3"> + <text><![CDATA[font-style: ${1:normal/italic/oblique}; +$0]]></text> + <description>font-style: normal/italic/oblique</description> + <tag>font</tag> + </snippet> + <snippet id="font-4"> + <text><![CDATA[font: ${1:normal/italic/oblique} ${2:normal/small-caps} ${3:normal/bold} ${4:1em/1.5em} ${5:Arial}, ${6:sans-}serif; +$0]]></text> + <description>font: style variant weight size/line-height font-family</description> + <tag>font</tag> + </snippet> + <snippet id="font-5"> + <text><![CDATA[font-variant: ${1:normal/small-caps}; +$0]]></text> + <description>font-variant: normal/small-caps</description> + <tag>font</tag> + </snippet> + <snippet id="font-6"> + <text><![CDATA[font-weight: ${1:normal/bold}; +$0]]></text> + <description>font-weight: weight</description> + <tag>font</tag> + </snippet> + <snippet id="letter"> + <text><![CDATA[letter-spacing: $1em; +$0]]></text> + <description>letter-spacing: length-em</description> + <tag>letter</tag> + </snippet> + <snippet id="letter-1"> + <text><![CDATA[letter-spacing: $1px; +$0]]></text> + <description>letter-spacing: length-px</description> + <tag>letter</tag> + </snippet> + <snippet id="list"> + <text><![CDATA[list-style-image: url($1); +$0]]></text> + <description>list-style-image: url</description> + <tag>list</tag> + </snippet> + <snippet id="list-1"> + <text><![CDATA[list-style-position: ${1:inside/outside}; +$0]]></text> + <description>list-style-position: pos</description> + <tag>list</tag> + </snippet> + <snippet id="list-2"> + <text><![CDATA[list-style-type: ${1:cjk-ideographic/hiragana/katakana/hiragana-iroha/katakana-iroha}; +$0]]></text> + <description>list-style-type: asian</description> + <tag>list</tag> + </snippet> + <snippet id="list-3"> + <text><![CDATA[list-style-type: ${1:none/disc/circle/square}; +$0]]></text> + <description>list-style-type: marker</description> + <tag>list</tag> + </snippet> + <snippet id="list-4"> + <text><![CDATA[list-style-type: ${1:decimal/decimal-leading-zero/zero}; +$0]]></text> + <description>list-style-type: numeric</description> + <tag>list</tag> + </snippet> + <snippet id="list-5"> + <text><![CDATA[list-style-type: ${1:hebrew/armenian/georgian}; +$0]]></text> + <description>list-style-type: other</description> + <tag>list</tag> + </snippet> + <snippet id="list-6"> + <text><![CDATA[list-style: ${1:none/disc/circle/square/decimal/zero} ${2:inside/outside} url($3); +$0]]></text> + <description>list-style: type position image</description> + <tag>list</tag> + </snippet> + <snippet id="list-7"> + <text><![CDATA[list-style-type: ${1:lower-roman/uppert-roman/lower-alpha/upper-alpha/lower-greek/lower-latin/upper-latin}; +$0]]></text> + <description>list-style-type: roman-alpha-greek</description> + <tag>list</tag> + </snippet> + <snippet id="margin"> + <text><![CDATA[margin: ${1:20px}; +$0]]></text> + <description>margin: all</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-1"> + <text><![CDATA[margin-bottom: ${1:20px}; +$0]]></text> + <description>margin-bottom: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-2"> + <text><![CDATA[margin-left: ${1:20px}; +$0]]></text> + <description>margin-left: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-3"> + <text><![CDATA[margin-right: ${1:20px}; +$0]]></text> + <description>margin-right: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-4"> + <text><![CDATA[margin-top: ${1:20px}; +$0]]></text> + <description>margin-top: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-5"> + <text><![CDATA[margin: ${1:20px} ${2:0px} ${3:40px} ${4:0px}; +$0]]></text> + <description>margin: T R B L</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-6"> + <text><![CDATA[margin: ${1:20px} ${2:0px}; +$0]]></text> + <description>margin: V H</description> + <tag>margin</tag> + </snippet> + <snippet id="marker"> + <text><![CDATA[marker-offset: auto; +$0]]></text> + <description>marker-offset: auto</description> + <tag>marker</tag> + </snippet> + <snippet id="marker-1"> + <text><![CDATA[marker-offset: ${1:10px}; +$0]]></text> + <description>marker-offset: length</description> + <tag>marker</tag> + </snippet> + <snippet id="overflow"> + <text><![CDATA[overflow: ${1:visible/hidden/scroll/auto}; +$0]]></text> + <description>overflow: type</description> + <tag>overflow</tag> + </snippet> + <snippet id="padding"> + <text><![CDATA[padding: ${1:20px}; +$0]]></text> + <description>padding: all</description> + <tag>padding</tag> + </snippet> + <snippet id="margin-7"> + <text><![CDATA[padding-bottom: ${1:20px}; +$0]]></text> + <description>padding-bottom: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-8"> + <text><![CDATA[padding-left: ${1:20px}; +$0]]></text> + <description>padding-left: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-9"> + <text><![CDATA[padding-right: ${1:20px}; +$0]]></text> + <description>padding-right: length</description> + <tag>margin</tag> + </snippet> + <snippet id="margin-10"> + <text><![CDATA[padding-top: ${1:20px}; +$0]]></text> + <description>padding-top: length</description> + <tag>margin</tag> + </snippet> + <snippet id="padding-1"> + <text><![CDATA[padding: ${1:20px} ${2:0px} ${3:40px} ${4:0px}; +$0]]></text> + <description>padding: T R B L</description> + <tag>padding</tag> + </snippet> + <snippet id="padding-2"> + <text><![CDATA[padding: ${1:20px} ${2:0px}; +$0]]></text> + <description>padding: V H</description> + <tag>padding</tag> + </snippet> + <snippet id="position"> + <text><![CDATA[position: ${1:static/relative/absolute/fixed}; +$0]]></text> + <description>position: type</description> + <tag>position</tag> + </snippet> + <snippet id="{"> + <text><![CDATA[{ + /* $1 */ + $0 +]]></text> + <description>properties { }</description> + <tag>{</tag> + </snippet> + <snippet id="text"> + <text><![CDATA[text-align: ${1:left/right/center/justify}; +$0]]></text> + <description>text-align: left/center/right</description> + <tag>text</tag> + </snippet> + <snippet id="text-1"> + <text><![CDATA[text-decoration: ${1:none/underline/overline/line-through/blink}; +$0]]></text> + <description>text-decoration: none/underline/overline/line-through/blink</description> + <tag>text</tag> + </snippet> + <snippet id="text-2"> + <text><![CDATA[text-indent: ${1:10p}x; +$0]]></text> + <description>text-indent: length</description> + <tag>text</tag> + </snippet> + <snippet id="text-3"> + <text><![CDATA[text-shadow: #${1:DDD} ${2:10px} ${3:10px} ${4:2px}; +$0]]></text> + <description>text-shadow: color-hex x y blur</description> + <tag>text</tag> + </snippet> + <snippet id="text-4"> + <text><![CDATA[text-shadow: rgb(${1:255},${2:255},${3:255}) ${4:10px} ${5:10px} ${6:2px}; +$0]]></text> + <description>text-shadow: color-rgb x y blur</description> + <tag>text</tag> + </snippet> + <snippet id="text-5"> + <text><![CDATA[text-shadow: none; +$0]]></text> + <description>text-shadow: none</description> + <tag>text</tag> + </snippet> + <snippet id="text-6"> + <text><![CDATA[text-transform: ${1:capitalize/uppercase/lowercase}; +$0]]></text> + <description>text-transform: capitalize/upper/lower</description> + <tag>text</tag> + </snippet> + <snippet id="text-7"> + <text><![CDATA[text-transform: none; +$0]]></text> + <description>text-transform: none</description> + <tag>text</tag> + </snippet> + <snippet id="vertical"> + <text><![CDATA[vertical-align: ${1:baseline/sub/super/top/text-top/middle/bottom/text-bottom/length/%}; +$0]]></text> + <description>vertical-align: type</description> + <tag>vertical</tag> + </snippet> + <snippet id="visibility"> + <text><![CDATA[visibility: ${1:visible/hidden/collapse}; +$0]]></text> + <description>visibility: type</description> + <tag>visibility</tag> + </snippet> + <snippet id="white"> + <text><![CDATA[white-space: ${1:normal/pre/nowrap}; +$0]]></text> + <description>white-space: normal/pre/nowrap</description> + <tag>white</tag> + </snippet> + <snippet id="word"> + <text><![CDATA[word-spacing: ${1:10px}; +$0]]></text> + <description>word-spacing: length</description> + <tag>word</tag> + </snippet> + <snippet id="word-1"> + <text><![CDATA[word-spacing: normal; +$0]]></text> + <description>word-spacing: normal</description> + <tag>word</tag> + </snippet> + <snippet id="z"> + <text><![CDATA[z-index: $1; +$0]]></text> + <description>z-index: index</description> + <tag>z</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/docbook.xml b/plugins/snippets/data/docbook.xml new file mode 100644 index 0000000..d2a07de --- /dev/null +++ b/plugins/snippets/data/docbook.xml @@ -0,0 +1,2645 @@ +<?xml version='1.0' encoding='utf-8'?> +<!-- + DocBook 4.5 snippets according to DocBook: The Definitive Guide (v2.0.17) + Copyright (C) 2012, 2013 Jaromir Hradilek + + Home Page: https://github.com/jhradilek/gedit-snippets + Last Change: 16 February 2013 +--> +<snippets language="docbook"> + <!-- Core DocBook Snippets: --> + <snippet id="abbrev"> + <text><![CDATA[<abbrev>${1}</abbrev>]]></text> + <tag>abbrev</tag> + <description>abbrev</description> + </snippet> + <snippet id="abstract"> + <text><![CDATA[<abstract> + ${1} +</abstract>]]></text> + <tag>abstract</tag> + <description>abstract</description> + </snippet> + <snippet id="accel"> + <text><![CDATA[<accel>${1}</accel>]]></text> + <tag>accel</tag> + <description>accel</description> + </snippet> + <snippet id="ackno"> + <text><![CDATA[<ackno> + ${1} +</ackno>]]></text> + <tag>ackno</tag> + <description>ackno</description> + </snippet> + <snippet id="acronym"> + <text><![CDATA[<acronym>${1}</acronym>]]></text> + <tag>acronym</tag> + <description>acronym</description> + </snippet> + <snippet id="action"> + <text><![CDATA[<action>${1}</action>]]></text> + <tag>action</tag> + <description>action</description> + </snippet> + <snippet id="address"> + <text><![CDATA[<address> + ${1} +</address>]]></text> + <tag>address</tag> + <description>address</description> + </snippet> + <snippet id="affiliation"> + <text><![CDATA[<affiliation> + ${1} +</affiliation>]]></text> + <tag>affiliation</tag> + <description>affiliation</description> + </snippet> + <snippet id="alt"> + <text><![CDATA[<alt>${1}</alt>]]></text> + <tag>alt</tag> + <description>alt</description> + </snippet> + <snippet id="anchor"> + <text><![CDATA[<anchor id="${1}" />]]></text> + <tag>anchor</tag> + <description>anchor</description> + </snippet> + <snippet id="answer"> + <text><![CDATA[<answer> + ${1} +</answer>]]></text> + <tag>answer</tag> + <description>answer</description> + </snippet> + <snippet id="appendix"> + <text><![CDATA[<appendix id="${1}"> + ${2} +</appendix>]]></text> + <tag>appendix</tag> + <description>appendix</description> + </snippet> + <snippet id="appendixinfo"> + <text><![CDATA[<appendixinfo> + ${1} +</appendixinfo>]]></text> + <tag>appendixinfo</tag> + <description>appendixinfo</description> + </snippet> + <snippet id="application"> + <text><![CDATA[<application>${1}</application>]]></text> + <tag>application</tag> + <description>application</description> + </snippet> + <snippet id="area"> + <text><![CDATA[<area id="${1}" coords="${2}" />]]></text> + <tag>area</tag> + <description>area</description> + </snippet> + <snippet id="areaset"> + <text><![CDATA[<areaset id="${1}" coords="${2}"> + ${3} +</areaset>]]></text> + <tag>areaset</tag> + <description>areaset</description> + </snippet> + <snippet id="areaspec"> + <text><![CDATA[<areaspec units="${1}"> + ${2} +</areaspec>]]></text> + <tag>areaspec</tag> + <description>areaspec</description> + </snippet> + <snippet id="arg"> + <text><![CDATA[<arg>${1}</arg>]]></text> + <tag>arg</tag> + <description>arg</description> + </snippet> + <snippet id="article"> + <text><![CDATA[<article id="${1}"> + ${2} +</article>]]></text> + <tag>article</tag> + <description>article</description> + </snippet> + <snippet id="articleinfo"> + <text><![CDATA[<articleinfo> + ${1} +</articleinfo>]]></text> + <tag>articleinfo</tag> + <description>articleinfo</description> + </snippet> + <snippet id="artpagenums"> + <text><![CDATA[<artpagenums>${1}</artpagenums>]]></text> + <tag>artpagenums</tag> + <description>artpagenums</description> + </snippet> + <snippet id="attribution"> + <text><![CDATA[<attribution>${1}</attribution>]]></text> + <tag>attribution</tag> + <description>attribution</description> + </snippet> + <snippet id="audiodata"> + <text><![CDATA[<audiodata fileref="${1}" />]]></text> + <tag>audiodata</tag> + <description>audiodata</description> + </snippet> + <snippet id="audioobject"> + <text><![CDATA[<audioobject> + ${1} +</audioobject>]]></text> + <tag>audioobject</tag> + <description>audioobject</description> + </snippet> + <snippet id="author"> + <text><![CDATA[<author> + ${1} +</author>]]></text> + <tag>author</tag> + <description>author</description> + </snippet> + <snippet id="authorblurb"> + <text><![CDATA[<authorblurb> + ${1} +</authorblurb>]]></text> + <tag>authorblurb</tag> + <description>authorblurb</description> + </snippet> + <snippet id="authorgroup"> + <text><![CDATA[<authorgroup> + ${1} +</authorgroup>]]></text> + <tag>authorgroup</tag> + <description>authorgroup</description> + </snippet> + <snippet id="authorinitials"> + <text><![CDATA[<authorinitials>${1}</authorinitials>]]></text> + <tag>authorinitials</tag> + <description>authorinitials</description> + </snippet> + <snippet id="beginpage"> + <text><![CDATA[<beginpage pagenum="${1}" />]]></text> + <tag>beginpage</tag> + <description>beginpage</description> + </snippet> + <snippet id="bibliocoverage"> + <text><![CDATA[<bibliocoverage> + ${1} +</bibliocoverage>]]></text> + <tag>bibliocoverage</tag> + <description>bibliocoverage</description> + </snippet> + <snippet id="bibliodiv"> + <text><![CDATA[<bibliodiv> + ${1} +</bibliodiv>]]></text> + <tag>bibliodiv</tag> + <description>bibliodiv</description> + </snippet> + <snippet id="biblioentry"> + <text><![CDATA[<biblioentry> + ${1} +</biblioentry>]]></text> + <tag>biblioentry</tag> + <description>biblioentry</description> + </snippet> + <snippet id="bibliography"> + <text><![CDATA[<bibliography> + ${1} +</bibliography>]]></text> + <tag>bibliography</tag> + <description>bibliography</description> + </snippet> + <snippet id="bibliographyinfo"> + <text><![CDATA[<bibliographyinfo> + ${1} +</bibliographyinfo>]]></text> + <tag>bibliographyinfo</tag> + <description>bibliographyinfo</description> + </snippet> + <snippet id="biblioid"> + <text><![CDATA[<biblioid class="${1:isbn}">${2}</biblioid>]]></text> + <tag>biblioid</tag> + <description>biblioid</description> + </snippet> + <snippet id="bibliolist"> + <text><![CDATA[<bibliolist> + ${1} +</bibliolist>]]></text> + <tag>bibliolist</tag> + <description>bibliolist</description> + </snippet> + <snippet id="bibliomisc"> + <text><![CDATA[<bibliomisc> + ${1} +</bibliomisc>]]></text> + <tag>bibliomisc</tag> + <description>bibliomisc</description> + </snippet> + <snippet id="bibliomixed"> + <text><![CDATA[<bibliomixed> + ${1} +</bibliomixed>]]></text> + <tag>bibliomixed</tag> + <description>bibliomixed</description> + </snippet> + <snippet id="bibliomset"> + <text><![CDATA[<bibliomset relation="${1}"> + ${2} +</bibliomset>]]></text> + <tag>bibliomset</tag> + <description>bibliomset</description> + </snippet> + <snippet id="biblioref"> + <text><![CDATA[<biblioref linkend="${1}" />]]></text> + <tag>biblioref</tag> + <description>biblioref</description> + </snippet> + <snippet id="bibliorelation"> + <text><![CDATA[<bibliorelation type="${1}" class="${2}">${3}</bibliorelation>]]></text> + <tag>bibliorelation</tag> + <description>bibliorelation</description> + </snippet> + <snippet id="biblioset"> + <text><![CDATA[<biblioset relation="${1}"> + ${2} +</biblioset>]]></text> + <tag>biblioset</tag> + <description>biblioset</description> + </snippet> + <snippet id="bibliosource"> + <text><![CDATA[<bibliosource class="${1:isbn}">${2}</bibliosource>]]></text> + <tag>bibliosource</tag> + <description>bibliosource</description> + </snippet> + <snippet id="blockinfo"> + <text><![CDATA[<blockinfo> + ${1} +</blockinfo>]]></text> + <tag>blockinfo</tag> + <description>blockinfo</description> + </snippet> + <snippet id="blockquote"> + <text><![CDATA[<blockquote> + ${1} +</blockquote>]]></text> + <tag>blockquote</tag> + <description>blockquote</description> + </snippet> + <snippet id="book"> + <text><![CDATA[<book id="${1}"> + ${2} +</book>]]></text> + <tag>book</tag> + <description>book</description> + </snippet> + <snippet id="bookinfo"> + <text><![CDATA[<bookinfo> + ${1} +</bookinfo>]]></text> + <tag>bookinfo</tag> + <description>bookinfo</description> + </snippet> + <snippet id="bridgehead"> + <text><![CDATA[<bridgehead id="${1}">${2}</bridgehead>]]></text> + <tag>bridgehead</tag> + <description>bridgehead</description> + </snippet> + <snippet id="callout"> + <text><![CDATA[<callout arearefs="${1}"> + ${2} +</callout>]]></text> + <tag>callout</tag> + <description>callout</description> + </snippet> + <snippet id="calloutlist"> + <text><![CDATA[<calloutlist> + ${1} +</calloutlist>]]></text> + <tag>calloutlist</tag> + <description>calloutlist</description> + </snippet> + <snippet id="caption"> + <text><![CDATA[<caption> + ${1} +</caption>]]></text> + <tag>caption</tag> + <description>caption</description> + </snippet> + <snippet id="caution"> + <text><![CDATA[<caution> + ${1} +</caution>]]></text> + <tag>caution</tag> + <description>caution</description> + </snippet> + <snippet id="chapter"> + <text><![CDATA[<chapter id="${1}"> + ${2} +</chapter>]]></text> + <tag>chapter</tag> + <description>chapter</description> + </snippet> + <snippet id="chapterinfo"> + <text><![CDATA[<chapterinfo> + ${1} +</chapterinfo>]]></text> + <tag>chapterinfo</tag> + <description>chapterinfo</description> + </snippet> + <snippet id="citation"> + <text><![CDATA[<citation>${1}</citation>]]></text> + <tag>citation</tag> + <description>citation</description> + </snippet> + <snippet id="citebiblioid"> + <text><![CDATA[<citebiblioid class="${1:isbn}">${2}</citebiblioid>]]></text> + <tag>citebiblioid</tag> + <description>citebiblioid</description> + </snippet> + <snippet id="citerefentry"> + <text><![CDATA[<citerefentry>${1}</citerefentry>]]></text> + <tag>citerefentry</tag> + <description>citerefentry</description> + </snippet> + <snippet id="citetitle"> + <text><![CDATA[<citetitle pubwork="${1:book}">${2}</citetitle>]]></text> + <tag>citetitle</tag> + <description>citetitle</description> + </snippet> + <snippet id="city"> + <text><![CDATA[<city>${1}</city>]]></text> + <tag>city</tag> + <description>city</description> + </snippet> + <snippet id="classname"> + <text><![CDATA[<classname>${1}</classname>]]></text> + <tag>classname</tag> + <description>classname</description> + </snippet> + <snippet id="classsynopsis"> + <text><![CDATA[<classsynopsis class="${1}" language="${2}"> + ${3} +</classsynopsis>]]></text> + <tag>classsynopsis</tag> + <description>classsynopsis</description> + </snippet> + <snippet id="classsynopsisinfo"> + <text><![CDATA[<classsynopsisinfo> + ${1} +</classsynopsisinfo>]]></text> + <tag>classsynopsisinfo</tag> + <description>classsynopsisinfo</description> + </snippet> + <snippet id="cmdsynopsis"> + <text><![CDATA[<cmdsynopsis> + ${1} +</cmdsynopsis>]]></text> + <tag>cmdsynopsis</tag> + <description>cmdsynopsis</description> + </snippet> + <snippet id="co"> + <text><![CDATA[<co label="${1}" linkends="${2}" />]]></text> + <tag>co</tag> + <description>co</description> + </snippet> + <snippet id="code"> + <text><![CDATA[<code language="${1}">${2}</code>]]></text> + <tag>code</tag> + <description>code</description> + </snippet> + <snippet id="col"> + <text><![CDATA[<col> + ${1} +</col>]]></text> + <tag>col</tag> + <description>col</description> + </snippet> + <snippet id="colgroup"> + <text><![CDATA[<colgroup> + ${1} +</colgroup>]]></text> + <tag>colgroup</tag> + <description>colgroup</description> + </snippet> + <snippet id="collab"> + <text><![CDATA[<collab> + ${1} +</collab>]]></text> + <tag>collab</tag> + <description>collab</description> + </snippet> + <snippet id="collabname"> + <text><![CDATA[<collabname>${1}</collabname>]]></text> + <tag>collabname</tag> + <description>collabname</description> + </snippet> + <snippet id="colophon"> + <text><![CDATA[<colophon> + ${1} +</colophon>]]></text> + <tag>colophon</tag> + <description>colophon</description> + </snippet> + <snippet id="colspec"> + <text><![CDATA[<colspec colname="${1}" colnum="${2}" colwidth="${3}" />]]></text> + <tag>colspec</tag> + <description>colspec</description> + </snippet> + <snippet id="command"> + <text><![CDATA[<command>${1}</command>]]></text> + <tag>command</tag> + <description>command</description> + </snippet> + <snippet id="computeroutput"> + <text><![CDATA[<computeroutput>${1}</computeroutput>]]></text> + <tag>computeroutput</tag> + <description>computeroutput</description> + </snippet> + <snippet id="confdates"> + <text><![CDATA[<confdates>${1}</confdates>]]></text> + <tag>confdates</tag> + <description>confdates</description> + </snippet> + <snippet id="confgroup"> + <text><![CDATA[<confgroup> + ${1} +</confgroup>]]></text> + <tag>confgroup</tag> + <description>confgroup</description> + </snippet> + <snippet id="confnum"> + <text><![CDATA[<confnum>${1}</confnum>]]></text> + <tag>confnum</tag> + <description>confnum</description> + </snippet> + <snippet id="confsponsor"> + <text><![CDATA[<confsponsor>${1}</confsponsor>]]></text> + <tag>confsponsor</tag> + <description>confsponsor</description> + </snippet> + <snippet id="conftitle"> + <text><![CDATA[<conftitle>${1}</conftitle>]]></text> + <tag>conftitle</tag> + <description>conftitle</description> + </snippet> + <snippet id="constant"> + <text><![CDATA[<constant>${1}</constant>]]></text> + <tag>constant</tag> + <description>constant</description> + </snippet> + <snippet id="constructorsynopsis"> + <text><![CDATA[<constructorsynopsis language="${1}"> + ${2} +</constructorsynopsis>]]></text> + <tag>constructorsynopsis</tag> + <description>constructorsynopsis</description> + </snippet> + <snippet id="contractnum"> + <text><![CDATA[<contractnum>${1}</contractnum>]]></text> + <tag>contractnum</tag> + <description>contractnum</description> + </snippet> + <snippet id="contractsponsor"> + <text><![CDATA[<contractsponsor>${1}</contractsponsor>]]></text> + <tag>contractsponsor</tag> + <description>contractsponsor</description> + </snippet> + <snippet id="contrib"> + <text><![CDATA[<contrib>${1}</contrib>]]></text> + <tag>contrib</tag> + <description>contrib</description> + </snippet> + <snippet id="copyright"> + <text><![CDATA[<copyright> + ${1} +</copyright>]]></text> + <tag>copyright</tag> + <description>copyright</description> + </snippet> + <snippet id="coref"> + <text><![CDATA[<coref label="${1}" linkend="${1}" />]]></text> + <tag>coref</tag> + <description>coref</description> + </snippet> + <snippet id="corpauthor"> + <text><![CDATA[<corpauthor>${1}</corpauthor>]]></text> + <tag>corpauthor</tag> + <description>corpauthor</description> + </snippet> + <snippet id="corpcredit"> + <text><![CDATA[<corpcredit>${1}</corpcredit>]]></text> + <tag>corpcredit</tag> + <description>corpcredit</description> + </snippet> + <snippet id="corpname"> + <text><![CDATA[<corpname>${1}</corpname>]]></text> + <tag>corpname</tag> + <description>corpname</description> + </snippet> + <snippet id="country"> + <text><![CDATA[<country>${1}</country>]]></text> + <tag>country</tag> + <description>country</description> + </snippet> + <snippet id="database"> + <text><![CDATA[<database class="${1}">${2}</database>]]></text> + <tag>database</tag> + <description>database</description> + </snippet> + <snippet id="date"> + <text><![CDATA[<date>${1}</date>]]></text> + <tag>date</tag> + <description>date</description> + </snippet> + <snippet id="dedication"> + <text><![CDATA[<dedication> + ${1} +</dedication>]]></text> + <tag>dedication</tag> + <description>dedication</description> + </snippet> + <snippet id="destructorsynopsis"> + <text><![CDATA[<destructorsynopsis language="${1}"> + ${2} +</destructorsynopsis>]]></text> + <tag>destructorsynopsis</tag> + <description>destructorsynopsis</description> + </snippet> + <snippet id="edition"> + <text><![CDATA[<edition>${1}</edition>]]></text> + <tag>edition</tag> + <description>edition</description> + </snippet> + <snippet id="editor"> + <text><![CDATA[<editor> + ${1} +</editor>]]></text> + <tag>editor</tag> + <description>editor</description> + </snippet> + <snippet id="email"> + <text><![CDATA[<email>${1}</email>]]></text> + <tag>email</tag> + <description>email</description> + </snippet> + <snippet id="emphasis"> + <text><![CDATA[<emphasis>${1}</emphasis>]]></text> + <tag>emphasis</tag> + <description>emphasis</description> + </snippet> + <snippet id="entry"> + <text><![CDATA[<entry>${1}</entry>]]></text> + <tag>entry</tag> + <description>entry</description> + </snippet> + <snippet id="entrytbl"> + <text><![CDATA[<entrytbl cols="${1}"> + ${2} +</entrytbl>]]></text> + <tag>entrytbl</tag> + <description>entrytbl</description> + </snippet> + <snippet id="envar"> + <text><![CDATA[<envar>${1}</envar>]]></text> + <tag>envar</tag> + <description>envar</description> + </snippet> + <snippet id="epigraph"> + <text><![CDATA[<epigraph> + ${1} +</epigraph>]]></text> + <tag>epigraph</tag> + <description>epigraph</description> + </snippet> + <snippet id="equation"> + <text><![CDATA[<equation> + ${1} +</equation>]]></text> + <tag>equation</tag> + <description>equation</description> + </snippet> + <snippet id="errorcode"> + <text><![CDATA[<errorcode>${1}</errorcode>]]></text> + <tag>errorcode</tag> + <description>errorcode</description> + </snippet> + <snippet id="errorname"> + <text><![CDATA[<errorname>${1}</errorname>]]></text> + <tag>errorname</tag> + <description>errorname</description> + </snippet> + <snippet id="errortext"> + <text><![CDATA[<errortext>${1}</errortext>]]></text> + <tag>errortext</tag> + <description>errortext</description> + </snippet> + <snippet id="errortype"> + <text><![CDATA[<errortype>${1}</errortype>]]></text> + <tag>errortype</tag> + <description>errortype</description> + </snippet> + <snippet id="example"> + <text><![CDATA[<example id="${1}"> + ${2} +</example>]]></text> + <tag>example</tag> + <description>example</description> + </snippet> + <snippet id="exceptionname"> + <text><![CDATA[<exceptionname>${1}</exceptionname>]]></text> + <tag>exceptionname</tag> + <description>exceptionname</description> + </snippet> + <snippet id="fax"> + <text><![CDATA[<fax>${1}</fax>]]></text> + <tag>fax</tag> + <description>fax</description> + </snippet> + <snippet id="fieldsynopsis"> + <text><![CDATA[<fieldsynopsis language="${1}"> + ${2} +</fieldsynopsis>]]></text> + <tag>fieldsynopsis</tag> + <description>fieldsynopsis</description> + </snippet> + <snippet id="figure"> + <text><![CDATA[<figure id="${1}"> + ${2} +</figure>]]></text> + <tag>figure</tag> + <description>figure</description> + </snippet> + <snippet id="filename"> + <text><![CDATA[<filename>${1}</filename>]]></text> + <tag>filename</tag> + <description>filename</description> + </snippet> + <snippet id="firstname"> + <text><![CDATA[<firstname>${1}</firstname>]]></text> + <tag>firstname</tag> + <description>firstname</description> + </snippet> + <snippet id="firstterm"> + <text><![CDATA[<firstterm>${1}</firstterm>]]></text> + <tag>firstterm</tag> + <description>firstterm</description> + </snippet> + <snippet id="footnote"> + <text><![CDATA[<footnote> + ${1} +</footnote>]]></text> + <tag>footnote</tag> + <description>footnote</description> + </snippet> + <snippet id="footnoteref"> + <text><![CDATA[<footnoteref linkend="${1}" />]]></text> + <tag>footnoteref</tag> + <description>footnoteref</description> + </snippet> + <snippet id="foreignphrase"> + <text><![CDATA[<foreignphrase>${1}</foreignphrase>]]></text> + <tag>foreignphrase</tag> + <description>foreignphrase</description> + </snippet> + <snippet id="formalpara"> + <text><![CDATA[<formalpara> + ${1} +</formalpara>]]></text> + <tag>formalpara</tag> + <description>formalpara</description> + </snippet> + <snippet id="funcdef"> + <text><![CDATA[<funcdef>${1}</funcdef>]]></text> + <tag>funcdef</tag> + <description>funcdef</description> + </snippet> + <snippet id="funcparams"> + <text><![CDATA[<funcparams>${1}</funcparams>]]></text> + <tag>funcparams</tag> + <description>funcparams</description> + </snippet> + <snippet id="funcprototype"> + <text><![CDATA[<funcprototype> + ${1} +</funcprototype>]]></text> + <tag>funcprototype</tag> + <description>funcprototype</description> + </snippet> + <snippet id="funcsynopsis"> + <text><![CDATA[<funcsynopsis> + ${1} +</funcsynopsis>]]></text> + <tag>funcsynopsis</tag> + <description>funcsynopsis</description> + </snippet> + <snippet id="funcsynopsisinfo"> + <text><![CDATA[<funcsynopsisinfo> + ${1} +</funcsynopsisinfo>]]></text> + <tag>funcsynopsisinfo</tag> + <description>funcsynopsisinfo</description> + </snippet> + <snippet id="function"> + <text><![CDATA[<function>${1}</function>]]></text> + <tag>function</tag> + <description>function</description> + </snippet> + <snippet id="glossary"> + <text><![CDATA[<glossary id="${1}"> + ${2} +</glossary>]]></text> + <tag>glossary</tag> + <description>glossary</description> + </snippet> + <snippet id="glossaryinfo"> + <text><![CDATA[<glossaryinfo> + ${1} +</glossaryinfo>]]></text> + <tag>glossaryinfo</tag> + <description>glossaryinfo</description> + </snippet> + <snippet id="glossdef"> + <text><![CDATA[<glossdef> + ${1} +</glossdef>]]></text> + <tag>glossdef</tag> + <description>glossdef</description> + </snippet> + <snippet id="glossdiv"> + <text><![CDATA[<glossdiv> + ${1} +</glossdiv>]]></text> + <tag>glossdiv</tag> + <description>glossdiv</description> + </snippet> + <snippet id="glossentry"> + <text><![CDATA[<glossentry> + ${1} +</glossentry>]]></text> + <tag>glossentry</tag> + <description>glossentry</description> + </snippet> + <snippet id="glosslist"> + <text><![CDATA[<glosslist> + ${1} +</glosslist>]]></text> + <tag>glosslist</tag> + <description>glosslist</description> + </snippet> + <snippet id="glosssee"> + <text><![CDATA[<glosssee otherterm="${1}">${2}</glosssee>]]></text> + <tag>glosssee</tag> + <description>glosssee</description> + </snippet> + <snippet id="glossseealso"> + <text><![CDATA[<glossseealso otherterm="${1}">${2}</glossseealso>]]></text> + <tag>glossseealso</tag> + <description>glossseealso</description> + </snippet> + <snippet id="glossterm"> + <text><![CDATA[<glossterm>${1}</glossterm>]]></text> + <tag>glossterm</tag> + <description>glossterm</description> + </snippet> + <snippet id="graphic"> + <text><![CDATA[<graphic fileref="${1}" />]]></text> + <tag>graphic</tag> + <description>graphic</description> + </snippet> + <snippet id="graphicco"> + <text><![CDATA[<graphicco> + ${1} +</graphicco>]]></text> + <tag>graphicco</tag> + <description>graphicco</description> + </snippet> + <snippet id="group"> + <text><![CDATA[<group> + ${1} +</group>]]></text> + <tag>group</tag> + <description>group</description> + </snippet> + <snippet id="guibutton"> + <text><![CDATA[<guibutton>${1}</guibutton>]]></text> + <tag>guibutton</tag> + <description>guibutton</description> + </snippet> + <snippet id="guiicon"> + <text><![CDATA[<guiicon>${1}</guiicon>]]></text> + <tag>guiicon</tag> + <description>guiicon</description> + </snippet> + <snippet id="guilabel"> + <text><![CDATA[<guilabel>${1}</guilabel>]]></text> + <tag>guilabel</tag> + <description>guilabel</description> + </snippet> + <snippet id="guimenu"> + <text><![CDATA[<guimenu>${1}</guimenu>]]></text> + <tag>guimenu</tag> + <description>guimenu</description> + </snippet> + <snippet id="guimenuitem"> + <text><![CDATA[<guimenuitem>${1}</guimenuitem>]]></text> + <tag>guimenuitem</tag> + <description>guimenuitem</description> + </snippet> + <snippet id="guisubmenu"> + <text><![CDATA[<guisubmenu>${1}</guisubmenu>]]></text> + <tag>guisubmenu</tag> + <description>guisubmenu</description> + </snippet> + <snippet id="hardware"> + <text><![CDATA[<hardware>${1}</hardware>]]></text> + <tag>hardware</tag> + <description>hardware</description> + </snippet> + <snippet id="highlights"> + <text><![CDATA[<highlights> + ${1} +</highlights>]]></text> + <tag>highlights</tag> + <description>highlights</description> + </snippet> + <snippet id="holder"> + <text><![CDATA[<holder>${1}</holder>]]></text> + <tag>holder</tag> + <description>holder</description> + </snippet> + <snippet id="honorific"> + <text><![CDATA[<honorific>${1}</honorific>]]></text> + <tag>honorific</tag> + <description>honorific</description> + </snippet> + <snippet id="imagedata"> + <text><![CDATA[<imagedata fileref="${1}" format="${2:PNG}" scalefit="${3:0}" />]]></text> + <tag>imagedata</tag> + <description>imagedata</description> + </snippet> + <snippet id="imageobject"> + <text><![CDATA[<imageobject> + ${1} +</imageobject>]]></text> + <tag>imageobject</tag> + <description>imageobject</description> + </snippet> + <snippet id="imageobjectco"> + <text><![CDATA[<imageobjectco> + ${1} +</imageobjectco>]]></text> + <tag>imageobjectco</tag> + <description>imageobjectco</description> + </snippet> + <snippet id="important"> + <text><![CDATA[<important> + ${1} +</important>]]></text> + <tag>important</tag> + <description>important</description> + </snippet> + <snippet id="index"> + <text><![CDATA[<index> + ${1} +</index>]]></text> + <tag>index</tag> + <description>index</description> + </snippet> + <snippet id="indexdiv"> + <text><![CDATA[<indexdiv> + ${1} +</indexdiv>]]></text> + <tag>indexdiv</tag> + <description>indexdiv</description> + </snippet> + <snippet id="indexentry"> + <text><![CDATA[<indexentry> + ${1} +</indexentry>]]></text> + <tag>indexentry</tag> + <description>indexentry</description> + </snippet> + <snippet id="indexinfo"> + <text><![CDATA[<indexinfo> + ${1} +</indexinfo>]]></text> + <tag>indexinfo</tag> + <description>indexinfo</description> + </snippet> + <snippet id="indexterm"> + <text><![CDATA[<indexterm> + ${1} +</indexterm>]]></text> + <tag>indexterm</tag> + <description>indexterm</description> + </snippet> + <snippet id="informalequation"> + <text><![CDATA[<informalequation> + ${1} +</informalequation>]]></text> + <tag>informalequation</tag> + <description>informalequation</description> + </snippet> + <snippet id="informalexample"> + <text><![CDATA[<informalexample> + ${1} +</informalexample>]]></text> + <tag>informalexample</tag> + <description>informalexample</description> + </snippet> + <snippet id="informalfigure"> + <text><![CDATA[<informalfigure> + ${1} +</informalfigure>]]></text> + <tag>informalfigure</tag> + <description>informalfigure</description> + </snippet> + <snippet id="informaltable"> + <text><![CDATA[<informaltable> + ${1} +</informaltable>]]></text> + <tag>informaltable</tag> + <description>informaltable</description> + </snippet> + <snippet id="initializer"> + <text><![CDATA[<initializer>${1}</initializer>]]></text> + <tag>initializer</tag> + <description>initializer</description> + </snippet> + <snippet id="inlineequation"> + <text><![CDATA[<inlineequation> + ${1} +</inlineequation>]]></text> + <tag>inlineequation</tag> + <description>inlineequation</description> + </snippet> + <snippet id="inlinegraphic"> + <text><![CDATA[<inlinegraphic fileref="${1}" format="${2:PNG}" scalefit="${3:0}" />]]></text> + <tag>inlinegraphic</tag> + <description>inlinegraphic</description> + </snippet> + <snippet id="inlinemediaobject"> + <text><![CDATA[<inlinemediaobject> + ${1} +</inlinemediaobject>]]></text> + <tag>inlinemediaobject</tag> + <description>inlinemediaobject</description> + </snippet> + <snippet id="interface"> + <text><![CDATA[<interface>${1}</interface>]]></text> + <tag>interface</tag> + <description>interface</description> + </snippet> + <snippet id="interfacename"> + <text><![CDATA[<interfacename>${1}</interfacename>]]></text> + <tag>interfacename</tag> + <description>interfacename</description> + </snippet> + <snippet id="invpartnumber"> + <text><![CDATA[<invpartnumber>${1}</invpartnumber>]]></text> + <tag>invpartnumber</tag> + <description>invpartnumber</description> + </snippet> + <snippet id="isbn"> + <text><![CDATA[<isbn>${1}</isbn>]]></text> + <tag>isbn</tag> + <description>isbn</description> + </snippet> + <snippet id="issn"> + <text><![CDATA[<issn>${1}</issn>]]></text> + <tag>issn</tag> + <description>issn</description> + </snippet> + <snippet id="issuenum"> + <text><![CDATA[<issuenum>${1}</issuenum>]]></text> + <tag>issuenum</tag> + <description>issuenum</description> + </snippet> + <snippet id="itemizedlist"> + <text><![CDATA[<itemizedlist> + ${1} +</itemizedlist>]]></text> + <tag>itemizedlist</tag> + <description>itemizedlist</description> + </snippet> + <snippet id="itermset"> + <text><![CDATA[<itermset> + ${1} +</itermset>]]></text> + <tag>itermset</tag> + <description>itermset</description> + </snippet> + <snippet id="jobtitle"> + <text><![CDATA[<jobtitle>${1}</jobtitle>]]></text> + <tag>jobtitle</tag> + <description>jobtitle</description> + </snippet> + <snippet id="keycap"> + <text><![CDATA[<keycap>${1}</keycap>]]></text> + <tag>keycap</tag> + <description>keycap</description> + </snippet> + <snippet id="keycode"> + <text><![CDATA[<keycode>${1}</keycode>]]></text> + <tag>keycode</tag> + <description>keycode</description> + </snippet> + <snippet id="keycombo"> + <text><![CDATA[<keycombo>${1}</keycombo>]]></text> + <tag>keycombo</tag> + <description>keycombo</description> + </snippet> + <snippet id="keysym"> + <text><![CDATA[<keysym>${1}</keysym>]]></text> + <tag>keysym</tag> + <description>keysym</description> + </snippet> + <snippet id="keyword"> + <text><![CDATA[<keyword>${1}</keyword>]]></text> + <tag>keyword</tag> + <description>keyword</description> + </snippet> + <snippet id="keywordset"> + <text><![CDATA[<keywordset> + ${1} +</keywordset>]]></text> + <tag>keywordset</tag> + <description>keywordset</description> + </snippet> + <snippet id="label"> + <text><![CDATA[<label>${1}</label>]]></text> + <tag>label</tag> + <description>label</description> + </snippet> + <snippet id="legalnotice"> + <text><![CDATA[<legalnotice> + ${1} +</legalnotice>]]></text> + <tag>legalnotice</tag> + <description>legalnotice</description> + </snippet> + <snippet id="lineage"> + <text><![CDATA[<lineage>${1}</lineage>]]></text> + <tag>lineage</tag> + <description>lineage</description> + </snippet> + <snippet id="lineannotation"> + <text><![CDATA[<lineannotation>${1}</lineannotation>]]></text> + <tag>lineannotation</tag> + <description>lineannotation</description> + </snippet> + <snippet id="link"> + <text><![CDATA[<link linkend="${1}">${2}</link>]]></text> + <tag>link</tag> + <description>link</description> + </snippet> + <snippet id="listitem"> + <text><![CDATA[<listitem> + ${1} +</listitem>]]></text> + <tag>listitem</tag> + <description>listitem</description> + </snippet> + <snippet id="literal"> + <text><![CDATA[<literal>${1}</literal>]]></text> + <tag>literal</tag> + <description>literal</description> + </snippet> + <snippet id="literallayout"> + <text><![CDATA[<literallayout>${1}</literallayout>]]></text> + <tag>literallayout</tag> + <description>literallayout</description> + </snippet> + <snippet id="lot"> + <text><![CDATA[<lot> + ${1} +</lot>]]></text> + <tag>lot</tag> + <description>lot</description> + </snippet> + <snippet id="lotentry"> + <text><![CDATA[<lotentry linkend="${1}"> + ${2} +</lotentry>]]></text> + <tag>lotentry</tag> + <description>lotentry</description> + </snippet> + <snippet id="manvolnum"> + <text><![CDATA[<manvolnum>${1}</manvolnum>]]></text> + <tag>manvolnum</tag> + <description>manvolnum</description> + </snippet> + <snippet id="markup"> + <text><![CDATA[<markup>${1}</markup>]]></text> + <tag>markup</tag> + <description>markup</description> + </snippet> + <snippet id="mathphrase"> + <text><![CDATA[<mathphrase>${1}</mathphrase>]]></text> + <tag>mathphrase</tag> + <description>mathphrase</description> + </snippet> + <snippet id="medialabel"> + <text><![CDATA[<medialabel>${1}</medialabel>]]></text> + <tag>medialabel</tag> + <description>medialabel</description> + </snippet> + <snippet id="mediaobject"> + <text><![CDATA[<mediaobject> + ${1} +</mediaobject>]]></text> + <tag>mediaobject</tag> + <description>mediaobject</description> + </snippet> + <snippet id="mediaobjectco"> + <text><![CDATA[<mediaobjectco> + ${1} +</mediaobjectco>]]></text> + <tag>mediaobjectco</tag> + <description>mediaobjectco</description> + </snippet> + <snippet id="member"> + <text><![CDATA[<member> + ${1} +</member>]]></text> + <tag>member</tag> + <description>member</description> + </snippet> + <snippet id="menuchoice"> + <text><![CDATA[<menuchoice>${1}</menuchoice>]]></text> + <tag>menuchoice</tag> + <description>menuchoice</description> + </snippet> + <snippet id="methodname"> + <text><![CDATA[<methodname>${1}</methodname>]]></text> + <tag>methodname</tag> + <description>methodname</description> + </snippet> + <snippet id="methodparam"> + <text><![CDATA[<methodparam>${1}</methodparam>]]></text> + <tag>methodparam</tag> + <description>methodparam</description> + </snippet> + <snippet id="methodsynopsis"> + <text><![CDATA[<methodsynopsis language="${1}"> + ${2} +</methodsynopsis>]]></text> + <tag>methodsynopsis</tag> + <description>methodsynopsis</description> + </snippet> + <snippet id="modespec"> + <text><![CDATA[<modespec application="${1}">${2}</modespec>]]></text> + <tag>modespec</tag> + <description>modespec</description> + </snippet> + <snippet id="modifier"> + <text><![CDATA[<modifier>${1}</modifier>]]></text> + <tag>modifier</tag> + <description>modifier</description> + </snippet> + <snippet id="mousebutton"> + <text><![CDATA[<mousebutton>${1}</mousebutton>]]></text> + <tag>mousebutton</tag> + <description>mousebutton</description> + </snippet> + <snippet id="msg"> + <text><![CDATA[<msg> + ${1} +</msg>]]></text> + <tag>msg</tag> + <description>msg</description> + </snippet> + <snippet id="msgaud"> + <text><![CDATA[<msgaud>${1}</msgaud>]]></text> + <tag>msgaud</tag> + <description>msgaud</description> + </snippet> + <snippet id="msgentry"> + <text><![CDATA[<msgentry> + ${1} +</msgentry>]]></text> + <tag>msgentry</tag> + <description>msgentry</description> + </snippet> + <snippet id="msgexplan"> + <text><![CDATA[<msgexplan> + ${1} +</msgexplan>]]></text> + <tag>msgexplan</tag> + <description>msgexplan</description> + </snippet> + <snippet id="msginfo"> + <text><![CDATA[<msginfo> + ${1} +</msginfo>]]></text> + <tag>msginfo</tag> + <description>msginfo</description> + </snippet> + <snippet id="msglevel"> + <text><![CDATA[<msglevel>${1}</msglevel>]]></text> + <tag>msglevel</tag> + <description>msglevel</description> + </snippet> + <snippet id="msgmain"> + <text><![CDATA[<msgmain> + ${1} +</msgmain>]]></text> + <tag>msgmain</tag> + <description>msgmain</description> + </snippet> + <snippet id="msgorig"> + <text><![CDATA[<msgorig>${1}</msgorig>]]></text> + <tag>msgorig</tag> + <description>msgorig</description> + </snippet> + <snippet id="msgrel"> + <text><![CDATA[<msgrel> + ${1} +</msgrel>]]></text> + <tag>msgrel</tag> + <description>msgrel</description> + </snippet> + <snippet id="msgset"> + <text><![CDATA[<msgset> + ${1} +</msgset>]]></text> + <tag>msgset</tag> + <description>msgset</description> + </snippet> + <snippet id="msgsub"> + <text><![CDATA[<msgsub> + ${1} +</msgsub>]]></text> + <tag>msgsub</tag> + <description>msgsub</description> + </snippet> + <snippet id="msgtext"> + <text><![CDATA[<msgtext> + ${1} +</msgtext>]]></text> + <tag>msgtext</tag> + <description>msgtext</description> + </snippet> + <snippet id="note"> + <text><![CDATA[<note> + ${1} +</note>]]></text> + <tag>note</tag> + <description>note</description> + </snippet> + <snippet id="objectinfo"> + <text><![CDATA[<objectinfo> + ${1} +</objectinfo>]]></text> + <tag>objectinfo</tag> + <description>objectinfo</description> + </snippet> + <snippet id="olink"> + <text><![CDATA[<olink targetdocent="${1}">${2}</olink>]]></text> + <tag>olink</tag> + <description>olink</description> + </snippet> + <snippet id="ooclass"> + <text><![CDATA[<ooclass>${1}</ooclass>]]></text> + <tag>ooclass</tag> + <description>ooclass</description> + </snippet> + <snippet id="ooexception"> + <text><![CDATA[<ooexception>${1}</ooexception>]]></text> + <tag>ooexception</tag> + <description>ooexception</description> + </snippet> + <snippet id="oointerface"> + <text><![CDATA[<oointerface>${1}</oointerface>]]></text> + <tag>oointerface</tag> + <description>oointerface</description> + </snippet> + <snippet id="option"> + <text><![CDATA[<option>${1}</option>]]></text> + <tag>option</tag> + <description>option</description> + </snippet> + <snippet id="optional"> + <text><![CDATA[<optional>${1}</optional>]]></text> + <tag>optional</tag> + <description>optional</description> + </snippet> + <snippet id="orderedlist"> + <text><![CDATA[<orderedlist> + ${1} +</orderedlist>]]></text> + <tag>orderedlist</tag> + <description>orderedlist</description> + </snippet> + <snippet id="orgdiv"> + <text><![CDATA[<orgdiv>${1}</orgdiv>]]></text> + <tag>orgdiv</tag> + <description>orgdiv</description> + </snippet> + <snippet id="orgname"> + <text><![CDATA[<orgname>${1}</orgname>]]></text> + <tag>orgname</tag> + <description>orgname</description> + </snippet> + <snippet id="otheraddr"> + <text><![CDATA[<otheraddr>${1}</otheraddr>]]></text> + <tag>otheraddr</tag> + <description>otheraddr</description> + </snippet> + <snippet id="othercredit"> + <text><![CDATA[<othercredit> + ${1} +</othercredit>]]></text> + <tag>othercredit</tag> + <description>othercredit</description> + </snippet> + <snippet id="othername"> + <text><![CDATA[<othername>${1}</othername>]]></text> + <tag>othername</tag> + <description>othername</description> + </snippet> + <snippet id="package"> + <text><![CDATA[<package>${1}</package>]]></text> + <tag>package</tag> + <description>package</description> + </snippet> + <snippet id="pagenums"> + <text><![CDATA[<pagenums>${1}</pagenums>]]></text> + <tag>pagenums</tag> + <description>pagenums</description> + </snippet> + <snippet id="para"> + <text><![CDATA[<para> + ${1} +</para>]]></text> + <tag>para</tag> + <description>para</description> + </snippet> + <snippet id="paramdef"> + <text><![CDATA[<paramdef>${1}</paramdef>]]></text> + <tag>paramdef</tag> + <description>paramdef</description> + </snippet> + <snippet id="parameter"> + <text><![CDATA[<parameter class="${1:function}">${2}</parameter>]]></text> + <tag>parameter</tag> + <description>parameter</description> + </snippet> + <snippet id="part"> + <text><![CDATA[<part id="${1}"> + ${2} +</part>]]></text> + <tag>part</tag> + <description>part</description> + </snippet> + <snippet id="partinfo"> + <text><![CDATA[<partinfo> + ${1} +</partinfo>]]></text> + <tag>partinfo</tag> + <description>partinfo</description> + </snippet> + <snippet id="partintro"> + <text><![CDATA[<partintro> + ${1} +</partintro>]]></text> + <tag>partintro</tag> + <description>partintro</description> + </snippet> + <snippet id="personblurb"> + <text><![CDATA[<personblurb> + ${1} +</personblurb>]]></text> + <tag>personblurb</tag> + <description>personblurb</description> + </snippet> + <snippet id="personname"> + <text><![CDATA[<personname>${1}</personname>]]></text> + <tag>personname</tag> + <description>personname</description> + </snippet> + <snippet id="phone"> + <text><![CDATA[<phone>${1}</phone>]]></text> + <tag>phone</tag> + <description>phone</description> + </snippet> + <snippet id="phrase"> + <text><![CDATA[<phrase>${1}</phrase>]]></text> + <tag>phrase</tag> + <description>phrase</description> + </snippet> + <snippet id="pob"> + <text><![CDATA[<pob>${1}</pob>]]></text> + <tag>pob</tag> + <description>pob</description> + </snippet> + <snippet id="postcode"> + <text><![CDATA[<postcode>${1}</postcode>]]></text> + <tag>postcode</tag> + <description>postcode</description> + </snippet> + <snippet id="preface"> + <text><![CDATA[<preface id="${1}"> + ${2} +</preface>]]></text> + <tag>preface</tag> + <description>preface</description> + </snippet> + <snippet id="prefaceinfo"> + <text><![CDATA[<prefaceinfo> + ${1} +</prefaceinfo>]]></text> + <tag>prefaceinfo</tag> + <description>prefaceinfo</description> + </snippet> + <snippet id="primary"> + <text><![CDATA[<primary>${1}</primary>]]></text> + <tag>primary</tag> + <description>primary</description> + </snippet> + <snippet id="primaryie"> + <text><![CDATA[<primaryie>${1}</primaryie>]]></text> + <tag>primaryie</tag> + <description>primaryie</description> + </snippet> + <snippet id="printhistory"> + <text><![CDATA[<printhistory> + ${1} +</printhistory>]]></text> + <tag>printhistory</tag> + <description>printhistory</description> + </snippet> + <snippet id="procedure"> + <text><![CDATA[<procedure> + ${1} +</procedure>]]></text> + <tag>procedure</tag> + <description>procedure</description> + </snippet> + <snippet id="productname"> + <text><![CDATA[<productname class="${1:trade}">${2}</productname>]]></text> + <tag>productname</tag> + <description>productname</description> + </snippet> + <snippet id="productnumber"> + <text><![CDATA[<productnumber>${1}</productnumber>]]></text> + <tag>productnumber</tag> + <description>productnumber</description> + </snippet> + <snippet id="programlisting"> + <text><![CDATA[<programlisting language="${1}">${2}</programlisting>]]></text> + <tag>programlisting</tag> + <description>programlisting</description> + </snippet> + <snippet id="programlistingco"> + <text><![CDATA[<programlistingco> + ${1} +</programlistingco>]]></text> + <tag>programlistingco</tag> + <description>programlistingco</description> + </snippet> + <snippet id="prompt"> + <text><![CDATA[<prompt>${1}</prompt>]]></text> + <tag>prompt</tag> + <description>prompt</description> + </snippet> + <snippet id="property"> + <text><![CDATA[<property>${1}</property>]]></text> + <tag>property</tag> + <description>property</description> + </snippet> + <snippet id="pubdate"> + <text><![CDATA[<pubdate>${1}</pubdate>]]></text> + <tag>pubdate</tag> + <description>pubdate</description> + </snippet> + <snippet id="publisher"> + <text><![CDATA[<publisher> + ${1} +</publisher>]]></text> + <tag>publisher</tag> + <description>publisher</description> + </snippet> + <snippet id="publishername"> + <text><![CDATA[<publishername>${1}</publishername>]]></text> + <tag>publishername</tag> + <description>publishername</description> + </snippet> + <snippet id="pubsnumber"> + <text><![CDATA[<pubsnumber>${1}</pubsnumber>]]></text> + <tag>pubsnumber</tag> + <description>pubsnumber</description> + </snippet> + <snippet id="qandadiv"> + <text><![CDATA[<qandadiv> + ${1} +</qandadiv>]]></text> + <tag>qandadiv</tag> + <description>qandadiv</description> + </snippet> + <snippet id="qandaentry"> + <text><![CDATA[<qandaentry> + ${1} +</qandaentry>]]></text> + <tag>qandaentry</tag> + <description>qandaentry</description> + </snippet> + <snippet id="qandaset"> + <text><![CDATA[<qandaset> + ${1} +</qandaset>]]></text> + <tag>qandaset</tag> + <description>qandaset</description> + </snippet> + <snippet id="question"> + <text><![CDATA[<question> + ${1} +</question>]]></text> + <tag>question</tag> + <description>question</description> + </snippet> + <snippet id="quote"> + <text><![CDATA[<quote>${1}</quote>]]></text> + <tag>quote</tag> + <description>quote</description> + </snippet> + <snippet id="refclass"> + <text><![CDATA[<refclass>${1}</refclass>]]></text> + <tag>refclass</tag> + <description>refclass</description> + </snippet> + <snippet id="refdescriptor"> + <text><![CDATA[<refdescriptor>${1}</refdescriptor>]]></text> + <tag>refdescriptor</tag> + <description>refdescriptor</description> + </snippet> + <snippet id="refentry"> + <text><![CDATA[<refentry> + ${1} +</refentry>]]></text> + <tag>refentry</tag> + <description>refentry</description> + </snippet> + <snippet id="refentryinfo"> + <text><![CDATA[<refentryinfo> + ${1} +</refentryinfo>]]></text> + <tag>refentryinfo</tag> + <description>refentryinfo</description> + </snippet> + <snippet id="refentrytitle"> + <text><![CDATA[<refentrytitle>${1}</refentrytitle>]]></text> + <tag>refentrytitle</tag> + <description>refentrytitle</description> + </snippet> + <snippet id="reference"> + <text><![CDATA[<reference> + ${1} +</reference>]]></text> + <tag>reference</tag> + <description>reference</description> + </snippet> + <snippet id="referenceinfo"> + <text><![CDATA[<referenceinfo> + ${1} +</referenceinfo>]]></text> + <tag>referenceinfo</tag> + <description>referenceinfo</description> + </snippet> + <snippet id="refmeta"> + <text><![CDATA[<refmeta> + ${1} +</refmeta>]]></text> + <tag>refmeta</tag> + <description>refmeta</description> + </snippet> + <snippet id="refmiscinfo"> + <text><![CDATA[<refmiscinfo> + ${1} +</refmiscinfo>]]></text> + <tag>refmiscinfo</tag> + <description>refmiscinfo</description> + </snippet> + <snippet id="refname"> + <text><![CDATA[<refname>${1}</refname>]]></text> + <tag>refname</tag> + <description>refname</description> + </snippet> + <snippet id="refnamediv"> + <text><![CDATA[<refnamediv> + ${1} +</refnamediv>]]></text> + <tag>refnamediv</tag> + <description>refnamediv</description> + </snippet> + <snippet id="refpurpose"> + <text><![CDATA[<refpurpose>${1}</refpurpose>]]></text> + <tag>refpurpose</tag> + <description>refpurpose</description> + </snippet> + <snippet id="refsect1"> + <text><![CDATA[<refsect1> + ${1} +</refsect1>]]></text> + <tag>refsect1</tag> + <description>refsect1</description> + </snippet> + <snippet id="refsect1info"> + <text><![CDATA[<refsect1info> + ${1} +</refsect1info>]]></text> + <tag>refsect1info</tag> + <description>refsect1info</description> + </snippet> + <snippet id="refsect2"> + <text><![CDATA[<refsect2> + ${1} +</refsect2>]]></text> + <tag>refsect2</tag> + <description>refsect2</description> + </snippet> + <snippet id="refsect2info"> + <text><![CDATA[<refsect2info> + ${1} +</refsect2info>]]></text> + <tag>refsect2info</tag> + <description>refsect2info</description> + </snippet> + <snippet id="refsect3"> + <text><![CDATA[<refsect3> + ${1} +</refsect3>]]></text> + <tag>refsect3</tag> + <description>refsect3</description> + </snippet> + <snippet id="refsect3info"> + <text><![CDATA[<refsect3info> + ${1} +</refsect3info>]]></text> + <tag>refsect3info</tag> + <description>refsect3info</description> + </snippet> + <snippet id="refsection"> + <text><![CDATA[<refsection> + ${1} +</refsection>]]></text> + <tag>refsection</tag> + <description>refsection</description> + </snippet> + <snippet id="refsectioninfo"> + <text><![CDATA[<refsectioninfo> + ${1} +</refsectioninfo>]]></text> + <tag>refsectioninfo</tag> + <description>refsectioninfo</description> + </snippet> + <snippet id="refsynopsisdiv"> + <text><![CDATA[<refsynopsisdiv> + ${1} +</refsynopsisdiv>]]></text> + <tag>refsynopsisdiv</tag> + <description>refsynopsisdiv</description> + </snippet> + <snippet id="refsynopsisdivinfo"> + <text><![CDATA[<refsynopsisdivinfo> + ${1} +</refsynopsisdivinfo>]]></text> + <tag>refsynopsisdivinfo</tag> + <description>refsynopsisdivinfo</description> + </snippet> + <snippet id="releaseinfo"> + <text><![CDATA[<releaseinfo>${1}</releaseinfo>]]></text> + <tag>releaseinfo</tag> + <description>releaseinfo</description> + </snippet> + <snippet id="remark"> + <text><![CDATA[<remark>${1}</remark>]]></text> + <tag>remark</tag> + <description>remark</description> + </snippet> + <snippet id="replaceable"> + <text><![CDATA[<replaceable>${1}</replaceable>]]></text> + <tag>replaceable</tag> + <description>replaceable</description> + </snippet> + <snippet id="returnvalue"> + <text><![CDATA[<returnvalue>${1}</returnvalue>]]></text> + <tag>returnvalue</tag> + <description>returnvalue</description> + </snippet> + <snippet id="revdescription"> + <text><![CDATA[<revdescription> + ${1} +</revdescription>]]></text> + <tag>revdescription</tag> + <description>revdescription</description> + </snippet> + <snippet id="revhistory"> + <text><![CDATA[<revhistory> + ${1} +</revhistory>]]></text> + <tag>revhistory</tag> + <description>revhistory</description> + </snippet> + <snippet id="revision"> + <text><![CDATA[<revision> + ${1} +</revision>]]></text> + <tag>revision</tag> + <description>revision</description> + </snippet> + <snippet id="revnumber"> + <text><![CDATA[<revnumber>${1}</revnumber>]]></text> + <tag>revnumber</tag> + <description>revnumber</description> + </snippet> + <snippet id="revremark"> + <text><![CDATA[<revremark>${1}</revremark>]]></text> + <tag>revremark</tag> + <description>revremark</description> + </snippet> + <snippet id="row"> + <text><![CDATA[<row> + ${1} +</row>]]></text> + <tag>row</tag> + <description>row</description> + </snippet> + <snippet id="sbr"> + <text><![CDATA[<sbr />]]></text> + <tag>sbr</tag> + <description>sbr</description> + </snippet> + <snippet id="screen"> + <text><![CDATA[<screen>${1}</screen>]]></text> + <tag>screen</tag> + <description>screen</description> + </snippet> + <snippet id="screenco"> + <text><![CDATA[<screenco> + ${1} +</screenco>]]></text> + <tag>screenco</tag> + <description>screenco</description> + </snippet> + <snippet id="screeninfo"> + <text><![CDATA[<screeninfo>${1}</screeninfo>]]></text> + <tag>screeninfo</tag> + <description>screeninfo</description> + </snippet> + <snippet id="screenshot"> + <text><![CDATA[<screenshot> + ${1} +</screenshot>]]></text> + <tag>screenshot</tag> + <description>screenshot</description> + </snippet> + <snippet id="secondary"> + <text><![CDATA[<secondary>${1}</secondary>]]></text> + <tag>secondary</tag> + <description>secondary</description> + </snippet> + <snippet id="secondaryie"> + <text><![CDATA[<secondaryie>${1}</secondaryie>]]></text> + <tag>secondaryie</tag> + <description>secondaryie</description> + </snippet> + <snippet id="sect1"> + <text><![CDATA[<sect1 id="${1}"> + ${2} +</sect1>]]></text> + <tag>sect1</tag> + <description>sect1</description> + </snippet> + <snippet id="sect1info"> + <text><![CDATA[<sect1info> + ${1} +</sect1info>]]></text> + <tag>sect1info</tag> + <description>sect1info</description> + </snippet> + <snippet id="sect2"> + <text><![CDATA[<sect2 id="${1}"> + ${2} +</sect2>]]></text> + <tag>sect2</tag> + <description>sect2</description> + </snippet> + <snippet id="sect2info"> + <text><![CDATA[<sect2info> + ${1} +</sect2info>]]></text> + <tag>sect2info</tag> + <description>sect2info</description> + </snippet> + <snippet id="sect3"> + <text><![CDATA[<sect3 id="${1}"> + ${2} +</sect3>]]></text> + <tag>sect3</tag> + <description>sect3</description> + </snippet> + <snippet id="sect3info"> + <text><![CDATA[<sect3info> + ${1} +</sect3info>]]></text> + <tag>sect3info</tag> + <description>sect3info</description> + </snippet> + <snippet id="sect4"> + <text><![CDATA[<sect4 id="${1}"> + ${2} +</sect4>]]></text> + <tag>sect4</tag> + <description>sect4</description> + </snippet> + <snippet id="sect4info"> + <text><![CDATA[<sect4info> + ${1} +</sect4info>]]></text> + <tag>sect4info</tag> + <description>sect4info</description> + </snippet> + <snippet id="sect5"> + <text><![CDATA[<sect5 id="${1}"> + ${2} +</sect5>]]></text> + <tag>sect5</tag> + <description>sect5</description> + </snippet> + <snippet id="sect5info"> + <text><![CDATA[<sect5info> + ${1} +</sect5info>]]></text> + <tag>sect5info</tag> + <description>sect5info</description> + </snippet> + <snippet id="section"> + <text><![CDATA[<section id="${1}"> + ${2} +</section>]]></text> + <tag>section</tag> + <description>section</description> + </snippet> + <snippet id="sectioninfo"> + <text><![CDATA[<sectioninfo> + ${1} +</sectioninfo>]]></text> + <tag>sectioninfo</tag> + <description>sectioninfo</description> + </snippet> + <snippet id="see"> + <text><![CDATA[<see>${1}</see>]]></text> + <tag>see</tag> + <description>see</description> + </snippet> + <snippet id="seealso"> + <text><![CDATA[<seealso>${1}</seealso>]]></text> + <tag>seealso</tag> + <description>seealso</description> + </snippet> + <snippet id="seealsoie"> + <text><![CDATA[<seealsoie>${1}</seealsoie>]]></text> + <tag>seealsoie</tag> + <description>seealsoie</description> + </snippet> + <snippet id="seeie"> + <text><![CDATA[<seeie>${1}</seeie>]]></text> + <tag>seeie</tag> + <description>seeie</description> + </snippet> + <snippet id="seg"> + <text><![CDATA[<seg>${1}</seg>]]></text> + <tag>seg</tag> + <description>seg</description> + </snippet> + <snippet id="seglistitem"> + <text><![CDATA[<seglistitem> + ${1} +</seglistitem>]]></text> + <tag>seglistitem</tag> + <description>seglistitem</description> + </snippet> + <snippet id="segmentedlist"> + <text><![CDATA[<segmentedlist> + ${1} +</segmentedlist>]]></text> + <tag>segmentedlist</tag> + <description>segmentedlist</description> + </snippet> + <snippet id="segtitle"> + <text><![CDATA[<segtitle>${1}</segtitle>]]></text> + <tag>segtitle</tag> + <description>segtitle</description> + </snippet> + <snippet id="seriesvolnums"> + <text><![CDATA[<seriesvolnums>${1}</seriesvolnums>]]></text> + <tag>seriesvolnums</tag> + <description>seriesvolnums</description> + </snippet> + <snippet id="set"> + <text><![CDATA[<set> + ${1} +</set>]]></text> + <tag>set</tag> + <description>set</description> + </snippet> + <snippet id="setindex"> + <text><![CDATA[<setindex> + ${1} +</setindex>]]></text> + <tag>setindex</tag> + <description>setindex</description> + </snippet> + <snippet id="setindexinfo"> + <text><![CDATA[<setindexinfo> + ${1} +</setindexinfo>]]></text> + <tag>setindexinfo</tag> + <description>setindexinfo</description> + </snippet> + <snippet id="setinfo"> + <text><![CDATA[<setinfo> + ${1} +</setinfo>]]></text> + <tag>setinfo</tag> + <description>setinfo</description> + </snippet> + <snippet id="sgmltag"> + <text><![CDATA[<sgmltag>${1}</sgmltag>]]></text> + <tag>sgmltag</tag> + <description>sgmltag</description> + </snippet> + <snippet id="shortaffil"> + <text><![CDATA[<shortaffil>${1}</shortaffil>]]></text> + <tag>shortaffil</tag> + <description>shortaffil</description> + </snippet> + <snippet id="shortcut"> + <text><![CDATA[<shortcut>${1}</shortcut>]]></text> + <tag>shortcut</tag> + <description>shortcut</description> + </snippet> + <snippet id="sidebar"> + <text><![CDATA[<sidebar> + ${1} +</sidebar>]]></text> + <tag>sidebar</tag> + <description>sidebar</description> + </snippet> + <snippet id="sidebarinfo"> + <text><![CDATA[<sidebarinfo> + ${1} +</sidebarinfo>]]></text> + <tag>sidebarinfo</tag> + <description>sidebarinfo</description> + </snippet> + <snippet id="simpara"> + <text><![CDATA[<simpara> + ${1} +</simpara>]]></text> + <tag>simpara</tag> + <description>simpara</description> + </snippet> + <snippet id="simplelist"> + <text><![CDATA[<simplelist> + ${1} +</simplelist>]]></text> + <tag>simplelist</tag> + <description>simplelist</description> + </snippet> + <snippet id="simplemsgentry"> + <text><![CDATA[<simplemsgentry> + ${1} +</simplemsgentry>]]></text> + <tag>simplemsgentry</tag> + <description>simplemsgentry</description> + </snippet> + <snippet id="simplesect"> + <text><![CDATA[<simplesect id="${1}"> + ${2} +</simplesect>]]></text> + <tag>simplesect</tag> + <description>simplesect</description> + </snippet> + <snippet id="spanspec"> + <text><![CDATA[<spanspec spanname="${1}" namest="${2}" nameend="${3}" />]]></text> + <tag>spanspec</tag> + <description>spanspec</description> + </snippet> + <snippet id="state"> + <text><![CDATA[<state>${1}</state>]]></text> + <tag>state</tag> + <description>state</description> + </snippet> + <snippet id="step"> + <text><![CDATA[<step> + ${1} +</step>]]></text> + <tag>step</tag> + <description>step</description> + </snippet> + <snippet id="stepalternatives"> + <text><![CDATA[<stepalternatives> + ${1} +</stepalternatives>]]></text> + <tag>stepalternatives</tag> + <description>stepalternatives</description> + </snippet> + <snippet id="street"> + <text><![CDATA[<street>${1}</street>]]></text> + <tag>street</tag> + <description>street</description> + </snippet> + <snippet id="structfield"> + <text><![CDATA[<structfield>${1}</structfield>]]></text> + <tag>structfield</tag> + <description>structfield</description> + </snippet> + <snippet id="structname"> + <text><![CDATA[<structname>${1}</structname>]]></text> + <tag>structname</tag> + <description>structname</description> + </snippet> + <snippet id="subject"> + <text><![CDATA[<subject> + ${1} +</subject>]]></text> + <tag>subject</tag> + <description>subject</description> + </snippet> + <snippet id="subjectset"> + <text><![CDATA[<subjectset> + ${1} +</subjectset>]]></text> + <tag>subjectset</tag> + <description>subjectset</description> + </snippet> + <snippet id="subjectterm"> + <text><![CDATA[<subjectterm>${1}</subjectterm>]]></text> + <tag>subjectterm</tag> + <description>subjectterm</description> + </snippet> + <snippet id="subscript"> + <text><![CDATA[<subscript>${1}</subscript>]]></text> + <tag>subscript</tag> + <description>subscript</description> + </snippet> + <snippet id="substeps"> + <text><![CDATA[<substeps> + ${1} +</substeps>]]></text> + <tag>substeps</tag> + <description>substeps</description> + </snippet> + <snippet id="subtitle"> + <text><![CDATA[<subtitle>${1}</subtitle>]]></text> + <tag>subtitle</tag> + <description>subtitle</description> + </snippet> + <snippet id="superscript"> + <text><![CDATA[<superscript>${1}</superscript>]]></text> + <tag>superscript</tag> + <description>superscript</description> + </snippet> + <snippet id="surname"> + <text><![CDATA[<surname>${1}</surname>]]></text> + <tag>surname</tag> + <description>surname</description> + </snippet> + <snippet id="symbol"> + <text><![CDATA[<symbol>${1}</symbol>]]></text> + <tag>symbol</tag> + <description>symbol</description> + </snippet> + <snippet id="synopfragment"> + <text><![CDATA[<synopfragment id="${1}"> + ${2} +</synopfragment>]]></text> + <tag>synopfragment</tag> + <description>synopfragment</description> + </snippet> + <snippet id="synopfragmentref"> + <text><![CDATA[<synopfragmentref linkend="${1}"> + ${2} +</synopfragmentref>]]></text> + <tag>synopfragmentref</tag> + <description>synopfragmentref</description> + </snippet> + <snippet id="synopsis"> + <text><![CDATA[<synopsis>${1}</synopsis>]]></text> + <tag>synopsis</tag> + <description>synopsis</description> + </snippet> + <snippet id="systemitem"> + <text><![CDATA[<systemitem>${1}</systemitem>]]></text> + <tag>systemitem</tag> + <description>systemitem</description> + </snippet> + <snippet id="table"> + <text><![CDATA[<table id="${1}"> + ${2} +</table>]]></text> + <tag>table</tag> + <description>table</description> + </snippet> + <snippet id="task"> + <text><![CDATA[<task> + ${1} +</task>]]></text> + <tag>task</tag> + <description>task</description> + </snippet> + <snippet id="taskprerequisites"> + <text><![CDATA[<taskprerequisites> + ${1} +</taskprerequisites>]]></text> + <tag>taskprerequisites</tag> + <description>taskprerequisites</description> + </snippet> + <snippet id="taskrelated"> + <text><![CDATA[<taskrelated> + ${1} +</taskrelated>]]></text> + <tag>taskrelated</tag> + <description>taskrelated</description> + </snippet> + <snippet id="tasksummary"> + <text><![CDATA[<tasksummary> + ${1} +</tasksummary>]]></text> + <tag>tasksummary</tag> + <description>tasksummary</description> + </snippet> + <snippet id="tbody"> + <text><![CDATA[<tbody> + ${1} +</tbody>]]></text> + <tag>tbody</tag> + <description>tbody</description> + </snippet> + <snippet id="td"> + <text><![CDATA[<td> + ${1} +</td>]]></text> + <tag>td</tag> + <description>td</description> + </snippet> + <snippet id="term"> + <text><![CDATA[<term>${1}</term>]]></text> + <tag>term</tag> + <description>term</description> + </snippet> + <snippet id="termdef"> + <text><![CDATA[<termdef>${1}</termdef>]]></text> + <tag>termdef</tag> + <description>termdef</description> + </snippet> + <snippet id="tertiary"> + <text><![CDATA[<tertiary>${1}</tertiary>]]></text> + <tag>tertiary</tag> + <description>tertiary</description> + </snippet> + <snippet id="tertiaryie"> + <text><![CDATA[<tertiaryie>${1}</tertiaryie>]]></text> + <tag>tertiaryie</tag> + <description>tertiaryie</description> + </snippet> + <snippet id="textdata"> + <text><![CDATA[<textdata fileref="${1}" />]]></text> + <tag>textdata</tag> + <description>textdata</description> + </snippet> + <snippet id="textobject"> + <text><![CDATA[<textobject> + ${1} +</textobject>]]></text> + <tag>textobject</tag> + <description>textobject</description> + </snippet> + <snippet id="tfoot"> + <text><![CDATA[<tfoot> + ${1} +</tfoot>]]></text> + <tag>tfoot</tag> + <description>tfoot</description> + </snippet> + <snippet id="tgroup"> + <text><![CDATA[<tgroup cols="${1}"> + ${2} +</tgroup>]]></text> + <tag>tgroup</tag> + <description>tgroup</description> + </snippet> + <snippet id="th"> + <text><![CDATA[<th> + ${1} +</th>]]></text> + <tag>th</tag> + <description>th</description> + </snippet> + <snippet id="thead"> + <text><![CDATA[<thead> + ${1} +</thead>]]></text> + <tag>thead</tag> + <description>thead</description> + </snippet> + <snippet id="tip"> + <text><![CDATA[<tip> + ${1} +</tip>]]></text> + <tag>tip</tag> + <description>tip</description> + </snippet> + <snippet id="title"> + <text><![CDATA[<title>${1}</title>]]></text> + <tag>title</tag> + <description>title</description> + </snippet> + <snippet id="titleabbrev"> + <text><![CDATA[<titleabbrev>${1}</titleabbrev>]]></text> + <tag>titleabbrev</tag> + <description>titleabbrev</description> + </snippet> + <snippet id="toc"> + <text><![CDATA[<toc> + ${1} +</toc>]]></text> + <tag>toc</tag> + <description>toc</description> + </snippet> + <snippet id="tocback"> + <text><![CDATA[<tocback linkend="${1}">${2}</tocback>]]></text> + <tag>tocback</tag> + <description>tocback</description> + </snippet> + <snippet id="tocchap"> + <text><![CDATA[<tocchap> + ${1} +</tocchap>]]></text> + <tag>tocchap</tag> + <description>tocchap</description> + </snippet> + <snippet id="tocentry"> + <text><![CDATA[<tocentry linkend="${1}">${2}</tocentry>]]></text> + <tag>tocentry</tag> + <description>tocentry</description> + </snippet> + <snippet id="tocfront"> + <text><![CDATA[<tocfront linkend="${1}">${2}</tocfront>]]></text> + <tag>tocfront</tag> + <description>tocfront</description> + </snippet> + <snippet id="toclevel1"> + <text><![CDATA[<toclevel1> + ${1} +</toclevel1>]]></text> + <tag>toclevel1</tag> + <description>toclevel1</description> + </snippet> + <snippet id="toclevel2"> + <text><![CDATA[<toclevel2> + ${1} +</toclevel2>]]></text> + <tag>toclevel2</tag> + <description>toclevel2</description> + </snippet> + <snippet id="toclevel3"> + <text><![CDATA[<toclevel3> + ${1} +</toclevel3>]]></text> + <tag>toclevel3</tag> + <description>toclevel3</description> + </snippet> + <snippet id="toclevel4"> + <text><![CDATA[<toclevel4> + ${1} +</toclevel4>]]></text> + <tag>toclevel4</tag> + <description>toclevel4</description> + </snippet> + <snippet id="toclevel5"> + <text><![CDATA[<toclevel5> + ${1} +</toclevel5>]]></text> + <tag>toclevel5</tag> + <description>toclevel5</description> + </snippet> + <snippet id="tocpart"> + <text><![CDATA[<tocpart> + ${1} +</tocpart>]]></text> + <tag>tocpart</tag> + <description>tocpart</description> + </snippet> + <snippet id="token"> + <text><![CDATA[<token>${1}</token>]]></text> + <tag>token</tag> + <description>token</description> + </snippet> + <snippet id="tr"> + <text><![CDATA[<tr> + ${1} +</tr>]]></text> + <tag>tr</tag> + <description>tr</description> + </snippet> + <snippet id="trademark"> + <text><![CDATA[<trademark class="${1:trade}">${2}</trademark>]]></text> + <tag>trademark</tag> + <description>trademark</description> + </snippet> + <snippet id="type"> + <text><![CDATA[<type>${1}</type>]]></text> + <tag>type</tag> + <description>type</description> + </snippet> + <snippet id="ulink"> + <text><![CDATA[<ulink url="${1}">${2}</ulink>]]></text> + <tag>ulink</tag> + <description>ulink</description> + </snippet> + <snippet id="uri"> + <text><![CDATA[<uri>${1}</uri>]]></text> + <tag>uri</tag> + <description>uri</description> + </snippet> + <snippet id="userinput"> + <text><![CDATA[<userinput>${1}</userinput>]]></text> + <tag>userinput</tag> + <description>userinput</description> + </snippet> + <snippet id="varargs"> + <text><![CDATA[<varargs />]]></text> + <tag>varargs</tag> + <description>varargs</description> + </snippet> + <snippet id="variablelist"> + <text><![CDATA[<variablelist> + ${1} +</variablelist>]]></text> + <tag>variablelist</tag> + <description>variablelist</description> + </snippet> + <snippet id="varlistentry"> + <text><![CDATA[<varlistentry> + ${1} +</varlistentry>]]></text> + <tag>varlistentry</tag> + <description>varlistentry</description> + </snippet> + <snippet id="varname"> + <text><![CDATA[<varname>${1}</varname>]]></text> + <tag>varname</tag> + <description>varname</description> + </snippet> + <snippet id="videodata"> + <text><![CDATA[<videodata fileref="${1}" scalefit="${2:0}" />]]></text> + <tag>videodata</tag> + <description>videodata</description> + </snippet> + <snippet id="videoobject"> + <text><![CDATA[<videoobject> + ${1} +</videoobject>]]></text> + <tag>videoobject</tag> + <description>videoobject</description> + </snippet> + <snippet id="void"> + <text><![CDATA[<void />]]></text> + <tag>void</tag> + <description>void</description> + </snippet> + <snippet id="volumenum"> + <text><![CDATA[<volumenum>${1}</volumenum>]]></text> + <tag>volumenum</tag> + <description>volumenum</description> + </snippet> + <snippet id="warning"> + <text><![CDATA[<warning> + ${1} +</warning>]]></text> + <tag>warning</tag> + <description>warning</description> + </snippet> + <snippet id="wordasword"> + <text><![CDATA[<wordasword>${1}</wordasword>]]></text> + <tag>wordasword</tag> + <description>wordasword</description> + </snippet> + <snippet id="xref"> + <text><![CDATA[<xref linkend="${1}" />]]></text> + <tag>xref</tag> + <description>xref</description> + </snippet> + <snippet id="year"> + <text><![CDATA[<year>${1}</year>]]></text> + <tag>year</tag> + <description>year</description> + </snippet> + <!-- DocBook Element Aliases: --> + <snippet id="bold"> + <text><![CDATA[<emphasis role="bold">${1}</emphasis>]]></text> + <tag>bold</tag> + <description>emphasis, role bold</description> + </snippet> + <snippet id="strong"> + <text><![CDATA[<emphasis role="strong">${1}</emphasis>]]></text> + <tag>strong</tag> + <description>emphasis, role strong</description> + </snippet> + <snippet id="devicefile"> + <text><![CDATA[<filename class="devicefile">${1}</filename>]]></text> + <tag>devicefile</tag> + <description>filename, class devicefile</description> + </snippet> + <snippet id="directory"> + <text><![CDATA[<filename class="directory">${1}</filename>]]></text> + <tag>directory</tag> + <description>filename, class directory</description> + </snippet> + <snippet id="extension"> + <text><![CDATA[<filename class="extension">${1}</filename>]]></text> + <tag>extension</tag> + <description>filename, class extension</description> + </snippet> + <snippet id="headerfile"> + <text><![CDATA[<filename class="headerfile">${1}</filename>]]></text> + <tag>headerfile</tag> + <description>filename, class headerfile</description> + </snippet> + <snippet id="libraryfile"> + <text><![CDATA[<filename class="libraryfile">${1}</filename>]]></text> + <tag>libraryfile</tag> + <description>filename, class libraryfile</description> + </snippet> + <snippet id="partition"> + <text><![CDATA[<filename class="partition">${1}</filename>]]></text> + <tag>partition</tag> + <description>filename, class partition</description> + </snippet> + <snippet id="symlink"> + <text><![CDATA[<filename class="symlink">${1}</filename>]]></text> + <tag>symlink</tag> + <description>filename, class symlink</description> + </snippet> + <snippet id="cartridge"> + <text><![CDATA[<medialabel class="cartridge">${1}</medialabel>]]></text> + <tag>cartridge</tag> + <description>medialabel, class cartridge</description> + </snippet> + <snippet id="cdrom"> + <text><![CDATA[<medialabel class="cdrom">${1}</medialabel>]]></text> + <tag>cdrom</tag> + <description>medialabel, class cdrom</description> + </snippet> + <snippet id="disk"> + <text><![CDATA[<medialabel class="disk">${1}</medialabel>]]></text> + <tag>disk</tag> + <description>medialabel, class disk</description> + </snippet> + <snippet id="tape"> + <text><![CDATA[<medialabel class="tape">${1}</medialabel>]]></text> + <tag>tape</tag> + <description>medialabel, class tape</description> + </snippet> + <snippet id="daemon"> + <text><![CDATA[<systemitem class="daemon">${1}</systemitem>]]></text> + <tag>daemon</tag> + <description>systemitem, class daemon</description> + </snippet> + <snippet id="domainname"> + <text><![CDATA[<systemitem class="domainname">${1}</systemitem>]]></text> + <tag>domainname</tag> + <description>systemitem, class domainname</description> + </snippet> + <snippet id="etheraddress"> + <text><![CDATA[<systemitem class="etheraddress">${1}</systemitem>]]></text> + <tag>etheraddress</tag> + <description>systemitem, class etheraddress</description> + </snippet> + <snippet id="eventhandler"> + <text><![CDATA[<systemitem class="eventhandler">${1}</systemitem>]]></text> + <tag>eventhandler</tag> + <description>systemitem, class eventhandler</description> + </snippet> + <snippet id="event"> + <text><![CDATA[<systemitem class="event">${1}</systemitem>]]></text> + <tag>event</tag> + <description>systemitem, class event</description> + </snippet> + <snippet id="filesystem"> + <text><![CDATA[<systemitem class="filesystem">${1}</systemitem>]]></text> + <tag>filesystem</tag> + <description>systemitem, class filesystem</description> + </snippet> + <snippet id="fqdomainname"> + <text><![CDATA[<systemitem class="fqdomainname">${1}</systemitem>]]></text> + <tag>fqdomainname</tag> + <description>systemitem, class fqdomainname</description> + </snippet> + <snippet id="groupname"> + <text><![CDATA[<systemitem class="groupname">${1}</systemitem>]]></text> + <tag>groupname</tag> + <description>systemitem, class groupname</description> + </snippet> + <snippet id="ipaddress"> + <text><![CDATA[<systemitem class="ipaddress">${1}</systemitem>]]></text> + <tag>ipaddress</tag> + <description>systemitem, class ipaddress</description> + </snippet> + <snippet id="library"> + <text><![CDATA[<systemitem class="library">${1}</systemitem>]]></text> + <tag>library</tag> + <description>systemitem, class library</description> + </snippet> + <snippet id="macro"> + <text><![CDATA[<systemitem class="macro">${1}</systemitem>]]></text> + <tag>macro</tag> + <description>systemitem, class macro</description> + </snippet> + <snippet id="netmask"> + <text><![CDATA[<systemitem class="netmask">${1}</systemitem>]]></text> + <tag>netmask</tag> + <description>systemitem, class netmask</description> + </snippet> + <snippet id="newsgroup"> + <text><![CDATA[<systemitem class="newsgroup">${1}</systemitem>]]></text> + <tag>newsgroup</tag> + <description>systemitem, class newsgroup</description> + </snippet> + <snippet id="osname"> + <text><![CDATA[<systemitem class="osname">${1}</systemitem>]]></text> + <tag>osname</tag> + <description>systemitem, class osname</description> + </snippet> + <snippet id="process"> + <text><![CDATA[<systemitem class="process">${1}</systemitem>]]></text> + <tag>process</tag> + <description>systemitem, class process</description> + </snippet> + <snippet id="protocol"> + <text><![CDATA[<systemitem class="protocol">${1}</systemitem>]]></text> + <tag>protocol</tag> + <description>systemitem, class protocol</description> + </snippet> + <snippet id="resource"> + <text><![CDATA[<systemitem class="resource">${1}</systemitem>]]></text> + <tag>resource</tag> + <description>systemitem, class resource</description> + </snippet> + <snippet id="server"> + <text><![CDATA[<systemitem class="server">${1}</systemitem>]]></text> + <tag>server</tag> + <description>systemitem, class server</description> + </snippet> + <snippet id="service"> + <text><![CDATA[<systemitem class="service">${1}</systemitem>]]></text> + <tag>service</tag> + <description>systemitem, class service</description> + </snippet> + <snippet id="systemname"> + <text><![CDATA[<systemitem class="systemname">${1}</systemitem>]]></text> + <tag>systemname</tag> + <description>systemitem, class systemname</description> + </snippet> + <snippet id="username"> + <text><![CDATA[<systemitem class="username">${1}</systemitem>]]></text> + <tag>username</tag> + <description>systemitem, class username</description> + </snippet> + <!-- XML-related Snippets: --> + <snippet id="include"> + <text><![CDATA[<xi:include href="${1}.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />]]></text> + <tag>include</tag> + <description>xi:include</description> + </snippet> + <snippet id="fallback"> + <text><![CDATA[<xi:fallback xmlns:xi="http://www.w3.org/2001/XInclude"> + ${1} +</xi:fallback>]]></text> + <tag>fallback</tag> + <description>xi:fallback</description> + </snippet> + <snippet id="xml"> + <text><![CDATA[<?xml version='1.0' encoding='utf-8' ?>]]></text> + <tag>xml</tag> + <description>xml</description> + </snippet> + <snippet id="doctype"> + <text><![CDATA[<!DOCTYPE ${1:chapter} PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "${2}.ent"> +%BOOK_ENTITIES; +]>]]></text> + <tag>doctype</tag> + <description>DOCTYPE</description> + </snippet> + <snippet id="entity"> + <text><![CDATA[<!ENTITY ${1} "${2}">]]></text> + <tag>entity</tag> + <description>ENTITY</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/fortran.xml b/plugins/snippets/data/fortran.xml new file mode 100644 index 0000000..205abe6 --- /dev/null +++ b/plugins/snippets/data/fortran.xml @@ -0,0 +1,164 @@ +<?xml version='1.0' encoding='utf-8'?> +<snippets language="fortran"> + <snippet id="c"> + <text><![CDATA[character(len=${1:10}) :: $0]]></text> + <tag>c</tag> + <description>character</description> + </snippet> + <snippet id="cl"> + <text><![CDATA[close(${1:unit}, status='${2:keep}')]]></text> + <tag>cl</tag> + <description>close</description> + </snippet> + <snippet id="do"> + <text><![CDATA[do ${1:i}=$2, $3, ${4:1} + ${0:source} +end do]]></text> + <tag>do</tag> + <description>do ... end do</description> + </snippet> + <snippet id="func"> + <text><![CDATA[function ${1:name}( ${2:parameter} ) + ${3:integer/real ::} $1 + ${4:integer/real ::} $2 + + ${0:source} + + $1 = !result +end function]]></text> + <tag>func</tag> + <description>function</description> + </snippet> + <snippet id="ifel"> + <text><![CDATA[if( $1 ) then + ${2:source} +else + ${0:source} +end if]]></text> + <tag>ifel</tag> + <description>if ... else ... end if</description> + </snippet> + <snippet id="if"> + <text><![CDATA[if( $1 ) then + ${0:source} +end if]]></text> + <tag>if</tag> + <description>if ... end if</description> + </snippet> + <snippet id="i"> + <text><![CDATA[integer(kind=${1:4}) :: $0]]></text> + <tag>i</tag> + <description>integer</description> + </snippet> + <snippet id="ida"> + <text><![CDATA[integer(kind=${1:4}), dimension(${2::}), allocatable :: $0]]></text> + <tag>ida</tag> + <description>integerdimalloc</description> + </snippet> + <snippet id="id"> + <text><![CDATA[integer(kind=${1:4}), dimension(${2::}) :: $0]]></text> + <tag>id</tag> + <description>integerdim</description> + </snippet> + <snippet id="l"> + <text><![CDATA[logical(kind=${1:1}) :: $0]]></text> + <tag>l</tag> + <description>logical</description> + </snippet> + <snippet id="mod"> + <text><![CDATA[module ${1:name} + implicit none + ${2:integer/real ::} $3 + + ${4:contains} + + ${0:source} +end module]]></text> + <tag>mod</tag> + <description>module</description> + </snippet> + <snippet id="op"> + <text><![CDATA[open(${1:unit}, file='${2:name}', status='${3:new}')]]></text> + <tag>op</tag> + <description>open</description> + </snippet> + <snippet id="prog"> + <text><![CDATA[program ${1:name} + implicit none + + ${0:source} +end program]]></text> + <tag>prog</tag> + <description>program</description> + </snippet> + <snippet id="re"> + <text><![CDATA[read(unit=${1:*},fmt=${2:*}) $0]]></text> + <tag>re</tag> + <description>read</description> + </snippet> + <snippet id="r"> + <text><![CDATA[real(kind=${1:8}) :: $0]]></text> + <tag>r</tag> + <description>real</description> + </snippet> + <snippet id="rda"> + <text><![CDATA[real(kind=${1:8}), dimension(${2::}), allocatable :: $0]]></text> + <tag>rda</tag> + <description>realdimalloc</description> + </snippet> + <snippet id="rd"> + <text><![CDATA[real(kind=${1:8}), dimension(${2::}) :: $0]]></text> + <tag>rd</tag> + <description>realdim</description> + </snippet> + <snippet id="rec"> + <text><![CDATA[recursive function ${1:name}( ${2:parameter} ) result( ${3:res} ) + ${4:integer/real ::} $3 + ${5:integer/real ::} $2 + + ${0:source} + + $3 = !result +end function]]></text> + <tag>rec</tag> + <description>recursivfunc</description> + </snippet> + <snippet id="sel"> + <text><![CDATA[select case( $1 ) + case( $2 ) + ${3:source} + case default + ${0:source} +end select]]></text> + <tag>sel</tag> + <description>select</description> + </snippet> + <snippet id="sub"> + <text><![CDATA[subroutine ${1:name}( ${2:parameter} ) + ${3:integer/real ::} $2 + + ${0:source} +end subroutine]]></text> + <tag>sub</tag> + <description>subroutine</description> + </snippet> + <snippet id="t"> + <text><![CDATA[type :: ${1:name} + ${2:integer/real ::} $0 +end type $1]]></text> + <tag>t</tag> + <description>type</description> + </snippet> + <snippet id="dow"> + <text><![CDATA[do while( ${1} ) + ${0:source} +end do]]></text> + <tag>dow</tag> + <description>while</description> + </snippet> + <snippet id="wr"> + <text><![CDATA[write(unit=${1:*},fmt=${2:*}) "$3", $0]]></text> + <tag>wr</tag> + <description>write</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/global.xml b/plugins/snippets/data/global.xml new file mode 100644 index 0000000..afe3c0b --- /dev/null +++ b/plugins/snippets/data/global.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets/> diff --git a/plugins/snippets/data/haskell.xml b/plugins/snippets/data/haskell.xml new file mode 100644 index 0000000..54a8e7d --- /dev/null +++ b/plugins/snippets/data/haskell.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Haskell"> + <snippet id="mod"> + <text><![CDATA[module ${1:Main} where + $0]]></text> + <description>module</description> + <tag>mod</tag> + </snippet> + <snippet id="\"> + <text><![CDATA[\\${1:t} -> ${1:t}]]></text> + <description>\t -> t</description> + <tag>\</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/html.xml b/plugins/snippets/data/html.xml new file mode 100644 index 0000000..dd9faea --- /dev/null +++ b/plugins/snippets/data/html.xml @@ -0,0 +1,252 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="HTML"> + <snippet id="doctype"> + <text><![CDATA[<!DOCTYPE html> +]]></text> + <description>HTML5 Doctype</description> + <tag>doctype</tag> + </snippet> + <snippet id="doctype-1"> + <text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> +]]></text> + <description>XHTML — 1.0 Frameset</description> + <tag>doctype</tag> + </snippet> + <snippet id="doctype-2"> + <text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +]]></text> + <description>XHTML — 1.0 Strict</description> + <tag>doctype</tag> + </snippet> + <snippet id="doctype-3"> + <text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +]]></text> + <description>XHTML — 1.0 Transitional</description> + <tag>doctype</tag> + </snippet> + <snippet id="doctype-4"> + <text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +]]></text> + <description>XHTML — 1.1</description> + <tag>doctype</tag> + </snippet> + <snippet id="doctype-5"> + <text><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +]]></text> + <description>HTML — 4.0 Transitional</description> + <tag>doctype</tag> + </snippet> + <snippet id="doctype-6"> + <text><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +]]></text> + <description>HTML — 4.01 Strict</description> + <tag>doctype</tag> + </snippet> + <snippet id="author"> + <text><![CDATA[<meta name="author" content="${1:author}" /> +$0]]></text> + <tag>author</tag> + <description>Author</description> + </snippet> + <snippet id="date"> + <text><![CDATA[<meta name="date" content="$<1: import time; return time.strftime("%Y-%m-%d") >" /> +$0]]></text> + <tag>date</tag> + <description>Date</description> + </snippet> + <snippet id="ref"> + <text><![CDATA[<a href="${1:http://somesite.com/}">${2:$GEDIT_SELECTED_TEXT}</a> +]]></text> + <accelerator><![CDATA[<Shift><Alt>l]]></accelerator> + <description>Wrap Selection as Link</description> + <tag>ref</tag> + </snippet> + <snippet id="open/close"> + <text><![CDATA[<${1:p}>$GEDIT_SELECTED_TEXT</${1}>]]></text> + <accelerator><![CDATA[<Shift><Alt>w]]></accelerator> + <description>Wrap Selection in Open/Close Tag</description> + </snippet> + <snippet id="mailto"> + <text><![CDATA[<a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a> $0]]></text> + <description>Mail Anchor</description> + <tag>mailto</tag> + </snippet> + <snippet id="base"> + <text><![CDATA[<base href="$1" ${2}/>$0]]></text> + <description>Base</description> + <tag>base</tag> + </snippet> + <snippet id="body"> + <text><![CDATA[<body id="${1:ID}"> + $0 +</body>]]></text> + <description>Body</description> + <tag>body</tag> + </snippet> + <snippet id="br"> + <text><![CDATA[<br /> +$0]]></text> + <accelerator><![CDATA[<Shift><Control>space]]></accelerator> + <description>Br</description> + </snippet> + <snippet id="button"> + <text><![CDATA[<button type="button" name="${1:name}" value="${2:caption}" onclick="$3" />$4 +]]></text> + <tag>button</tag> + <description>Button</description> + </snippet> + <snippet id="div"> + <text><![CDATA[<div ${1}> + ${0:$GEDIT_SELECTED_TEXT} +</div>]]></text> + <description>Div</description> + <tag>div</tag> + </snippet> + <snippet id="file"> + <text><![CDATA[<input type="file" name="${1:name}" size="$2" accept="$3" />$0 +]]></text> + <tag>file</tag> + <description>File</description> + </snippet> + <snippet id="form"> + <text><![CDATA[<form action="${1}" method="${2:get}"> + $0 + + <p><input type="submit" value="${3:Continue →}" /></p> +</form>]]></text> + <description>Form</description> + <tag>form</tag> + </snippet> + <snippet id="h"> + <text><![CDATA[<h${1:1} id="${2}">${3:$GEDIT_SELECTED_TEXT}</h${1}> +$0]]></text> + <description>Heading</description> + <tag>h</tag> + </snippet> + <snippet id="head"> + <text><![CDATA[<head> + <meta charset="utf-8"> + <title>${1:Page Title}</title> + $0 +</head>]]></text> + <description>Head</description> + <tag>head</tag> + </snippet> + <snippet id="image"> + <text><![CDATA[<img src="${1:path/to/file}" alt="${2:description}" title="${3:tool tip}" width="$4" height="$5" />$0]]></text> + <tag>img</tag> + <description>Image</description> + </snippet> + <snippet id="input"> + <text><![CDATA[<input type="${1:[button,checkbox,color,date,datetime,datetime-local,email,file,hidden,image,month,number,password,radio,range,reset,search,submit,tel,text,url,week]}" name="${2:some_name}" value="${3:default_value}" placeholder="${4:default_placeholder}" id="$5" />]]></text> + <description>Input</description> + <tag>input</tag> + </snippet> + <snippet id="li"> + <text><![CDATA[<li>$1</li>$0]]></text> + <tag>li</tag> + <description>List Element</description> + </snippet> + <snippet id="link"> + <text><![CDATA[<link rel="${1:stylesheet}" href="${2:/css/master.css}"> +$0]]></text> + <description>Link</description> + <tag>link</tag> + </snippet> + <snippet id="meta"> + <text><![CDATA[<meta name="${1:name}" content="${2:content}" /> +$0]]></text> + <description>Meta</description> + <tag>meta</tag> + </snippet> + <snippet id="nbsp"> + <text><![CDATA[ ]]></text> + <accelerator><![CDATA[<Control><Alt>space]]></accelerator> + <description>Non-Breaking Space</description> + </snippet> + <snippet id="noscript"> + <text><![CDATA[<noscript>$1</noscript>$0]]></text> + <tag>noscript</tag> + <description>Noscript</description> + </snippet> + <snippet id="option"> + <text><![CDATA[<option value="${1:value}">$2</option>$0]]></text> + <tag>option</tag> + <description>Option</description> + </snippet> + <snippet id="script"> + <text><![CDATA[<script type="text/javascript"> + $0 +</script>]]></text> + <description>Script</description> + <tag>script</tag> + </snippet> + <snippet id="scriptsrc"> + <text><![CDATA[<script src="$1" type="text/javascript"></script>]]></text> + <description>Script With External Source</description> + <tag>scriptsrc</tag> + </snippet> + <snippet id="select"> + <text><![CDATA[<select name="${1:name}"> + <option value="${2:value}">$3</option> + $4 +</select>$0 +]]></text> + <tag>select</tag> + <description>Select</description> + </snippet> + <snippet id="span"> + <text><![CDATA[<span ${1}>$2</span>$0]]></text> + <tag>span</tag> + <description>Span</description> + </snippet> + <snippet id="style"> + <text><![CDATA[<style type="text/css" media="screen"> + $0 +</style> +]]></text> + <description>Style</description> + <tag>style</tag> + </snippet> + <snippet id="table"> + <text><![CDATA[<table border="${1:0}" cellspacing="${2:0}" cellpadding="${3:0}"> + <tr><th>${4:Header}</th></tr> + <tr><td>${5:Data}</td></tr> + $0 +</table>]]></text> + <description>Table</description> + <tag>table</tag> + </snippet> + <snippet id="textarea"> + <text><![CDATA[<textarea name="${1:Name}" rows="${2:8}" cols="${3:40}">$0</textarea>]]></text> + <description>Text Area</description> + <tag>textarea</tag> + </snippet> + <snippet id="title"> + <text><![CDATA[<title>${1:Page Title}</title> +$0]]></text> + <description>Title</description> + <tag>title</tag> + </snippet> + <snippet id="tr"> + <text><![CDATA[<tr><td>$1</td></tr> +$0]]></text> + <tag>tr</tag> + <description>Table Row</description> + </snippet> + <snippet id="ul"> + <text><![CDATA[<ul> + <li>$1</li> + <li>$2</li> + $3 +</ul> +$0]]></text> + <tag>ul</tag> + <description>Unordered List</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/idl.xml b/plugins/snippets/data/idl.xml new file mode 100644 index 0000000..2b6ef30 --- /dev/null +++ b/plugins/snippets/data/idl.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="IDL"> + <snippet id="mod"> + <text><![CDATA[module ${1:name} +{ + $0 +}; +]]></text> + <tag>mod</tag> + <description>Module</description> + </snippet> + <snippet id="if"> + <text><![CDATA[interface ${1:name} +{ + $0 +}; +]]></text> + <tag>if</tag> + <description>Interface</description> + </snippet> + <snippet id="str"> + <text><![CDATA[struct ${1:name} +{ + $0 +}; +]]></text> + <tag>str</tag> + <description>Struct</description> + </snippet> + <snippet id="exc"> + <text><![CDATA[exception ${1:name} +{ + $0 +}; +]]></text> + <tag>exc</tag> + <description>Exception</description> + </snippet> + <snippet id="seq"> + <text><![CDATA[sequence<${1:type}> ]]></text> + <tag>seq</tag> + <description>Sequence</description> + </snippet> + <snippet id="tseq"> + <text><![CDATA[typedef sequence<${1:type}> ${0:newtype};]]></text> + <tag>tseq</tag> + <description>Typedef Sequence</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/java.xml b/plugins/snippets/data/java.xml new file mode 100644 index 0000000..f7f11c0 --- /dev/null +++ b/plugins/snippets/data/java.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Java"> + <snippet id="cd"> + <text><![CDATA[private static final ${1:String} ${2:var} = "$0";]]></text> + <description>const def</description> + <tag>cd</tag> + </snippet> + <snippet id="ife"> + <text><![CDATA[if ($1) { // $2 + + $0 + +} else { // $3 + + + +} + +]]></text> + <description>if .. else</description> + <tag>ife</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[if ($1) { // $2 + $0 +}]]></text> + <description>if</description> + <tag>if</tag> + </snippet> + <snippet id="log"> + <text><![CDATA[/** Logger for this class and subclasses. */ +protected final Log log = LogFactory.getLog(getClass()); +]]></text> + <description>logger</description> + <tag>log</tag> + </snippet> + <snippet id="tcf"> + <text><![CDATA[try { + $2 +} catch (${1:Exception} e) { + $3 +} finally { + $4 +} +$0]]></text> + <description>try .. catch .. finally</description> + <tag>tcf</tag> + </snippet> + <snippet id="while"> + <text><![CDATA[while ($1) { // $2 + $0 +}]]></text> + <description>while statement</description> + <tag>while</tag> + </snippet> + <snippet id="main"> + <text><![CDATA[public static void main(String[] args) { + ${1:System.exit(0)}; +}]]></text> + <description>main</description> + <tag>main</tag> + </snippet> + <snippet id="sout"> + <text><![CDATA[System.out.println("${1}"); +$0 +]]></text> + <description>System.out.println</description> + <tag>sout</tag> + </snippet> + <snippet id="try/catch"> + <text><![CDATA[try { + $GEDIT_SELECTED_TEXT +} +catch (Exception e) { + ${1:e.printStackTrace();} +} +$0]]></text> + <accelerator><![CDATA[<Shift><Alt>t]]></accelerator> + <description>Wrap Selection in Try/Catch</description> + </snippet> + <snippet id="tc"> + <text><![CDATA[try { + $2 +} catch (${1:Exception} e) { + $3 +} +$0]]></text> + <tag>tc</tag> + <description>try .. catch</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/javascript.xml b/plugins/snippets/data/javascript.xml new file mode 100644 index 0000000..b55c5b3 --- /dev/null +++ b/plugins/snippets/data/javascript.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="js"> + <snippet id="fun"> + <text><![CDATA[function ${1:function_name}(${2:first_argument}) { + $0 +}]]></text> + <description>function</description> + <tag>fun</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/lang/snippets.lang b/plugins/snippets/data/lang/snippets.lang new file mode 100644 index 0000000..7b755cd --- /dev/null +++ b/plugins/snippets/data/lang/snippets.lang @@ -0,0 +1,160 @@ +<?xml version="1.0"?> +<!-- + + Author: Jesse van den Kieboom <jesse@icecrew.nl> + Copyright (C) 2007-2008 Jesse van den Kieboom <jesse@icecrew.nl> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. + +--> +<language id="snippets" name="Snippets" hidden="true" version="2.0"> + <styles> + <style id="placeholder-bounds" name="Placeholder begin and end" map-to="def:function"/> + <style id="default-value" name="Default Value" map-to="def:string"/> + <style id="single-placeholder" name="Single Placeholder" map-to="def:decimal"/> + <style id="shell-placeholder" name="Shell Placeholder" map-to="def:preprocessor"/> + <style id="python-placeholder" name="Python Placeholder" map-to="def:preprocessor"/> + <style id="regex-placeholder" name="Regular Expression Placeholder" map-to="def:preprocessor"/> + <style id="tabstop" name="Tabstop" map-to="def:decimal"/> + <style id="placeholder-ref" name="Placeholder Reference" map-to="def:decimal"/> + <style id="placeholder-def" name="Placeholder Default" map-to="def:string"/> + <style id="escape" name="Escape" map-to="def:special-char"/> + <style id="environmental-var" name="Environmental Variable" map-to="def:string"/> + <style id="seperator" name="Seperator" map-to="def:shebang"/> + <style id="regex-pattern" name="Regular Expression Pattern" map-to="def:string"/> + <style id="replace-pattern" name="Regular Expression Replace Pattern" map-to="def:string"/> + <style id="modifier" name="Modifier" map-to="def:keyword"/> + </styles> + + <definitions> + <define-regex id="number">[0-9]+</define-regex> + <define-regex id="tabstop">\s*((\%{number})(:))</define-regex> + <define-regex id="number-list" extended="true">\s*(\[(\%{number}(,\%{number})*)\](:))</define-regex> + <define-regex id="environment">\$[A-Z_]+</define-regex> + <define-regex id="regex-pattern">((?:\\[/]|\\}|[^/}])+)</define-regex> + + <context id="escape" style-ref="escape"> + <match>\\\$</match> + </context> + <context id="single-placeholder" style-ref="single-placeholder"> + <match>\$\%{number}|\${\%{number}}</match> + </context> + <context id="simple-placeholder-def" style-ref="default-value"> + <start>\${\%{tabstop}</start> + <end>}</end> + <include> + <context sub-pattern="0" style-ref="placeholder-bounds" where="start"/> + <context sub-pattern="0" style-ref="placeholder-bounds" where="end"/> + <context sub-pattern="2" where="start" style-ref="tabstop"/> + <context sub-pattern="3" where="start" style-ref="seperator"/> + <context> + <match>\\}</match> + </context> + <context ref="escape"/> + <context ref="environmental-variable"/> + </include> + </context> + <context id="simple-placeholder"> + <include> + <context ref="single-placeholder"/> + <context ref="simple-placeholder-def"/> + </include> + </context> + <context id="shell-placeholder-contents"> + <include> + <context ref="escape"/> + <context ref="environmental-variable"/> + <context ref="single-placeholder"/> + </include> + </context> + <context id="shell-placeholder"> + <include> + <context style-ref="shell-placeholder"> + <start>\$\(\%{tabstop}?</start> + <end>\)</end> + <include> + <context sub-pattern="0" style-ref="placeholder-bounds" where="start"/> + <context sub-pattern="0" style-ref="placeholder-bounds" where="end"/> + <context sub-pattern="2" where="start" style-ref="tabstop"/> + <context sub-pattern="3" where="start" style-ref="seperator"/> + <context ref="shell-placeholder-contents"/> + <context> + <match>\\\)</match> + </context> + </include> + </context> + <context style-ref="shell-placeholder"> + <start>`\%{tabstop}?</start> + <end>`</end> + <include> + <context sub-pattern="0" style-ref="placeholder-bounds" where="start"/> + <context sub-pattern="0" style-ref="placeholder-bounds" where="end"/> + <context sub-pattern="2" where="start" style-ref="tabstop"/> + <context sub-pattern="3" where="start" style-ref="seperator"/> + <context ref="shell-placeholder-contents"/> + <context> + <match>\\`</match> + </context> + </include> + </context> + </include> + </context> + <context id="python-placeholder"> + <start>\$<\%{tabstop}?\%{number-list}?</start> + <end>></end> + <include> + <context sub-pattern="0" style-ref="placeholder-bounds" where="start"/> + <context sub-pattern="0" style-ref="placeholder-bounds" where="end"/> + <context sub-pattern="2" where="start" style-ref="tabstop"/> + <context sub-pattern="3" where="start" style-ref="seperator"/> + <context sub-pattern="5" where="start" style-ref="tabstop"/> + <context sub-pattern="7" where="start" style-ref="seperator"/> + <context> + <match>\\></match> + </context> + <context ref="escape"/> + <context ref="environmental-variable"/> + <context ref="single-placeholder"/> + <context ref="python:python"/> + </include> + </context> + <context id="regex-placeholder" style-ref="regex-placeholder"> + <match>(\${)\%{tabstop}?(?:\s*(?:(\%{number})|(\%{environment})))/\%{regex-pattern}/\%{regex-pattern}(?:[/]([a-zA-Z]*))?(})</match> + <include> + <context sub-pattern="1" style-ref="placeholder-bounds"/> + <context sub-pattern="10" style-ref="placeholder-bounds"/> + <context sub-pattern="3" style-ref="tabstop"/> + <context sub-pattern="4" style-ref="seperator"/> + <context sub-pattern="5" style-ref="tabstop"/> + <context sub-pattern="6" style-ref="environmental-var"/> + <context sub-pattern="7" style-ref="regex-pattern"/> + <context sub-pattern="8" style-ref="replace-pattern"/> + <context sub-pattern="9" style-ref="modifier"/> + </include> + </context> + <context id="environmental-variable" style-ref="environmental-var"> + <match>\%{environment}</match> + </context> + <context id="snippets"> + <include> + <context ref="escape"/> + <context ref="regex-placeholder"/> + <context ref="simple-placeholder"/> + <context ref="shell-placeholder"/> + <context ref="python-placeholder"/> + <context ref="environmental-variable"/> + </include> + </context> + </definitions> +</language> diff --git a/plugins/snippets/data/latex.xml b/plugins/snippets/data/latex.xml new file mode 100644 index 0000000..71672ec --- /dev/null +++ b/plugins/snippets/data/latex.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="LaTeX"> + <snippet id="command"> + <text><![CDATA[{\\${1:bf} $GEDIT_SELECTED_TEXT}]]></text> + <accelerator><![CDATA[<Shift><Alt>w]]></accelerator> + <description>Wrap Selection in Command</description> + </snippet> + <snippet id="$"> + <text><![CDATA[\[ + $1 +\]]]></text> + <description>Displaymath</description> + <tag>$</tag> + </snippet> + <snippet id="itd"> + <text><![CDATA[\item[${1:description}] ${0:item}]]></text> + <description>\item[description]</description> + <tag>itd</tag> + </snippet> + <snippet id="sec"> + <text><![CDATA[\section{${1:section name}}\label{${2:label}} +]]></text> + <description>Section</description> + <tag>sec</tag> + </snippet> + <snippet id="sub"> + <text><![CDATA[\subsection{${1:subsection name}}\label{${2:label}} +]]></text> + <description>Sub Section</description> + <tag>sub</tag> + </snippet> + <snippet id="ssub"> + <text><![CDATA[\subsubsection{${1:subsubsection name}}\label{${2:label}} +]]></text> + <description>Sub Sub Section</description> + <tag>ssub</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/mallard.xml b/plugins/snippets/data/mallard.xml new file mode 100644 index 0000000..bb08b43 --- /dev/null +++ b/plugins/snippets/data/mallard.xml @@ -0,0 +1,316 @@ +<?xml version='1.0' encoding='utf-8'?> +<!-- + Mallard 1.0 snippets according to Mallard 1.0 DRAFT (as of 2013-02-11) + Copyright (C) 2013 Jaromir Hradilek + + Home Page: https://github.com/jhradilek/gedit-snippets + Last Change: 12 February 2013 +--> +<snippets language="mallard"> + <snippet id="app"> + <text><![CDATA[<app>${1}</app>]]></text> + <tag>app</tag> + <description>app</description> + </snippet> + <snippet id="cite"> + <text><![CDATA[<cite>${1}</cite>]]></text> + <tag>cite</tag> + <description>cite</description> + </snippet> + <snippet id="cmd"> + <text><![CDATA[<cmd>${1}</cmd>]]></text> + <tag>cmd</tag> + <description>cmd</description> + </snippet> + <snippet id="code"> + <text><![CDATA[<code>${1}</code>]]></text> + <tag>code</tag> + <description>code</description> + </snippet> + <snippet id="col"> + <text><![CDATA[<col/>${1}]]></text> + <tag>col</tag> + <description>col</description> + </snippet> + <snippet id="colgroup"> + <text><![CDATA[<colgroup>${1}</colgroup>]]></text> + <tag>colgroup</tag> + <description>colgroup</description> + </snippet> + <snippet id="comment"> + <text><![CDATA[<comment> + ${1} +</comment>]]></text> + <tag>comment</tag> + <description>comment</description> + </snippet> + <snippet id="credit"> + <text><![CDATA[<credit type="${1:author}"> + ${2} +</credit>]]></text> + <tag>credit</tag> + <description>credit</description> + </snippet> + <snippet id="desc"> + <text><![CDATA[<desc>${1}</desc>]]></text> + <tag>desc</tag> + <description>desc</description> + </snippet> + <snippet id="em"> + <text><![CDATA[<em>${1}</em>]]></text> + <tag>em</tag> + <description>em</description> + </snippet> + <snippet id="email"> + <text><![CDATA[<email>${1}</email>]]></text> + <tag>email</tag> + <description>email</description> + </snippet> + <snippet id="example"> + <text><![CDATA[<example> + ${1} +</example>]]></text> + <tag>example</tag> + <description>example</description> + </snippet> + <snippet id="figure"> + <text><![CDATA[<figure> + ${1} +</figure>]]></text> + <tag>figure</tag> + <description>figure</description> + </snippet> + <snippet id="file"> + <text><![CDATA[<file>${1}</file>]]></text> + <tag>file</tag> + <description>file</description> + </snippet> + <snippet id="gui"> + <text><![CDATA[<gui>${1}</gui>]]></text> + <tag>gui</tag> + <description>gui</description> + </snippet> + <snippet id="guiseq"> + <text><![CDATA[<guiseq>${1}</guiseq>]]></text> + <tag>guiseq</tag> + <description>guiseq</description> + </snippet> + <snippet id="info"> + <text><![CDATA[<info> + ${1} +</info>]]></text> + <tag>info</tag> + <description>info</description> + </snippet> + <snippet id="input"> + <text><![CDATA[<input>${1}</input>]]></text> + <tag>input</tag> + <description>input</description> + </snippet> + <snippet id="item"> + <text><![CDATA[<item>${1}</item>]]></text> + <tag>item</tag> + <description>item</description> + </snippet> + <snippet id="key"> + <text><![CDATA[<key>${1}</key>]]></text> + <tag>key</tag> + <description>key</description> + </snippet> + <snippet id="keyseq"> + <text><![CDATA[<keyseq type="${1:combo}">${2}</keyseq>]]></text> + <tag>keyseq</tag> + <description>keyseq</description> + </snippet> + <snippet id="license"> + <text><![CDATA[<license href="${1}"> + ${2} +</license>]]></text> + <tag>license</tag> + <description>license</description> + </snippet> + <snippet id="link"> + <text><![CDATA[<link type="${1:guide}" xref="${2:index}" group="${3}"/>]]></text> + <tag>link</tag> + <description>link</description> + </snippet> + <snippet id="links"> + <text><![CDATA[<links type="${1:topic}" groups="${2}"> + ${3} +</links>]]></text> + <tag>links</tag> + <description>links</description> + </snippet> + <snippet id="list"> + <text><![CDATA[<list type="${1:disc}"> + ${2} +</list>]]></text> + <tag>list</tag> + <description>list</description> + </snippet> + <snippet id="listing"> + <text><![CDATA[<listing> + ${1} +</listing>]]></text> + <tag>listing</tag> + <description>listing</description> + </snippet> + <snippet id="media"> + <text><![CDATA[<media type="${1:image}" mime="${2:image/png}" src="${3}"> + ${4} +</media>]]></text> + <tag>media</tag> + <description>media</description> + </snippet> + <snippet id="name"> + <text><![CDATA[<name>${1}</name>]]></text> + <tag>name</tag> + <description>name</description> + </snippet> + <snippet id="note"> + <text><![CDATA[<note style="${1:advanced}"> + ${2} +</note>]]></text> + <tag>note</tag> + <description>note</description> + </snippet> + <snippet id="output"> + <text><![CDATA[<output>${1}</output>]]></text> + <tag>output</tag> + <description>output</description> + </snippet> + <snippet id="p"> + <text><![CDATA[<p>${1}</p>]]></text> + <tag>p</tag> + <description>p</description> + </snippet> + <snippet id="page"> + <text><![CDATA[<page xmlns="http://projectmallard.org/1.0/" type="${1:topic}" id="${2}"> + ${3} +</page>]]></text> + <tag>page</tag> + <description>page</description> + </snippet> + <snippet id="quote"> + <text><![CDATA[<quote> + ${1} +</quote>]]></text> + <tag>quote</tag> + <description>quote</description> + </snippet> + <snippet id="revision"> + <text><![CDATA[<revision version="${1:0.1}" date="$(2:date +%Y-%m-%d)" status="${3:stub}"/>]]></text> + <tag>revision</tag> + <description>revision</description> + </snippet> + <snippet id="screen"> + <text><![CDATA[<screen>${1}</screen>]]></text> + <tag>screen</tag> + <description>screen</description> + </snippet> + <snippet id="section"> + <text><![CDATA[<section id="${1}"> + ${2} +</section>]]></text> + <tag>section</tag> + <description>section</description> + </snippet> + <snippet id="span"> + <text><![CDATA[<span>${1}</span>]]></text> + <tag>span</tag> + <description>span</description> + </snippet> + <snippet id="steps"> + <text><![CDATA[<steps> + ${1} +</steps>]]></text> + <tag>steps</tag> + <description>steps</description> + </snippet> + <snippet id="subtitle"> + <text><![CDATA[<subtitle>${1}</subtitle>]]></text> + <tag>subtitle</tag> + <description>subtitle</description> + </snippet> + <snippet id="synopsis"> + <text><![CDATA[<synopsis> + ${1} +</synopsis>]]></text> + <tag>synopsis</tag> + <description>synopsis</description> + </snippet> + <snippet id="sys"> + <text><![CDATA[<sys>${1}</sys>]]></text> + <tag>sys</tag> + <description>sys</description> + </snippet> + <snippet id="table"> + <text><![CDATA[<table frame="${1:all}" rules="${2:all}" shade="${3:none}"> + ${4} +</table>]]></text> + <tag>table</tag> + <description>table</description> + </snippet> + <snippet id="tbody"> + <text><![CDATA[<tbody> + ${1} +</tbody>]]></text> + <tag>tbody</tag> + <description>tbody</description> + </snippet> + <snippet id="td"> + <text><![CDATA[<td>${1}</td>]]></text> + <tag>td</tag> + <description>td</description> + </snippet> + <snippet id="terms"> + <text><![CDATA[<terms> + ${1} +</terms>]]></text> + <tag>terms</tag> + <description>terms</description> + </snippet> + <snippet id="tfoot"> + <text><![CDATA[<tfoot> + ${1} +</tfoot>]]></text> + <tag>tfoot</tag> + <description>tfoot</description> + </snippet> + <snippet id="thead"> + <text><![CDATA[<thead> + ${1} +</thead>]]></text> + <tag>thead</tag> + <description>thead</description> + </snippet> + <snippet id="title"> + <text><![CDATA[<title>${1}</title>]]></text> + <tag>title</tag> + <description>title</description> + </snippet> + <snippet id="tr"> + <text><![CDATA[<tr> + ${1} +</tr>]]></text> + <tag>tr</tag> + <description>tr</description> + </snippet> + <snippet id="tree"> + <text><![CDATA[<tree> + ${1} +</tree>]]></text> + <tag>tree</tag> + <description>tree</description> + </snippet> + <snippet id="var"> + <text><![CDATA[<var>${1}</var>]]></text> + <tag>var</tag> + <description>var</description> + </snippet> + <snippet id="years"> + <text><![CDATA[<years>$(1:date +%Y)</years>]]></text> + <tag>years</tag> + <description>years</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/markdown.xml b/plugins/snippets/data/markdown.xml new file mode 100644 index 0000000..e49209b --- /dev/null +++ b/plugins/snippets/data/markdown.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Markdown"> + <snippet id="atx-header"> + <text><![CDATA[${1:#} ${2:Header} $1 + +]]></text> + <tag>h</tag> + <description>Header (atx-style)</description> + </snippet> + + <snippet id="setext-header-1"> + <text><![CDATA[${1:Header} +=============== + +]]></text> + <tag>Hs</tag> + <description>Header 1 (setext-style)</description> + </snippet> + + <snippet id="setext-header-2"> + <text><![CDATA[${1:Header} +--------------- + +]]></text> + <tag>hs</tag> + <description>Header 2 (setext-style)</description> + </snippet> + + <snippet id="horizontal-rule"> + <text><![CDATA[*************** + +$0]]></text> + <tag>hr</tag> + <description>Horizontal Rule</description> + </snippet> + + <snippet id="unordered-list"> + <text><![CDATA[* $1 +* $2 +* $3 +* $4 + +]]></text> + <tag>ul</tag> + <description>Unordered List</description> + </snippet> + + <snippet id="ordered-list"> + <text><![CDATA[1. $1 +2. $2 +3. $3 +4. $4 + +]]></text> + <tag>ol</tag> + <description>Ordered List</description> + </snippet> + + <snippet id="code-span"> + <text><![CDATA[\`${1:$GEDIT_SELECTED_TEXT}\`]]></text> + <tag>code</tag> + <description>Wrap Selection as Code Span</description> + <accelerator><![CDATA[<Control><Alt>c]]></accelerator> + </snippet> + + <snippet id="inline-link"> + <text><![CDATA[[${1:$GEDIT_SELECTED_TEXT}](${2:URL})]]></text> + <tag>a</tag> + <description>Wrap Selection as Inline Link</description> + <accelerator><![CDATA[<Control><Alt>a]]></accelerator> + </snippet> + + <snippet id="reference-link"> + <text><![CDATA[[${1:$GEDIT_SELECTED_TEXT}][${2:link label}]]]></text> + <tag>aref</tag> + <description>Wrap Selection as Reference Link</description> + <accelerator><![CDATA[<Control><Alt>r]]></accelerator> + </snippet> + + <snippet id="link-definition"> + <text><![CDATA[[${1:link label}]: ${2:URL} +]]></text> + <tag>adef</tag> + <description>Link Definition</description> + </snippet> + + <snippet id="inline-image"> + <text><![CDATA[![${1:alt text}](${2:URL})]]></text> + <tag>img</tag> + <description>Inline Image</description> + </snippet> + + <snippet id="reference-image"> + <text><![CDATA[![${1:alt text}][${2:image label}]]]></text> + <tag>iref</tag> + <description>Reference Image</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/perl.xml b/plugins/snippets/data/perl.xml new file mode 100644 index 0000000..add148f --- /dev/null +++ b/plugins/snippets/data/perl.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Perl"> + <snippet id="perl"> + <text><![CDATA[#!/usr/bin/perl +$0]]></text> + <tag>perl</tag> + <description>#!/usr/bin/perl</description> + </snippet> + <snippet id="ife"> + <text><![CDATA[if ($1) { + ${2:# body...} +} else { + ${3:# else...} +} +]]></text> + <description>Conditional if..else</description> + <tag>ife</tag> + </snippet> + <snippet id="ifee"> + <text><![CDATA[if ($1) { + ${2:# body...} +} elsif ($3) { + ${4:# elsif...} +} else { + ${5:# else...} +} +]]></text> + <description>Conditional if..elsif..else</description> + <tag>ifee</tag> + </snippet> + <snippet id="xunless"> + <text><![CDATA[${1:expression} unless ${2:condition}; +]]></text> + <description>Conditional one-line</description> + <tag>xunless</tag> + </snippet> + <snippet id="xif"> + <text><![CDATA[${1:expression} if ${2:condition}; +]]></text> + <description>Conditional one-line</description> + <tag>xif</tag> + </snippet> + <snippet id="eval"> + <text><![CDATA[eval { + ${1:# do something risky...} +}; +if ($@) { + ${2:# handle failure...} +} +]]></text> + <description>Try/Except</description> + <tag>eval</tag> + </snippet> + <snippet id="fore"> + <text><![CDATA[foreach ${1:my $${2:x} }(@${3:array}) { + ${4:# body...} +} +]]></text> + <description>Loop</description> + <tag>fore</tag> + </snippet> + <snippet id="for"> + <text><![CDATA[for (my $${1:var} = 0; $$1 < ${2:expression}; $$1++) { + ${3:# body...} +} +]]></text> + <description>Loop</description> + <tag>for</tag> + </snippet> + <snippet id="sub"> + <text><![CDATA[sub ${1:function_name} { + ${2:# body...} +} +]]></text> + <description>Function</description> + <tag>sub</tag> + </snippet> + <snippet id="hashpointer"> + <text><![CDATA[ => ]]></text> + <accelerator><![CDATA[<Shift><Alt>l]]></accelerator> + <description>hash pointer</description> + </snippet> + <snippet id="if"> + <text><![CDATA[if ($1) { + ${2:# body...} +} +]]></text> + <description>Conditional</description> + <tag>if</tag> + </snippet> + <snippet id="xfore"> + <text><![CDATA[${1:expression} foreach @${2:array}; +]]></text> + <description>Loop one-line</description> + <tag>xfore</tag> + </snippet> + <snippet id="xwhile"> + <text><![CDATA[${1:expression} while ${2:condition}; +]]></text> + <description>Loop one-line</description> + <tag>xwhile</tag> + </snippet> + <snippet id="slurp"> + <text><![CDATA[my $${1:var}; +{ local $/ = undef; local *FILE; open FILE, "<${2:file}"; $$1 = <FILE>; close FILE } +]]></text> + <description>Read File</description> + <tag>slurp</tag> + </snippet> + <snippet id="unless"> + <text><![CDATA[unless ($1) { + ${2:# body...} +} +]]></text> + <description>Conditional</description> + <tag>unless</tag> + </snippet> + <snippet id="while"> + <text><![CDATA[while ($1) { + ${2:# body...} +} +]]></text> + <description>Loop</description> + <tag>while</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/php.xml b/plugins/snippets/data/php.xml new file mode 100644 index 0000000..89b27e7 --- /dev/null +++ b/plugins/snippets/data/php.xml @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="PHP"> + <snippet id="class"> + <text><![CDATA[class ${1:ClassName}${2: extends AnotherClass} +{ + function __construct(${3:argument}) + { + $0 + } +}]]></text> + <description>class ..</description> + <tag>class</tag> + </snippet> + <snippet id="$"> + <text><![CDATA[\$_COOKIE['${1:variable}']]]></text> + <description>COOKIE['..']</description> + <tag>$</tag> + </snippet> + <snippet id="do"> + <text><![CDATA[do { + $0 +} while (${1:$a <= 10});]]></text> + <description>do .. while ..</description> + <tag>do</tag> + </snippet> + <snippet id="elseif"> + <text><![CDATA[elseif (${1:condition}) { + $0 +}]]></text> + <description>elseif ..</description> + <tag>elseif</tag> + </snippet> + <snippet id="else"> + <text><![CDATA[else { + $0 +}]]></text> + <description>else ..</description> + <tag>else</tag> + </snippet> + <snippet id="$-1"> + <text><![CDATA[\$_ENV['${1:variable}']]]></text> + <description>ENV['..']</description> + <tag>$</tag> + </snippet> + <snippet id="$-2"> + <text><![CDATA[\$_FILES['${1:variable}']]]></text> + <description>FILES['..']</description> + <tag>$</tag> + </snippet> + <snippet id="foreach"> + <text><![CDATA[foreach ($${1:variable} as $${2:key} => $${3:value}) { + $0 +}]]></text> + <description>foreach ..</description> + <tag>foreach</tag> + </snippet> + <snippet id="for"> + <text><![CDATA[for ($${1:i} = ${2:0}; $${1:i} < $3; $${1:i}++) { + $0 +}]]></text> + <description>for ..</description> + <tag>for</tag> + </snippet> + <snippet id="function"> + <text><![CDATA[${1:public }function ${2:FunctionName}($3) +{ + ${0:# code...} +}]]></text> + <description>function ..</description> + <tag>function</tag> + </snippet> + <snippet id="$-3"> + <text><![CDATA[\$_GET['${1:variable}']]]></text> + <description>GET['..']</description> + <tag>$</tag> + </snippet> + <snippet id="globals"> + <text><![CDATA[\$GLOBALS['${1:variable}']${2: =} ${3:something} ${4:;}]]></text> + <description>$GLOBALS['..']</description> + <tag>globals</tag> + </snippet> + <snippet id="if?"> + <text><![CDATA[$${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};]]></text> + <description>$.. =</description> + <tag>iff</tag> + </snippet> + <snippet id="ifelse"> + <text><![CDATA[if (${1:condition}) { + ${2} +} else { + ${3} +} +$0]]></text> + <description>if .. else ..</description> + <tag>ifelse</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[if (${1:condition}) { + $0 +}]]></text> + <description>if ..</description> + <tag>if</tag> + </snippet> + <snippet id="incl1"> + <text><![CDATA[include_once('${1:file}');$0]]></text> + <description>include_once</description> + <tag>inclo</tag> + </snippet> + <snippet id="incl"> + <text><![CDATA[include('${1:file}');$0]]></text> + <description>include</description> + <tag>incl</tag> + </snippet> + <snippet id="array"> + <text><![CDATA[$${1:arrayName} = array('$2'${3:,});]]></text> + <description>$.. = array</description> + <tag>array</tag> + </snippet> + <snippet id="php"> + <text><![CDATA[<?php + + $0 + +?>]]></text> + <description><?php .. ?></description> + <tag>php</tag> + </snippet> + <snippet id="$-4"> + <text><![CDATA[\$_POST['${1:variable}']]]></text> + <description>POST['..']</description> + <tag>$</tag> + </snippet> + <snippet id="print"> + <text><![CDATA[print "${1:string}"${2: . };]]></text> + <description>print ".."</description> + <tag>print</tag> + </snippet> + <snippet id="$-5"> + <text><![CDATA[\$_REQUEST['${1:variable}']]]></text> + <description>REQUEST['..']</description> + <tag>$</tag> + </snippet> + <snippet id="req1"> + <text><![CDATA[require_once('${1:file}');]]></text> + <description>require_once</description> + <tag>reqo</tag> + </snippet> + <snippet id="req"> + <text><![CDATA[require('${1:file}');]]></text> + <description>require</description> + <tag>req</tag> + </snippet> + <snippet id="$-6"> + <text><![CDATA[\$_SERVER['${1:variable}']]]></text> + <description>SERVER['..']</description> + <tag>$</tag> + </snippet> + <snippet id="$-7"> + <text><![CDATA[\$_SESSION['${1:variable}']]]></text> + <description>SESSION['..']</description> + <tag>$</tag> + </snippet> + <snippet id="case"> + <text><![CDATA[case '${1:variable}': + $0 + break;]]></text> + <description>case ..</description> + <tag>case</tag> + </snippet> + <snippet id="switch"> + <text><![CDATA[switch (${1:variable}) { + case '${2:value}': + ${3} + break; + + $0 + + default: + ${4} + break; +}]]></text> + <description>switch ..</description> + <tag>switch</tag> + </snippet> + <snippet id="while"> + <text><![CDATA[while (${1:$a <= 10}) { + $0 +}]]></text> + <description>while ..</description> + <tag>while</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/python.xml b/plugins/snippets/data/python.xml new file mode 100644 index 0000000..a25617b --- /dev/null +++ b/plugins/snippets/data/python.xml @@ -0,0 +1,112 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Python"> + <snippet id="py"> + <text><![CDATA[#!/usr/bin/env python +#-*- coding:utf-8 -*- + +$0]]></text> + <description>#!/usr/bin/env python</description> + <tag>py</tag> + </snippet> + <snippet id="def"> + <text><![CDATA[def ${1:fname}(${2:self}): + ${3:pass}]]></text> + <description>New Function</description> + <tag>def</tag> + </snippet> + <snippet id="doc"> + <text><![CDATA[""" + $1 +""" +$0]]></text> + <description>doc string</description> + <tag>doc</tag> + </snippet> + <snippet id="get"> + <text><![CDATA[def get$1(self): return self._$1]]></text> + <description>New Get Method</description> + <tag>get</tag> + </snippet> + <snippet id="class"> + <text><![CDATA[class ${1:ClassName} (${2:object}): + + def __init__(self${3:,}): + ${4:pass} + +$0]]></text> + <description>New Class</description> + <tag>class</tag> + </snippet> + <snippet id="for"> + <text><![CDATA[for ${1:i} in ${2:xrange}(${3:count}): + $0]]></text> + <description>for loop</description> + <tag>for</tag> + </snippet> + <snippet id="from"> + <text><![CDATA[from $1 import $2 +$0]]></text> + <description>from</description> + <tag>from</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[if ${1:condition}: + $0]]></text> + <description>if</description> + <tag>if</tag> + </snippet> + <snippet id="elif"> + <text><![CDATA[elif ${1:condition}: + $0]]></text> + <description>elif</description> + <tag>elif</tag> + </snippet> + <snippet id="else"> + <text><![CDATA[else: + $0]]></text> + <description>else</description> + <tag>else</tag> + </snippet> + <snippet id="while"> + <text><![CDATA[while ${1:condition}: + $0]]></text> + <tag>while</tag> + <description>while loop</description> + </snippet> + <snippet id="insert"> + <text><![CDATA["${1:$GEDIT_SELECTED_TEXT}"]]></text> + <accelerator><![CDATA[<Control>2]]></accelerator> + <description>Inside String: Insert "…"</description> + </snippet> + <snippet id="insert-1"> + <text><![CDATA['${1:$GEDIT_SELECTED_TEXT}']]></text> + <accelerator><![CDATA[<Control>apostrophe]]></accelerator> + <description>Inside String: Insert '…'</description> + </snippet> + <snippet id="."> + <text><![CDATA[self.]]></text> + <description>self</description> + <tag>.</tag> + </snippet> + <snippet id="set"> + <text><![CDATA[def set$1(self, ${2:newValue}): self._$1 = $2]]></text> + <description>New Set Method</description> + <tag>set</tag> + </snippet> + <snippet id="try"> + <text><![CDATA[try: + $1 +except ${2:Error}: + $0]]></text> + <tag>try</tag> + <description>Try... Except</description> + </snippet> + <snippet id="main"> + <text><![CDATA[if __name__ == '__main__': + ${1:sys.exit(main())} + +$0]]></text> + <description>main</description> + <tag>main</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/rpmspec.xml b/plugins/snippets/data/rpmspec.xml new file mode 100644 index 0000000..eb3396d --- /dev/null +++ b/plugins/snippets/data/rpmspec.xml @@ -0,0 +1,22 @@ +<?xml version='1.0' encoding='utf-8'?> +<!-- requires rpm-python package installed --> +<snippets language="rpmspec"> + <snippet id="ch"> + <text><![CDATA[$< +import rpm +import datetime + +spec = rpm.spec($GEDIT_CURRENT_DOCUMENT_PATH) +date = datetime.date.today().strftime("%a %b %d %Y") +headers = spec.packages[0].header +version = headers['Version'] +release = ".".join(headers['Release'].split(".")[:-1]) +packager = headers['Packager'] +newheader = "* %s %s - %s-%s\n- " % (date, packager, version, release) +return newheader +> +]]></text> + <tag>ch</tag> + <description>changelog entry</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/ruby.xml b/plugins/snippets/data/ruby.xml new file mode 100644 index 0000000..db13e69 --- /dev/null +++ b/plugins/snippets/data/ruby.xml @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Ruby"> + <snippet id="forin"> + <text><![CDATA[for ${1:element} in ${2:collection} + ${1:element}.$0 +end]]></text> + <description>for .. in .. end</description> + <tag>forin</tag> + </snippet> + <snippet id="inject"> + <text><![CDATA[inject(${1:object}) { |${2:injection}, ${3:element}| $0 }]]></text> + <description>inject object</description> + <tag>inject</tag> + </snippet> + <snippet id="reject"> + <text><![CDATA[reject { |${1:element}| ${1:element}.$0 }]]></text> + <description>reject element</description> + <tag>reject</tag> + </snippet> + <snippet id="select"> + <text><![CDATA[select { |${1:element}| ${1:element}.$0 }]]></text> + <description>select element</description> + <tag>select</tag> + </snippet> + <snippet id="ife"> + <text><![CDATA[if ${1:condition} + $2 +else + $3 +end]]></text> + <description>if .. else .. end</description> + <tag>ife</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[if ${1:condition} + $0 +end]]></text> + <description>if .. end</description> + <tag>if</tag> + </snippet> + <snippet id="case"> + <text><![CDATA[case ${1:object} + when ${2:condition} + $0 +end]]></text> + <description>case .. end</description> + <tag>case</tag> + </snippet> + <snippet id="begin"> + <text><![CDATA[begin + $1 +rescue ${2:Exception} => ${3:e} + $0 +end]]></text> + <description>begin .. rescue .. end</description> + <tag>begin</tag> + </snippet> + <snippet id="class"> + <text><![CDATA[class ${1:class_name} + $0 +end]]></text> + <description>class .. end</description> + <tag>class</tag> + </snippet> + <snippet id="collecto"> + <text><![CDATA[collect do |${1:element}| + ${1:element}.$0 +end]]></text> + <description>collect element do</description> + <tag>collecto</tag> + </snippet> + <snippet id="collect"> + <text><![CDATA[collect { |${1:element}| ${1:element}.$0 }]]></text> + <description>collect element</description> + <tag>collect</tag> + </snippet> + <snippet id="def"> + <text><![CDATA[def ${1:method_name} + $0 +end]]></text> + <description>def .. end</description> + <tag>def</tag> + </snippet> + <snippet id="do"> + <text><![CDATA[do + $0 +end]]></text> + <description>do .. end</description> + <tag>do</tag> + </snippet> + <snippet id="doo"> + <text><![CDATA[do |${1:object}| + $0 +end]]></text> + <description>do |object| .. end</description> + <tag>doo</tag> + </snippet> + <snippet id="eacho"> + <text><![CDATA[each do |${1:element}| + ${1:element}.$0 +end]]></text> + <description>each element do</description> + <tag>eacho</tag> + </snippet> + <snippet id="each"> + <text><![CDATA[each { |${1:element}| ${1:element}.$0 }]]></text> + <description>each element</description> + <tag>each</tag> + </snippet> + <snippet id="each_with_indexo"> + <text><![CDATA[each_with_index do |${1:element}, ${2:idx}| + ${1:element}.$0 +end]]></text> + <description>each_with_index do</description> + <tag>eachwithindexo</tag> + </snippet> + <snippet id="each_with_index"> + <text><![CDATA[each_with_index { |${1:element}, ${2:idx}| ${1:element}.$0 }]]></text> + <description>each_with_index</description> + <tag>eachwithindex</tag> + </snippet> + <snippet id=":"> + <text><![CDATA[:${1:key} => ${2:"value"}${3:, }]]></text> + <description>hash pair</description> + <tag>:</tag> + </snippet> + <snippet id="hashpointer"> + <text><![CDATA[ => ]]></text> + <accelerator><![CDATA[<Shift><Alt>l]]></accelerator> + <description>hash pointer</description> + </snippet> + <snippet id="injecto"> + <text><![CDATA[inject(${1:object}) do |${2:injection}, ${3:element}| + $0 +end]]></text> + <description>inject object do</description> + <tag>injecto</tag> + </snippet> + <snippet id="rejecto"> + <text><![CDATA[reject do |${1:element}| + ${1:element}.$0 +end]]></text> + <description>reject element do</description> + <tag>rejecto</tag> + </snippet> + <snippet id="selecto"> + <text><![CDATA[select do |${1:element}| + ${1:element}.$0 +end]]></text> + <description>select element do</description> + <tag>selecto</tag> + </snippet> + <snippet id="unless"> + <text><![CDATA[unless ${1:condition} + $0 +end]]></text> + <description>unless</description> + <tag>unless</tag> + </snippet> + <snippet id="when"> + <text><![CDATA[when ${1:condition} + $0]]></text> + <description>when</description> + <tag>when</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/sh.xml b/plugins/snippets/data/sh.xml new file mode 100644 index 0000000..b8fc0a6 --- /dev/null +++ b/plugins/snippets/data/sh.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="sh"> + <snippet id="elif"> + <text><![CDATA[elif [[ ${1:condition} ]]; then + $0]]></text> + <description>elif ..</description> + <tag>elif</tag> + </snippet> + <snippet id="case"> + <text><![CDATA[case ${1:choice} in +${2:first}) + $3 + ;; +*) + $4 + ;; +esac]]></text> + <description>case ..</description> + <tag>case</tag> + </snippet> + <snippet id="for"> + <text><![CDATA[for (( ${1:i = 0}; ${2:i < 10}; ${3:i++} )); do + $0 +done]]></text> + <description>for .. done</description> + <tag>for</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[if [[ ${1:condition} ]]; then + $0 +fi]]></text> + <description>if .. then</description> + <tag>if</tag> + </snippet> + <snippet id="sh"> + <text><![CDATA[#!/bin/sh +$0]]></text> + <description>#!/bin/sh</description> + <tag>sh</tag> + </snippet> + <snippet id="bash"> + <text><![CDATA[#!/bin/bash +$0]]></text> + <description>#!/bin/bash</description> + <tag>bash</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/snippets.xml b/plugins/snippets/data/snippets.xml new file mode 100644 index 0000000..ee405e6 --- /dev/null +++ b/plugins/snippets/data/snippets.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="snippets"> + <snippet id="simple"> + <text><![CDATA[\${${1:n:default}}]]></text> + <description>Simple Placeholder</description> + <tag>simple</tag> + </snippet> + <snippet id="simple-fallback"> + <text><![CDATA[\${${1:n:}[${2:default1,default2}]}]]></text> + <description>Simple Fallback Placeholder</description> + <tag>simplef</tag> + </snippet> + <snippet id="shell"> + <text><![CDATA[\$(${1:n:} ${2:shell code})]]></text> + <description>Shell Placeholder</description> + <tag>shell</tag> + </snippet> + <snippet id="python"> + <text><![CDATA[\$<${1:n:} ${2:[refs]:} return 'python code' >]]></text> + <description>Python Placeholder</description> + <tag>python</tag> + </snippet> + <snippet id="regex"> + <text><![CDATA[\${${1:n:} ${2:input}/${3:regex-pattern}/${4:replacement}/${5:modifiers}}]]></text> + <description>Regular Expression Placeholder</description> + <tag>regex</tag> + </snippet> + <snippet id="$-CURRENT_DOCUMENT_PATH"> + <text><![CDATA[\$GEDIT_CURRENT_DOCUMENT_PATH]]></text> + <description>Gedit Current Document Path Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_DOCUMENT_NAME"> + <text><![CDATA[\$GEDIT_CURRENT_DOCUMENT_NAME]]></text> + <description>Gedit Current Document Name Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_DOCUMENT_URI"> + <text><![CDATA[\$GEDIT_CURRENT_DOCUMENT_URI]]></text> + <description>Gedit Current Document Uri Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_DOCUMENT_SCHEME"> + <text><![CDATA[\$GEDIT_CURRENT_DOCUMENT_SCHEME]]></text> + <description>Gedit Current Document Scheme Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_DOCUMENT_TYPE"> + <text><![CDATA[\$GEDIT_CURRENT_DOCUMENT_TYPE]]></text> + <description>Gedit Current Document Type Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-DOCUMENTS_URI"> + <text><![CDATA[\$GEDIT_DOCUMENTS_URI]]></text> + <description>Gedit Documents Uri Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-DOCUMENTS_PATH"> + <text><![CDATA[\$GEDIT_DOCUMENTS_PATH]]></text> + <description>Gedit Documents Path Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-SELECTED_TEXT"> + <text><![CDATA[\$GEDIT_SELECTED_TEXT]]></text> + <description>Gedit Selected Text Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_WORD"> + <text><![CDATA[\$GEDIT_CURRENT_WORD]]></text> + <description>Gedit Current Word Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_LINE"> + <text><![CDATA[\$GEDIT_CURRENT_LINE]]></text> + <description>Gedit Current Line Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-CURRENT_LINE_NUMBER"> + <text><![CDATA[\$GEDIT_CURRENT_LINE_NUMBER]]></text> + <description>Gedit Current Line Number Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-DROP_FILENAME"> + <text><![CDATA[\$GEDIT_DROP_FILENAME]]></text> + <description>Gedit Drop Filename Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-DROP_REL_FILENAME"> + <text><![CDATA[\$GEDIT_DROP_REL_FILENAME]]></text> + <description>Gedit Drop Relative Filename Variable</description> + <tag>$</tag> + </snippet> + <snippet id="$-DROP_MIME_TYPE"> + <text><![CDATA[\$GEDIT_DROP_MIME_TYPE]]></text> + <description>Gedit Drop Mime Type Variable</description> + <tag>$</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/tcl.xml b/plugins/snippets/data/tcl.xml new file mode 100644 index 0000000..73a50c0 --- /dev/null +++ b/plugins/snippets/data/tcl.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="Tcl"> + <snippet id="foreach"> + <text><![CDATA[foreach ${1:var} ${2:$list} { + ${3} +} +]]></text> + <description>foreach...</description> + <tag>foreach</tag> + </snippet> + <snippet id="for"> + <text><![CDATA[for {${1:set i 0}} {${2:$i < $n}} {${3:incr i}} { + ${4} +} +]]></text> + <description>for...</description> + <tag>for</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[if {${1:condition}} { + ${2} +} +]]></text> + <description>if...</description> + <tag>if</tag> + </snippet> + <snippet id="proc"> + <text><![CDATA[proc ${1:name} {${2:args}} \ +{ + ${3} +} +]]></text> + <description>proc...</description> + <tag>proc</tag> + </snippet> + <snippet id="switch"> + <text><![CDATA[switch ${1:-exact} -- ${2:$var} { + ${3:match} { + ${4} + } + default {${5}} +} +]]></text> + <description>switch...</description> + <tag>switch</tag> + </snippet> + <snippet id="while"> + <text><![CDATA[while {${1:condition}} { + ${2} +} +]]></text> + <description>while...</description> + <tag>while</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/data/xml.xml b/plugins/snippets/data/xml.xml new file mode 100644 index 0000000..a53d565 --- /dev/null +++ b/plugins/snippets/data/xml.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="XML"> + <snippet id="""> + <text><![CDATA[<${1:name} ${2:attr}="${3:value}">$0</${1}>]]></text> + <description>Long Attribute Tag</description> + <tag>"</tag> + </snippet> + <snippet id="<"> + <text><![CDATA[<${1:name}>$0</${1}> + +]]></text> + <description>Long Tag</description> + <tag><</tag> + </snippet> + <snippet id=">"> + <text><![CDATA[<${1:name} />]]></text> + <description>Short Tag</description> + <tag>></tag> + </snippet> + <snippet id="cdata"> + <text><![CDATA[<![CDATA[$0]]]]><![CDATA[>]]></text> + <tag>cdata</tag> + <description>CDATA</description> + </snippet> +</snippets> diff --git a/plugins/snippets/data/xslt.xml b/plugins/snippets/data/xslt.xml new file mode 100644 index 0000000..0ff5cc1 --- /dev/null +++ b/plugins/snippets/data/xslt.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<snippets language="xslt"> + <snippet id="stylesheet"> + <text><![CDATA[<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +$0 +</xsl:stylesheet> +]]></text> + <description>StyleSheet</description> + <tag>stylesheet</tag> + </snippet> + <snippet id="include"> + <text><![CDATA[<xsl:include href="$1"/> +]]></text> + <description>Include</description> + <tag>inc</tag> + </snippet> + <snippet id="import"> + <text><![CDATA[<xsl:import href="$1"/> +]]></text> + <description>Import</description> + <tag>imp</tag> + </snippet> + <snippet id="param"> + <text><![CDATA[<xsl:param name="$1"/> +]]></text> + <description>Parameter</description> + <tag>param</tag> + </snippet> + <snippet id="template"> + <text><![CDATA[<xsl:template ${1:[match,name]}="$2" ${3:mode=""}> + $0 +</xsl:template> +]]></text> + <description>Template</description> + <tag>templ</tag> + </snippet> + <snippet id="variable-1"> + <text><![CDATA[<xsl:variable name="$1"> + $0 +</xsl:variable> +]]></text> + <description>Variable</description> + <tag>var</tag> + </snippet> + <snippet id="variable-2"> + <text><![CDATA[<xsl:variable name="$1" select="$2"/> +$0]]></text> + <description>Variable with Select Attribute</description> + <tag>var</tag> + </snippet> + <snippet id="choose"> + <text><![CDATA[<xsl:choose> + <xsl:when test="$1"> + $2 + </xsl:when> + $3 +</xsl:choose> +]]></text> + <description>Choose</description> + <tag>choose</tag> + </snippet> + <snippet id="when"> + <text><![CDATA[<xsl:when test="$1"> + $2 +</xsl:when> +$0]]></text> + <description>When</description> + <tag>when</tag> + </snippet> + <snippet id="otherwise"> + <text><![CDATA[<xsl:otherwise> + $1 +</xsl:otherwise> +$0]]></text> + <description>Otherwise</description> + <tag>otherwise</tag> + </snippet> + <snippet id="if"> + <text><![CDATA[<xsl:if test="$1"> + $2 +</xsl:if> +$0]]></text> + <description>If</description> + <tag>if</tag> + </snippet> + <snippet id="value-of"> + <text><![CDATA[<xsl:value-of select="$1"/> +]]></text> + <description>Value of</description> + <tag>val</tag> + </snippet> + <snippet id="element"> + <text><![CDATA[<xsl:element name="$1"> +</xsl:element> +$0]]></text> + <description>Element</description> + <tag>elem</tag> + </snippet> + <snippet id="attribute"> + <text><![CDATA[<xsl:attribute name="$1">$2</xsl:attribute> +$0]]></text> + <description>Attribute</description> + <tag>attr</tag> + </snippet> + <snippet id="text"> + <text><![CDATA[<xsl:text>${1:$GEDIT_SELECTED_TEXT}</xsl:text> +]]></text> + <description>Text</description> + <tag>text</tag> + </snippet> + <snippet id="comment"> + <text><![CDATA[<xsl:comment>${1:$GEDIT_SELECTED_TEXT}</xsl:comment> +]]></text> + <description>Comment</description> + <tag>comment</tag> + </snippet> + <snippet id="call-template"> + <text><![CDATA[<xsl:call-template name="$1"/> +]]></text> + <description>Call Template</description> + <tag>call</tag> + </snippet> + <snippet id="apply-templates"> + <text><![CDATA[<xsl:apply-templates mode="$1" select="$2"/> +$0]]></text> + <description>Apply Templates</description> + <tag>applyt</tag> + </snippet> + <snippet id="apply-imports"> + <text><![CDATA[<xsl:apply-imports/> +]]></text> + <description>Apply Imports</description> + <tag>applyimp</tag> + </snippet> + <snippet id="with-param"> + <text><![CDATA[<xsl:with-param name="$1"> + $2 +</xsl:with-param> +$0]]></text> + <description>With Param</description> + <tag>with</tag> + </snippet> +</snippets> diff --git a/plugins/snippets/meson.build b/plugins/snippets/meson.build new file mode 100644 index 0000000..91401d1 --- /dev/null +++ b/plugins/snippets/meson.build @@ -0,0 +1,23 @@ +subdir('snippets') + +install_subdir( + 'data', + strip_directory : true, + install_dir: join_paths( + pkgdatadir, + 'plugins', + 'snippets', + ) +) + +custom_target( + 'snippets.plugin', + input: 'snippets.plugin.desktop.in', + output: 'snippets.plugin', + command: msgfmt_plugin_cmd, + install: true, + install_dir: join_paths( + pkglibdir, + 'plugins', + ) +) diff --git a/plugins/snippets/snippets.plugin.desktop.in b/plugins/snippets/snippets.plugin.desktop.in new file mode 100644 index 0000000..129db21 --- /dev/null +++ b/plugins/snippets/snippets.plugin.desktop.in @@ -0,0 +1,9 @@ +[Plugin] +Loader=python3 +Module=snippets +IAge=3 +Name=Snippets +Description=Insert often-used pieces of text in a fast way. +Authors=Jesse van den Kieboom <jesse@icecrew.nl> +Copyright=Copyright © 2005 Jesse van den Kieboom +Website=http://www.gedit.org diff --git a/plugins/snippets/snippets/__init__.py b/plugins/snippets/snippets/__init__.py new file mode 100644 index 0000000..147aa69 --- /dev/null +++ b/plugins/snippets/snippets/__init__.py @@ -0,0 +1,26 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gi +gi.require_version('Gedit', '3.0') +gi.require_version('Gtk', '3.0') + +from .appactivatable import AppActivatable +from .windowactivatable import WindowActivatable +from .document import Document + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/appactivatable.py b/plugins/snippets/snippets/appactivatable.py new file mode 100644 index 0000000..fb56e51 --- /dev/null +++ b/plugins/snippets/snippets/appactivatable.py @@ -0,0 +1,133 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import platform +from gi.repository import Gedit, Gtk, Gdk, GObject, Gio, GLib +from .library import Library +from .shareddata import SharedData + +try: + import gettext + gettext.bindtextdomain('gedit') + gettext.textdomain('gedit') + _ = gettext.gettext +except: + _ = lambda s: s + +class AppActivatable(GObject.Object, Gedit.AppActivatable): + __gtype_name__ = "GeditSnippetsAppActivatable" + + app = GObject.Property(type=Gedit.App) + + def __init__(self): + GObject.Object.__init__(self) + + def do_activate(self): + # Initialize snippets library + library = Library() + + if platform.system() == 'Windows': + snippetsdir = os.path.expanduser('~/gedit/snippets') + else: + snippetsdir = os.path.join(GLib.get_user_config_dir(), 'gedit/snippets') + + library.set_dirs(snippetsdir, self.system_dirs()) + + self.css = Gtk.CssProvider() + self.css.load_from_data(""" +.gedit-snippet-manager-paned { + border-style: solid; + border-color: @borders; +} +.gedit-snippet-manager-paned:dir(ltr) { + border-width: 0 1px 0 0; +} + +.gedit-snippet-manager-paned:dir(rtl) { + border-width: 0 0 0 1px; +} + +.gedit-snippet-manager-view { + border-width: 0 0 1px 0; +} + +.gedit-snippet-manager-treeview { + border-top-width: 0; +} + +.gedit-snippet-manager-treeview:dir(ltr) { + border-left-width: 0; +} + +.gedit-snippet-manager-treeview:dir(rtl) { + border-right-width: 0; +} +""".encode('utf-8')) + Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), + self.css, 600) + + action = Gio.SimpleAction(name="snippets") + action.connect('activate', self.on_action_snippets_activate) + self.app.add_action(action) + + item = Gio.MenuItem.new(_("Manage _Snippets…"), "app.snippets") + self.menu = self.extend_menu("preferences-section") + self.menu.append_menu_item(item) + + def do_deactivate(self): + self.app.remove_action("snippets") + self.menu = None + Gtk.StyleContext.remove_provider_for_screen(Gdk.Screen.get_default(), + self.css) + + def system_dirs(self): + dirs = [] + + if 'XDG_DATA_DIRS' in os.environ: + datadirs = os.environ['XDG_DATA_DIRS'] + elif platform.system() != 'Windows': + datadirs = '/usr/local/share' + os.pathsep + '/usr/share' + else: + datadirs = GLib.win32_get_package_installation_directory_of_module(None) + + for d in datadirs.split(os.pathsep): + d = os.path.join(d, 'gedit', 'plugins', 'snippets') + + if os.path.isdir(d): + dirs.append(d) + + dirs.append(self.plugin_info.get_data_dir()) + return dirs + + def accelerator_activated(self, group, obj, keyval, mod): + activatable = SharedData().lookup_window_activatable(obj) + + ret = False + + if activatable: + ret = activatable.accelerator_activated(keyval, mod) + + return ret + + def create_configure_dialog(self): + SharedData().show_manager(self.app.get_active_window(), self.plugin_info.get_data_dir()) + + def on_action_snippets_activate(self, action, parameter): + self.create_configure_dialog() + +# vi:ex:ts=4:et diff --git a/plugins/snippets/snippets/completion.py b/plugins/snippets/snippets/completion.py new file mode 100644 index 0000000..562b268 --- /dev/null +++ b/plugins/snippets/snippets/completion.py @@ -0,0 +1,187 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from gi.repository import GObject, Gtk, GtkSource, Gedit + +from .library import Library +from .languagemanager import get_language_manager +from .snippet import Snippet + +class Proposal(GObject.Object, GtkSource.CompletionProposal): + __gtype_name__ = "GeditSnippetsProposal" + + def __init__(self, snippet): + super(Proposal, self).__init__() + self._snippet = Snippet(snippet) + + def snippet(self): + return self._snippet.data + + # Interface implementation + def do_get_markup(self): + return self._snippet.display() + + def do_get_info(self): + return self._snippet.data['text'] + +class Provider(GObject.Object, GtkSource.CompletionProvider): + __gtype_name__ = "GeditSnippetsProvider" + + def __init__(self, name, language_id, handler): + super(Provider, self).__init__() + + self.name = name + self.info_widget = None + self.proposals = [] + self.language_id = language_id + self.handler = handler + self.info_widget = None + self.mark = None + + theme = Gtk.IconTheme.get_default() + f, w, h = Gtk.icon_size_lookup(Gtk.IconSize.MENU) + + try: + self.icon = theme.load_icon(Gtk.STOCK_JUSTIFY_LEFT, w, 0) + except: + self.icon = None + + def __del__(self): + if self.mark: + self.mark.get_buffer().delete_mark(self.mark) + + def set_proposals(self, proposals): + self.proposals = proposals + + def mark_position(self, it): + if not self.mark: + self.mark = it.get_buffer().create_mark(None, it, True) + else: + self.mark.get_buffer().move_mark(self.mark, it) + + def get_word(self, context): + (valid_context, it) = context.get_iter() + if not valid_context: + return None + + if it.starts_word() or it.starts_line() or not it.ends_word(): + return None + + start = it.copy() + + if start.backward_word_start(): + self.mark_position(start) + return start.get_text(it) + else: + return None + + def do_get_start_iter(self, context, proposal): + if not self.mark or self.mark.get_deleted(): + return (False, None) + + return (True, self.mark.get_buffer().get_iter_at_mark(self.mark)) + + def do_match(self, context): + return True + + def get_proposals(self, word): + if self.proposals: + proposals = self.proposals + else: + proposals = Library().get_snippets(None) + + if self.language_id: + proposals += Library().get_snippets(self.language_id) + + # Filter based on the current word + if word: + proposals = (x for x in proposals if x['tag'].startswith(word)) + + return [Proposal(x) for x in proposals] + + def do_populate(self, context): + proposals = self.get_proposals(self.get_word(context)) + context.add_proposals(self, proposals, True) + + def do_get_name(self): + return self.name + + def do_activate_proposal(self, proposal, piter): + return self.handler(proposal, piter) + + def do_get_info_widget(self, proposal): + if not self.info_widget: + view = Gedit.View.new_with_buffer(Gedit.Document()) + manager = get_language_manager() + + lang = manager.get_language('snippets') + view.get_buffer().set_language(lang) + + sw = Gtk.ScrolledWindow() + sw.add(view) + sw.show_all() + + # Fixed size + sw.set_size_request(300, 200) + + self.info_view = view + self.info_widget = sw + + return self.info_widget + + def do_update_info(self, proposal, info): + buf = self.info_view.get_buffer() + + buf.set_text(proposal.get_info()) + buf.move_mark(buf.get_insert(), buf.get_start_iter()) + buf.move_mark(buf.get_selection_bound(), buf.get_start_iter()) + self.info_view.scroll_to_iter(buf.get_start_iter(), 0.0, False, 0.5, 0.5) + + def do_get_icon(self): + return self.icon + + def do_get_activation(self): + return GtkSource.CompletionActivation.USER_REQUESTED + +class Defaults(GObject.Object, GtkSource.CompletionProvider): + __gtype_name__ = "GeditSnippetsDefaultsProvider" + + def __init__(self, handler): + GObject.Object.__init__(self) + + self.handler = handler + self.proposals = [] + + def set_defaults(self, defaults): + self.proposals = [] + + for d in defaults: + self.proposals.append(GtkSource.CompletionItem.new(d, d, None, None)) + + def do_get_name(self): + return "" + + def do_activate_proposal(self, proposal, piter): + return self.handler(proposal, piter) + + def do_populate(self, context): + context.add_proposals(self, self.proposals, True) + + def do_get_activation(self): + return GtkSource.CompletionActivation.USER_REQUESTED + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/document.py b/plugins/snippets/snippets/document.py new file mode 100644 index 0000000..23df280 --- /dev/null +++ b/plugins/snippets/snippets/document.py @@ -0,0 +1,1097 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import re + +from gi.repository import Gtk, Gdk, Gio, GLib, Gedit, GObject + +from .library import Library +from .snippet import Snippet +from .placeholder import PlaceholderEnd +from . import completion +from .signals import Signals +from .shareddata import SharedData +from . import helper + +try: + import gettext + gettext.bindtextdomain('gedit') + gettext.textdomain('gedit') + _ = gettext.gettext +except: + _ = lambda s: s + +class DynamicSnippet(dict): + def __init__(self, text): + self['text'] = text + self.valid = True + +class Document(GObject.Object, Gedit.ViewActivatable, Signals): + TAB_KEY_VAL = (Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab) + SPACE_KEY_VAL = (Gdk.KEY_space,) + + view = GObject.Property(type=Gedit.View) + + def __init__(self): + GObject.Object.__init__(self) + Signals.__init__(self) + + self.placeholders = [] + self.active_snippets = [] + self.active_placeholder = None + + self.ordered_placeholders = [] + self.update_placeholders = [] + self.jump_placeholders = [] + self.language_id = 0 + self.timeout_update_id = 0 + + self.provider = completion.Provider(_('Snippets'), self.language_id, self.on_proposal_activated) + + def do_activate(self): + # Always have a reference to the global snippets + Library().ref(None) + + buf = self.view.get_buffer() + + self.connect_signal(self.view, 'key-press-event', self.on_view_key_press) + self.connect_signal(buf, 'notify::language', self.on_notify_language) + self.connect_signal(self.view, 'drag-data-received', self.on_drag_data_received) + + self.connect_signal_after(self.view, 'draw', self.on_draw) + + self.update_language() + + completion = self.view.get_completion() + completion.add_provider(self.provider) + + SharedData().register_controller(self.view, self) + + def do_deactivate(self): + if self.timeout_update_id != 0: + GLib.source_remove(self.timeout_update_id) + self.timeout_update_id = 0 + + del self.update_placeholders[:] + del self.jump_placeholders[:] + + # Always release the reference to the global snippets + Library().unref(None) + self.active_placeholder = None + + self.disconnect_signals(self.view) + self.disconnect_signals(self.view.get_buffer()) + + # Remove all active snippets + for snippet in list(self.active_snippets): + self.deactivate_snippet(snippet, True) + + completion = self.view.get_completion() + + if completion: + completion.remove_provider(self.provider) + + if self.language_id != 0: + Library().unref(self.language_id) + + SharedData().unregister_controller(self.view, self) + + # Call this whenever the language in the view changes. This makes sure that + # the correct language is used when finding snippets + def update_language(self): + lang = self.view.get_buffer().get_language() + + if lang is None and self.language_id is None: + return + elif lang and lang.get_id() == self.language_id: + return + + langid = self.language_id + + if lang: + self.language_id = lang.get_id() + else: + self.language_id = None + + if langid != 0: + Library().unref(langid) + + Library().ref(self.language_id) + self.provider.language_id = self.language_id + + SharedData().update_state(self.view.get_toplevel()) + + def accelerator_activate(self, keyval, mod): + if not self.view or not self.view.get_editable(): + return False + + accelerator = Gtk.accelerator_name(keyval, mod) + snippets = Library().from_accelerator(accelerator, \ + self.language_id) + + if len(snippets) == 0: + return False + elif len(snippets) == 1: + self.apply_snippet(snippets[0]) + else: + # Do the fancy completion dialog + provider = completion.Provider(_('Snippets'), self.language_id, self.on_proposal_activated) + provider.set_proposals(snippets) + + cm = self.view.get_completion() + cm.show([provider], cm.create_context(None)) + + return True + + def first_snippet_inserted(self): + buf = self.view.get_buffer() + + self.connect_signal(buf, 'changed', self.on_buffer_changed) + self.connect_signal(buf, 'cursor-moved', self.on_buffer_cursor_moved) + self.connect_signal_after(buf, 'insert-text', self.on_buffer_insert_text) + + def last_snippet_removed(self): + buf = self.view.get_buffer() + self.disconnect_signal(buf, 'changed') + self.disconnect_signal(buf, 'cursor-moved') + self.disconnect_signal(buf, 'insert-text') + + def current_placeholder(self): + buf = self.view.get_buffer() + + piter = buf.get_iter_at_mark(buf.get_insert()) + found = [] + + for placeholder in self.placeholders: + begin = placeholder.begin_iter() + end = placeholder.end_iter() + + if piter.compare(begin) >= 0 and piter.compare(end) <= 0: + found.append(placeholder) + + if self.active_placeholder in found: + return self.active_placeholder + elif len(found) > 0: + return found[0] + else: + return None + + def advance_placeholder(self, direction): + # Returns (CurrentPlaceholder, NextPlaceholder), depending on direction + buf = self.view.get_buffer() + + piter = buf.get_iter_at_mark(buf.get_insert()) + found = current = next = None + length = len(self.placeholders) + + placeholders = list(self.placeholders) + + if self.active_placeholder: + begin = self.active_placeholder.begin_iter() + end = self.active_placeholder.end_iter() + + if piter.compare(begin) >= 0 and piter.compare(end) <= 0: + current = self.active_placeholder + currentIndex = placeholders.index(self.active_placeholder) + + if direction == 1: + # w = piter, x = begin, y = end, z = found + nearest = lambda w, x, y, z: (w.compare(x) <= 0 and (not z or \ + x.compare(z.begin_iter()) < 0)) + indexer = lambda x: x < length - 1 + else: + # w = piter, x = begin, y = end, z = prev + nearest = lambda w, x, y, z: (w.compare(x) >= 0 and (not z or \ + x.compare(z.begin_iter()) >= 0)) + indexer = lambda x: x > 0 + + for index in range(0, length): + placeholder = placeholders[index] + begin = placeholder.begin_iter() + end = placeholder.end_iter() + + # Find the nearest placeholder + if nearest(piter, begin, end, found): + found = placeholder + + # Find the current placeholder + if piter.compare(begin) >= 0 and \ + piter.compare(end) <= 0 and \ + current is None: + currentIndex = index + current = placeholder + + if current and current != found and \ + (current.begin_iter().compare(found.begin_iter()) == 0 or \ + current.end_iter().compare(found.begin_iter()) == 0) and \ + self.active_placeholder and \ + current.begin_iter().compare(self.active_placeholder.begin_iter()) == 0: + # if current and found are at the same place, then + # resolve the 'hugging' problem + current = self.active_placeholder + currentIndex = placeholders.index(current) + + if current: + if indexer(currentIndex): + next = placeholders[currentIndex + direction] + elif found: + next = found + elif length > 0: + next = self.placeholders[0] + + return current, next + + def next_placeholder(self): + return self.advance_placeholder(1) + + def previous_placeholder(self): + return self.advance_placeholder(-1) + + def cursor_on_screen(self): + buf = self.view.get_buffer() + self.view.scroll_mark_onscreen(buf.get_insert()) + + def set_active_placeholder(self, placeholder): + self.active_placeholder = placeholder + + def goto_placeholder(self, current, next): + last = None + + if current: + # Signal this placeholder to end action + self.view.get_completion().hide() + current.leave() + + if current.__class__ == PlaceholderEnd: + last = current + + self.set_active_placeholder(next) + + if next: + next.enter() + + if next.__class__ == PlaceholderEnd: + last = next + elif len(next.defaults) > 1 and next.get_text() == next.default: + provider = completion.Defaults(self.on_default_activated) + provider.set_defaults(next.defaults) + + cm = self.view.get_completion() + cm.show([provider], cm.create_context(None)) + + if last: + # This is the end of the placeholder, remove the snippet etc + for snippet in list(self.active_snippets): + if snippet.placeholders[0] == last: + self.deactivate_snippet(snippet) + break + + self.cursor_on_screen() + + return next != None + + def skip_to_next_placeholder(self): + (current, next) = self.next_placeholder() + return self.goto_placeholder(current, next) + + def skip_to_previous_placeholder(self): + (current, prev) = self.previous_placeholder() + return self.goto_placeholder(current, prev) + + def string_in_native_doc_encoding(self, buf, s): + enc = buf.get_file().get_encoding() + + if not enc or enc.get_charset() == 'UTF-8': + return s + + try: + cv = GLib.convert(s, -1, enc.get_charset(), 'UTF-8') + return cv[0] + except GLib.GError: + pass + + return s + + def env_get_selected_text(self, buf): + bounds = buf.get_selection_bounds() + + if bounds: + u8 = buf.get_text(bounds[0], bounds[1], False) + + return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)} + else: + return '' + + def env_get_current_word(self, buf): + start, end = helper.buffer_word_boundary(buf) + + u8 = buf.get_text(start, end, False) + + return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)} + + def env_get_current_line(self, buf): + start, end = helper.buffer_line_boundary(buf) + + u8 = buf.get_text(start, end, False) + + return {'utf8': u8, 'noenc': self.string_in_native_doc_encoding(buf, u8)} + + def env_get_current_line_number(self, buf): + start, end = helper.buffer_line_boundary(buf) + + return str(start.get_line() + 1) + + def location_uri_for_env(self, location): + if not location: + return {'utf8': '', 'noenc': ''} + + u8 = location.get_parse_name() + + if location.has_uri_scheme('file'): + u8 = "file://" + u8 + + return {'utf8': u8, 'noenc': location.get_uri()} + + def location_name_for_env(self, location): + if location: + try: + info = location.query_info("standard::display-name", 0, None) + display_name = info.get_display_name() + except: + display_name = '' + + return {'utf8': display_name, + 'noenc': location.get_basename()} + else: + return '' + + def location_scheme_for_env(self, location): + if location: + return location.get_uri_scheme() + else: + return '' + + def location_path_for_env(self, location): + if location and location.has_uri_scheme('file'): + return {'utf8': location.get_parse_name(), + 'noenc': location.get_path()} + else: + return '' + + def location_dir_for_env(self, location): + if location: + parent = location.get_parent() + + if parent and parent.has_uri_scheme('file'): + return {'utf8': parent.get_parse_name(), + 'noenc': parent.get_path()} + + return '' + + def env_add_for_location(self, environ, location, prefix): + parts = {'URI': self.location_uri_for_env, + 'NAME': self.location_name_for_env, + 'SCHEME': self.location_scheme_for_env, + 'PATH': self.location_path_for_env, + 'DIR': self.location_dir_for_env} + + for k in parts: + v = parts[k](location) + key = prefix + '_' + k + + if isinstance(v, dict): + environ['utf8'][key] = v['utf8'] + environ['noenc'][key] = v['noenc'] + else: + environ['utf8'][key] = v + environ['noenc'][key] = str(v) + + return environ + + def env_get_document_type(self, buf): + typ = buf.get_mime_type() + + if typ: + return typ + else: + return '' + + def env_get_documents_uri(self, buf): + toplevel = self.view.get_toplevel() + + documents_uri = {'utf8': [], 'noenc': []} + + if isinstance(toplevel, Gedit.Window): + for doc in toplevel.get_documents(): + r = self.location_uri_for_env(doc.get_file().get_location()) + + if isinstance(r, dict): + documents_uri['utf8'].append(r['utf8']) + documents_uri['noenc'].append(r['noenc']) + else: + documents_uri['utf8'].append(r) + documents_uri['noenc'].append(str(r)) + + return {'utf8': ' '.join(documents_uri['utf8']), + 'noenc': ' '.join(documents_uri['noenc'])} + + def env_get_documents_path(self, buf): + toplevel = self.view.get_toplevel() + + documents_path = {'utf8': [], 'noenc': []} + + if isinstance(toplevel, Gedit.Window): + for doc in toplevel.get_documents(): + r = self.location_path_for_env(doc.get_file().get_location()) + + if isinstance(r, dict): + documents_path['utf8'].append(r['utf8']) + documents_path['noenc'].append(r['noenc']) + else: + documents_path['utf8'].append(r) + documents_path['noenc'].append(str(r)) + + return {'utf8': ' '.join(documents_path['utf8']), + 'noenc': ' '.join(documents_path['noenc'])} + + def get_environment(self): + buf = self.view.get_buffer() + environ = {'utf8': {}, 'noenc': {}} + + for k in os.environ: + # Get the original environment, as utf-8 + v = os.environ[k] + environ['noenc'][k] = v + environ['utf8'][k] = os.environ[k].encode('utf-8') + + variables = {'GEDIT_SELECTED_TEXT': self.env_get_selected_text, + 'GEDIT_CURRENT_WORD': self.env_get_current_word, + 'GEDIT_CURRENT_LINE': self.env_get_current_line, + 'GEDIT_CURRENT_LINE_NUMBER': self.env_get_current_line_number, + 'GEDIT_CURRENT_DOCUMENT_TYPE': self.env_get_document_type, + 'GEDIT_DOCUMENTS_URI': self.env_get_documents_uri, + 'GEDIT_DOCUMENTS_PATH': self.env_get_documents_path} + + for var in variables: + v = variables[var](buf) + + if isinstance(v, dict): + environ['utf8'][var] = v['utf8'] + environ['noenc'][var] = v['noenc'] + else: + environ['utf8'][var] = v + environ['noenc'][var] = str(v) + + self.env_add_for_location(environ, buf.get_file().get_location(), 'GEDIT_CURRENT_DOCUMENT') + + return environ + + def uses_current_word(self, snippet): + matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_WORD', snippet['text']) + + for match in matches: + if len(match) % 2 == 0: + return True + + return False + + def uses_current_line(self, snippet): + matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_LINE', snippet['text']) + + for match in matches: + if len(match) % 2 == 0: + return True + + return False + + def apply_snippet(self, snippet, start = None, end = None, environ = {}): + if not snippet.valid: + return False + + # Set environmental variables + env = self.get_environment() + + if environ: + for k in environ['utf8']: + env['utf8'][k] = environ['utf8'][k] + + for k in environ['noenc']: + env['noenc'][k] = environ['noenc'][k] + + buf = self.view.get_buffer() + s = Snippet(snippet, env) + + if not start: + start = buf.get_iter_at_mark(buf.get_insert()) + + if not end: + end = buf.get_iter_at_mark(buf.get_selection_bound()) + + if start.equal(end) and self.uses_current_word(s): + # There is no tab trigger and no selection and the snippet uses + # the current word. Set start and end to the word boundary so that + # it will be removed + start, end = helper.buffer_word_boundary(buf) + elif start.equal(end) and self.uses_current_line(s): + # There is no tab trigger and no selection and the snippet uses + # the current line. Set start and end to the line boundary so that + # it will be removed + start, end = helper.buffer_line_boundary(buf) + + # You know, we could be in an end placeholder + (current, next) = self.next_placeholder() + if current and current.__class__ == PlaceholderEnd: + self.goto_placeholder(current, None) + + if len(self.active_snippets) > 0: + self.block_signal(buf, 'cursor-moved') + + buf.begin_user_action() + + # Remove the tag, selection or current word + buf.delete(start, end) + + # Insert the snippet + if len(self.active_snippets) == 0: + self.first_snippet_inserted() + self.block_signal(buf, 'cursor-moved') + + sn = s.insert_into(self, start) + self.active_snippets.append(sn) + + # Put cursor at first tab placeholder + keys = [x for x in sn.placeholders.keys() if x > 0] + + if len(keys) == 0: + if 0 in sn.placeholders: + self.goto_placeholder(self.active_placeholder, sn.placeholders[0]) + else: + buf.place_cursor(sn.begin_iter()) + else: + self.goto_placeholder(self.active_placeholder, sn.placeholders[keys[0]]) + + self.unblock_signal(buf, 'cursor-moved') + + if sn in self.active_snippets: + # Check if we can get end_iter in view without moving the + # current cursor position out of view + cur = buf.get_iter_at_mark(buf.get_insert()) + last = sn.end_iter() + + curloc = self.view.get_iter_location(cur) + lastloc = self.view.get_iter_location(last) + + if (lastloc.y + lastloc.height) - curloc.y <= \ + self.view.get_visible_rect().height: + self.view.scroll_mark_onscreen(sn.end_mark) + + buf.end_user_action() + self.view.grab_focus() + + return True + + def get_tab_tag(self, buf, end = None): + if not end: + end = buf.get_iter_at_mark(buf.get_insert()) + + start = end.copy() + word = None + first = True + + # Move start backward as long as there is a valid character + while start.backward_char(): + c = start.get_char() + + if not helper.is_tab_trigger_character(c): + # Check this for a single special char + if first and helper.is_tab_trigger(c): + break + + # Make sure first char is valid + while not start.equal(end) and \ + not helper.is_first_tab_trigger_character(start.get_char()): + start.forward_char() + + break + + first = False + + if not start.equal(end): + word = buf.get_text(start, end, False) + + if word and word != '': + return (word, start, end) + + return (None, None, None) + + def parse_and_run_snippet(self, data, iter): + if not self.view.get_editable(): + return + + self.apply_snippet(DynamicSnippet(data), iter, iter) + + def run_snippet_trigger(self, trigger, bounds): + if not self.view: + return False + + if not self.view.get_editable(): + return False + + buf = self.view.get_buffer() + + if buf.get_has_selection(): + return False + + snippets = Library().from_tag(trigger, self.language_id) + + if snippets: + if len(snippets) == 1: + return self.apply_snippet(snippets[0], bounds[0], bounds[1]) + else: + # Do the fancy completion dialog + provider = completion.Provider(_('Snippets'), self.language_id, self.on_proposal_activated) + provider.set_proposals(snippets) + + cm = self.view.get_completion() + cm.show([provider], cm.create_context(None)) + + return True + + return False + + def run_snippet(self): + if not self.view: + return False + + if not self.view.get_editable(): + return False + + buf = self.view.get_buffer() + + # get the word preceding the current insertion position + (word, start, end) = self.get_tab_tag(buf) + + if not word: + return self.skip_to_next_placeholder() + + if not self.run_snippet_trigger(word, (start, end)): + return self.skip_to_next_placeholder() + else: + return True + + def deactivate_snippet(self, snippet, force = False): + remove = [] + ordered_remove = [] + + for tabstop in snippet.placeholders: + if tabstop == -1: + placeholders = snippet.placeholders[-1] + else: + placeholders = [snippet.placeholders[tabstop]] + + for placeholder in placeholders: + if placeholder in self.placeholders: + if placeholder in self.update_placeholders: + placeholder.update_contents() + + self.update_placeholders.remove(placeholder) + elif placeholder in self.jump_placeholders: + placeholder[0].leave() + + remove.append(placeholder) + elif placeholder in self.ordered_placeholders: + ordered_remove.append(placeholder) + + for placeholder in remove: + if placeholder == self.active_placeholder: + self.active_placeholder = None + + self.placeholders.remove(placeholder) + self.ordered_placeholders.remove(placeholder) + + placeholder.remove(force) + + for placeholder in ordered_remove: + self.ordered_placeholders.remove(placeholder) + placeholder.remove(force) + + snippet.deactivate() + self.active_snippets.remove(snippet) + + if len(self.active_snippets) == 0: + self.last_snippet_removed() + + self.view.queue_draw() + + def update_snippet_contents(self): + self.timeout_update_id = 0 + + for placeholder in self.update_placeholders: + placeholder.update_contents() + + for placeholder in self.jump_placeholders: + self.goto_placeholder(placeholder[0], placeholder[1]) + + del self.update_placeholders[:] + del self.jump_placeholders[:] + + return False + + def on_buffer_cursor_moved(self, buf): + piter = buf.get_iter_at_mark(buf.get_insert()) + + # Check for all snippets if the cursor is outside its scope + for snippet in list(self.active_snippets): + if snippet.begin_mark.get_deleted() or snippet.end_mark.get_deleted(): + self.deactivate(snippet) + else: + begin = snippet.begin_iter() + end = snippet.end_iter() + + if piter.compare(begin) < 0 or piter.compare(end) > 0: + # Oh no! Remove the snippet this instant!! + self.deactivate_snippet(snippet) + + current = self.current_placeholder() + + if current != self.active_placeholder: + self.jump_placeholders.append((self.active_placeholder, current)) + + if self.timeout_update_id == 0: + self.timeout_update_id = GLib.timeout_add(0, + self.update_snippet_contents) + + def on_buffer_changed(self, buf): + for snippet in list(self.active_snippets): + begin = snippet.begin_iter() + end = snippet.end_iter() + + if begin.compare(end) >= 0: + # Begin collapsed on end, just remove it + self.deactivate_snippet(snippet) + + current = self.current_placeholder() + + if current: + if not current in self.update_placeholders: + self.update_placeholders.append(current) + + if self.timeout_update_id == 0: + self.timeout_update_id = GLib.timeout_add(0, \ + self.update_snippet_contents) + + def on_buffer_insert_text(self, buf, piter, text, length): + ctx = helper.get_buffer_context(buf) + + # do nothing special if there is no context and no active + # placeholder + if (not ctx) and (not self.active_placeholder): + return + + if not ctx: + ctx = self.active_placeholder + + if not ctx in self.ordered_placeholders: + return + + # move any marks that were incorrectly moved by this insertion + # back to where they belong + begin = ctx.begin_iter() + end = ctx.end_iter() + idx = self.ordered_placeholders.index(ctx) + + for placeholder in self.ordered_placeholders: + if placeholder == ctx: + continue + + ob = placeholder.begin_iter() + oe = placeholder.end_iter() + + if ob.compare(begin) == 0 and ((not oe) or oe.compare(end) == 0): + oidx = self.ordered_placeholders.index(placeholder) + + if oidx > idx and ob: + buf.move_mark(placeholder.begin, end) + elif oidx < idx and oe: + buf.move_mark(placeholder.end, begin) + elif ob.compare(begin) >= 0 and ob.compare(end) < 0 and (oe and oe.compare(end) >= 0): + buf.move_mark(placeholder.begin, end) + elif (oe and oe.compare(begin) > 0) and ob.compare(begin) <= 0: + buf.move_mark(placeholder.end, begin) + + def on_notify_language(self, buf, spec): + self.update_language() + + def on_view_key_press(self, view, event): + library = Library() + + state = event.get_state() + + if not self.view.get_editable(): + return False + + if not (state & Gdk.ModifierType.CONTROL_MASK) and \ + not (state & Gdk.ModifierType.MOD1_MASK) and \ + event.keyval in self.TAB_KEY_VAL: + if not state & Gdk.ModifierType.SHIFT_MASK: + return self.run_snippet() + else: + return self.skip_to_previous_placeholder() + elif not library.loaded and \ + library.valid_accelerator(event.keyval, state): + library.ensure_files() + library.ensure(self.language_id) + self.accelerator_activate(event.keyval, \ + state & Gtk.accelerator_get_default_mod_mask()) + + return False + + def path_split(self, path, components=[]): + head, tail = os.path.split(path) + + if not tail and head: + return [head] + components + elif tail: + return self.path_split(head, [tail] + components) + else: + return components + + def apply_uri_snippet(self, snippet, mime, uri): + # Remove file scheme + gfile = Gio.file_new_for_uri(uri) + + environ = {'utf8': {'GEDIT_DROP_DOCUMENT_TYPE': mime.encode('utf-8')}, + 'noenc': {'GEDIT_DROP_DOCUMENT_TYPE': mime}} + + self.env_add_for_location(environ, gfile, 'GEDIT_DROP_DOCUMENT') + + buf = self.view.get_buffer() + location = buf.get_file().get_location() + + relpath = location.get_relative_path(gfile) + + # CHECK: what is the encoding of relpath? + environ['utf8']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath.encode('utf-8') + environ['noenc']['GEDIT_DROP_DOCUMENT_RELATIVE_PATH'] = relpath + + mark = buf.get_mark('gtk_drag_target') + + if not mark: + mark = buf.get_insert() + + piter = buf.get_iter_at_mark(mark) + self.apply_snippet(snippet, piter, piter, environ) + + def in_bounds(self, x, y): + rect = self.view.get_visible_rect() + rect.x, rect.y = self.view.buffer_to_window_coords(Gtk.TextWindowType.WIDGET, rect.x, rect.y) + + return not (x < rect.x or x > rect.x + rect.width or y < rect.y or y > rect.y + rect.height) + + def on_drag_data_received(self, view, context, x, y, data, info, timestamp): + if not self.view.get_editable(): + return + + uris = helper.drop_get_uris(data) + if not uris: + return + + if not self.in_bounds(x, y): + return + + uris.reverse() + stop = False + + for uri in uris: + try: + mime = Gio.content_type_guess(uri) + except: + mime = None + + if not mime: + continue + + snippets = Library().from_drop_target(mime, self.language_id) + + if snippets: + stop = True + self.apply_uri_snippet(snippets[0], mime, uri) + + if stop: + context.finish(True, False, timestamp) + view.stop_emission('drag-data-received') + view.get_toplevel().present() + view.grab_focus() + + def find_uri_target(self, context): + lst = Gtk.target_list_add_uri_targets((), 0) + + return self.view.drag_dest_find_target(context, lst) + + def on_proposal_activated(self, proposal, piter): + if not self.view.get_editable(): + return False + + buf = self.view.get_buffer() + bounds = buf.get_selection_bounds() + + if bounds: + self.apply_snippet(proposal.snippet(), None, None) + else: + (word, start, end) = self.get_tab_tag(buf, piter) + self.apply_snippet(proposal.snippet(), start, end) + + return True + + def on_default_activated(self, proposal, piter): + buf = self.view.get_buffer() + bounds = buf.get_selection_bounds() + + if bounds: + buf.begin_user_action() + buf.delete(bounds[0], bounds[1]) + buf.insert(bounds[0], proposal.props.label) + buf.end_user_action() + + return True + else: + return False + + def iter_coords(self, piter): + rect = self.view.get_iter_location(piter) + rect.x, rect.y = self.view.buffer_to_window_coords(Gtk.TextWindowType.TEXT, rect.x, rect.y) + + return rect + + def placeholder_in_area(self, placeholder, area): + start = placeholder.begin_iter() + end = placeholder.end_iter() + + if not start or not end: + return False + + # Test if start is before bottom, and end is after top + start_rect = self.iter_coords(start) + end_rect = self.iter_coords(end) + + return start_rect.y <= area.y + area.height and \ + end_rect.y + end_rect.height >= area.y + + def draw_placeholder_rect(self, ctx, placeholder): + start = placeholder.begin_iter() + start_rect = self.iter_coords(start) + start_line = start.get_line() + + end = placeholder.end_iter() + end_rect = self.iter_coords(end) + end_line = end.get_line() + + line = start.copy() + line.set_line_offset(0) + geom = self.view.get_window(Gtk.TextWindowType.TEXT).get_geometry() + + ctx.translate(0.5, 0.5) + + while line.get_line() <= end_line: + ypos, height = self.view.get_line_yrange(line) + x_, ypos = self.view.window_to_buffer_coords(Gtk.TextWindowType.TEXT, 0, ypos) + + if line.get_line() == start_line and line.get_line() == end_line: + # Simply draw a box, both are on the same line + ctx.rectangle(start_rect.x, start_rect.y, end_rect.x - start_rect.x, start_rect.height - 1) + ctx.stroke() + elif line.get_line() == start_line or line.get_line() == end_line: + if line.get_line() == start_line: + rect = start_rect + else: + rect = end_rect + + ctx.move_to(0, rect.y + rect.height - 1) + ctx.rel_line_to(rect.x, 0) + ctx.rel_line_to(0, -rect.height + 1) + ctx.rel_line_to(geom[2], 0) + ctx.stroke() + + if not line.forward_line(): + break + + def draw_placeholder_bar(self, ctx, placeholder): + start = placeholder.begin_iter() + start_rect = self.iter_coords(start) + + ctx.translate(0.5, 0.5) + extend_width = 2.5 + + ctx.move_to(start_rect.x - extend_width, start_rect.y) + ctx.rel_line_to(extend_width * 2, 0) + + ctx.move_to(start_rect.x, start_rect.y) + ctx.rel_line_to(0, start_rect.height - 1) + + ctx.rel_move_to(-extend_width, 0) + ctx.rel_line_to(extend_width * 2, 0) + ctx.stroke() + + def draw_placeholder(self, ctx, placeholder): + if isinstance(placeholder, PlaceholderEnd): + return + + col = self.view.get_style_context().get_color(Gtk.StateFlags.INSENSITIVE) + col.alpha = 0.5 + Gdk.cairo_set_source_rgba(ctx, col) + + if placeholder.tabstop > 0: + ctx.set_dash([], 0) + else: + ctx.set_dash([2], 0) + + start = placeholder.begin_iter() + end = placeholder.end_iter() + + if start.equal(end): + self.draw_placeholder_bar(ctx, placeholder) + else: + self.draw_placeholder_rect(ctx, placeholder) + + def on_draw(self, view, ctx): + window = view.get_window(Gtk.TextWindowType.TEXT) + + if not Gtk.cairo_should_draw_window(ctx, window): + return False + + # Draw something + ctx.set_line_width(1.0) + + Gtk.cairo_transform_to_window(ctx, view, window) + + clipped, clip = Gdk.cairo_get_clip_rectangle(ctx) + + if not clipped: + return False + + for placeholder in self.ordered_placeholders: + if not self.placeholder_in_area(placeholder, clip): + continue + + ctx.save() + self.draw_placeholder(ctx, placeholder) + ctx.restore() + + return False + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/exporter.py b/plugins/snippets/snippets/exporter.py new file mode 100644 index 0000000..8f8249e --- /dev/null +++ b/plugins/snippets/snippets/exporter.py @@ -0,0 +1,122 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import tempfile +import shutil + +import xml.etree.ElementTree as et +from . import helper + +try: + import gettext + gettext.bindtextdomain('gedit') + gettext.textdomain('gedit') + _ = gettext.gettext +except: + _ = lambda s: s + +class Exporter: + def __init__(self, filename, snippets): + self.filename = filename + self.set_snippets(snippets) + + def set_snippets(self, snippets): + self.snippets = {} + + for snippet in snippets: + lang = snippet.language() + + if lang in self.snippets: + self.snippets[lang].append(snippet) + else: + self.snippets[lang] = [snippet] + + def export_xml(self, dirname, language, snippets): + # Create the root snippets node + root = et.Element('snippets') + + # Create filename based on language + if language: + filename = os.path.join(dirname, language + '.xml') + + # Set the language attribute + root.attrib['language'] = language + else: + filename = os.path.join(dirname, 'global.xml') + + # Add all snippets to the root node + for snippet in snippets: + root.append(snippet.to_xml()) + + # Write xml + helper.write_xml(root, filename, ('text', 'accelerator')) + + def export_archive(self, cmd): + dirname = tempfile.mkdtemp() + + # Save current working directory and change to temporary directory + curdir = os.getcwd() + + try: + os.chdir(dirname) + + # Write snippet xml files + for language, snippets in self.snippets.items(): + self.export_xml(dirname, language , snippets) + + # Archive files + status = os.system('%s "%s" *.xml' % (cmd, self.filename)) + finally: + os.chdir(curdir) + + if status != 0: + return _('The archive “%s” could not be created' % self.filename) + + # Remove the temporary directory + shutil.rmtree(dirname) + + def export_targz(self): + self.export_archive('tar -c --gzip -f') + + def export_tarbz2(self): + self.export_archive('tar -c --bzip2 -f') + + def export_tar(self): + self.export_archive('tar -cf') + + def run(self): + dirname = os.path.dirname(self.filename) + if not os.path.exists(dirname): + return _('Target directory “%s” does not exist') % dirname + + if not os.path.isdir(dirname): + return _('Target directory “%s” is not a valid directory') % dirname + + (root, ext) = os.path.splitext(self.filename) + + actions = {'.tar.gz': self.export_targz, + '.tar.bz2': self.export_tarbz2, + '.tar': self.export_tar} + + for k, v in actions.items(): + if self.filename.endswith(k): + return v() + + return self.export_targz() + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/helper.py b/plugins/snippets/snippets/helper.py new file mode 100644 index 0000000..2fa3b3f --- /dev/null +++ b/plugins/snippets/snippets/helper.py @@ -0,0 +1,204 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from xml.sax import saxutils +import xml.etree.ElementTree as et +import re +import codecs + +from gi.repository import Gtk + +def message_dialog(par, typ, msg): + d = Gtk.MessageDialog(par, Gtk.DialogFlags.MODAL, typ, Gtk.ButtonsType.OK, msg) + d.set_property('use-markup', True) + + d.run() + d.destroy() + +def compute_indentation(view, piter): + line = piter.get_line() + start = view.get_buffer().get_iter_at_line(line) + end = start.copy() + + ch = end.get_char() + + while (ch.isspace() and ch != '\r' and ch != '\n' and \ + end.compare(piter) < 0): + if not end.forward_char(): + break; + + ch = end.get_char() + + if start.equal(end): + return '' + + return start.get_slice(end) + +def markup_escape(text): + return saxutils.escape(text) + +def spaces_instead_of_tabs(view, text): + if not view.get_insert_spaces_instead_of_tabs(): + return text + + return text.replace("\t", view.get_tab_width() * ' ') + +def insert_with_indent(view, piter, text, indentfirst = True, context = None): + text = spaces_instead_of_tabs(view, text) + lines = text.split('\n') + buf = view.get_buffer() + + buf._snippets_context = context + + if len(lines) == 1: + view.get_buffer().insert(piter, text) + else: + # Compute indentation + indent = compute_indentation(view, piter) + text = '' + + for i in range(0, len(lines)): + if indentfirst or i > 0: + text += indent + lines[i] + '\n' + else: + text += lines[i] + '\n' + + buf.insert(piter, text[:-1]) + + buf._snippets_context = None + +def get_buffer_context(buf): + if hasattr(buf, "_snippets_context"): + return buf._snippets_context + return None + +def snippets_debug(*s): + return + +def write_xml(node, f, cdata_nodes=()): + assert node is not None + + if not hasattr(f, "write"): + f = codecs.open(f, "wb", encoding="utf-8") + + # Encoding + f.write("<?xml version='1.0' encoding='utf-8'?>\n") + + _write_node(node, f, cdata_nodes) + +def _write_indent(file, text, indent): + file.write(' ' * indent + text) + +def _write_node(node, file, cdata_nodes=(), indent=0): + # write XML to file + tag = node.tag + + if node is et.Comment: + _write_indent(file, "<!-- %s -->\n" % saxutils.escape(node.text), indent) + elif node is et.ProcessingInstruction: + _write_indent(file, "<?%s?>\n" % saxutils.escape(node.text), indent) + else: + items = node.items() + + if items or node.text or len(node): + _write_indent(file, "<" + tag, indent) + + if items: + items.sort() # lexical order + for k, v in items: + file.write(" %s=%s" % (k, saxutils.quoteattr(v))) + if node.text or len(node): + file.write(">") + if node.text and node.text.strip() != "": + if tag in cdata_nodes: + file.write(_cdata(node.text)) + else: + file.write(saxutils.escape(node.text)) + else: + file.write("\n") + + for n in node: + _write_node(n, file, cdata_nodes, indent + 1) + + if not len(node): + file.write("</" + tag + ">\n") + else: + _write_indent(file, "</" + tag + ">\n", \ + indent) + else: + file.write(" />\n") + + if node.tail and node.tail.strip() != "": + file.write(saxutils.escape(node.tail)) + +def _cdata(text): + return '<![CDATA[' + text.replace(']]>', ']]]]><![CDATA[>') + ']]>' + +def is_tab_trigger(w): + if len(w) == 1 and not (w.isalnum() or w.isspace()): + return True + + if not is_first_tab_trigger_character(w[0]): + return False + + for c in w: + if not is_tab_trigger_character(c): + return False + + return True + +def is_first_tab_trigger_character(c): + return c.isalpha() or c in '_:.' + +def is_tab_trigger_character(c): + return c.isalnum() or c in '_:.' + +def buffer_word_boundary(buf): + iter = buf.get_iter_at_mark(buf.get_insert()) + start = iter.copy() + + if not iter.starts_word() and (iter.inside_word() or iter.ends_word()): + start.backward_word_start() + + if not iter.ends_word() and iter.inside_word(): + iter.forward_word_end() + + return (start, iter) + +def buffer_line_boundary(buf): + iter = buf.get_iter_at_mark(buf.get_insert()) + start = iter.copy() + start.set_line_offset(0) + + if not iter.ends_line(): + iter.forward_to_line_end() + + return (start, iter) + +def drop_get_uris(selection): + uris = [] + if selection.targets_include_uri(): + data = selection.get_data() + lines = re.split('\\s*[\\n\\r]+\\s*', data.strip()) + + for line in lines: + if not line.startswith('#'): + uris.append(line) + + return uris + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/importer.py b/plugins/snippets/snippets/importer.py new file mode 100644 index 0000000..2718596 --- /dev/null +++ b/plugins/snippets/snippets/importer.py @@ -0,0 +1,134 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import errno +import tempfile +import sys +import shutil + +from .library import Library + +try: + import gettext + gettext.bindtextdomain('gedit') + gettext.textdomain('gedit') + _ = gettext.gettext +except: + _ = lambda s: s + +class Importer: + def __init__(self, filename): + self.filename = filename + + def import_destination(self, filename): + userdir = Library().userdir + + filename = os.path.basename(filename) + (root, ext) = os.path.splitext(filename) + + filename = os.path.join(userdir, root + ext) + i = 1 + + while os.path.exists(filename): + filename = os.path.join(userdir, root + '_' + str(i) + ext) + i += 1 + + return (userdir, filename) + + def import_file(self, filename): + if not os.path.exists(filename): + return _('File “%s” does not exist') % filename + + if not os.path.isfile(filename): + return _('File “%s” is not a valid snippets file') % filename + + # Find destination for file to copy to + destdir, dest = self.import_destination(filename) + + # Make sure dir exists + try: + os.makedirs(destdir) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + # Copy file + shutil.copy(filename, dest) + + # Add library + if not Library().add_user_library(dest): + return _('Imported file “%s” is not a valid snippets file') % os.path.basename(dest) + + def import_xml(self): + return self.import_file(self.filename) + + def import_archive(self, cmd): + dirname = tempfile.mkdtemp() + status = os.system('cd %s; %s "%s"' % (dirname, cmd, self.filename)) + + if status != 0: + return _('The archive “%s” could not be extracted' % self.filename) + + errors = [] + + # Now import all the files from the archive + for f in os.listdir(dirname): + f = os.path.join(dirname, f) + + if os.path.isfile(f): + if self.import_file(f): + errors.append(os.path.basename(f)) + else: + sys.stderr.write('Skipping %s, not a valid snippets file' % os.path.basename(f)) + + # Remove the temporary directory + shutil.rmtree(dirname) + + if len(errors) > 0: + return _('The following files could not be imported: %s') % ', '.join(errors) + + def import_targz(self): + self.import_archive('tar -x --gzip -f') + + def import_tarbz2(self): + self.import_archive('tar -x --bzip2 -f') + + def import_tar(self): + self.import_archive('tar -xf') + + def run(self): + if not os.path.exists(self.filename): + return _('File “%s” does not exist') % self.filename + + if not os.path.isfile(self.filename): + return _('File “%s” is not a valid snippets archive') % self.filename + + (root, ext) = os.path.splitext(self.filename) + + actions = {'.tar.gz': self.import_targz, + '.tar.bz2': self.import_tarbz2, + '.xml': self.import_xml, + '.tar': self.import_tar} + + for k, v in actions.items(): + if self.filename.endswith(k): + return v() + + return _('File “%s” is not a valid snippets archive') % self.filename + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/languagemanager.py b/plugins/snippets/snippets/languagemanager.py new file mode 100644 index 0000000..6f74319 --- /dev/null +++ b/plugins/snippets/snippets/languagemanager.py @@ -0,0 +1,40 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from gi.repository import GtkSource +import os + +from .library import Library + +global manager +manager = None + +def get_language_manager(): + global manager + + if not manager: + dirs = [] + + for d in Library().systemdirs: + dirs.append(os.path.join(d, 'lang')) + + manager = GtkSource.LanguageManager() + manager.set_search_path(dirs + manager.get_search_path()) + + return manager + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/library.py b/plugins/snippets/snippets/library.py new file mode 100644 index 0000000..7ce163b --- /dev/null +++ b/plugins/snippets/snippets/library.py @@ -0,0 +1,989 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import weakref +import sys +import re + +from gi.repository import Gdk, Gtk + +import xml.etree.ElementTree as et +from . import helper + +class NamespacedId: + def __init__(self, namespace, id): + if not id: + self.id = None + else: + if namespace: + self.id = namespace + '-' + else: + self.id = 'global-' + + self.id += id + +class SnippetData: + PROPS = {'tag': '', 'text': '', 'description': 'New snippet', + 'accelerator': '', 'drop-targets': ''} + + def __init__(self, node, library): + self.priv_id = node.attrib.get('id') + + self.set_library(library) + self.valid = False + self.set_node(node) + + def can_modify(self): + return (self.library and (isinstance(self.library(), SnippetsUserFile))) + + def set_library(self, library): + if library: + self.library = weakref.ref(library) + else: + self.library = None + + self.id = NamespacedId(self.language(), self.priv_id).id + + def set_node(self, node): + if self.can_modify(): + self.node = node + else: + self.node = None + + self.init_snippet_data(node) + + def init_snippet_data(self, node): + if node is None: + return + + self.override = node.attrib.get('override') + + self.properties = {} + props = SnippetData.PROPS.copy() + + # Store all properties present + for child in node: + if child.tag in props: + del props[child.tag] + + # Normalize accelerator + if child.tag == 'accelerator' and child.text != None: + keyval, mod = Gtk.accelerator_parse(child.text) + + if Gtk.accelerator_valid(keyval, mod): + child.text = Gtk.accelerator_name(keyval, mod) + else: + child.text = '' + + if self.can_modify(): + self.properties[child.tag] = child + else: + self.properties[child.tag] = child.text or '' + + # Create all the props that were not found so we stay consistent + for prop in props: + if self.can_modify(): + child = et.SubElement(node, prop) + + child.text = props[prop] + self.properties[prop] = child + else: + self.properties[prop] = props[prop] + + self.check_validation() + + def check_validation(self): + if not self['tag'] and not self['accelerator'] and not self['drop-targets']: + return False + + library = Library() + keyval, mod = Gtk.accelerator_parse(self['accelerator']) + + self.valid = library.valid_tab_trigger(self['tag']) and \ + (not self['accelerator'] or library.valid_accelerator(keyval, mod)) + + def _format_prop(self, prop, value): + if prop == 'drop-targets' and value != '': + return re.split('\\s*[,;]\\s*', value) + else: + return value + + def __getitem__(self, prop): + if prop in self.properties: + if self.can_modify(): + return self._format_prop(prop, self.properties[prop].text or '') + else: + return self._format_prop(prop, self.properties[prop] or '') + + return self._format_prop(prop, '') + + def __setitem__(self, prop, value): + if not prop in self.properties: + return + + if isinstance(value, list): + value = ','.join(value) + + if not self.can_modify() and self.properties[prop] != value: + # ohoh, this is not can_modify, but it needs to be changed... + # make sure it is transfered to the changes file and set all the + # fields. + # This snippet data container will effectively become the container + # for the newly created node, but transparently to whoever uses + # it + self._override() + + if self.can_modify() and self.properties[prop].text != value: + if self.library(): + self.library().tainted = True + + oldvalue = self.properties[prop].text + self.properties[prop].text = value + + if prop == 'tag' or prop == 'accelerator' or prop == 'drop-targets': + container = Library().container(self.language()) + container.prop_changed(self, prop, oldvalue) + + self.check_validation() + + def language(self): + if self.library and self.library(): + return self.library().language + else: + return None + + def is_override(self): + return self.override and Library().overridden[self.override] + + def to_xml(self): + return self._create_xml() + + def _create_xml(self, parent=None, update=False, attrib={}): + # Create a new node + if parent != None: + element = et.SubElement(parent, 'snippet', attrib) + else: + element = et.Element('snippet') + + # Create all the properties + for p in self.properties: + prop = et.SubElement(element, p) + prop.text = self[p] + + if update: + self.properties[p] = prop + + return element + + def _override(self): + # Find the user file + target = Library().get_user_library(self.language()) + + # Create a new node there with override + element = self._create_xml(target.root, True, {'override': self.id}) + + # Create an override snippet data, feed it element so that it stores + # all the values and then set the node to None so that it only contains + # the values in .properties + override = SnippetData(element, self.library()) + override.set_node(None) + override.id = self.id + + # Set our node to the new element + self.node = element + + # Set the override to our id + self.override = self.id + self.id = None + + # Set the new library + self.set_library(target) + + # The library is tainted because we added this snippet + target.tainted = True + + # Add the override + Library().overridden[self.override] = override + + def revert(self, snippet): + userlib = self.library() + self.set_library(snippet.library()) + + userlib.remove(self.node) + + self.set_node(None) + + # Copy the properties + self.properties = snippet.properties + + # Set the id + self.id = snippet.id + + # Reset the override flag + self.override = None + +class SnippetsTreeBuilder(et.TreeBuilder): + def __init__(self, start=None, end=None): + et.TreeBuilder.__init__(self) + self.set_start(start) + self.set_end(end) + + def set_start(self, start): + self._start_cb = start + + def set_end(self, end): + self._end_cb = end + + def start(self, tag, attrs): + result = et.TreeBuilder.start(self, tag, attrs) + + if self._start_cb: + self._start_cb(result) + + return result + + def end(self, tag): + result = et.TreeBuilder.end(self, tag) + + if self._end_cb: + self._end_cb(result) + + return result + +class LanguageContainer: + def __init__(self, language): + self.language = language + self.snippets = [] + self.snippets_by_prop = {'tag': {}, 'accelerator': {}, 'drop-targets': {}} + self.accel_group = Gtk.AccelGroup() + self._refs = 0 + + def _add_prop(self, snippet, prop, value=0): + if value == 0: + value = snippet[prop] + + if not value or value == '': + return + + helper.snippets_debug('Added ', prop ,' ', value, ' to ', str(self.language)) + + if prop == 'accelerator': + keyval, mod = Gtk.accelerator_parse(value) + self.accel_group.connect(keyval, mod, 0, \ + Library().accelerator_activated) + + snippets = self.snippets_by_prop[prop] + + if not isinstance(value, list): + value = [value] + + for val in value: + if val in snippets: + snippets[val].append(snippet) + else: + snippets[val] = [snippet] + + def _remove_prop(self, snippet, prop, value=0): + if value == 0: + value = snippet[prop] + + if not value or value == '': + return + + helper.snippets_debug('Removed ', prop, ' ', value, ' from ', str(self.language)) + + if prop == 'accelerator': + keyval, mod = Gtk.accelerator_parse(value) + self.accel_group.disconnect_key(keyval, mod) + + snippets = self.snippets_by_prop[prop] + + if not isinstance(value, list): + value = [value] + + for val in value: + try: + snippets[val].remove(snippet) + except: + True + + def append(self, snippet): + self.snippets.append(snippet) + + self._add_prop(snippet, 'tag') + self._add_prop(snippet, 'accelerator') + self._add_prop(snippet, 'drop-targets') + + return snippet + + def remove(self, snippet): + try: + self.snippets.remove(snippet) + except: + True + + self._remove_prop(snippet, 'tag') + self._remove_prop(snippet, 'accelerator') + self._remove_prop(snippet, 'drop-targets') + + def prop_changed(self, snippet, prop, oldvalue): + helper.snippets_debug('PROP CHANGED (', prop, ')', oldvalue) + + self._remove_prop(snippet, prop, oldvalue) + self._add_prop(snippet, prop) + + def from_prop(self, prop, value): + snippets = self.snippets_by_prop[prop] + + if prop == 'drop-targets': + s = [] + + # FIXME: change this to use + # gnomevfs.mime_type_get_equivalence when it comes + # available + for key, val in snippets.items(): + if not value.startswith(key): + continue + + for snippet in snippets[key]: + if not snippet in s: + s.append(snippet) + + return s + else: + if value in snippets: + return snippets[value] + else: + return [] + + def ref(self): + self._refs += 1 + + return True + + def unref(self): + if self._refs > 0: + self._refs -= 1 + + return self._refs != 0 + +class SnippetsSystemFile: + def __init__(self, path=None): + self.path = path + self.loaded = False + self.language = None + self.ok = True + self.need_id = True + + def load_error(self, message): + sys.stderr.write("An error occurred loading " + self.path + ":\n") + sys.stderr.write(message + "\nSnippets in this file will not be " \ + "available, please correct or remove the file.\n") + + def _add_snippet(self, element): + if not self.need_id or element.attrib.get('id'): + self.loading_elements.append(element) + + def set_language(self, element): + self.language = element.attrib.get('language') + + if self.language: + self.language = self.language.lower() + + def _set_root(self, element): + self.set_language(element) + + def _preprocess_element(self, element): + if not self.loaded: + if not element.tag == "snippets": + self.load_error("Root element should be `snippets' instead " \ + "of `%s'" % element.tag) + return False + else: + self._set_root(element) + self.loaded = True + elif element.tag != 'snippet' and not self.insnippet: + self.load_error("Element should be `snippet' instead of `%s'" \ + % element.tag) + return False + else: + self.insnippet = True + + return True + + def _process_element(self, element): + if element.tag == 'snippet': + self._add_snippet(element) + self.insnippet = False + + return True + + def ensure(self): + if not self.ok or self.loaded: + return + + self.load() + + def parse_xml(self, readsize=16384): + if not self.path: + return + + elements = [] + + builder = SnippetsTreeBuilder( \ + lambda node: elements.append((node, True)), \ + lambda node: elements.append((node, False))) + + parser = et.XMLParser(target=builder) + self.insnippet = False + + try: + f = open(self.path, "r", encoding='utf-8') + except IOError: + self.ok = False + return + + while True: + try: + data = f.read(readsize) + except IOError: + self.ok = False + break + + if not data: + break + + try: + parser.feed(data) + except Exception: + self.ok = False + break + + for element in elements: + yield element + + del elements[:] + + f.close() + + def load(self): + if not self.ok: + return + + helper.snippets_debug("Loading library (" + str(self.language) + "): " + \ + self.path) + + self.loaded = False + self.ok = False + self.loading_elements = [] + + for element in self.parse_xml(): + if element[1]: + if not self._preprocess_element(element[0]): + del self.loading_elements[:] + return + else: + if not self._process_element(element[0]): + del self.loading_elements[:] + return + + for element in self.loading_elements: + Library().add_snippet(self, element) + + del self.loading_elements[:] + self.ok = True + + # This function will get the language for a file by just inspecting the + # root element of the file. This is provided so that a cache can be built + # for which file contains which language. + # It returns the name of the language + def ensure_language(self): + if not self.loaded: + self.ok = False + + for element in self.parse_xml(256): + if element[1]: + if element[0].tag == 'snippets': + self.set_language(element[0]) + self.ok = True + + break + + def unload(self): + helper.snippets_debug("Unloading library (" + str(self.language) + "): " + \ + self.path) + self.language = None + self.loaded = False + self.ok = True + +class SnippetsUserFile(SnippetsSystemFile): + def __init__(self, path=None): + SnippetsSystemFile.__init__(self, path) + self.tainted = False + self.need_id = False + + def _set_root(self, element): + SnippetsSystemFile._set_root(self, element) + self.root = element + + def add_prop(self, node, tag, data): + if data[tag]: + prop = et.SubElement(node, tag) + prop.text = data[tag] + + return prop + else: + return None + + def new_snippet(self, properties=None): + if (not self.ok) or self.root is None: + return None + + element = et.SubElement(self.root, 'snippet') + + if properties: + for prop in properties: + sub = et.SubElement(element, prop) + sub.text = properties[prop] + + self.tainted = True + + return Library().add_snippet(self, element) + + def set_language(self, element): + SnippetsSystemFile.set_language(self, element) + + filename = os.path.basename(self.path).lower() + + if not self.language and filename == "global.xml": + self.modifier = True + elif self.language and filename == self.language + ".xml": + self.modifier = True + else: + self.modifier = False + + def create_root(self, language): + if self.loaded: + helper.snippets_debug('Not creating root, already loaded') + return + + if language: + root = et.Element('snippets', {'language': language}) + self.path = os.path.join(Library().userdir, language.lower() + '.xml') + else: + root = et.Element('snippets') + self.path = os.path.join(Library().userdir, 'global.xml') + + self._set_root(root) + self.loaded = True + self.ok = True + self.tainted = True + self.save() + + def remove(self, element): + try: + self.root.remove(element) + self.tainted = True + except: + return + + try: + self.root[0] + except: + # No more elements, this library is useless now + Library().remove_library(self) + + def save(self): + if not self.ok or self.root is None or not self.tainted: + return + + path = os.path.dirname(self.path) + + try: + if not os.path.isdir(path): + os.makedirs(path, 0o755) + except OSError: + # TODO: this is bad... + sys.stderr.write("Error in making dirs\n") + + try: + helper.write_xml(self.root, self.path, ('text', 'accelerator')) + self.tainted = False + except IOError: + # Couldn't save, what to do + sys.stderr.write("Could not save user snippets file to " + \ + self.path + "\n") + + def unload(self): + SnippetsSystemFile.unload(self) + self.root = None + +class Singleton(object): + _instance = None + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super(Singleton, cls).__new__( + cls, *args, **kwargs) + cls._instance.__init_once__() + + return cls._instance + +class Library(Singleton): + def __init_once__(self): + self._accelerator_activated_cb = [] + self.loaded = False + self.check_buffer = Gtk.TextBuffer() + + def set_dirs(self, userdir, systemdirs): + self.userdir = userdir + self.systemdirs = systemdirs + + self.libraries = {} + self.containers = {} + self.overridden = {} + self.loaded_ids = [] + + self.loaded = False + + def add_accelerator_callback(self, cb): + self._accelerator_activated_cb.append(cb) + + def remove_accelerator_callback(self, cb): + self._accelerator_activated_cb.remove(cb) + + def accelerator_activated(self, group, obj, keyval, mod): + ret = False + + for cb in self._accelerator_activated_cb: + ret = cb(group, obj, keyval, mod) + + if ret: + break + + return ret + + def add_snippet(self, library, element): + container = self.container(library.language) + overrided = self.overrided(library, element) + + if overrided: + overrided.set_library(library) + helper.snippets_debug('Snippet is overriden: ' + overrided['description']) + return None + + snippet = SnippetData(element, library) + + if snippet.id in self.loaded_ids: + helper.snippets_debug('Not added snippet ' + str(library.language) + \ + '::' + snippet['description'] + ' (duplicate)') + return None + + snippet = container.append(snippet) + helper.snippets_debug('Added snippet ' + str(library.language) + '::' + \ + snippet['description']) + + if snippet and snippet.override: + self.add_override(snippet) + + if snippet.id: + self.loaded_ids.append(snippet.id) + + return snippet + + def container(self, language): + language = self.normalize_language(language) + + if not language in self.containers: + self.containers[language] = LanguageContainer(language) + + return self.containers[language] + + def get_user_library(self, language): + target = None + + if language in self.libraries: + for library in self.libraries[language]: + if isinstance(library, SnippetsUserFile) and library.modifier: + target = library + elif not isinstance(library, SnippetsUserFile): + break + + if not target: + # Create a new user file then + helper.snippets_debug('Creating a new user file for language ' + \ + str(language)) + target = SnippetsUserFile() + target.create_root(language) + self.add_library(target) + + return target + + def new_snippet(self, language, properties=None): + language = self.normalize_language(language) + library = self.get_user_library(language) + + return library.new_snippet(properties) + + def revert_snippet(self, snippet): + # This will revert the snippet to the one it overrides + if not snippet.can_modify() or not snippet.override in self.overridden: + # It can't be reverted, shouldn't happen, but oh.. + return + + # The snippet in self.overriden only contains the property contents and + # the library it belongs to + revertto = self.overridden[snippet.override] + del self.overridden[snippet.override] + + if revertto: + snippet.revert(revertto) + + if revertto.id: + self.loaded_ids.append(revertto.id) + + def remove_snippet(self, snippet): + if not snippet.can_modify() or snippet.is_override(): + return + + # Remove from the library + userlib = snippet.library() + userlib.remove(snippet.node) + + # Remove from the container + container = self.containers[userlib.language] + container.remove(snippet) + + def overrided(self, library, element): + id = NamespacedId(library.language, element.attrib.get('id')).id + + if id in self.overridden: + snippet = SnippetData(element, None) + snippet.set_node(None) + + self.overridden[id] = snippet + return snippet + else: + return None + + def add_override(self, snippet): + helper.snippets_debug('Add override:', snippet.override) + if not snippet.override in self.overridden: + self.overridden[snippet.override] = None + + def add_library(self, library): + library.ensure_language() + + if not library.ok: + helper.snippets_debug('Library in wrong format, ignoring') + return False + + helper.snippets_debug('Adding library (' + str(library.language) + '): ' + \ + library.path) + + if library.language in self.libraries: + # Make sure all the user files are before the system files + if isinstance(library, SnippetsUserFile): + self.libraries[library.language].insert(0, library) + else: + self.libraries[library.language].append(library) + else: + self.libraries[library.language] = [library] + + return True + + def remove_library(self, library): + if not library.ok: + return + + if library.path and os.path.isfile(library.path): + os.unlink(library.path) + + try: + self.libraries[library.language].remove(library) + except KeyError: + True + + container = self.containers[library.language] + + for snippet in list(container.snippets): + if snippet.library() == library: + container.remove(snippet) + + def add_user_library(self, path): + library = SnippetsUserFile(path) + return self.add_library(library) + + def add_system_library(self, path): + library = SnippetsSystemFile(path) + return self.add_library(library) + + def find_libraries(self, path, searched, addcb): + helper.snippets_debug("Finding in: " + path) + + if not os.path.isdir(path): + return searched + + files = os.listdir(path) + searched.append(path) + + for f in files: + f = os.path.realpath(os.path.join(path, f)) + + # Determine what language this file provides snippets for + if os.path.isfile(f): + addcb(f) + + return searched + + def normalize_language(self, language): + if language: + return language.lower() + + return language + + def remove_container(self, language): + for snippet in self.containers[language].snippets: + if snippet.id in self.loaded_ids: + self.loaded_ids.remove(snippet.id) + + if snippet.override in self.overridden: + del self.overridden[snippet.override] + + del self.containers[language] + + def get_accel_group(self, language): + language = self.normalize_language(language) + container = self.container(language) + + self.ensure(language) + return container.accel_group + + def save(self, language): + language = self.normalize_language(language) + + if language in self.libraries: + for library in self.libraries[language]: + if isinstance(library, SnippetsUserFile): + library.save() + else: + break + + def ref(self, language): + language = self.normalize_language(language) + + helper.snippets_debug('Ref:', language) + self.container(language).ref() + + def unref(self, language): + language = self.normalize_language(language) + + helper.snippets_debug('Unref:', language) + + if language in self.containers: + if not self.containers[language].unref() and \ + language in self.libraries: + + for library in self.libraries[language]: + library.unload() + + self.remove_container(language) + + def ensure(self, language): + self.ensure_files() + language = self.normalize_language(language) + + # Ensure language as well as the global snippets (None) + for lang in (None, language): + if lang in self.libraries: + # Ensure the container exists + self.container(lang) + + for library in self.libraries[lang]: + library.ensure() + + def ensure_files(self): + if self.loaded: + return + + searched = [] + searched = self.find_libraries(self.userdir, searched, \ + self.add_user_library) + + for d in self.systemdirs: + searched = self.find_libraries(d, searched, \ + self.add_system_library) + + self.loaded = True + + def valid_accelerator(self, keyval, mod): + mod &= Gtk.accelerator_get_default_mod_mask() + + return (mod and (Gdk.keyval_to_unicode(keyval) or \ + keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1))) + + def valid_tab_trigger(self, trigger): + if not trigger: + return True + + return helper.is_tab_trigger(trigger) + + # Snippet getters + # =============== + def _from_prop(self, prop, value, language=None): + self.ensure_files() + + result = [] + language = self.normalize_language(language) + + if not language in self.containers: + return [] + + self.ensure(language) + result = self.containers[language].from_prop(prop, value) + + if len(result) == 0 and language and None in self.containers: + result = self.containers[None].from_prop(prop, value) + + return result + + # Get snippets for a given language + def get_snippets(self, language=None): + self.ensure_files() + language = self.normalize_language(language) + + if not language in self.libraries: + return [] + + self.ensure(language) + + return list(self.containers[language].snippets) + + # Get snippets for a given accelerator + def from_accelerator(self, accelerator, language=None): + return self._from_prop('accelerator', accelerator, language) + + # Get snippets for a given tag + def from_tag(self, tag, language=None): + return self._from_prop('tag', tag, language) + + # Get snippets for a given drop target + def from_drop_target(self, drop_target, language=None): + return self._from_prop('drop-targets', drop_target, language) + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/manager.py b/plugins/snippets/snippets/manager.py new file mode 100644 index 0000000..ca64f18 --- /dev/null +++ b/plugins/snippets/snippets/manager.py @@ -0,0 +1,1143 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import tempfile +import shutil + +from gi.repository import Gtk, Gio, Gdk, GObject + +from .snippet import Snippet +from . import helper +from .library import Library +from .importer import Importer +from .exporter import Exporter +from .languagemanager import get_language_manager + +try: + import gettext + gettext.bindtextdomain('gedit') + gettext.textdomain('gedit') + _ = gettext.gettext +except: + _ = lambda s: s + +class Manager(Gtk.Window, Gtk.Buildable): + NAME_COLUMN = 0 + SORT_COLUMN = 1 + LANG_COLUMN = 2 + SNIPPET_COLUMN = 3 + TARGET_URI = 105 + + __gtype_name__ = "GeditSnippetsManager" + + model = None + drag_icons = ('gnome-mime-application-x-tarz', 'gnome-package', 'package') + default_export_name = _('Snippets archive') + '.tar.gz' + dragging = False + + def __init__(self): + self.snippet = None + self._temp_export = None + self._size = (0, 0) + + self.key_press_id = 0 + self.dnd_target_list = Gtk.TargetList.new([]) + self.dnd_target_list.add(Gdk.atom_intern("text/uri-list", True), 0, self.TARGET_URI) + + def get_final_size(self): + return self._size + + def get_language_snippets(self, path, name = None): + library = Library() + + name = self.get_language(path) + nodes = library.get_snippets(name) + + return nodes + + def add_new_snippet_node(self, parent): + return self.model.append(parent, ('<i>' + _('Add a new snippet…') + \ + '</i>', '', None, None)) + + def fill_language(self, piter, expand=True): + # Remove all children + child = self.model.iter_children(piter) + + while child and self.model.remove(child): + True + + path = self.model.get_path(piter) + nodes = self.get_language_snippets(path) + language = self.get_language(path) + + Library().ref(language) + + if nodes: + for node in nodes: + self.add_snippet(piter, node) + else: + # Add node that tells there are no snippets currently + self.add_new_snippet_node(piter) + + if expand: + self.tree_view.expand_row(path, False) + + def build_model(self, force_reload = False): + window = Gio.Application.get_default().get_active_window() + if window: + view = window.get_active_view() + + if not view: + current_lang = None + else: + current_lang = view.get_buffer().get_language() + else: + current_lang = None + + tree_view = self['tree_view_snippets'] + expand = None + + if not self.model or force_reload: + self.model = Gtk.TreeStore(str, str, GObject.Object, object) + self.model.set_sort_column_id(self.SORT_COLUMN, Gtk.SortType.ASCENDING) + + manager = get_language_manager() + + langs = [manager.get_language(x) for x in manager.get_language_ids()] + langs.sort(key=lambda x: x.get_name()) + + piter = self.model.append(None, (_('Global'), '', None, None)) + + # Add dummy node + self.model.append(piter, ('', '', None, None)) + + nm = None + + if current_lang: + nm = current_lang.get_name() + + for lang in langs: + name = lang.get_name() + parent = self.model.append(None, (name, name, lang, None)) + + # Add dummy node + self.model.append(parent, ('', '', None, None)) + + if (nm == name): + expand = parent + else: + if current_lang: + piter = self.model.get_iter_first() + nm = current_lang.get_name() + + while piter: + lang = self.model.get_value(piter, \ + self.SORT_COLUMN) + + if lang == nm: + expand = piter + break; + + piter = self.model.iter_next(piter) + + tree_view.set_model(self.model) + + if not expand: + expand = self.model.get_iter_first() + + tree_view.expand_row(self.model.get_path(expand), False) + self.select_iter(expand) + + def get_cell_data_pixbuf_cb(self, column, cell, model, iter, data): + snippet = model.get_value(iter, self.SNIPPET_COLUMN) + + if snippet and not snippet.valid: + cell.set_property('icon-name', 'dialog-error') + else: + cell.set_property('icon-name', None) + + cell.set_property('xalign', 1.0) + + def get_cell_data_cb(self, column, cell, model, iter, data): + snippet = model.get_value(iter, self.SNIPPET_COLUMN) + + cell.set_property('editable', snippet != None) + cell.set_property('markup', model.get_value(iter, self.NAME_COLUMN)) + + def on_tree_view_drag_data_get(self, widget, context, selection_data, info, time): + gfile = Gio.file_new_for_path(self._temp_export) + selection_data.set_uris([gfile.get_uri()]) + + def on_tree_view_drag_begin(self, widget, context): + self.dragging = True + + if self._temp_export: + shutil.rmtree(os.path.dirname(self._temp_export)) + self._temp_export = None + + if self.dnd_name: + Gtk.drag_set_icon_name(context, self.dnd_name, 0, 0) + + dirname = tempfile.mkdtemp() + filename = os.path.join(dirname, self.default_export_name) + + # Generate temporary file name + self.export_snippets(filename, False) + self._temp_export = filename + + def on_tree_view_drag_end(self, widget, context): + self.dragging = False + + def on_tree_view_drag_data_received(self, widget, context, x, y, selection, info, timestamp): + uris = selection.get_uris() + + files = [Gio.file_new_for_uri(u) for u in uris] + + self.import_snippets(files) + + def on_tree_view_drag_motion(self, widget, context, x, y, timestamp): + # Return False if we are dragging + if self.dragging: + return False + + # Check uri target + if not Gtk.targets_include_uri(context.targets): + return False + + # Check action + action = None + if context.suggested_action == Gdk.DragAction.COPY: + action = Gdk.DragAction.COPY + else: + for act in context.actions: + if act == Gdk.DragAction.COPY: + action = Gdk.DragAction.COPY + break + + if action == Gdk.DragAction.COPY: + context.drag_status(Gdk.DragAction.COPY, timestamp) + return True + else: + return False + + def build_dnd(self): + tv = self.tree_view + + # Set it as a drag source for exporting snippets + tv.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.DEFAULT | Gdk.DragAction.COPY) + tv.drag_source_set_target_list(self.dnd_target_list) + + # Set it as a drag destination for importing snippets + tv.drag_dest_set(Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP, + [], Gdk.DragAction.DEFAULT | Gdk.DragAction.COPY) + + tv.drag_dest_set_target_list(self.dnd_target_list) + + tv.connect('drag_data_get', self.on_tree_view_drag_data_get) + tv.connect('drag_begin', self.on_tree_view_drag_begin) + tv.connect('drag_end', self.on_tree_view_drag_end) + tv.connect('drag_data_received', self.on_tree_view_drag_data_received) + tv.connect('drag_motion', self.on_tree_view_drag_motion) + + theme = Gtk.IconTheme.get_for_screen(tv.get_screen()) + + self.dnd_name = None + for name in self.drag_icons: + icon = theme.lookup_icon(name, Gtk.IconSize.DND, 0) + + if icon: + self.dnd_name = name + break + + def build_tree_view(self): + self.tree_view = self['tree_view_snippets'] + + self.column = Gtk.TreeViewColumn(None) + + self.renderer = Gtk.CellRendererText() + self.column.pack_start(self.renderer, False) + self.column.set_cell_data_func(self.renderer, self.get_cell_data_cb, None) + + renderer = Gtk.CellRendererPixbuf() + self.column.pack_start(renderer, True) + self.column.set_cell_data_func(renderer, self.get_cell_data_pixbuf_cb, None) + + self.tree_view.append_column(self.column) + + self.renderer.connect('edited', self.on_cell_edited) + self.renderer.connect('editing-started', self.on_cell_editing_started) + + selection = self.tree_view.get_selection() + selection.set_mode(Gtk.SelectionMode.MULTIPLE) + selection.connect('changed', self.on_tree_view_selection_changed) + + self.build_dnd() + + def do_parser_finished(self, builder): + self.builder = builder + + handlers_dic = { + 'on_add_snippet_button_clicked': self.on_add_snippet_button_clicked, + 'on_remove_snippet_button_clicked': self.on_remove_snippet_button_clicked, + 'on_import_snippets_button_clicked': self.on_import_snippets_button_clicked, + 'on_export_snippets_button_clicked': self.on_export_snippets_button_clicked, + 'on_entry_tab_trigger_focus_out': self.on_entry_tab_trigger_focus_out, + 'on_entry_tab_trigger_changed': self.on_entry_tab_trigger_changed, + 'on_entry_accelerator_focus_out': self.on_entry_accelerator_focus_out, + 'on_entry_accelerator_focus_in': self.on_entry_accelerator_focus_in, + 'on_entry_accelerator_key_press': self.on_entry_accelerator_key_press, + 'on_source_view_snippet_focus_out': self.on_source_view_snippet_focus_out, + 'on_tree_view_snippets_row_expanded': self.on_tree_view_snippets_row_expanded, + 'on_tree_view_snippets_key_press': self.on_tree_view_snippets_key_press} + + self.builder.connect_signals(handlers_dic) + + self.build_tree_view() + self.build_model() + + # join treeview and toolbar + context = self['scrolled_window_snippets'].get_style_context() + context.set_junction_sides(Gtk.JunctionSides.BOTTOM) + context = self['toolbar'].get_style_context() + context.set_junction_sides(Gtk.JunctionSides.TOP) + context.set_junction_sides(Gtk.JunctionSides.BOTTOM) + + source_view = self['source_view_snippet'] + manager = get_language_manager() + lang = manager.get_language('snippets') + + if lang: + source_view.get_buffer().set_highlight_syntax(True) + source_view.get_buffer().set_language(lang) + + combo = self['combo_drop_targets'] + + entry = combo.get_child() + entry.connect('focus-out-event', self.on_entry_drop_targets_focus_out) + entry.connect('drag-data-received', self.on_entry_drop_targets_drag_data_received) + + lst = entry.drag_dest_get_target_list() + lst.add_uri_targets(self.TARGET_URI) + + def do_configure_event(self, event): + if self.get_realized(): + alloc = self.get_allocation() + self._size = (alloc.width, alloc.height) + + return Gtk.Dialog.do_configure_event(self, event) + + def __getitem__(self, key): + return self.builder.get_object(key) + + def is_filled(self, piter): + if not self.model.iter_has_child(piter): + return True + + child = self.model.iter_children(piter) + nm = self.model.get_value(child, self.NAME_COLUMN) + lang = self.model.get_value(child, self.LANG_COLUMN) + snippet = self.model.get_value(child, self.SNIPPET_COLUMN) + + return (lang or snippet or nm) + + def fill_if_needed(self, piter, expand=True): + if not self.is_filled(piter): + self.fill_language(piter, expand) + + def find_iter(self, parent, snippet): + self.fill_if_needed(parent) + piter = self.model.iter_children(parent) + + while (piter): + sn = self.model.get_value(piter, self.SNIPPET_COLUMN) + + if sn == snippet.data: + return piter + + piter = self.model.iter_next(piter) + + return None + + def selected_snippets_state(self): + snippets = self.selected_snippets(False) + override = False + remove = False + system = False + + for snippet in snippets: + if not snippet: + continue + + if snippet.is_override(): + override = True + elif snippet.can_modify(): + remove = True + else: + system = True + + # No need to continue if both are found + if override and remove: + break + + return (override, remove, system) + + def update_toolbar_buttons(self): + button_add = self['add_snippet_button'] + button_remove = self['remove_snippet_button'] + + button_add.set_sensitive(self.language_path != None) + override, remove, system = self.selected_snippets_state() + + if not (override ^ remove) or system: + button_remove.set_sensitive(False) + button_remove.set_icon_name('list-remove-symbolic') + else: + button_remove.set_sensitive(True) + + if override: + button_remove.set_icon_name('edit-undo-symbolic') + tooltip = _('Revert selected snippet') + else: + button_remove.set_icon_name('list-remove-symbolic') + tooltip = _('Delete selected snippet') + + button_remove.set_tooltip_text(tooltip) + + def snippet_changed(self, piter = None): + if piter: + node = self.model.get_value(piter, self.SNIPPET_COLUMN) + s = Snippet(node) + else: + s = self.snippet + piter = self.find_iter(self.model.get_iter(self.language_path), s) + + if piter: + nm = s.display() + + self.model.set_value(piter, self.NAME_COLUMN, nm) + self.model.set_value(piter, self.SORT_COLUMN, nm) + self.update_toolbar_buttons() + self.entry_tab_trigger_update_valid() + + return piter + + def add_snippet(self, parent, snippet): + piter = self.model.append(parent, ('', '', None, snippet)) + + return self.snippet_changed(piter) + + def snippet_from_iter(self, model, piter): + parent = model.iter_parent(piter) + + if parent: + return model.get_value(piter, self.SNIPPET_COLUMN) + else: + return None + + def language_snippets(self, model, parent, as_path=False): + self.fill_if_needed(parent, False) + piter = model.iter_children(parent) + snippets = [] + + if not piter: + return snippets + + while piter: + snippet = self.snippet_from_iter(model, piter) + + if snippet: + if as_path: + snippets.append(model.get_path(piter)) + else: + snippets.append(snippet) + + piter = model.iter_next(piter) + + return snippets + + def selected_snippets(self, include_languages=True, as_path=False): + selection = self.tree_view.get_selection() + (model, paths) = selection.get_selected_rows() + snippets = [] + + if paths and len(paths) != 0: + for p in paths: + piter = model.get_iter(p) + parent = model.iter_parent(piter) + + if not piter: + continue + + if parent: + snippet = self.snippet_from_iter(model, piter) + + if not snippet: + continue + + if as_path: + snippets.append(p) + else: + snippets.append(snippet) + elif include_languages: + snippets += self.language_snippets(model, piter, as_path) + + return snippets + + def selected_snippet(self): + selection = self.tree_view.get_selection() + (model, paths) = selection.get_selected_rows() + + if len(paths) == 1: + piter = model.get_iter(paths[0]) + parent = model.iter_parent(piter) + snippet = self.snippet_from_iter(model, piter) + + return parent, piter, snippet + else: + return None, None, None + + def selection_changed(self): + if not self.snippet: + sens = False + + self['entry_tab_trigger'].set_text('') + self['entry_accelerator'].set_text('') + buf = self['source_view_snippet'].get_buffer() + buf.begin_not_undoable_action() + buf.set_text('') + buf.end_not_undoable_action() + self['combo_drop_targets'].get_child().set_text('') + + else: + sens = True + + self['entry_tab_trigger'].set_text(self.snippet['tag']) + self['entry_accelerator'].set_text( \ + self.snippet.accelerator_display()) + self['combo_drop_targets'].get_child().set_text(', '.join(self.snippet['drop-targets'])) + + buf = self['source_view_snippet'].get_buffer() + buf.begin_not_undoable_action() + buf.set_text(self.snippet['text']) + buf.end_not_undoable_action() + + + for name in ['source_view_snippet', 'label_tab_trigger', + 'entry_tab_trigger', 'label_accelerator', + 'entry_accelerator', 'label_drop_targets', + 'combo_drop_targets']: + self[name].set_sensitive(sens) + + self.update_toolbar_buttons() + + def select_iter(self, piter, unselect=True): + selection = self.tree_view.get_selection() + + if unselect: + selection.unselect_all() + + selection.select_iter(piter) + + self.tree_view.scroll_to_cell(self.model.get_path(piter), None, \ + True, 0.5, 0.5) + + def get_language(self, path): + if path.get_indices()[0] == 0: + return None + else: + return self.model.get_value(self.model.get_iter(path), + self.LANG_COLUMN).get_id() + + def new_snippet(self, properties=None): + if not self.language_path: + return None + + snippet = Library().new_snippet(self.get_language(self.language_path), properties) + + return Snippet(snippet) + + def get_dummy(self, parent): + if not self.model.iter_n_children(parent) == 1: + return None + + dummy = self.model.iter_children(parent) + + if not self.model.get_value(dummy, self.SNIPPET_COLUMN): + return dummy + + return None + + def unref_languages(self): + piter = self.model.get_iter_first() + library = Library() + + while piter: + if self.is_filled(piter): + language = self.get_language(self.model.get_path(piter)) + library.save(language) + + library.unref(language) + + piter = self.model.iter_next(piter) + + # Callbacks + def do_destroy(self): + Gtk.Dialog.do_destroy(self) + + if not self.model: + return + + # Remove temporary drag export + if self._temp_export: + shutil.rmtree(os.path.dirname(self._temp_export)) + self._temp_export = None + + self.unref_languages() + self.snippet = None + self.model = None + + def on_cell_editing_started(self, renderer, editable, path): + piter = self.model.get_iter(path) + + if not self.model.iter_parent(piter): + renderer.stop_editing(True) + editable.remove_widget() + elif isinstance(editable, Gtk.Entry): + if self.snippet: + editable.set_text(self.snippet['description']) + else: + # This is the `Add a new snippet...` item + editable.set_text('') + + editable.grab_focus() + + def on_cell_edited(self, cell, path, new_text): + if new_text != '': + piter = self.model.get_iter(path) + node = self.model.get_value(piter, self.SNIPPET_COLUMN) + + if node: + if node == self.snippet.data: + s = self.snippet + else: + s = Snippet(node) + + s['description'] = new_text + self.snippet_changed(piter) + self.select_iter(piter) + else: + # This is the `Add a new snippet...` item + # We create a new snippet + snippet = self.new_snippet({'description': new_text}) + + if snippet: + self.model.set_value(piter, self.SNIPPET_COLUMN, snippet.data) + self.snippet_changed(piter) + self.snippet = snippet + self.selection_changed() + + def on_entry_accelerator_focus_out(self, entry, event): + if not self.snippet: + return + + entry.set_text(self.snippet.accelerator_display()) + + def entry_tab_trigger_update_valid(self): + entry = self['entry_tab_trigger'] + text = entry.get_text() + + if text and not Library().valid_tab_trigger(text): + img = self['image_tab_trigger'] + img.set_from_icon_name('dialog-error', Gtk.IconSize.BUTTON) + img.show() + + #self['hbox_tab_trigger'].set_spacing(3) + tip = _('This is not a valid Tab trigger. Triggers can either contain alphanumeric characters (or _, : and .) or a single (non-alphanumeric) character like: {, [, etc.') + + entry.set_tooltip_text(tip) + img.set_tooltip_text(tip) + else: + self['image_tab_trigger'].hide() + #self['hbox_tab_trigger'].set_spacing(0) + entry.set_tooltip_text(_('Single word the snippet is activated with after pressing Tab')) + + return False + + def on_entry_tab_trigger_focus_out(self, entry, event): + if not self.snippet: + return + + text = entry.get_text() + + # save tag + self.snippet['tag'] = text + self.snippet_changed() + + def on_entry_drop_targets_focus_out(self, entry, event): + if not self.snippet: + return + + text = entry.get_text() + + # save drop targets + self.snippet['drop-targets'] = text + self.snippet_changed() + + def on_entry_tab_trigger_changed(self, entry): + self.entry_tab_trigger_update_valid() + + def on_source_view_snippet_focus_out(self, source_view, event): + if not self.snippet: + return + + buf = source_view.get_buffer() + text = buf.get_text(buf.get_start_iter(), \ + buf.get_end_iter(), False) + + self.snippet['text'] = text + self.snippet_changed() + + def on_add_snippet_button_clicked(self, button): + snippet = self.new_snippet() + + if not snippet: + return + + parent = self.model.get_iter(self.language_path) + path = self.model.get_path(parent) + + dummy = self.get_dummy(parent) + + if dummy: + # Remove the dummy + self.model.remove(dummy) + + # Add the snippet + piter = self.add_snippet(parent, snippet.data) + self.select_iter(piter) + + if not self.tree_view.row_expanded(path): + self.tree_view.expand_row(path, False) + self.select_iter(piter) + + self.tree_view.grab_focus() + + path = self.model.get_path(piter) + self.tree_view.set_cursor(path, self.column, True) + + def file_filter(self, name, pattern): + fil = Gtk.FileFilter() + fil.set_name(name) + + for p in pattern: + fil.add_pattern(p) + + return fil + + def import_snippets(self, files): + success = True + + for gfile in files: + if not gfile.has_uri_scheme('file'): + continue + + # Remove file:// + filename = gfile.get_path() + + importer = Importer(filename) + error = importer.run() + + if error: + message = _('The following error occurred while importing: %s') % error + success = False + helper.message_dialog(self.get_toplevel(), Gtk.MessageType.ERROR, message) + + self.build_model(True) + + if success: + message = _('Import successfully completed') + helper.message_dialog(self.get_toplevel(), Gtk.MessageType.INFO, message) + + def on_import_response(self, dialog, response): + if response == Gtk.ResponseType.CANCEL or response == Gtk.ResponseType.CLOSE: + dialog.destroy() + return + + f = dialog.get_files() + dialog.destroy() + + self.import_snippets(f) + + def on_import_snippets_button_clicked(self, button): + dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_("Import snippets"), + action=Gtk.FileChooserAction.OPEN, + buttons=(_("_Cancel"), Gtk.ResponseType.CANCEL, + _("_Open"), Gtk.ResponseType.OK)) + + dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar', '*.xml'))) + dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',))) + dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',))) + dlg.add_filter(self.file_filter(_('Single snippets file'), ('*.xml',))) + dlg.add_filter(self.file_filter(_('All files'), '*')) + + dlg.connect('response', self.on_import_response) + dlg.set_local_only(True) + + dlg.show() + + def export_snippets_real(self, filename, snippets, show_dialogs=True): + export = Exporter(filename, snippets) + error = export.run() + + if error: + message = _('The following error occurred while exporting: %s') % error + msgtype = Gtk.MessageType.ERROR + retval = False + else: + message = _('Export successfully completed') + msgtype = Gtk.MessageType.INFO + retval = True + + if show_dialogs: + helper.message_dialog(self.get_toplevel(), msgtype, message) + + return retval + + def on_export_response(self, dialog, response): + filename = dialog.get_filename() + snippets = dialog._export_snippets + + dialog.destroy() + + if response != Gtk.ResponseType.OK: + return + + self.export_snippets_real(filename, snippets); + + def export_snippets(self, filename=None, show_dialogs=True): + snippets = self.selected_snippets() + + if not snippets or len(snippets) == 0: + return False + + usersnippets = [] + systemsnippets = [] + + # Iterate through snippets and look for system snippets + for snippet in snippets: + if snippet.can_modify(): + usersnippets.append(snippet) + else: + systemsnippets.append(snippet) + + export_snippets = snippets + + if len(systemsnippets) != 0 and show_dialogs: + # Ask if system snippets should also be exported + message = _('Do you want to include selected <b>system</b> snippets in your export?') + mes = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL, + type=Gtk.MessageType.QUESTION, + buttons=Gtk.ButtonsType.YES_NO, + message_format=message) + mes.set_property('use-markup', True) + resp = mes.run() + mes.destroy() + + if resp == Gtk.ResponseType.NO: + export_snippets = usersnippets + elif resp != Gtk.ResponseType.YES: + return False + + if len(export_snippets) == 0 and show_dialogs: + message = _('There are no snippets selected to be exported') + helper.message_dialog(self.get_toplevel(), Gtk.MessageType.QUESTION, message) + return False + + if not filename: + dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_('Export snippets'), + action=Gtk.FileChooserAction.SAVE, + buttons=(_("_Cancel"), Gtk.ResponseType.CANCEL, + _("_Save"), Gtk.ResponseType.OK)) + + dlg._export_snippets = export_snippets + dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar'))) + dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',))) + dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',))) + + dlg.add_filter(self.file_filter(_('All files'), '*')) + dlg.set_do_overwrite_confirmation(True) + dlg.set_current_name(self.default_export_name) + + dlg.connect('response', self.on_export_response) + dlg.set_local_only(True) + + dlg.show() + return True + else: + return self.export_snippets_real(filename, export_snippets, show_dialogs) + + def on_export_snippets_button_clicked(self, button): + snippets = self.selected_snippets() + + if not snippets or len(snippets) == 0: + return + + usersnippets = [] + systemsnippets = [] + + # Iterate through snippets and look for system snippets + for snippet in snippets: + if snippet.can_modify(): + usersnippets.append(snippet) + else: + systemsnippets.append(snippet) + + dlg = Gtk.FileChooserDialog(parent=self.get_toplevel(), title=_('Export snippets'), + action=Gtk.FileChooserAction.SAVE, + buttons=(_('_Cancel'), Gtk.ResponseType.CANCEL, + _('_Save'), Gtk.ResponseType.OK)) + + dlg._export_snippets = snippets + + if len(systemsnippets) != 0: + # Ask if system snippets should also be exported + message = _('Do you want to include selected <b>system</b> snippets in your export?') + mes = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL, + type=Gtk.MessageType.QUESTION, + buttons=Gtk.ButtonsType.YES_NO, + message_format=message) + mes.set_property('use-markup', True) + resp = mes.run() + mes.destroy() + + if resp == Gtk.ResponseType.NO: + dlg._export_snippets = usersnippets + elif resp != Gtk.ResponseType.YES: + dlg.destroy() + return + + if len(dlg._export_snippets) == 0: + dlg.destroy() + + message = _('There are no snippets selected to be exported') + helper.message_dialog(self.get_toplevel(), Gtk.MessageType.QUESTION, message) + return + + dlg.add_filter(self.file_filter(_('All supported archives'), ('*.gz','*.bz2','*.tar'))) + dlg.add_filter(self.file_filter(_('Gzip compressed archive'), ('*.tar.gz',))) + dlg.add_filter(self.file_filter(_('Bzip2 compressed archive'), ('*.tar.bz2',))) + + dlg.add_filter(self.file_filter(_('All files'), '*')) + dlg.set_do_overwrite_confirmation(True) + dlg.set_current_name(self.default_export_name) + + dlg.connect('response', self.on_export_response) + dlg.set_local_only(True) + + dlg.show() + + def remove_snippet_revert(self, path, piter): + node = self.snippet_from_iter(self.model, piter) + Library().revert_snippet(node) + + return piter + + def remove_snippet_delete(self, path, piter): + node = self.snippet_from_iter(self.model, piter) + parent = self.model.iter_parent(piter) + + Library().remove_snippet(node) + idx = path.get_indices() + + if self.model.remove(piter): + return piter + elif idx[-1] != 0: + self.select_iter(self.model.get_iter((idx[0], idx[1] - 1))) + else: + dummy = self.add_new_snippet_node(parent) + self.tree_view.expand_row(self.model.get_path(parent), False) + return dummy + + def on_remove_snippet_button_clicked(self, button): + override, remove, system = self.selected_snippets_state() + + if not (override ^ remove) or system: + return + + paths = self.selected_snippets(include_languages=False, as_path=True) + + if override: + action = self.remove_snippet_revert + else: + action = self.remove_snippet_delete + + # Remove selection + self.tree_view.get_selection().unselect_all() + + # Create tree row references + references = [] + for path in paths: + # FIXME: this should be fixed in pygobject or something + references.append(Gtk.TreeRowReference.new(self.model, path)) + + # Remove/revert snippets + select = None + for reference in references: + path = reference.get_path() + piter = self.model.get_iter(path) + + res = action(path, piter) + + if res: + select = res + + if select: + self.select_iter(select) + + self.selection_changed() + + def set_accelerator(self, keyval, mod): + accelerator = Gtk.accelerator_name(keyval, mod) + self.snippet['accelerator'] = accelerator + + return True + + def on_entry_accelerator_key_press(self, entry, event): + if event.keyval == Gdk.keyval_from_name('Escape'): + # Reset + entry.set_text(self.snippet.accelerator_display()) + self.tree_view.grab_focus() + + return True + elif event.keyval == Gdk.keyval_from_name('Delete') or \ + event.keyval == Gdk.keyval_from_name('BackSpace'): + # Remove the accelerator + entry.set_text('') + self.snippet['accelerator'] = '' + self.tree_view.grab_focus() + + self.snippet_changed() + return True + elif Library().valid_accelerator(event.keyval, event.get_state()): + # New accelerator + self.set_accelerator(event.keyval, \ + event.get_state() & Gtk.accelerator_get_default_mod_mask()) + entry.set_text(self.snippet.accelerator_display()) + self.snippet_changed() + self.tree_view.grab_focus() + + else: + return True + + def on_entry_accelerator_focus_in(self, entry, event): + if self.snippet['accelerator']: + entry.set_text(_('Type a new shortcut, or press Backspace to clear')) + else: + entry.set_text(_('Type a new shortcut')) + + def update_language_path(self): + model, paths = self.tree_view.get_selection().get_selected_rows() + + # Check if all have the same language parent + current_parent = None + + for path in paths: + piter = model.get_iter(path) + parent = model.iter_parent(piter) + + if parent: + path = model.get_path(parent) + + if current_parent != None and current_parent != path: + current_parent = None + break + else: + current_parent = path + + self.language_path = current_parent + + def on_tree_view_selection_changed(self, selection): + parent, piter, node = self.selected_snippet() + + if self.snippet: + self.on_entry_tab_trigger_focus_out(self['entry_tab_trigger'], + None) + self.on_source_view_snippet_focus_out(self['source_view_snippet'], + None) + self.on_entry_drop_targets_focus_out(self['combo_drop_targets'].get_child(), + None) + + self.update_language_path() + + if node: + self.snippet = Snippet(node) + else: + self.snippet = None + + self.selection_changed() + + def iter_after(self, target, after): + if not after: + return True + + tp = self.model.get_path(target) + ap = self.model.get_path(after) + + if tp[0] > ap[0] or (tp[0] == ap[0] and (len(ap) == 1 or tp[1] > ap[1])): + return True + + return False + + def on_tree_view_snippets_key_press(self, treeview, event): + if event.keyval == Gdk.keyval_from_name('Delete'): + self.on_remove_snippet_button_clicked(None) + return True + + def on_tree_view_snippets_row_expanded(self, treeview, piter, path): + # Check if it is already filled + self.fill_if_needed(piter) + self.select_iter(piter) + + def on_entry_drop_targets_drag_data_received(self, entry, context, x, y, selection_data, info, timestamp): + uris = helper.drop_get_uris(selection_data) + if not uris: + return + + text = entry.get_text() + + if text: + mimes = [text] + else: + mimes = [] + + for uri in uris: + try: + mime = Gio.content_type_guess(uri) + except: + mime = None + + if mime: + mimes.append(mime) + + entry.set_text(', '.join(mimes)) + self.on_entry_drop_targets_focus_out(entry, None) + context.finish(True, False, timestamp) + + entry.stop_emission('drag_data_received') + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/meson.build b/plugins/snippets/snippets/meson.build new file mode 100644 index 0000000..1ca34de --- /dev/null +++ b/plugins/snippets/snippets/meson.build @@ -0,0 +1,39 @@ +snippets_sources = [ + '__init__.py', + 'appactivatable.py', + 'completion.py', + 'document.py', + 'exporter.py', + 'helper.py', + 'importer.py', + 'languagemanager.py', + 'library.py', + 'manager.py', + 'parser.py', + 'placeholder.py', + 'shareddata.py', + 'signals.py', + 'singleton.py', + 'snippet.py', + 'substitutionparser.py', + 'windowactivatable.py', +] + +install_data( + snippets_sources, + install_dir: join_paths( + pkglibdir, + 'plugins', + 'snippets', + ) +) + +install_data( + 'snippets.ui', + install_dir: join_paths( + pkgdatadir, + 'plugins', + 'snippets', + 'ui', + ) +) diff --git a/plugins/snippets/snippets/parser.py b/plugins/snippets/snippets/parser.py new file mode 100644 index 0000000..2b6043d --- /dev/null +++ b/plugins/snippets/snippets/parser.py @@ -0,0 +1,256 @@ +# Gedit snippets plugin +# Copyright (C) 2006-2007 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import re + +class Token: + def __init__(self, klass, data): + self.klass = klass + self.data = data + + def __str__(self): + return '%s: [%s]' % (self.klass, self.data) + + def __eq__(self, other): + return self.klass == other.klass and self.data == other.data + + def __ne__(self, other): + return not self.__eq__(other) + +class Parser: + SREG_ENV = '[A-Z_]+' + SREG_ID = '[0-9]+' + + REG_ESCAPE = re.compile('(\\$(%s|\\(|\\{|<|%s)|`|\\\\)' % (SREG_ENV, SREG_ID)) + + def __init__(self, **kwargs): + for k, v in kwargs.items(): + setattr(self, k, v) + + self.position = 0 + self.data_length = len(self.data) + + self.RULES = (self._match_env, self._match_regex, self._match_placeholder, self._match_shell, self._match_eval, self._text) + + def remains(self): + return self.data[self.position:] + + def next_char(self): + if self.position + 1 >= self.data_length: + return '' + else: + return self.data[self.position + 1] + + def char(self): + if self.position >= self.data_length: + return '' + else: + return self.data[self.position] + + def token(self): + self.tktext = '' + + while self.position < self.data_length: + try: + # Get first character + func = {'$': self._rule, + '`': self._try_match_shell}[self.char()] + except: + func = self._text + + # Detect end of text token + if func != self._text and self.tktext != '': + return Token('text', self.tktext) + + tk = func() + + if tk: + return tk + + if self.tktext != '': + return Token('text', self.tktext) + + def _need_escape(self): + text = self.remains()[1:] + + if text == '': + return False + + return self.REG_ESCAPE.match(text) + + def _escape(self): + if not self._need_escape(): + return + + # Increase position with 1 + self.position += 1 + + def _text(self): + if self.char() == '\\': + self._escape() + + self.tktext += self.char() + self.position += 1 + + def _rule(self): + for rule in self.RULES: + res = rule() + + if res: + return res + + def _match_env(self): + text = self.remains() + match = re.match('\\$(%s)' % self.SREG_ENV, text) or re.match('\\${(%s)}' % self.SREG_ENV, text) + + if match: + self.position += len(match.group(0)) + return Token('environment', match.group(1)) + + def _parse_list(self, lst): + pos = 0 + length = len(lst) + items = [] + last = None + + while pos < length: + char = lst[pos] + next = pos < length - 1 and lst[pos + 1] + + if char == '\\' and (next == ',' or next == ']'): + char = next + pos += 1 + elif char == ',': + if last != None: + items.append(last) + + last = None + pos += 1 + continue + + last = (last != None and last + char) or char + pos += 1 + + if last != None: + items.append(last) + + return items + + def _parse_default(self, default): + match = re.match('^\\s*(\\\\)?(\\[((\\\\]|[^\\]])+)\\]\\s*)$', default) + + if not match: + return [default] + + groups = match.groups() + + if groups[0]: + return [groups[1]] + + return self._parse_list(groups[2]) + + def _match_placeholder(self): + text = self.remains() + + match = re.match('\\${(%s)(:((\\\\\\}|[^}])+))?}' % self.SREG_ID, text) or re.match('\\$(%s)' % self.SREG_ID, text) + + if not match: + return None + + groups = match.groups() + default = '' + tabstop = int(groups[0]) + self.position += len(match.group(0)) + + if len(groups) > 1 and groups[2]: + default = self._parse_default(groups[2].replace('\\}', '}')) + + return Token('placeholder', {'tabstop': tabstop, 'default': default}) + + def _match_shell(self): + text = self.remains() + match = re.match('`((%s):)?((\\\\`|[^`])+?)`' % self.SREG_ID, text) or re.match('\\$\\(((%s):)?((\\\\\\)|[^\\)])+?)\\)' % self.SREG_ID, text) + + if not match: + return None + + groups = match.groups() + tabstop = (groups[1] and int(groups[1])) or -1 + self.position += len(match.group(0)) + + if text[0] == '`': + contents = groups[2].replace('\\`', '`') + else: + contents = groups[2].replace('\\)', ')') + + return Token('shell', {'tabstop': tabstop, 'contents': contents}) + + def _try_match_shell(self): + return self._match_shell() or self._text() + + def _eval_options(self, options): + reg = re.compile(self.SREG_ID) + tabstop = -1 + depend = [] + + options = options.split(':') + + for opt in options: + if reg.match(opt): + tabstop = int(opt) + else: + depend += self._parse_list(opt[1:-1]) + + return (tabstop, depend) + + def _match_eval(self): + text = self.remains() + + options = '((%s)|\\[([0-9, ]+)\\])' % self.SREG_ID + match = re.match('\\$<((%s:)*)((\\\\>|[^>])+?)>' % options, text) + + if not match: + return None + + groups = match.groups() + (tabstop, depend) = (groups[0] and self._eval_options(groups[0][:-1])) or (-1, []) + self.position += len(match.group(0)) + + return Token('eval', {'tabstop': tabstop, 'dependencies': depend, 'contents': groups[5].replace('\\>', '>')}) + + def _match_regex(self): + text = self.remains() + + content = '((?:\\\\[/]|\\\\}|[^/}])+)' + match = re.match('\\${(?:(%s):)?\\s*(%s|\\$([A-Z_]+))?[/]%s[/]%s(?:[/]([a-zA-Z]*))?}' % (self.SREG_ID, self.SREG_ID, content, content), text) + + if not match: + return None + + groups = match.groups() + tabstop = (groups[0] and int(groups[0])) or -1 + inp = (groups[2] or (groups[1] and int(groups[1]))) or '' + + pattern = re.sub('\\\\([/}])', '\\1', groups[3]) + substitution = re.sub('\\\\([/}])', '\\1', groups[4]) + modifiers = groups[5] or '' + + self.position += len(match.group(0)) + + return Token('regex', {'tabstop': tabstop, 'input': inp, 'pattern': pattern, 'substitution': substitution, 'modifiers': modifiers}) + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/placeholder.py b/plugins/snippets/snippets/placeholder.py new file mode 100644 index 0000000..e70a31e --- /dev/null +++ b/plugins/snippets/snippets/placeholder.py @@ -0,0 +1,714 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import traceback +import re +import sys +import signal +import locale +import subprocess +from gi.repository import GObject, Gtk + +from . import helper +from .substitutionparser import SubstitutionParser + +try: + import gettext + gettext.bindtextdomain('gedit') + gettext.textdomain('gedit') + _ = gettext.gettext +except: + _ = lambda s: s + +# These are places in a view where the cursor can go and do things +class Placeholder: + def __init__(self, view, tabstop, environ, defaults, begin): + self.ok = True + self.done = False + self.buf = view.get_buffer() + self.view = view + self.has_references = False + self.mirrors = [] + self.leave_mirrors = [] + self.tabstop = tabstop + self.environ = environ + self.set_default(defaults) + self.prev_contents = self.default + self.set_mark_gravity() + + if begin: + self.begin = self.buf.create_mark(None, begin, self.mark_gravity[0]) + else: + self.begin = None + + self.end = None + + def get_environ(self): + return self.environ['utf8'] + + def __str__(self): + return '%s (%s)' % (str(self.__class__), str(self.default)) + + def set_mark_gravity(self): + self.mark_gravity = [True, False] + + def set_default(self, defaults): + self.default = None + self.defaults = [] + + if not defaults: + return + + for d in defaults: + dm = self.expand_environment(d) + + if dm: + self.defaults.append(dm) + + if not self.default: + self.default = dm + + if dm != d: + break + + def literal(self, s): + return repr(s) + + def format_environment(self, s): + return s + + def re_environment(self, m): + env = self.get_environ() + + if m.group(1) or not m.group(2) in env: + return '$' + m.group(2) + else: + return self.format_environment(env[m.group(2)]) + + def expand_environment(self, text): + if not text: + return text + + return re.sub('(\\\\)?\\$([A-Z_]+)', self.re_environment, text) + + def get_iter(self, mark): + if mark and not mark.get_deleted(): + return self.buf.get_iter_at_mark(mark) + else: + return None + + def begin_iter(self): + return self.get_iter(self.begin) + + def end_iter(self): + return self.get_iter(self.end) + + def run_last(self, placeholders): + begin = self.begin_iter() + self.end = self.buf.create_mark(None, begin, self.mark_gravity[1]) + + if self.default: + helper.insert_with_indent(self.view, begin, self.default, False, self) + + def remove(self, force = False): + if self.begin and not self.begin.get_deleted(): + self.buf.delete_mark(self.begin) + + if self.end and not self.end.get_deleted(): + self.buf.delete_mark(self.end) + + # Do something on beginning this placeholder + def enter(self): + if not self.begin or self.begin.get_deleted(): + return + + self.buf.move_mark(self.buf.get_insert(), self.begin_iter()) + + if self.end: + self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter()) + else: + self.buf.move_mark(self.buf.get_selection_bound(), self.begin_iter()) + + def get_text(self): + if self.begin and self.end: + biter = self.begin_iter() + eiter = self.end_iter() + + if biter and eiter: + return self.buf.get_text(self.begin_iter(), self.end_iter(), False) + else: + return '' + else: + return '' + + def add_mirror(self, mirror, onleave = False): + mirror.has_references = True + + if onleave: + self.leave_mirrors.append(mirror) + else: + self.mirrors.append(mirror) + + def set_text(self, text): + if self.begin.get_deleted() or self.end.get_deleted(): + return + + # Set from self.begin to self.end to text! + self.buf.begin_user_action() + # Remove everything between self.begin and self.end + begin = self.begin_iter() + self.buf.delete(begin, self.end_iter()) + + # Insert the text from the mirror + helper.insert_with_indent(self.view, begin, text, True, self) + self.buf.end_user_action() + + self.update_contents() + + def update_contents(self): + prev = self.prev_contents + self.prev_contents = self.get_text() + + if prev != self.get_text(): + for mirror in self.mirrors: + if not mirror.update(self): + return + + def update_leave_mirrors(self): + # Notify mirrors + for mirror in self.leave_mirrors: + if not mirror.update(self): + return + + # Do something on ending this placeholder + def leave(self): + self.update_leave_mirrors() + + def find_mirrors(self, text, placeholders): + mirrors = [] + + while (True): + m = re.search('(\\\\)?\\$(?:{([0-9]+)}|([0-9]+))', text) + + if not m: + break + + # Skip escaped mirrors + if m.group(1): + text = text[m.end():] + continue + + tabstop = int(m.group(2) or m.group(3)) + + if tabstop in placeholders: + if not tabstop in mirrors: + mirrors.append(tabstop) + + text = text[m.end():] + else: + self.ok = False + return None + + return mirrors + +# This is an placeholder which inserts a mirror of another Placeholder +class PlaceholderMirror(Placeholder): + def __init__(self, view, tabstop, environ, begin): + Placeholder.__init__(self, view, -1, environ, None, begin) + self.mirror_stop = tabstop + + def update(self, mirror): + self.set_text(mirror.get_text()) + return True + + def run_last(self, placeholders): + Placeholder.run_last(self, placeholders) + + if self.mirror_stop in placeholders: + mirror = placeholders[self.mirror_stop] + + mirror.add_mirror(self) + + if mirror.default: + self.set_text(mirror.default) + else: + self.ok = False + +# This placeholder indicates the end of a snippet +class PlaceholderEnd(Placeholder): + def __init__(self, view, environ, begin, default): + Placeholder.__init__(self, view, 0, environ, default, begin) + + def run_last(self, placeholders): + Placeholder.run_last(self, placeholders) + + # Remove the begin mark and set the begin mark + # to the end mark, this is needed so the end placeholder won't contain + # any text + + if not self.default: + self.mark_gravity[0] = False + self.buf.delete_mark(self.begin) + self.begin = self.buf.create_mark(None, self.end_iter(), self.mark_gravity[0]) + + def enter(self): + if self.begin and not self.begin.get_deleted(): + self.buf.move_mark(self.buf.get_insert(), self.begin_iter()) + + if self.end and not self.end.get_deleted(): + self.buf.move_mark(self.buf.get_selection_bound(), self.end_iter()) + + def leave(self): + self.enter() + +# This placeholder is used to expand a command with embedded mirrors +class PlaceholderExpand(Placeholder): + def __init__(self, view, tabstop, environ, begin, s): + Placeholder.__init__(self, view, tabstop, environ, None, begin) + + self.mirror_text = {0: ''} + self.timeout_id = None + self.cmd = s + self.instant_update = False + + def __str__(self): + s = Placeholder.__str__(self) + + return s + ' ' + self.cmd + + def get_mirrors(self, placeholders): + return self.find_mirrors(self.cmd, placeholders) + + # Check if all substitution placeholders are accounted for + def run_last(self, placeholders): + Placeholder.run_last(self, placeholders) + + self.ok = True + mirrors = self.get_mirrors(placeholders) + + if mirrors: + allDefault = True + + for mirror in mirrors: + p = placeholders[mirror] + p.add_mirror(self, not self.instant_update) + self.mirror_text[p.tabstop] = p.default + + if not p.default and not isinstance(p, PlaceholderExpand): + allDefault = False + + if allDefault: + self.update(None) + self.default = self.get_text() or None + else: + self.update(None) + self.default = self.get_text() or None + + if self.tabstop == -1: + self.done = True + + def re_placeholder(self, m, formatter): + if m.group(1): + return '"$' + m.group(2) + '"' + else: + if m.group(3): + index = int(m.group(3)) + else: + index = int(m.group(4)) + + return formatter(self.mirror_text[index]) + + def remove_timeout(self): + if self.timeout_id != None: + GObject.source_remove(self.timeout_id) + self.timeout_id = None + + def install_timeout(self): + self.remove_timeout() + self.timeout_id = GObject.timeout_add(1000, self.timeout_cb) + + def timeout_cb(self): + self.timeout_id = None + + return False + + def format_environment(self, text): + return self.literal(text) + + def substitute(self, text, formatter = None): + formatter = formatter or self.literal + + # substitute all mirrors, but also environmental variables + text = re.sub('(\\\\)?\\$({([0-9]+)}|([0-9]+))', lambda m: self.re_placeholder(m, formatter), + text) + + return self.expand_environment(text) + + def run_update(self): + text = self.substitute(self.cmd) + + if text: + ret = self.expand(text) + + if ret: + self.update_leave_mirrors() + else: + ret = True + + return ret + + def update(self, mirror): + if mirror: + self.mirror_text[mirror.tabstop] = mirror.get_text() + + # Check if all substitutions have been made + for tabstop in self.mirror_text: + if tabstop == 0: + continue + + if self.mirror_text[tabstop] is None: + return False + + return self.run_update() + + def expand(self, text): + return True + +# The shell placeholder executes commands in a subshell +class PlaceholderShell(PlaceholderExpand): + def __init__(self, view, tabstop, environ, begin, s): + PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s) + + self.shell = None + self.remove_me = False + + def get_environ(self): + return self.environ['noenc'] + + def close_shell(self): + self.shell.stdout.close() + self.shell = None + + def timeout_cb(self): + PlaceholderExpand.timeout_cb(self) + self.remove_timeout() + + if not self.shell: + return False + + GObject.source_remove(self.watch_id) + self.close_shell() + + if self.remove_me: + PlaceholderExpand.remove(self) + + helper.message_dialog(None, Gtk.MessageType.ERROR, 'Execution of the shell ' \ + 'command (%s) exceeded the maximum time; ' \ + 'execution aborted.' % self.command) + + return False + + def process_close(self): + self.close_shell() + self.remove_timeout() + + self.set_text(str.join('', self.shell_output).rstrip('\n')) + + if self.default is None: + self.default = self.get_text() + self.leave() + + if self.remove_me: + PlaceholderExpand.remove(self, True) + + def process_cb(self, source, condition): + if condition & GObject.IO_IN: + line = source.readline() + + if len(line) > 0: + try: + line = line.decode('utf-8') + except UnicodeDecodeError: + line = line.decode(locale.getdefaultlocale()[1], errors='replace') + + self.shell_output += line + self.install_timeout() + + return True + + self.process_close() + return False + + def literal_replace(self, match): + return "\\%s" % (match.group(0)) + + def literal(self, text): + return '"' + re.sub('([\\\\"])', self.literal_replace, text) + '"' + + def expand(self, text): + self.remove_timeout() + + if self.shell: + GObject.source_remove(self.watch_id) + self.close_shell() + + popen_args = { + 'cwd': None, + 'shell': True, + 'env': self.get_environ(), + 'stdout': subprocess.PIPE + } + + self.command = text + self.shell = subprocess.Popen(text, **popen_args) + self.shell_output = '' + self.watch_id = GObject.io_add_watch(self.shell.stdout, GObject.IO_IN | \ + GObject.IO_HUP, self.process_cb) + self.install_timeout() + + return True + + def remove(self, force = False): + if not force and self.shell: + # Still executing shell command + self.remove_me = True + else: + if force: + self.remove_timeout() + + if self.shell: + self.close_shell() + + PlaceholderExpand.remove(self, force) + +class TimeoutError(Exception): + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + +# The python placeholder evaluates commands in python +class PlaceholderEval(PlaceholderExpand): + def __init__(self, view, tabstop, environ, refs, begin, s, namespace): + PlaceholderExpand.__init__(self, view, tabstop, environ, begin, s) + + self.fdread = 0 + self.remove_me = False + self.namespace = namespace + + self.refs = [] + + if refs: + for ref in refs: + self.refs.append(int(ref.strip())) + + def get_mirrors(self, placeholders): + mirrors = PlaceholderExpand.get_mirrors(self, placeholders) + + if not self.ok: + return None + + for ref in self.refs: + if ref in placeholders: + if ref not in mirrors: + mirrors.append(ref) + else: + self.ok = False + return None + + return mirrors + + # SIGALRM is not supported on all platforms (e.g. windows). Timeout + # with SIGALRM will not be used on those platforms. This will + # potentially block gedit if you have a placeholder which gets stuck, + # but it's better than not supporting them at all. At some point we + # might have proper thread support and we can fix this in a better way + def timeout_supported(self): + return hasattr(signal, 'SIGALRM') + + def timeout_cb(self, signum = 0, frame = 0): + raise TimeoutError("Operation timed out (>2 seconds)") + + def install_timeout(self): + if not self.timeout_supported(): + return + + if self.timeout_id != None: + self.remove_timeout() + + self.timeout_id = signal.signal(signal.SIGALRM, self.timeout_cb) + signal.alarm(2) + + def remove_timeout(self): + if not self.timeout_supported(): + return + + if self.timeout_id != None: + signal.alarm(0) + + signal.signal(signal.SIGALRM, self.timeout_id) + + self.timeout_id = None + + def expand(self, text): + self.remove_timeout() + + text = text.strip() + self.command = text + + if not self.command or self.command == '': + self.set_text('') + return + + text = "def process_snippet():\n\t" + "\n\t".join(text.split("\n")) + + if 'process_snippet' in self.namespace: + del self.namespace['process_snippet'] + + try: + exec(text, self.namespace) + except: + traceback.print_exc() + + if 'process_snippet' in self.namespace: + try: + # Install a sigalarm signal. This is a HACK to make sure + # gedit doesn't get freezed by someone creating a python + # placeholder which for instance loops indefinately. Since + # the code is executed synchronously it will hang gedit. With + # the alarm signal we raise an exception and catch this + # (see below). We show an error message and return False. + # ___this is a HACK___ and should be fixed properly (I just + # don't know how) + self.install_timeout() + result = self.namespace['process_snippet']() + self.remove_timeout() + except TimeoutError: + self.remove_timeout() + + helper.message_dialog(None, Gtk.MessageType.ERROR, \ + _('Execution of the Python command (%s) exceeds the maximum ' \ + 'time, execution aborted.') % self.command) + + return False + except Exception as detail: + self.remove_timeout() + + helper.message_dialog(None, Gtk.MessageType.ERROR, + _('Execution of the Python command (%s) failed: %s') % + (self.command, detail)) + + return False + + if result is None: + # sys.stderr.write("%s:\n>> %s\n" % (_('The following python code, run in a snippet, does not return a value'), "\n>> ".join(self.command.split("\n")))) + result = '' + + self.set_text(str(result)) + + return True + +# Regular expression placeholder +class PlaceholderRegex(PlaceholderExpand): + def __init__(self, view, tabstop, environ, begin, inp, pattern, substitution, modifiers): + PlaceholderExpand.__init__(self, view, tabstop, environ, begin, '') + + self.instant_update = True + self.inp = inp + self.pattern = pattern + self.substitution = substitution + + self.init_modifiers(modifiers) + + def init_modifiers(self, modifiers): + mods = {'I': re.I, + 'L': re.L, + 'M': re.M, + 'S': re.S, + 'U': re.U, + 'X': re.X} + + self.modifiers = 0 + + for modifier in modifiers: + if modifier in mods: + self.modifiers |= mods[modifier] + + def get_mirrors(self, placeholders): + mirrors = self.find_mirrors(self.pattern, placeholders) + self.find_mirrors(self.substitution, placeholders) + + if isinstance(self.inp, int): + if self.inp not in placeholders: + self.ok = False + return None + elif self.inp not in mirrors: + mirrors.append(self.inp) + + return mirrors + + def literal(self, s): + return re.escape(s) + + def get_input(self): + env = self.get_environ() + + if isinstance(self.inp, int): + return self.mirror_text[self.inp] + elif self.inp in env: + return env[self.inp] + else: + return '' + + def run_update(self): + pattern = self.substitute(self.pattern) + substitution = self.substitute(self.substitution, SubstitutionParser.escape_substitution) + + if pattern: + return self.expand(pattern, substitution) + + return True + + def expand(self, pattern, substitution): + # Try to compile pattern + try: + regex = re.compile(pattern, self.modifiers) + except re.error as message: + sys.stderr.write('Could not compile regular expression: %s\n%s\n' % (pattern, message)) + return False + + inp = self.get_input() + match = regex.search(inp) + + if not match: + self.set_text(inp) + else: + groups = match.groupdict() + + idx = 0 + for group in match.groups(): + groups[str(idx + 1)] = group + idx += 1 + + groups['0'] = match.group(0) + + parser = SubstitutionParser(substitution, groups) + self.set_text(parser.parse()) + + return True + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/shareddata.py b/plugins/snippets/snippets/shareddata.py new file mode 100644 index 0000000..be6fd14 --- /dev/null +++ b/plugins/snippets/snippets/shareddata.py @@ -0,0 +1,83 @@ +# Gedit snippets plugin +# Copyright (C) 2011 Jesse van den Kieboom <jessevdk@gnome.org> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from .singleton import Singleton +import os + +from gi.repository import Gtk + +# To register the GeditSnippetsManager type +from .manager import Manager + +class SharedData(object, metaclass=Singleton): + def __init__(self): + self.dlg = None + self.dlg_default_size = None + self.controller_registry = {} + self.windows = {} + + def register_controller(self, view, controller): + self.controller_registry[view] = controller + + def unregister_controller(self, view, controller): + if self.controller_registry[view] == controller: + del self.controller_registry[view] + + def register_window(self, window): + self.windows[window.window] = window + + def unregister_window(self, window): + if window.window in self.windows: + del self.windows[window.window] + + def update_state(self, window): + if window in self.windows: + self.windows[window].do_update_state() + + def get_active_controller(self, window): + view = window.get_active_view() + + if not view or not view in self.controller_registry: + return None + + return self.controller_registry[view] + + def get_controller(self, view): + if view in self.controller_registry: + return self.controller_registry[view] + else: + return None + + def manager_destroyed(self, dlg): + self.dlg_default_size = dlg.get_final_size() + self.dlg = None + + def show_manager(self, window, datadir): + if not self.dlg: + builder = Gtk.Builder() + builder.add_from_file(os.path.join(datadir, 'ui', 'snippets.ui')) + + self.dlg = builder.get_object('snippets_manager') + self.dlg.connect('destroy', self.manager_destroyed) + + if self.dlg_default_size: + self.dlg.set_default_size(self.dlg_default_size[0], self.dlg_default_size[1]) + + self.dlg.set_transient_for(window) + self.dlg.present() + +# vi:ex:ts=4:et diff --git a/plugins/snippets/snippets/signals.py b/plugins/snippets/snippets/signals.py new file mode 100644 index 0000000..647b616 --- /dev/null +++ b/plugins/snippets/snippets/signals.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# +# signals.py +# +# Copyright (C) 2009 - Jesse van den Kieboom +# +# 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 2 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/>. + +class Signals: + def __init__(self): + self._signals = {} + + def _connect(self, obj, name, handler, connector): + ret = self._signals.setdefault(obj, {}) + + hid = connector(name, handler) + ret.setdefault(name, []).append(hid) + + return hid + + def connect_signal(self, obj, name, handler): + return self._connect(obj, name, handler, obj.connect) + + def connect_signal_after(self, obj, name, handler): + return self._connect(obj, name, handler, obj.connect_after) + + def disconnect_signals(self, obj): + if obj not in self._signals: + return False + + for name in self._signals[obj]: + for hid in self._signals[obj][name]: + obj.disconnect(hid) + + del self._signals[obj] + return True + + def block_signal(self, obj, name): + if obj not in self._signals: + return False + + if name not in self._signals[obj]: + return False + + for hid in self._signals[obj][name]: + obj.handler_block(hid) + + return True + + def unblock_signal(self, obj, name): + if obj not in self._signals: + return False + + if name not in self._signals[obj]: + return False + + for hid in self._signals[obj][name]: + obj.handler_unblock(hid) + + return True + + def disconnect_signal(self, obj, name): + if obj not in self._signals: + return False + + if name not in self._signals[obj]: + return False + + for hid in self._signals[obj][name]: + obj.disconnect(hid) + + del self._signals[obj][name] + + if len(self._signals[obj]) == 0: + del self._signals[obj] + + return True + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/singleton.py b/plugins/snippets/snippets/singleton.py new file mode 100644 index 0000000..9bc346d --- /dev/null +++ b/plugins/snippets/snippets/singleton.py @@ -0,0 +1,27 @@ +# Gedit snippets plugin +# Copyright (C) 2011 Jesse van den Kieboom <jessevdk@gnome.org> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +class Singleton(type): + def __init__(cls, name, bases, dict): + super(Singleton, cls).__init__(name, bases, dict) + cls.instance = None + + def __call__(cls, *args, **kw): + if cls.instance is None: + cls.instance = super(Singleton, cls).__call__(*args, **kw) + + return cls.instance diff --git a/plugins/snippets/snippets/snippet.py b/plugins/snippets/snippets/snippet.py new file mode 100644 index 0000000..6b18156 --- /dev/null +++ b/plugins/snippets/snippets/snippet.py @@ -0,0 +1,360 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from gi.repository import Gio, Gtk + +import sys + +from .placeholder import PlaceholderEnd, PlaceholderMirror, Placeholder, PlaceholderShell, PlaceholderEval, PlaceholderRegex, PlaceholderExpand +from .parser import Parser +from . import helper + +class EvalUtilities: + def __init__(self, view=None): + self.view = view + self._init_namespace() + + def _init_namespace(self): + self.namespace = { + '__builtins__': __builtins__, + 'align': self.util_align, + 'readfile': self.util_readfile, + 'filesize': self.util_filesize + } + + def _real_len(self, s, tablen = 0): + if tablen == 0: + tablen = self.view.get_tab_width() + + return len(s.expandtabs(tablen)) + + def _filename_to_uri(self, filename): + gfile = Gio.file_new_for_path(filename) + + return gfile.get_uri() + + def util_readfile(self, filename): + stream = Gio.file_new_for_path(filename).read() + + if not stream: + return '' + + res = stream.read() + stream.close() + + return res + + def util_filesize(self, filename): + gfile = Gio.file_new_for_path(filename) + info = gfile.query_info(Gio.FILE_ATTRIBUTE_STANDARD_SIZE) + + if not info: + return 0 + + return info.get_size() + + def util_align(self, items): + maxlen = [] + tablen = self.view.get_tab_width() + + for row in range(0, len(items)): + for col in range(0, len(items[row]) - 1): + if row == 0: + maxlen.append(0) + + items[row][col] += "\t" + rl = self._real_len(items[row][col], tablen) + + if (rl > maxlen[col]): + maxlen[col] = rl + + result = '' + + for row in range(0, len(items)): + for col in range(0, len(items[row]) - 1): + item = items[row][col] + + result += item + ("\t" * int(((maxlen[col] - \ + self._real_len(item, tablen)) / tablen))) + + result += items[row][len(items[row]) - 1] + + if row != len(items) - 1: + result += "\n" + + return result + +class Snippet: + def __init__(self, data, environ = {}): + self.data = data + self.environ = environ + + def __getitem__(self, prop): + return self.data[prop] + + def __setitem__(self, prop, value): + self.data[prop] = value + + def accelerator_display(self): + accel = self['accelerator'] + + if accel: + keyval, mod = Gtk.accelerator_parse(accel) + accel = Gtk.accelerator_get_label(keyval, mod) + + return accel or '' + + def display(self): + nm = helper.markup_escape(self['description']) + + tag = self['tag'] + accel = self.accelerator_display() + detail = [] + + if tag and tag != '': + detail.append(tag) + + if accel and accel != '': + detail.append(accel) + + if not detail: + return nm + else: + return nm + ' (<b>' + helper.markup_escape(', '.join(detail)) + \ + '</b>)' + + def _add_placeholder(self, placeholder): + if placeholder.tabstop in self.placeholders: + if placeholder.tabstop == -1: + self.placeholders[-1].append(placeholder) + self.plugin_data.ordered_placeholders.append(placeholder) + elif placeholder.tabstop == -1: + self.placeholders[-1] = [placeholder] + self.plugin_data.ordered_placeholders.append(placeholder) + else: + self.placeholders[placeholder.tabstop] = placeholder + self.plugin_data.ordered_placeholders.append(placeholder) + + def _insert_text(self, text): + # Insert text keeping indentation in mind + indented = str.join('\n' + self._indent, helper.spaces_instead_of_tabs(self._view, text).split('\n')) + self._view.get_buffer().insert(self._insert_iter(), indented) + + def _insert_iter(self): + return self._view.get_buffer().get_iter_at_mark(self._insert_mark) + + def _create_environment(self, data): + if data in self.environ['utf8']: + val = self.environ['utf8'][data] + else: + val = '' + + # Get all the current indentation + all_indent = helper.compute_indentation(self._view, self._insert_iter()) + + # Substract initial indentation to get the snippet indentation + indent = all_indent[len(self._indent):] + + # Keep indentation + return str.join('\n' + indent, val.split('\n')) + + def _create_placeholder(self, data): + tabstop = data['tabstop'] + begin = self._insert_iter() + + if tabstop == 0: + # End placeholder + return PlaceholderEnd(self._view, self.environ, begin, data['default']) + elif tabstop in self.placeholders: + # Mirror placeholder + return PlaceholderMirror(self._view, tabstop, self.environ, begin) + else: + # Default placeholder + return Placeholder(self._view, tabstop, self.environ, data['default'], begin) + + def _create_shell(self, data): + begin = self._insert_iter() + return PlaceholderShell(self._view, data['tabstop'], self.environ, begin, data['contents']) + + def _create_eval(self, data): + begin = self._insert_iter() + return PlaceholderEval(self._view, data['tabstop'], self.environ, data['dependencies'], begin, data['contents'], self._utils.namespace) + + def _create_regex(self, data): + begin = self._insert_iter() + return PlaceholderRegex(self._view, data['tabstop'], self.environ, begin, data['input'], data['pattern'], data['substitution'], data['modifiers']) + + def _create_text(self, data): + return data + + def _invalid_placeholder(self, placeholder, remove): + buf = self._view.get_buffer() + + # Remove the text because this placeholder is invalid + if placeholder.default and remove: + buf.delete(placeholder.begin_iter(), placeholder.end_iter()) + + placeholder.remove() + + if placeholder.tabstop == -1: + index = self.placeholders[-1].index(placeholder) + del self.placeholders[-1][index] + else: + del self.placeholders[placeholder.tabstop] + + self.plugin_data.ordered_placeholders.remove(placeholder) + + def _parse(self, plugin_data): + # Initialize current variables + self._view = plugin_data.view + self._indent = helper.compute_indentation(self._view, self._view.get_buffer().get_iter_at_mark(self.begin_mark)) + self._utils = EvalUtilities(self._view) + self.placeholders = {} + self._insert_mark = self.end_mark + self.plugin_data = plugin_data + + # Create parser + parser = Parser(data=self['text']) + + # Parse tokens + while (True): + token = parser.token() + + if not token: + break + + try: + val = {'environment': self._create_environment, + 'placeholder': self._create_placeholder, + 'shell': self._create_shell, + 'eval': self._create_eval, + 'regex': self._create_regex, + 'text': self._create_text}[token.klass](token.data) + except KeyError: + sys.stderr.write('Token class not supported: %s (%s)\n' % token.klass) + continue + + if isinstance(val, str): + # Insert text + self._insert_text(val) + else: + # Insert placeholder + self._add_placeholder(val) + + # Create end placeholder if there isn't one yet + if 0 not in self.placeholders: + self.placeholders[0] = PlaceholderEnd(self._view, self.environ, self.end_iter(), None) + self.plugin_data.ordered_placeholders.append(self.placeholders[0]) + + # Make sure run_last is ran for all placeholders and remove any + # non `ok` placeholders + for tabstop in self.placeholders.copy(): + ph = (tabstop == -1 and list(self.placeholders[-1])) or [self.placeholders[tabstop]] + + for placeholder in ph: + placeholder.run_last(self.placeholders) + + if not placeholder.ok or placeholder.done: + self._invalid_placeholder(placeholder, not placeholder.ok) + + # Remove all the Expand placeholders which have a tabstop because + # they can be used to mirror, but they shouldn't be real tabstops + # (if they have mirrors installed). This is problably a bit of + # a dirty hack :) + if -1 not in self.placeholders: + self.placeholders[-1] = [] + + for tabstop in self.placeholders.copy(): + placeholder = self.placeholders[tabstop] + + if tabstop != -1: + if isinstance(placeholder, PlaceholderExpand) and \ + placeholder.has_references: + # Add to anonymous placeholders + self.placeholders[-1].append(placeholder) + + # Remove placeholder + del self.placeholders[tabstop] + + self.plugin_data = None + + def insert_into(self, plugin_data, insert): + buf = plugin_data.view.get_buffer() + last_index = 0 + + # Find closest mark at current insertion, so that we may insert + # our marks in the correct order + (current, next) = plugin_data.next_placeholder() + + if current: + # Insert AFTER current + last_index = plugin_data.placeholders.index(current) + 1 + elif next: + # Insert BEFORE next + last_index = plugin_data.placeholders.index(next) + else: + # Insert at first position + last_index = 0 + + # lastIndex now contains the position of the last mark + # Create snippet bounding marks + self.begin_mark = buf.create_mark(None, insert, True) + self.end_mark = buf.create_mark(None, insert, False) + + # Now parse the contents of this snippet, create Placeholders + # and insert the placholder marks in the marks array of plugin_data + self._parse(plugin_data) + + # So now all of the snippet is in the buffer, we have all our + # placeholders right here, what's next, put all marks in the + # plugin_data.marks + k = sorted(self.placeholders.keys(), reverse=True) + + plugin_data.placeholders.insert(last_index, self.placeholders[0]) + last_iter = self.placeholders[0].end_iter() + + for tabstop in k: + if tabstop != -1 and tabstop != 0: + placeholder = self.placeholders[tabstop] + end_iter = placeholder.end_iter() + + if last_iter.compare(end_iter) < 0: + last_iter = end_iter + + # Inserting placeholder + plugin_data.placeholders.insert(last_index, placeholder) + + # Move end mark to last placeholder + buf.move_mark(self.end_mark, last_iter) + + return self + + def deactivate(self): + buf = self.begin_mark.get_buffer() + + buf.delete_mark(self.begin_mark) + buf.delete_mark(self.end_mark) + + self.placeholders = {} + + def begin_iter(self): + return self.begin_mark.get_buffer().get_iter_at_mark(self.begin_mark) + + def end_iter(self): + return self.end_mark.get_buffer().get_iter_at_mark(self.end_mark) + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/snippets.ui b/plugins/snippets/snippets/snippets.ui new file mode 100644 index 0000000..e80d633 --- /dev/null +++ b/plugins/snippets/snippets/snippets.ui @@ -0,0 +1,417 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.16.0 --> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkListStore" id="model1"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0">text</col> + </row> + <row> + <col id="0">text/plain</col> + </row> + <row> + <col id="0">text/xml</col> + </row> + <row> + <col id="0">image</col> + </row> + <row> + <col id="0">image/png</col> + </row> + <row> + <col id="0">image/jpeg</col> + </row> + <row> + <col id="0">audio</col> + </row> + <row> + <col id="0">video</col> + </row> + </data> + </object> + <object class="GeditDocument" id="source_buffer"/> + <object class="GeditSnippetsManager" id="snippets_manager"> + <property name="can_focus">False</property> + <property name="title" translatable="yes">Manage Snippets</property> + <property name="default_width">800</property> + <property name="default_height">600</property> + <property name="type_hint">dialog</property> + <child type="titlebar"> + <object class="GtkHeaderBar" id="headerbar"> + <property name="visible">True</property> + <property name="title" translatable="yes">Manage Snippets</property> + <property name="show_close_button">True</property> + </object> + </child> + <child> + <object class="GtkPaned" id="hpaned_paned"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="position">275</property> + <style> + <class name="gedit-snippet-manager-paned"/> + </style> + <child> + <object class="GtkBox" id="box2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkScrolledWindow" id="scrolled_window_snippets"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <style> + <class name="gedit-snippet-manager-treeview"/> + </style> + <child> + <object class="GtkTreeView" id="tree_view_snippets"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <signal name="key-press-event" handler="on_tree_view_snippets_key_press" swapped="no"/> + <signal name="row-expanded" handler="on_tree_view_snippets_row_expanded" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection"/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkToolbar" id="toolbar"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="toolbar_style">icons</property> + <property name="icon_size">1</property> + <child> + <object class="GtkToolButton" id="add_snippet_button"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup" translatable="yes">Create new snippet</property> + <property name="tooltip_text" translatable="yes">Create new snippet</property> + <property name="label" translatable="yes">Add Snippet</property> + <property name="use_underline">True</property> + <property name="icon_name">list-add-symbolic</property> + <signal name="clicked" handler="on_add_snippet_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolButton" id="remove_snippet_button"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup" translatable="yes">Delete selected snippet</property> + <property name="tooltip_text" translatable="yes">Delete selected snippet</property> + <property name="label" translatable="yes">Remove Snippet</property> + <property name="use_underline">True</property> + <property name="icon_name">list-remove-symbolic</property> + <signal name="clicked" handler="on_remove_snippet_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolButton" id="import_snippets_button"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup" translatable="yes">Import snippets</property> + <property name="tooltip_text" translatable="yes">Import snippets</property> + <property name="label" translatable="yes">Import Snippets</property> + <property name="use_underline">True</property> + <property name="icon_name">document-open-symbolic</property> + <signal name="clicked" handler="on_import_snippets_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <child> + <object class="GtkToolButton" id="export_snippets_button"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup" translatable="yes">Export selected snippets</property> + <property name="tooltip_text" translatable="yes">Export selected snippets</property> + <property name="label" translatable="yes">Export Snippets</property> + <property name="use_underline">True</property> + <property name="icon_name">document-save-as-symbolic</property> + <signal name="clicked" handler="on_export_snippets_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="homogeneous">True</property> + </packing> + </child> + <style> + <class name="inline-toolbar"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="resize">False</property> + <property name="shrink">True</property> + </packing> + </child> + <child> + <object class="GtkBox" id="vbox_snippet"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkScrolledWindow" id="scrolled_window_snippet"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <style> + <class name="gedit-snippet-manager-view"/> + </style> + <child> + <object class="GeditView" id="source_view_snippet"> + <property name="buffer">source_buffer</property> + <property name="visible">True</property> + <signal handler="on_source_view_snippet_focus_out" name="focus_out_event"/> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_start">6</property> + <property name="margin_end">6</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Activation</property> + <property name="use_markup">True</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="hbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label"> </property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkLabel" id="label_tab_trigger"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes" comments=""tab" here means the tab key, not the notebook tab!">_Tab trigger:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_tab_trigger</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkBox" id="hbox_tab_trigger"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkEntry" id="entry_tab_trigger"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">Single word the snippet is activated with after pressing Tab</property> + <signal name="changed" handler="on_entry_tab_trigger_changed" swapped="no"/> + <signal name="focus-out-event" handler="on_entry_tab_trigger_focus_out" swapped="no"/> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkImage" id="image_tab_trigger"> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="padding">3</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_accelerator"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">S_hortcut key:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_accelerator</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_accelerator"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">Shortcut key with which the snippet is activated</property> + <property name="editable">False</property> + <signal name="focus-in-event" handler="on_entry_accelerator_focus_in" swapped="no"/> + <signal name="focus-out-event" handler="on_entry_accelerator_focus_out" swapped="no"/> + <signal name="key-press-event" handler="on_entry_accelerator_key_press" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_drop_targets"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Drop targets:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_accelerator</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combo_drop_targets"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">model1</property> + <property name="has_entry">True</property> + <child> + <object class="GtkCellRendererText" id="renderer1"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + <child internal-child="entry"> + <object class="GtkEntry" id="combobox-entry"> + <property name="can_focus">True</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="resize">True</property> + <property name="shrink">True</property> + </packing> + </child> + </object> + </child> + </object> +</interface> diff --git a/plugins/snippets/snippets/substitutionparser.py b/plugins/snippets/snippets/substitutionparser.py new file mode 100644 index 0000000..8469dd3 --- /dev/null +++ b/plugins/snippets/snippets/substitutionparser.py @@ -0,0 +1,203 @@ +# Gedit snippets plugin +# Copyright (C) 2006-2007 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import re + +class ParseError(Exception): + def __str__(self): + return 'Parse error, resume next' + +class Modifiers: + def _first_char(s): + first = (s != '' and s[0]) or '' + rest = (len(s) > 1 and s[1:]) or '' + + return first, rest + + def upper_first(s): + first, rest = Modifiers._first_char(s) + + return '%s%s' % (first.upper(), rest) + + def upper(s): + return s.upper() + + def lower_first(s): + first, rest = Modifiers._first_char(s) + + return '%s%s' % (first.lower(), rest) + + def lower(s): + return s.lower() + + def title(s): + return s.title() + + upper_first = staticmethod(upper_first) + upper = staticmethod(upper) + lower_first = staticmethod(lower_first) + lower = staticmethod(lower) + title = staticmethod(title) + _first_char = staticmethod(_first_char) + +class SubstitutionParser: + REG_ID = '[0-9]+' + REG_NAME = '[a-zA-Z_]+' + REG_MOD = '[a-zA-Z]+' + REG_ESCAPE = '\\\\|\\(\\?|,|\\)' + + REG_GROUP = '(?:(%s)|<(%s|%s)(?:,(%s))?>)' % (REG_ID, REG_ID, REG_NAME, REG_MOD) + + def __init__(self, pattern, groups = {}, modifiers = {}): + self.pattern = pattern + self.groups = groups + + self.modifiers = {'u': Modifiers.upper_first, + 'U': Modifiers.upper, + 'l': Modifiers.lower_first, + 'L': Modifiers.lower, + 't': Modifiers.title} + + for k, v in modifiers.items(): + self.modifiers[k] = v + + def parse(self): + result, tokens = self._parse(self.pattern, None) + + return result + + def _parse(self, tokens, terminator): + result = '' + + while tokens != '': + if self._peek(tokens) == '' or self._peek(tokens) == terminator: + tokens = self._remains(tokens) + break + + try: + res, tokens = self._expr(tokens, terminator) + except ParseError: + res, tokens = self._text(tokens) + + result += res + + return result, tokens + + def _peek(self, tokens, num = 0): + return (num < len(tokens) and tokens[num]) + + def _token(self, tokens): + if tokens == '': + return '', ''; + + return tokens[0], (len(tokens) > 1 and tokens[1:]) or '' + + def _remains(self, tokens, num = 1): + return (num < len(tokens) and tokens[num:]) or '' + + def _expr(self, tokens, terminator): + if tokens == '': + return '' + + try: + return {'\\': self._escape, + '(': self._condition}[self._peek(tokens)](tokens, terminator) + except KeyError: + raise ParseError + + def _text(self, tokens): + return self._token(tokens) + + def _substitute(self, group, modifiers = ''): + result = (self.groups.has_key(group) and self.groups[group]) or '' + + for modifier in modifiers: + if self.modifiers.has_key(modifier): + result = self.modifiers[modifier](result) + + return result + + def _match_group(self, tokens): + match = re.match('\\\\%s' % self.REG_GROUP, tokens) + + if not match: + return None, tokens + + return self._substitute(match.group(1) or match.group(2), match.group(3) or ''), tokens[match.end():] + + def _escape(self, tokens, terminator): + # Try to match a group + result, tokens = self._match_group(tokens) + + if result != None: + return result, tokens + + s = self.REG_GROUP + + if terminator: + s += '|%s' % re.escape(terminator) + + match = re.match('\\\\(\\\\%s|%s)' % (s, self.REG_ESCAPE), tokens) + + if not match: + raise ParseError + + return match.group(1), tokens[match.end():] + + def _condition_value(self, tokens): + match = re.match('\\\\?%s\s*' % self.REG_GROUP, tokens) + + if not match: + return None, tokens + + groups = match.groups() + name = groups[0] or groups[1] + + return self.groups.has_key(name) and self.groups[name] != None, tokens[match.end():] + + def _condition(self, tokens, terminator): + # Match ? after ( + if self._peek(tokens, 1) != '?': + raise ParseError + + # Remove initial (? token + tokens = self._remains(tokens, 2) + condition, tokens = self._condition_value(tokens) + + if condition is None or self._peek(tokens) != ',': + raise ParseError + + truepart, tokens = self._parse(self._remains(tokens), ',') + + if truepart is None: + raise ParseError + + falsepart, tokens = self._parse(tokens, ')') + + if falsepart is None: + raise ParseError + + if condition: + return truepart, tokens + else: + return falsepart, tokens + + @staticmethod + def escape_substitution(substitution): + return re.sub('(%s|%s)' % (SubstitutionParser.REG_GROUP, SubstitutionParser.REG_ESCAPE), '\\\\\\1', substitution) + +# ex:ts=4:et: diff --git a/plugins/snippets/snippets/windowactivatable.py b/plugins/snippets/snippets/windowactivatable.py new file mode 100644 index 0000000..6729a69 --- /dev/null +++ b/plugins/snippets/snippets/windowactivatable.py @@ -0,0 +1,186 @@ +# Gedit snippets plugin +# Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +from gi.repository import Gtk, Gedit, GObject +from .snippet import Snippet +from .library import Library +from .shareddata import SharedData +from .signals import Signals + + +class Message(Gedit.Message): + view = GObject.Property(type=Gedit.View) + iter = GObject.Property(type=Gtk.TextIter) + +class Activate(Message): + trigger = GObject.Property(type=str) + +class ParseAndActivate(Message): + snippet = GObject.Property(type=str) + +class WindowActivatable(GObject.Object, Gedit.WindowActivatable, Signals): + __gtype_name__ = "GeditSnippetsWindowActivatable" + + window = GObject.Property(type=Gedit.Window) + + def __init__(self): + GObject.Object.__init__(self) + Signals.__init__(self) + + self.current_language_accel_group = None + + def do_activate(self): + self.register_messages() + + library = Library() + library.add_accelerator_callback(self.accelerator_activated) + + self.accel_group = Library().get_accel_group(None) + + if self.accel_group: + self.window.add_accel_group(self.accel_group) + + self.connect_signal(self.window, + 'active-tab-changed', + self.on_active_tab_changed) + + self.do_update_state() + + SharedData().register_window(self) + + def do_deactivate(self): + if self.accel_group: + self.window.remove_accel_group(self.accel_group) + + self.accel_group = None + + self.unregister_messages() + + library = Library() + library.remove_accelerator_callback(self.accelerator_activated) + + self.disconnect_signals(self.window) + + SharedData().unregister_window(self) + + def do_update_state(self): + controller = SharedData().get_active_controller(self.window) + + self.update_language(controller) + + def register_messages(self): + bus = self.window.get_message_bus() + + bus.register(Activate, '/plugins/snippets', 'activate') + bus.register(ParseAndActivate, '/plugins/snippets', 'parse-and-activate') + + self.signal_ids = set() + + sid = bus.connect('/plugins/snippets', 'activate', self.on_message_activate, None) + self.signal_ids.add(sid) + + sid = bus.connect('/plugins/snippets', 'parse-and-activate', self.on_message_parse_and_activate, None) + self.signal_ids.add(sid) + + def unregister_messages(self): + bus = self.window.get_message_bus() + for sid in self.signal_ids: + bus.disconnect(sid) + self.signal_ids = set() + bus.unregister_all('/plugins/snippets') + + def on_message_activate(self, bus, message, userdata): + view = message.props.view + + if not view: + view = self.window.get_active_view() + + controller = SharedData().get_controller(view) + + if not controller: + return + + iter = message.props.iter + + if not iter: + iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert()) + + controller.run_snippet_trigger(message.props.trigger, (iter, iter)) + + def on_message_parse_and_activate(self, bus, message, userdata): + view = message.props.view + + if not view: + view = self.window.get_active_view() + + controller = SharedData().get_controller(view) + + if not controller: + return + + iter = message.props.iter + + if not iter: + iter = view.get_buffer().get_iter_at_mark(view.get_buffer().get_insert()) + + controller.parse_and_run_snippet(message.props.snippet, iter) + + def find_snippet(self, snippets, tag): + result = [] + + for snippet in snippets: + if Snippet(snippet)['tag'] == tag: + result.append(snippet) + + return result + + def update_language(self, controller): + if not self.window: + return + + if controller: + langid = controller.language_id + else: + langid = None + + if langid != None: + accelgroup = Library().get_accel_group(langid) + else: + accelgroup = None + + if accelgroup != self.current_language_accel_group: + if self.current_language_accel_group: + self.window.remove_accel_group(self.current_language_accel_group) + + if accelgroup: + self.window.add_accel_group(accelgroup) + + self.current_language_accel_group = accelgroup + + def on_active_tab_changed(self, window, tab): + self.update_language(SharedData().get_controller(tab.get_view())) + + def accelerator_activated(self, group, obj, keyval, mod): + if obj == self.window: + controller = SharedData().get_active_controller(self.window) + + if controller: + return controller.accelerator_activate(keyval, mod) + else: + return False + +# ex:ts=4:et: |