[gtksourceview/wip/chergert/snippets] wip on snippet parsing
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/snippets] wip on snippet parsing
- Date: Tue, 28 Jan 2020 18:50:10 +0000 (UTC)
commit d6285fc633411a48183b3798be88a942009e920b
Author: Christian Hergert <chergert redhat com>
Date: Tue Jan 28 10:49:47 2020 -0800
wip on snippet parsing
data/meson.build | 11 +-
data/snippets/licenses.snippets | 342 ++++++++++++++++++++++++++++++++
gtksourceview/gtksourcesnippetbundle.c | 311 ++++++++++++++++++++++++++++-
gtksourceview/gtksourcesnippetmanager.c | 1 +
gtksourceview/gtksourcesnippetmanager.h | 2 +-
tests/meson.build | 8 +-
tests/test-snippets.c | 47 +++++
7 files changed, 714 insertions(+), 8 deletions(-)
---
diff --git a/data/meson.build b/data/meson.build
index 45387d48..98d5e739 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -1,7 +1,6 @@
install_subdir('language-specs',
install_dir: pkgdatadir,
- exclude_files: [ 'Makefile.am',
- 'check-language.sh',
+ exclude_files: [ 'check-language.sh',
'lang_v1_to_v2.xslt',
'language-specs.its',
'language-specs.pot',
@@ -10,10 +9,14 @@ install_subdir('language-specs',
'update-pot.sh' ]
)
+install_subdir('snippets',
+ install_dir: pkgdatadir,
+ exclude_files: [ ],
+)
+
install_subdir('styles',
install_dir: pkgdatadir,
- exclude_files: [ 'Makefile.am',
- 'check-style.sh',
+ exclude_files: [ 'check-style.sh',
'styles.its',
'styles.pot',
'testdark.xml',
diff --git a/data/snippets/licenses.snippets b/data/snippets/licenses.snippets
new file mode 100644
index 00000000..57c8bb78
--- /dev/null
+++ b/data/snippets/licenses.snippets
@@ -0,0 +1,342 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ This file is part of GtkSourceView
+
+ Copyright (C) 2020 Christian Hergert <chergert redhat com>
+
+ GtkSourceView 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.
+
+ GtkSourceView 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 this library; if not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: LGPL-2.1-or-later
+
+-->
+<snippets _group="Licenses">
+ <snippet _name="GPLv3 or later" trigger="gpl3" _description="File header with GPLv3+ license">
+ <text languages="python;python3;"><![CDATA[# ${1:$TM_FILENAME}
+#
+# Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+$0]]></text>
+ <text languages="c;chdr;cpp;cpphdr;css;js;java;"><![CDATA[/*
+ * ${1:$TM_FILENAME}
+ *
+ * Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+$0]]></text>
+ <text languages="c-sharp;rust;"><![CDATA[// ${1:$TM_FILENAME}
+//
+// Copyright $CURRENT_YEAR ${2:$USER_NAME} <${3:$USER_EMAIL}>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+$0]]></text>
+ </snippet>
+ <snippet _name="LGPLv3 or later" trigger="lgpl3" _description="File header with LGPLv3 or later license">
+ <text languages="python;python3;"><![CDATA[# ${1:$TM_FILENAME}
+#
+# Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+#
+# This file 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 3 of the License, or (at
+# your option) any later version.
+#
+# This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+$0]]></text>
+ <text languages="c;chdr;cpp;cpphdr;css;js;java;"><![CDATA[/*
+ * ${1:$TM_FILENAME}
+ *
+ * Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+ *
+ * This file 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 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-3.0-or-later
+ */
+$0]]></text>
+ <text languages="c-sharp;rust;"><![CDATA[// ${1:$TM_FILENAME}
+//
+// Copyright $CURRENT_YEAR ${2:$USER_NAME} <${3:$USER_EMAIL}>
+//
+// This file 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 3 of the License, or (at
+// your option) any later version.
+//
+// This file 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 this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+$0]]></text>
+ </snippet>
+ <snippet _name="LGPLv2.1 or later" trigger="lgpl2" _description="File header with LGPL 2.1 or later
license">
+ <text languages="python;python3;"><![CDATA[# ${1:$TM_FILENAME}
+#
+# Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+#
+# This program 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.
+#
+# 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, see <http://www.gnu.org/licenses/>.
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+$0]]></text>
+ <text languages="c;chdr;cpp;cpphdr;css;js;java;"><![CDATA[/*
+ * ${1:$TM_FILENAME}
+ *
+ * Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+ *
+ * This program 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.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+$0]]></text>
+ <text languages="c-sharp;rust;"><![CDATA[// ${1:$TM_FILENAME}
+//
+// Copyright $CURRENT_YEAR ${2:$USER_NAME} <${3:$USER_EMAIL}>
+//
+// This program 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.
+//
+// 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+$0]]></text>
+ </snippet>
+ <snippet _name="Apache 2.0" trigger="apache2" _description="File header with Apache 2.0 license">
+ <text languages="python;python3;"><![CDATA[# ${1:$TM_FILENAME}
+#
+# Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+$0]]></text>
+ <text languages="c;chdr;cpp;cpphdr;css;js;java;"><![CDATA[/*
+ * ${1:$TM_FILENAME}
+ *
+ * Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+$0]]></text>
+ <text languages="c-sharp;rust;"><![CDATA[// ${1:$TM_FILENAME}
+//
+// Copyright $CURRENT_YEAR ${2:$USER_NAME} <${3:$USER_EMAIL}>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// SPDX-License-Identifier: Apache-2.0
+$0]]></text>
+ </snippet>
+ <snippet _name="MIT" trigger="mit" _description="File header with MIT license">
+ <text languages="python;python3;"><![CDATA[# ${1:$TM_FILENAME}
+#
+# Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# SPDX-License-Identifier: MIT
+$0]]></text>
+ <text languages="c;chdr;cpp;cpphdr;css;js;java;"><![CDATA[/*
+ * ${1:$TM_FILENAME}
+ *
+ * Copyright $CURRENT_YEAR ${2:$FULLNAME} <${3:$EMAIL}>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+$0]]></text>
+ <text languages="c-sharp;rust;"><![CDATA[// ${1:$TM_FILENAME}
+//
+// Copyright $CURRENT_YEAR ${2:$USER_NAME} <${3:$USER_EMAIL}>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// SPDX-License-Identifier: MIT
+$0]]></text>
+ </snippet>
+</snippets>
diff --git a/gtksourceview/gtksourcesnippetbundle.c b/gtksourceview/gtksourcesnippetbundle.c
index 24f875cb..408f369a 100644
--- a/gtksourceview/gtksourcesnippetbundle.c
+++ b/gtksourceview/gtksourcesnippetbundle.c
@@ -20,17 +20,37 @@
#include "config.h"
#include "gtksourcesnippetbundle-private.h"
+#include "gtksourcesnippetmanager.h"
struct _GtkSourceSnippetBundle
{
- GObject parent_instance;
+ GObject parent_instance;
};
+typedef struct
+{
+ GtkSourceSnippetBundle *self;
+ gchar *group;
+ gchar *name;
+ gchar *description;
+ gchar *trigger;
+ gchar **languages;
+} ParseState;
+
G_DEFINE_TYPE (GtkSourceSnippetBundle, _gtk_source_snippet_bundle, G_TYPE_OBJECT)
+static void
+gtk_source_snippet_bundle_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (_gtk_source_snippet_bundle_parent_class)->finalize (object);
+}
+
static void
_gtk_source_snippet_bundle_class_init (GtkSourceSnippetBundleClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gtk_source_snippet_bundle_finalize;
}
static void
@@ -38,9 +58,296 @@ _gtk_source_snippet_bundle_init (GtkSourceSnippetBundle *self)
{
}
+static void
+text_and_cdata (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+ gchar *copy;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+
+ copy = g_strndup (text, text_len);
+ g_print ("%s", copy);
+ g_free (copy);
+}
+
+static const GMarkupParser text_parser = {
+ .text = text_and_cdata,
+};
+
+static void
+elements_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+ g_assert (element_name != NULL);
+
+ if (g_strcmp0 (element_name, "text") == 0)
+ {
+ const gchar *languages = NULL;
+
+ if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL,
"languages", &languages,
+ G_MARKUP_COLLECT_INVALID))
+ return;
+
+ if (languages != NULL && languages[0] != 0)
+ {
+ gchar **strv = g_strsplit (languages, ";", 0);
+
+ g_strfreev (state->languages);
+ state->languages = g_steal_pointer (&strv);
+ }
+
+ g_markup_parse_context_push (context, &text_parser, state);
+ }
+ else
+ {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ "Element %s not supported",
+ element_name);
+ }
+}
+
+static void
+elements_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+ g_assert (element_name != NULL);
+
+ g_clear_pointer (&state->languages, g_strfreev);
+
+ g_markup_parse_context_pop (context);
+}
+
+static const GMarkupParser elements_parser = {
+ .start_element = elements_start_element,
+ .end_element = elements_end_element,
+};
+
+static void
+snippet_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+ const gchar *_name = NULL;
+ const gchar *_description = NULL;
+ const gchar *trigger = NULL;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+ g_assert (element_name != NULL);
+
+ if (g_strcmp0 (element_name, "snippet") != 0)
+ {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ "Element %s not supported",
+ element_name);
+ return;
+ }
+
+ if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
+ G_MARKUP_COLLECT_STRING, "trigger", &trigger,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "_name",
&_name,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL,
"_description", &_description,
+ G_MARKUP_COLLECT_INVALID))
+ return;
+
+ if (_name != NULL)
+ {
+ const gchar *name = g_dgettext (GETTEXT_PACKAGE, _name);
+
+ if (g_strcmp0 (state->name, name) != 0)
+ {
+ g_free (state->name);
+ state->name = g_strdup (name);
+ }
+ }
+
+ if (_description != NULL)
+ {
+ const gchar *description = g_dgettext (GETTEXT_PACKAGE, _description);
+
+ if (g_strcmp0 (state->description, description) != 0)
+ {
+ g_free (state->description);
+ state->description = g_strdup (description);
+ }
+ }
+
+ if (g_strcmp0 (state->trigger, trigger) != 0)
+ {
+ g_free (state->trigger);
+ state->trigger = g_strdup (trigger);
+ }
+
+ g_markup_parse_context_push (context, &elements_parser, state);
+}
+
+static void
+snippet_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+ g_assert (element_name != NULL);
+
+ g_clear_pointer (&state->trigger, g_free);
+ g_clear_pointer (&state->name, g_free);
+
+ g_markup_parse_context_pop (context);
+}
+
+static const GMarkupParser snippet_parser = {
+ .start_element = snippet_start_element,
+ .end_element = snippet_end_element,
+};
+
+static void
+snippets_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+ const gchar *_group = NULL;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+ g_assert (element_name != NULL);
+
+ if (g_strcmp0 (element_name, "snippets") != 0)
+ {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ "Element %s not supported",
+ element_name);
+ return;
+ }
+
+ if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
+ G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL, "_group",
&_group,
+ G_MARKUP_COLLECT_INVALID))
+ return;
+
+ if (_group != NULL)
+ {
+ g_free (state->group);
+ state->group = g_strdup (g_dgettext (GETTEXT_PACKAGE, _group));
+ }
+
+ g_markup_parse_context_push (context, &snippet_parser, state);
+}
+
+static void
+snippets_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParseState *state = user_data;
+
+ g_assert (state != NULL);
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (state->self));
+ g_assert (element_name != NULL);
+
+ g_clear_pointer (&state->group, g_free);
+
+ g_markup_parse_context_pop (context);
+}
+
+static const GMarkupParser snippets_parser = {
+ .start_element = snippets_start_element,
+ .end_element = snippets_end_element,
+};
+
+static gboolean
+gtk_source_snippet_bundle_parse (GtkSourceSnippetBundle *self,
+ const gchar *path)
+{
+ gchar *contents = NULL;
+ gsize length = 0;
+ gboolean ret = FALSE;
+
+ g_assert (GTK_SOURCE_IS_SNIPPET_BUNDLE (self));
+ g_assert (path != NULL);
+
+ if (g_file_get_contents (path, &contents, &length, NULL))
+ {
+ GMarkupParseContext *context;
+ ParseState state = { .self = self };
+
+ context = g_markup_parse_context_new (&snippets_parser,
+ (G_MARKUP_TREAT_CDATA_AS_TEXT |
+ G_MARKUP_PREFIX_ERROR_POSITION),
+ &state, NULL);
+
+ ret = g_markup_parse_context_parse (context, contents, length, NULL);
+
+ g_clear_pointer (&state.description, g_free);
+ g_clear_pointer (&state.languages, g_strfreev);
+ g_clear_pointer (&state.name, g_free);
+ g_clear_pointer (&state.trigger, g_free);
+ g_clear_pointer (&state.group, g_free);
+
+ g_markup_parse_context_free (context);
+ g_free (contents);
+ }
+
+ return ret;
+}
+
GtkSourceSnippetBundle *
_gtk_source_snippet_bundle_new_from_file (const gchar *path,
GtkSourceSnippetManager *manager)
{
- return NULL;
+ GtkSourceSnippetBundle *self;
+
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (GTK_SOURCE_IS_SNIPPET_MANAGER (manager), NULL);
+
+ self = g_object_new (GTK_SOURCE_TYPE_SNIPPET_BUNDLE, NULL);
+
+ if (gtk_source_snippet_bundle_parse (self, path))
+ {
+ return g_steal_pointer (&self);
+ }
+ else
+ {
+ g_object_unref (self);
+ return NULL;
+ }
}
diff --git a/gtksourceview/gtksourcesnippetmanager.c b/gtksourceview/gtksourcesnippetmanager.c
index 5e695d51..b1e5c7d3 100644
--- a/gtksourceview/gtksourcesnippetmanager.c
+++ b/gtksourceview/gtksourcesnippetmanager.c
@@ -146,6 +146,7 @@ gtk_source_snippet_manager_class_init (GtkSourceSnippetManagerClass *klass)
static void
gtk_source_snippet_manager_init (GtkSourceSnippetManager *self)
{
+ self->bundles = g_ptr_array_new_with_free_func (g_object_unref);
}
/**
diff --git a/gtksourceview/gtksourcesnippetmanager.h b/gtksourceview/gtksourcesnippetmanager.h
index 9d922a36..ee9b4a95 100644
--- a/gtksourceview/gtksourcesnippetmanager.h
+++ b/gtksourceview/gtksourcesnippetmanager.h
@@ -23,7 +23,7 @@
#error "Only <gtksourceview/gtksource.h> can be included directly."
#endif
-#include <glib-object.h>
+#include <gio/gio.h>
#include "gtksourcetypes.h"
diff --git a/tests/meson.build b/tests/meson.build
index a33e8228..4dddf302 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -8,6 +8,7 @@ tests_sources = {
'int2str': ['test-int2str.c'],
'search': ['test-search.c'],
'search-performances': ['test-search-performances.c'],
+ 'snippets': ['test-snippets.c'],
'space-drawing': ['test-space-drawing.c'],
'widget': ['test-widget.c'],
}
@@ -18,6 +19,11 @@ tests_resources = {
'widget': 'test-widget.gresource.xml',
}
+tests_deps = [gtksource_dep]
+if cc.get_id() == 'msvc'
+ tests_deps += [core_dep]
+endif
+
foreach test_name, test_sources: tests_sources
if tests_resources.has_key(test_name)
test_sources += gnome.compile_resources(
@@ -30,6 +36,6 @@ foreach test_name, test_sources: tests_sources
# well as the static core lib
executable('test-@0@'.format(test_name), test_sources,
c_args: tests_c_args,
- dependencies: cc.get_id() == 'msvc' ? [gtksource_dep, core_dep] : [gtksource_dep],
+ dependencies: tests_deps,
)
endforeach
diff --git a/tests/test-snippets.c b/tests/test-snippets.c
new file mode 100644
index 00000000..2d1e26be
--- /dev/null
+++ b/tests/test-snippets.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * GtkSourceView 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.
+ *
+ * GtkSourceView 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 this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gtksourceview/gtksource.h>
+#include <gtksourceview/gtksourceinit.h>
+
+gint
+main (gint argc,
+ gchar *argv[])
+{
+ GtkSourceSnippetManager *mgr;
+ GListModel *model;
+ static const gchar *search_path[] = {
+ TOP_SRCDIR"/data/snippets",
+ NULL
+ };
+
+ gtk_source_init ();
+
+ mgr = gtk_source_snippet_manager_get_default ();
+ gtk_source_snippet_manager_set_search_path (mgr, search_path);
+
+ model = gtk_source_snippet_manager_get_snippets (mgr, "c");
+ g_clear_object (&model);
+
+ gtk_source_finalize ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]