Use GtkSourceView and implement simple syntax highlighting
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 7 Aug 2010 13:01:17 +0000 (15:01 +0200)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 11 Aug 2010 17:25:53 +0000 (10:25 -0700)
configure.ac
src/ui/gui/automake.mk
src/ui/gui/pspp.lang [new file with mode: 0644]
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-syntax-window.h
src/ui/gui/syntax-editor.ui

index e30f93c064ed626d58ce1094fd25290df2f54b44..14e3f9047aaef40aa8e551a67bff9e80c8f64518 100644 (file)
@@ -76,6 +76,8 @@ if test "$with_cairo" != no && test "$with_gui" != "no"; then
   PKG_CHECK_MODULES([GTK], [gtk+-2.0 >= 2.16], [],
     [PSPP_REQUIRED_PREREQ([gtk+ 2.0 version 2.16 or later (or use --without-gui)])])
 
+  PKG_CHECK_MODULES([GTKSOURCEVIEW], [gtksourceview-2.0 >= 2.2])
+
   AC_ARG_VAR([GLIB_GENMARSHAL])
   AC_CHECK_PROGS([GLIB_GENMARSHAL], [glib-genmarshal])
   if test "x$GLIB_GENMARSHAL" = x; then
index 5731ae533bd48fda9ed6ce355d44d4c94e503af3..f78a7205966c5188f8b6a72cd976d24d8830e109 100644 (file)
@@ -41,7 +41,7 @@ EXTRA_DIST += \
 if HAVE_GUI
 bin_PROGRAMS += src/ui/gui/psppire 
 
-src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
+src_ui_gui_psppire_CFLAGS = $(GTK_CFLAGS) $(GTKSOURCEVIEW_CFLAGS) -Wall -DGDK_MULTIHEAD_SAFE=1
 
 
 src_ui_gui_psppire_LDFLAGS = \
@@ -63,6 +63,7 @@ src_ui_gui_psppire_LDADD = \
        src/libpspp.la \
        src/libpspp-core.la \
        $(GTK_LIBS) \
+       $(GTKSOURCEVIEW_LIBS) \
        $(CAIRO_LIBS) \
        $(LIBINTL)
 
@@ -73,6 +74,9 @@ themedir = $(DESTDIR)$(datadir)/icons/hicolor
 context = apps
 
 
+install-lang:
+       $(INSTALL) $(top_srcdir)/src/ui/gui/pspp.lang $(pkgdatadir)
+       
 install-icons:
        for size in 16x16 ; do \
          $(MKDIR_P) $(themedir)/$$size/$(context) ; \
@@ -80,7 +84,7 @@ install-icons:
        done 
        gtk-update-icon-cache --ignore-theme-index $(themedir)
 
-INSTALL_DATA_HOOKS += install-icons
+INSTALL_DATA_HOOKS += install-icons install-lang
 
 uninstall-icons:
        for size in 16x16 ; do \
@@ -92,6 +96,7 @@ UNINSTALL_DATA_HOOKS += uninstall-icons
 
 dist_src_ui_gui_psppire_DATA = \
        $(UI_FILES) \
+       $(top_srcdir)/src/ui/gui/pspp.lang \
        $(top_srcdir)/src/ui/gui/pspplogo.png \
        $(top_srcdir)/src/ui/gui/icons/value-labels.png \
        $(top_srcdir)/src/ui/gui/icons/goto-variable.png\
diff --git a/src/ui/gui/pspp.lang b/src/ui/gui/pspp.lang
new file mode 100644 (file)
index 0000000..199586e
--- /dev/null
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   PSPP - a program for statistical analysis.
+   Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+
+
+<language id="pspp" _name="PSPP" version="2.0" _section="Sources">
+
+  <styles>
+    <style id="string" _name="String" map-to="def:string"/>
+    <style id="escaped-character" _name="Escaped Character" map-to="def:special-char"/>
+    <style id="data-block" _name="Data Block" map-to="def:preprocessor"/>
+    <style id="included-file" _name="Included File" map-to="def:string"/>
+    <style id="char" _name="Character" map-to="def:character"/>
+    <style id="keyword" _name="Keyword" map-to="def:keyword"/>
+    <style id="type" _name="Data Type" map-to="def:type"/>
+    <style id="comment" _name="Comment" map-to="def:comment"/>
+  </styles>
+
+  <default-regex-options case-sensitive="false" />
+
+  <definitions>
+
+    <context id="pspp">
+
+      <include>
+
+        <context id="comment-star" style-ref="comment">
+          <start>^[\t ]*\*</start>
+          <end>^[\t ]*$|^(?=[^\t ])</end>
+        </context>
+
+        <context id="comment-keyword" style-ref="comment">
+          <start>^[\t ]*COMMENT</start>
+          <end>\.[\t ]*$|^[\t ]*$|^(?=[^\t ])</end>
+        </context>
+
+        <context id="data-block" style-ref="data-block">
+          <start>(?&lt;=(^BEGIN DATA$))</start>
+          <end>(?=(^END DATA\.?))</end>
+       </context>
+
+        <context id="string-double" end-at-line-end="true"
+                 style-ref="string">
+          <start>"</start>
+          <end>"</end>
+        </context>
+
+        <context id="string-single" end-at-line-end="true"
+                 style-ref="string">
+          <start>'</start>
+          <end>'</end>
+        </context>
+
+       <context id="keywords" style-ref="keyword">
+          <keyword>ALL</keyword>
+          <keyword>AND</keyword>
+          <keyword>BY</keyword>
+          <keyword>EQ</keyword>
+          <keyword>GE</keyword>
+          <keyword>GT</keyword>
+          <keyword>LE</keyword>
+          <keyword>LT</keyword>
+          <keyword>NE</keyword>
+          <keyword>NOT</keyword>
+          <keyword>OR</keyword>
+          <keyword>TO</keyword>
+          <keyword>WITH</keyword>
+        </context>
+
+      </include>
+    </context>
+  </definitions>
+
+
+</language>
index de12be49f21d7d96d6a1e9145d599f84bd1ef2bf..eb35ae5216f1c14396019e8289afecc667850fce 100644 (file)
 #include "executor.h"
 #include "helper.h"
 
+#include <gtksourceview/gtksourcebuffer.h>
+#include <gtksourceview/gtksourcelanguage.h>
+#include <gtksourceview/gtksourcelanguagemanager.h>
+
 #include <libpspp/message.h>
 #include <stdlib.h>
 
@@ -102,6 +106,26 @@ psppire_syntax_window_finalize (GObject *object)
 static void
 psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class)
 {
+  GtkSourceLanguageManager *lm = gtk_source_language_manager_get_default ();
+
+  const gchar * const *existing_paths =  gtk_source_language_manager_get_search_path (lm);
+
+  const gchar **new_paths = g_strdupv (existing_paths);
+
+  int n = g_strv_length (existing_paths);
+
+  new_paths = g_realloc (new_paths, (n+1) * sizeof (*new_paths));
+  new_paths[n] = g_strdup (PKGDATADIR);
+  new_paths[n+1] = NULL;
+
+  lm = gtk_source_language_manager_new ();
+  gtk_source_language_manager_set_search_path (lm, new_paths);
+
+  class->lan = gtk_source_language_manager_get_language (lm, "pspp");
+
+  if (class->lan == NULL)
+    g_warning ("pspp.lang file not found.  Syntax highlighting will not be available.");
+
   parent_class = g_type_class_peek_parent (class);
 }
 
@@ -110,7 +134,6 @@ static void
 psppire_syntax_window_base_init (PsppireSyntaxWindowClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
-
   object_class->finalize = psppire_syntax_window_finalize;
 }
 
@@ -395,9 +418,25 @@ psppire_syntax_window_init (PsppireSyntaxWindow *window)
   GtkWidget *menubar = get_widget_assert (xml, "menubar");
   GtkWidget *sw = get_widget_assert (xml, "scrolledwindow8");
 
-
   GtkWidget *text_view = get_widget_assert (xml, "syntax_text_view");
-  window->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+
+  PsppireSyntaxWindowClass *class
+    = PSPPIRE_SYNTAX_WINDOW_CLASS (G_OBJECT_GET_CLASS (window));
+
+  if (class->lan)
+    window->buffer = GTK_TEXT_BUFFER (gtk_source_buffer_new_with_language (class->lan));
+  else
+    window->buffer = GTK_TEXT_BUFFER (gtk_source_buffer_new (NULL));
+
+  gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), window->buffer);
+
+  g_object_set (text_view,
+               "show-line-numbers", TRUE,
+               "show-line-marks", TRUE,
+               "auto-indent", TRUE,
+               "indent-width", 4,
+               "highlight-current-line", TRUE,
+               NULL);
   window->lexer = lex_create (the_source_stream);
 
   window->sb = get_widget_assert (xml, "statusbar2");
index 3816a1319f8d6d57b0ee11fcc03823b0bbcf4860..cf6e0629f33ea0b82f1a32b18680afa9ccb359f5 100644 (file)
 #include "psppire-window.h"
 #include <gtk/gtk.h>
 
+#include <gtksourceview/gtksourcelanguage.h>
+#include <gtksourceview/gtksourcelanguagemanager.h>
+
 G_BEGIN_DECLS
 
 #define PSPPIRE_SYNTAX_WINDOW_TYPE            (psppire_syntax_window_get_type ())
 #define PSPPIRE_SYNTAX_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntaxWindow))
 #define PSPPIRE_SYNTAX_WINDOW_CLASS(class)    (G_TYPE_CHECK_CLASS_CAST ((class), \
-    PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntax_WindowClass))
+    PSPPIRE_SYNTAX_WINDOW_TYPE, PsppireSyntaxWindowClass))
 #define PSPPIRE_IS_SYNTAX_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
     PSPPIRE_SYNTAX_WINDOW_TYPE))
 #define PSPPIRE_IS_SYNTAX_WINDOW_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
@@ -57,6 +60,8 @@ struct _PsppireSyntaxWindowClass
 {
   PsppireWindowClass parent_class;
 
+
+  GtkSourceLanguage *lan ;
 };
 
 GType      psppire_syntax_window_get_type        (void);
index 5666b4995a1fdf745ac200db4edb4d2f4436a8a8..4e388f02befb9f878ea2504c38625683ed121adc 100644 (file)
     <property name="shadow_type">GTK_SHADOW_IN</property>
     <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
     <child>
-      <object class="GtkTextView" id="syntax_text_view">
+      <object class="GtkSourceView" id="syntax_text_view">
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="editable">True</property>