aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--cmdline.cpp27
-rw-r--r--interface-gtk.cpp196
-rw-r--r--interface-gtk.h60
-rw-r--r--interface.h54
-rw-r--r--main.cpp187
-rw-r--r--parser.cpp114
-rw-r--r--parser.h3
-rw-r--r--qbuffers.cpp90
-rw-r--r--sciteco.h21
-rw-r--r--undo.cpp3
11 files changed, 452 insertions, 307 deletions
diff --git a/Makefile b/Makefile
index 7742afd..97be838 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ GTK_LDFLAGS:=$(shell pkg-config --libs gtk+-2.0)
SCI_CFLAGS:=-I../scintilla/include -DGTK -DSCI_LEXER
SCI_LDFLAGS:=../scintilla/bin/scintilla.a
-CPPFLAGS:=
+CPPFLAGS:=-DINTERFACE_GTK
CFLAGS:=-Wall -std=c99 -g -O0 $(GTK_CFLAGS) $(SCI_CFLAGS)
CXXFLAGS:=-Wall -g -O0 $(GTK_CFLAGS) $(SCI_CFLAGS)
LDFLAGS:=$(GTK_LDFLAGS) $(SCI_LDFLAGS)
@@ -15,7 +15,7 @@ all : sciteco
sciteco : main.o cmdline.o undo.o expressions.o qbuffers.o \
parser.o goto.o rbtree.o \
- gtk-info-popup.o
+ interface-gtk.o gtk-info-popup.o
$(CXX) -o $@ $^ $(LDFLAGS)
main.o : gtk-info-popup.h
diff --git a/cmdline.cpp b/cmdline.cpp
index db1d1ef..557e056 100644
--- a/cmdline.cpp
+++ b/cmdline.cpp
@@ -6,6 +6,7 @@
#include <glib/gstdio.h>
#include "sciteco.h"
+#include "interface.h"
#include "parser.h"
#include "qbuffers.h"
#include "goto.h"
@@ -33,10 +34,7 @@ cmdline_keypress(gchar key)
/*
* Cleanup messages, popups, etc...
*/
- if (gtk_widget_get_visible(GTK_WIDGET(filename_popup))) {
- gtk_widget_hide(GTK_WIDGET(filename_popup));
- gtk_info_popup_clear(filename_popup);
- }
+ interface.popup_clear();
/*
* Process immediate editing commands
@@ -68,7 +66,7 @@ cmdline_keypress(gchar key)
* Echo command line
*/
echo = macro_echo(cmdline, "*");
- cmdline_display(echo);
+ interface.cmdline_update(echo);
g_free(echo);
}
@@ -231,23 +229,22 @@ filename_complete(const gchar *filename, gchar completed)
for (GList *file = g_list_first(matching);
file != NULL;
file = g_list_next(file)) {
- GtkInfoPopupFileType type;
- gboolean in_buffer = FALSE;
+ Interface::PopupFileType type;
+ bool in_buffer = false;
if (filename_is_dir((gchar *)file->data)) {
- type = GTK_INFO_POPUP_DIRECTORY;
+ type = Interface::POPUP_DIRECTORY;
} else {
- type = GTK_INFO_POPUP_FILE;
+ type = Interface::POPUP_FILE;
/* FIXME: inefficient */
- in_buffer = ring.find((gchar *)file->data)
- != NULL;
+ in_buffer = ring.find((gchar *)file->data);
}
- gtk_info_popup_add_filename(filename_popup,
- type, (gchar *)file->data,
- in_buffer);
+
+ interface.popup_add_filename(type, (gchar *)file->data,
+ in_buffer);
}
- gtk_widget_show(GTK_WIDGET(filename_popup));
+ interface.popup_show();
} else if (g_list_length(matching) == 1 &&
!filename_is_dir((gchar *)g_list_first(matching)->data)) {
gchar *new_insert;
diff --git a/interface-gtk.cpp b/interface-gtk.cpp
new file mode 100644
index 0000000..55e546e
--- /dev/null
+++ b/interface-gtk.cpp
@@ -0,0 +1,196 @@
+#include <stdarg.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <gtk/gtk.h>
+#include "gtk-info-popup.h"
+
+#include <Scintilla.h>
+#include <ScintillaWidget.h>
+
+#include "sciteco.h"
+#include "interface.h"
+#include "interface-gtk.h"
+
+InterfaceGtk interface;
+
+extern "C" {
+static gboolean cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event,
+ gpointer user_data);
+static gboolean exit_app(GtkWidget *w, GdkEventAny *e, gpointer p);
+}
+
+InterfaceGtk::InterfaceGtk()
+{
+ GtkWidget *window, *vbox;
+ GtkWidget *info_content;
+
+ gtk_init(NULL, NULL);
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window), "SciTECO");
+ g_signal_connect(G_OBJECT(window), "delete-event",
+ G_CALLBACK(exit_app), NULL);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+
+ editor_widget = scintilla_new();
+ scintilla_set_id(SCINTILLA(editor_widget), 0);
+ gtk_widget_set_usize(editor_widget, 500, 300);
+ gtk_widget_set_can_focus(editor_widget, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), editor_widget, TRUE, TRUE, 0);
+
+ info_widget = gtk_info_bar_new();
+ info_content = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_widget));
+ message_widget = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(message_widget), 0., 0.);
+ gtk_container_add(GTK_CONTAINER(info_content), message_widget);
+ gtk_box_pack_start(GTK_BOX(vbox), info_widget, FALSE, FALSE, 0);
+
+ cmdline_widget = gtk_entry_new();
+ gtk_entry_set_has_frame(GTK_ENTRY(cmdline_widget), FALSE);
+ gtk_editable_set_editable(GTK_EDITABLE(cmdline_widget), FALSE);
+ widget_set_font(cmdline_widget, "Courier");
+ g_signal_connect(G_OBJECT(cmdline_widget), "key-press-event",
+ G_CALLBACK(cmdline_key_pressed), NULL);
+ gtk_box_pack_start(GTK_BOX(vbox), cmdline_widget, FALSE, FALSE, 0);
+
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+
+ popup_widget = gtk_info_popup_new(cmdline_widget);
+
+ gtk_widget_grab_focus(cmdline_widget);
+ gtk_widget_show_all(window);
+}
+
+void
+InterfaceGtk::msg(MessageType type, const gchar *fmt, ...)
+{
+ static const GtkMessageType type2gtk[] = {
+ /* [MSG_USER] = */ GTK_MESSAGE_OTHER,
+ /* [MSG_INFO] = */ GTK_MESSAGE_INFO,
+ /* [MSG_WARNING] = */ GTK_MESSAGE_WARNING,
+ /* [MSG_ERROR] = */ GTK_MESSAGE_ERROR
+ };
+
+ va_list ap;
+ gchar buf[255];
+
+ va_start(ap, fmt);
+ g_vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ switch (type) {
+ case MSG_USER:
+ g_printf("%s\n", buf);
+ break;
+ case MSG_INFO:
+ g_printf("Info: %s\n", buf);
+ break;
+ case MSG_WARNING:
+ g_fprintf(stderr, "Warning: %s\n", buf);
+ break;
+ case MSG_ERROR:
+ g_fprintf(stderr, "Error: %s\n", buf);
+ break;
+ }
+
+ gtk_info_bar_set_message_type(GTK_INFO_BAR(info_widget),
+ type2gtk[type]);
+ gtk_label_set_text(GTK_LABEL(message_widget), buf);
+}
+
+void
+InterfaceGtk::cmdline_update(const gchar *cmdline_str)
+{
+ gtk_entry_set_text(GTK_ENTRY(cmdline_widget), cmdline_str);
+ gtk_editable_set_position(GTK_EDITABLE(cmdline_widget), -1);
+}
+
+void
+InterfaceGtk::popup_add_filename(PopupFileType type,
+ const gchar *filename, bool highlight)
+{
+ static const GtkInfoPopupFileType type2gtk[] = {
+ /* [POPUP_FILE] = */ GTK_INFO_POPUP_FILE,
+ /* [POPUP_DIRECTORY] = */ GTK_INFO_POPUP_DIRECTORY
+ };
+
+ gtk_info_popup_add_filename(GTK_INFO_POPUP(popup_widget),
+ type2gtk[type], filename, highlight);
+}
+
+void
+InterfaceGtk::popup_clear(void)
+{
+ if (gtk_widget_get_visible(popup_widget)) {
+ gtk_widget_hide(popup_widget);
+ gtk_info_popup_clear(GTK_INFO_POPUP(popup_widget));
+ }
+}
+
+void
+InterfaceGtk::widget_set_font(GtkWidget *widget, const gchar *font_name)
+{
+ PangoFontDescription *font_desc;
+
+ font_desc = pango_font_description_from_string(font_name);
+ gtk_widget_modify_font(widget, font_desc);
+ pango_font_description_free(font_desc);
+}
+
+/*
+ * GTK+ callbacks
+ */
+
+static gboolean
+cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event,
+ gpointer user_data __attribute__((unused)))
+{
+#ifdef DEBUG
+ g_printf("KEY \"%s\" (%d) SHIFT=%d CNTRL=%d\n",
+ event->string, *event->string,
+ event->state & GDK_SHIFT_MASK, event->state & GDK_CONTROL_MASK);
+#endif
+
+ switch (event->keyval) {
+ case GDK_BackSpace:
+ cmdline_keypress('\b');
+ break;
+ case GDK_Tab:
+ cmdline_keypress('\t');
+ break;
+ case GDK_Return:
+ switch (interface.ssm(SCI_GETEOLMODE)) {
+ case SC_EOL_CR:
+ cmdline_keypress('\r');
+ break;
+ case SC_EOL_CRLF:
+ cmdline_keypress('\r');
+ /* fall through */
+ case SC_EOL_LF:
+ default:
+ cmdline_keypress('\n');
+ }
+ break;
+ default:
+ if (*event->string)
+ cmdline_keypress(*event->string);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+exit_app(GtkWidget *w __attribute__((unused)),
+ GdkEventAny *e __attribute__((unused)),
+ gpointer p __attribute__((unused)))
+{
+ gtk_main_quit();
+ return TRUE;
+}
diff --git a/interface-gtk.h b/interface-gtk.h
new file mode 100644
index 0000000..76868fd
--- /dev/null
+++ b/interface-gtk.h
@@ -0,0 +1,60 @@
+#ifndef __INTERFACE_GTK_H
+#define __INTERFACE_GTK_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <Scintilla.h>
+#include <ScintillaWidget.h>
+
+#include "interface.h"
+
+extern class InterfaceGtk : public Interface {
+ GtkWidget *editor_widget;
+ GtkWidget *cmdline_widget;
+ GtkWidget *info_widget, *message_widget;
+
+ GtkWidget *popup_widget;
+
+public:
+ InterfaceGtk();
+ //~InterfaceGtk();
+
+ inline void
+ parse_args(int &argc, char **&argv)
+ {
+ gtk_parse_args(&argc, &argv);
+ }
+
+ void msg(MessageType type, const gchar *fmt, ...) G_GNUC_PRINTF(3, 4);
+
+ inline sptr_t
+ ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0)
+ {
+ return scintilla_send_message(SCINTILLA(editor_widget),
+ iMessage, wParam, lParam);
+ }
+
+ void cmdline_update(const gchar *cmdline);
+
+ void popup_add_filename(PopupFileType type,
+ const gchar *filename, bool highlight = false);
+ inline void
+ popup_show(void)
+ {
+ gtk_widget_show(popup_widget);
+ }
+ void popup_clear(void);
+
+ /* main entry point */
+ inline void
+ event_loop(void)
+ {
+ gtk_main();
+ }
+
+private:
+ static void widget_set_font(GtkWidget *widget, const gchar *font_name);
+} interface;
+
+#endif
diff --git a/interface.h b/interface.h
new file mode 100644
index 0000000..a67fbfa
--- /dev/null
+++ b/interface.h
@@ -0,0 +1,54 @@
+#ifndef __INTERFACE_H
+#define __INTERFACE_H
+
+#include <glib.h>
+
+#include <Scintilla.h>
+
+/*
+ * Base class for all user interfaces - used mereley as a class interface.
+ * The actual instance of the interface has the platform-specific type
+ * (e.g. InterfaceGtk) since we would like to have the benefits of using
+ * classes but avoid the calling overhead when invoking virtual methods
+ * on Interface pointers.
+ * There's only one Interface* instance in the system.
+ */
+class Interface {
+public:
+ virtual void parse_args(int &argc, char **&argv) {}
+
+ enum MessageType {
+ MSG_USER,
+ MSG_INFO,
+ MSG_WARNING,
+ MSG_ERROR
+ };
+ virtual void msg(MessageType type, const gchar *fmt, ...)
+ G_GNUC_PRINTF(3, 4) = 0;
+
+ virtual sptr_t ssm(unsigned int iMessage,
+ uptr_t wParam = 0, sptr_t lParam = 0) = 0;
+
+ virtual void cmdline_update(const gchar *cmdline) = 0;
+
+ enum PopupFileType {
+ POPUP_FILE,
+ POPUP_DIRECTORY
+ };
+ virtual void popup_add_filename(PopupFileType type,
+ const gchar *filename,
+ bool highlight = false) = 0;
+ virtual void popup_show(void) = 0;
+ virtual void popup_clear(void) = 0;
+
+ /* main entry point */
+ virtual void event_loop(void) = 0;
+};
+
+#ifdef INTERFACE_GTK
+#include "interface-gtk.h"
+#elif defined(INTERFACE_NCURSES)
+#include "interface-ncurses.h"
+#endif
+
+#endif
diff --git a/main.cpp b/main.cpp
index 3c82326..179d896 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,134 +1,22 @@
#include <stdio.h>
#include <string.h>
-#include <stdarg.h>
#include <stdlib.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <gtk/gtk.h>
-#include "gtk-info-popup.h"
-
#include <Scintilla.h>
#include <SciLexer.h>
-#include <ScintillaWidget.h>
#include "sciteco.h"
+#include "interface.h"
#include "parser.h"
#include "qbuffers.h"
#include "undo.h"
-static GtkWidget *editor_widget;
-static GtkWidget *cmdline_widget;
-static GtkWidget *info_widget, *message_widget;
-
-GtkInfoPopup *filename_popup;
-
#define INI_FILE ".teco_ini"
-void
-cmdline_display(const gchar *cmdline_str)
-{
- gtk_entry_set_text(GTK_ENTRY(cmdline_widget), cmdline_str);
- gtk_editable_set_position(GTK_EDITABLE(cmdline_widget), -1);
-}
-
-void
-message_display(GtkMessageType type, const gchar *fmt, ...)
-{
- va_list ap;
- gchar buf[255];
-
- va_start(ap, fmt);
- g_vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
-
- switch (type) {
- case GTK_MESSAGE_ERROR:
- g_fprintf(stderr, "Error: %s\n", buf);
- break;
- case GTK_MESSAGE_WARNING:
- g_fprintf(stderr, "Warning: %s\n", buf);
- break;
- case GTK_MESSAGE_INFO:
- g_printf("Info: %s\n", buf);
- break;
- default:
- g_printf("%s\n", buf);
- }
-
- gtk_info_bar_set_message_type(GTK_INFO_BAR(info_widget), type);
- gtk_label_set_text(GTK_LABEL(message_widget), buf);
-}
-
-sptr_t
-editor_msg(unsigned int iMessage, uptr_t wParam, sptr_t lParam)
-{
- return scintilla_send_message(SCINTILLA(editor_widget),
- iMessage, wParam, lParam);
-}
-
-static gboolean
-cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event,
- gpointer user_data __attribute__((unused)))
-{
-#ifdef DEBUG
- g_printf("KEY \"%s\" (%d) SHIFT=%d CNTRL=%d\n",
- event->string, *event->string,
- event->state & GDK_SHIFT_MASK, event->state & GDK_CONTROL_MASK);
-#endif
-
- switch (event->keyval) {
- case GDK_BackSpace:
- cmdline_keypress('\b');
- break;
- case GDK_Tab:
- cmdline_keypress('\t');
- break;
- case GDK_Return:
- switch (editor_msg(SCI_GETEOLMODE)) {
- case SC_EOL_CR:
- cmdline_keypress('\r');
- break;
- case SC_EOL_CRLF:
- cmdline_keypress('\r');
- /* fall through */
- case SC_EOL_LF:
- default:
- cmdline_keypress('\n');
- }
- break;
- default:
- if (*event->string)
- cmdline_keypress(*event->string);
- }
-
- return TRUE;
-}
-
-static gboolean
-exit_app(GtkWidget *w __attribute__((unused)),
- GdkEventAny *e __attribute__((unused)),
- gpointer p __attribute__((unused)))
-{
- gtk_main_quit();
- return TRUE;
-}
-
-static void
-widget_set_font(GtkWidget *widget, const gchar *font_name)
-{
- PangoFontDescription *font_desc;
-
- font_desc = pango_font_description_from_string(font_name);
- gtk_widget_modify_font(widget, font_desc);
- pango_font_description_free(font_desc);
-}
-
static gchar *mung_file = NULL;
static inline void
@@ -162,7 +50,7 @@ process_options(int &argc, char **&argv)
INI_FILE, NULL);
}
- gtk_init(&argc, &argv);
+ interface.parse_args(argc, argv);
/* remaining arguments, are arguments to the munged file */
}
@@ -170,65 +58,30 @@ process_options(int &argc, char **&argv)
int
main(int argc, char **argv)
{
- GtkWidget *window, *vbox;
- GtkWidget *info_content;
-
process_options(argc, argv);
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "SciTECO");
- g_signal_connect(G_OBJECT(window), "delete-event",
- G_CALLBACK(exit_app), NULL);
-
- vbox = gtk_vbox_new(FALSE, 0);
-
- editor_widget = scintilla_new();
- scintilla_set_id(SCINTILLA(editor_widget), 0);
- gtk_widget_set_usize(editor_widget, 500, 300);
- gtk_widget_set_can_focus(editor_widget, FALSE);
- gtk_box_pack_start(GTK_BOX(vbox), editor_widget, TRUE, TRUE, 0);
-
- info_widget = gtk_info_bar_new();
- info_content = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_widget));
- message_widget = gtk_label_new("");
- gtk_misc_set_alignment(GTK_MISC(message_widget), 0., 0.);
- gtk_container_add(GTK_CONTAINER(info_content), message_widget);
- gtk_box_pack_start(GTK_BOX(vbox), info_widget, FALSE, FALSE, 0);
-
- cmdline_widget = gtk_entry_new();
- gtk_entry_set_has_frame(GTK_ENTRY(cmdline_widget), FALSE);
- gtk_editable_set_editable(GTK_EDITABLE(cmdline_widget), FALSE);
- widget_set_font(cmdline_widget, "Courier");
- g_signal_connect(G_OBJECT(cmdline_widget), "key-press-event",
- G_CALLBACK(cmdline_key_pressed), NULL);
- gtk_box_pack_start(GTK_BOX(vbox), cmdline_widget, FALSE, FALSE, 0);
-
- gtk_container_add(GTK_CONTAINER(window), vbox);
-
- filename_popup = GTK_INFO_POPUP(gtk_info_popup_new(cmdline_widget));
-
- editor_msg(SCI_SETFOCUS, 1);
- editor_msg(SCI_SETCARETSTYLE, 2);
- editor_msg(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)"Courier");
- editor_msg(SCI_STYLECLEARALL);
- editor_msg(SCI_SETLEXER, SCLEX_CPP);
- editor_msg(SCI_SETKEYWORDS, 0, (sptr_t)"int char");
- editor_msg(SCI_STYLESETFORE, SCE_C_COMMENT, 0x008000);
- editor_msg(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x008000);
- editor_msg(SCI_STYLESETFORE, SCE_C_NUMBER, 0x808000);
- editor_msg(SCI_STYLESETFORE, SCE_C_WORD, 0x800000);
- editor_msg(SCI_STYLESETFORE, SCE_C_STRING, 0x800080);
- editor_msg(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1);
+ interface.ssm(SCI_SETFOCUS, 1);
+ interface.ssm(SCI_SETCARETSTYLE, 2);
+ interface.ssm(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)"Courier");
+ interface.ssm(SCI_STYLECLEARALL);
+ interface.ssm(SCI_SETLEXER, SCLEX_CPP);
+ interface.ssm(SCI_SETKEYWORDS, 0, (sptr_t)"int char");
+ interface.ssm(SCI_STYLESETFORE, SCE_C_COMMENT, 0x008000);
+ interface.ssm(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x008000);
+ interface.ssm(SCI_STYLESETFORE, SCE_C_NUMBER, 0x808000);
+ interface.ssm(SCI_STYLESETFORE, SCE_C_WORD, 0x800000);
+ interface.ssm(SCI_STYLESETFORE, SCE_C_STRING, 0x800080);
+ interface.ssm(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1);
qregisters.initialize();
ring.edit(NULL);
/* add remaining arguments to unnamed buffer */
for (int i = 1; i < argc; i++) {
- editor_msg(SCI_ADDTEXT, strlen(argv[i]), (sptr_t)argv[i]);
- editor_msg(SCI_ADDTEXT, 1, (sptr_t)"\r");
+ interface.ssm(SCI_ADDTEXT, strlen(argv[i]), (sptr_t)argv[i]);
+ interface.ssm(SCI_ADDTEXT, 1, (sptr_t)"\r");
}
- editor_msg(SCI_GOTOPOS, 0);
+ interface.ssm(SCI_GOTOPOS, 0);
if (g_file_test(mung_file, G_FILE_TEST_IS_REGULAR)) {
if (!file_execute(mung_file))
@@ -243,11 +96,9 @@ main(int argc, char **argv)
undo.enabled = true;
- cmdline_display("*");
- gtk_widget_grab_focus(cmdline_widget);
+ interface.cmdline_update("*");
- gtk_widget_show_all(window);
- gtk_main();
+ interface.event_loop();
return 0;
}
diff --git a/parser.cpp b/parser.cpp
index d0b56dd..a05533a 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -5,6 +5,7 @@
#include <glib/gstdio.h>
#include "sciteco.h"
+#include "interface.h"
#include "undo.h"
#include "expressions.h"
#include "goto.h"
@@ -53,9 +54,8 @@ macro_execute(const gchar *macro)
#endif
if (!State::input(macro[macro_pc])) {
- message_display(GTK_MESSAGE_ERROR,
- "Syntax error \"%c\"",
- macro[macro_pc]);
+ interface.msg(Interface::MSG_ERROR,
+ "Syntax error \"%c\"", macro[macro_pc]);
return false;
}
@@ -344,12 +344,12 @@ StateStart::StateStart() : State()
tecoBool
StateStart::move_chars(gint64 n)
{
- sptr_t pos = editor_msg(SCI_GETCURRENTPOS);
+ sptr_t pos = interface.ssm(SCI_GETCURRENTPOS);
if (!Validate::pos(pos + n))
return FAILURE;
- editor_msg(SCI_GOTOPOS, pos + n);
+ interface.ssm(SCI_GOTOPOS, pos + n);
undo.push_msg(SCI_GOTOPOS, pos);
return SUCCESS;
}
@@ -357,13 +357,13 @@ StateStart::move_chars(gint64 n)
tecoBool
StateStart::move_lines(gint64 n)
{
- sptr_t pos = editor_msg(SCI_GETCURRENTPOS);
- sptr_t line = editor_msg(SCI_LINEFROMPOSITION, pos) + n;
+ sptr_t pos = interface.ssm(SCI_GETCURRENTPOS);
+ sptr_t line = interface.ssm(SCI_LINEFROMPOSITION, pos) + n;
if (!Validate::line(line))
return FAILURE;
- editor_msg(SCI_GOTOLINE, line);
+ interface.ssm(SCI_GOTOLINE, line);
undo.push_msg(SCI_GOTOPOS, pos);
return SUCCESS;
}
@@ -376,9 +376,9 @@ StateStart::delete_words(gint64 n)
if (!n)
return SUCCESS;
- pos = editor_msg(SCI_GETCURRENTPOS);
- size = editor_msg(SCI_GETLENGTH);
- editor_msg(SCI_BEGINUNDOACTION);
+ pos = interface.ssm(SCI_GETCURRENTPOS);
+ size = interface.ssm(SCI_GETLENGTH);
+ interface.ssm(SCI_BEGINUNDOACTION);
/*
* FIXME: would be nice to do this with constant amount of
* editor messages. E.g. by using custom algorithm accessing
@@ -386,28 +386,28 @@ StateStart::delete_words(gint64 n)
*/
if (n > 0) {
while (n--) {
- sptr_t size = editor_msg(SCI_GETLENGTH);
- editor_msg(SCI_DELWORDRIGHTEND);
- if (size == editor_msg(SCI_GETLENGTH))
+ sptr_t size = interface.ssm(SCI_GETLENGTH);
+ interface.ssm(SCI_DELWORDRIGHTEND);
+ if (size == interface.ssm(SCI_GETLENGTH))
break;
}
} else {
n *= -1;
while (n--) {
- sptr_t pos = editor_msg(SCI_GETCURRENTPOS);
- //editor_msg(SCI_DELWORDLEFTEND);
- editor_msg(SCI_WORDLEFTEND);
- if (pos == editor_msg(SCI_GETCURRENTPOS))
+ sptr_t pos = interface.ssm(SCI_GETCURRENTPOS);
+ //interface.ssm(SCI_DELWORDLEFTEND);
+ interface.ssm(SCI_WORDLEFTEND);
+ if (pos == interface.ssm(SCI_GETCURRENTPOS))
break;
- editor_msg(SCI_DELWORDRIGHTEND);
+ interface.ssm(SCI_DELWORDRIGHTEND);
}
}
- editor_msg(SCI_ENDUNDOACTION);
+ interface.ssm(SCI_ENDUNDOACTION);
if (n >= 0) {
- if (size != editor_msg(SCI_GETLENGTH)) {
- editor_msg(SCI_UNDO);
- editor_msg(SCI_GOTOPOS, pos);
+ if (size != interface.ssm(SCI_GETLENGTH)) {
+ interface.ssm(SCI_UNDO);
+ interface.ssm(SCI_GOTOPOS, pos);
}
return FAILURE;
}
@@ -498,20 +498,20 @@ StateStart::custom(gchar chr)
case '.':
BEGIN_EXEC(this);
expressions.eval();
- expressions.push(editor_msg(SCI_GETCURRENTPOS));
+ expressions.push(interface.ssm(SCI_GETCURRENTPOS));
break;
case 'Z':
BEGIN_EXEC(this);
expressions.eval();
- expressions.push(editor_msg(SCI_GETLENGTH));
+ expressions.push(interface.ssm(SCI_GETLENGTH));
break;
case 'H':
BEGIN_EXEC(this);
expressions.eval();
expressions.push(0);
- expressions.push(editor_msg(SCI_GETLENGTH));
+ expressions.push(interface.ssm(SCI_GETLENGTH));
break;
/*
@@ -648,8 +648,8 @@ StateStart::custom(gchar chr)
v = expressions.pop_num_calc(1, 0);
if (Validate::pos(v)) {
undo.push_msg(SCI_GOTOPOS,
- editor_msg(SCI_GETCURRENTPOS));
- editor_msg(SCI_GOTOPOS, v);
+ interface.ssm(SCI_GETCURRENTPOS));
+ interface.ssm(SCI_GOTOPOS, v);
if (eval_colon())
expressions.push(SUCCESS);
@@ -703,7 +703,7 @@ StateStart::custom(gchar chr)
BEGIN_EXEC(this);
v = expressions.pop_num_calc();
- pos = editor_msg(SCI_GETCURRENTPOS);
+ pos = interface.ssm(SCI_GETCURRENTPOS);
/*
* FIXME: would be nice to do this with constant amount of
* editor messages. E.g. by using custom algorithm accessing
@@ -714,9 +714,9 @@ StateStart::custom(gchar chr)
msg = SCI_WORDLEFTEND;
}
while (v--) {
- sptr_t pos = editor_msg(SCI_GETCURRENTPOS);
- editor_msg(msg);
- if (pos == editor_msg(SCI_GETCURRENTPOS))
+ sptr_t pos = interface.ssm(SCI_GETCURRENTPOS);
+ interface.ssm(msg);
+ if (pos == interface.ssm(SCI_GETCURRENTPOS))
break;
}
if (v < 0) {
@@ -724,7 +724,7 @@ StateStart::custom(gchar chr)
if (eval_colon())
expressions.push(SUCCESS);
} else {
- editor_msg(SCI_GOTOPOS, pos);
+ interface.ssm(SCI_GOTOPOS, pos);
if (eval_colon())
expressions.push(FAILURE);
else
@@ -753,8 +753,8 @@ StateStart::custom(gchar chr)
case '=':
BEGIN_EXEC(this);
- message_display(GTK_MESSAGE_OTHER, "%" G_GINT64_FORMAT,
- expressions.pop_num_calc());
+ interface.msg(Interface::MSG_USER, "%" G_GINT64_FORMAT,
+ expressions.pop_num_calc());
break;
case 'K':
@@ -765,15 +765,15 @@ StateStart::custom(gchar chr)
expressions.eval();
if (expressions.args() <= 1) {
- from = editor_msg(SCI_GETCURRENTPOS);
+ from = interface.ssm(SCI_GETCURRENTPOS);
if (chr == 'D') {
len = expressions.pop_num_calc();
rc = TECO_BOOL(Validate::pos(from + len));
} else /* chr == 'K' */ {
sptr_t line;
- line = editor_msg(SCI_LINEFROMPOSITION, from) +
+ line = interface.ssm(SCI_LINEFROMPOSITION, from) +
expressions.pop_num_calc();
- len = editor_msg(SCI_POSITIONFROMLINE, line)
+ len = interface.ssm(SCI_POSITIONFROMLINE, line)
- from;
rc = TECO_BOOL(Validate::line(line));
}
@@ -797,12 +797,12 @@ StateStart::custom(gchar chr)
if (len == 0 || IS_FAILURE(rc))
break;
- undo.push_msg(SCI_GOTOPOS, editor_msg(SCI_GETCURRENTPOS));
+ undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS));
undo.push_msg(SCI_UNDO);
- editor_msg(SCI_BEGINUNDOACTION);
- editor_msg(SCI_DELETERANGE, from, len);
- editor_msg(SCI_ENDUNDOACTION);
+ interface.ssm(SCI_BEGINUNDOACTION);
+ interface.ssm(SCI_DELETERANGE, from, len);
+ interface.ssm(SCI_ENDUNDOACTION);
break;
}
@@ -1089,14 +1089,14 @@ StateInsert::initial(void)
if (!args)
return;
- editor_msg(SCI_BEGINUNDOACTION);
+ interface.ssm(SCI_BEGINUNDOACTION);
for (int i = args; i > 0; i--) {
gchar chr = (gchar)expressions.peek_num(i);
- editor_msg(SCI_ADDTEXT, 1, (sptr_t)&chr);
+ interface.ssm(SCI_ADDTEXT, 1, (sptr_t)&chr);
}
for (int i = args; i > 0; i--)
expressions.pop_num_calc();
- editor_msg(SCI_ENDUNDOACTION);
+ interface.ssm(SCI_ENDUNDOACTION);
undo.push_msg(SCI_UNDO);
}
@@ -1104,10 +1104,10 @@ StateInsert::initial(void)
void
StateInsert::process(const gchar *str, gint new_chars)
{
- editor_msg(SCI_BEGINUNDOACTION);
- editor_msg(SCI_ADDTEXT, new_chars,
+ interface.ssm(SCI_BEGINUNDOACTION);
+ interface.ssm(SCI_ADDTEXT, new_chars,
(sptr_t)(str + strlen(str) - new_chars));
- editor_msg(SCI_ENDUNDOACTION);
+ interface.ssm(SCI_ENDUNDOACTION);
undo.push_msg(SCI_UNDO);
}
@@ -1126,7 +1126,7 @@ StateSearch::initial(void)
undo.push_var<Parameters>(parameters);
- parameters.dot = editor_msg(SCI_GETCURRENTPOS);
+ parameters.dot = interface.ssm(SCI_GETCURRENTPOS);
v = expressions.pop_num_calc();
if (expressions.args()) {
/* TODO: optional count argument? */
@@ -1137,7 +1137,7 @@ StateSearch::initial(void)
parameters.count = (gint)v;
if (v >= 0) {
parameters.from = parameters.dot;
- parameters.to = editor_msg(SCI_GETLENGTH);
+ parameters.to = interface.ssm(SCI_GETLENGTH);
} else {
parameters.from = 0;
parameters.to = parameters.dot;
@@ -1360,7 +1360,7 @@ StateSearch::process(const gchar *str, gint new_chars __attribute__((unused)))
gint matched_from = -1, matched_to = -1;
- undo.push_msg(SCI_GOTOPOS, editor_msg(SCI_GETCURRENTPOS));
+ undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS));
undo.push_var<gint64>(search_reg->integer);
search_reg->integer = FAILURE;
@@ -1371,18 +1371,18 @@ StateSearch::process(const gchar *str, gint new_chars __attribute__((unused)))
g_printf("REGEXP: %s\n", re_pattern);
#endif
if (!re_pattern) {
- editor_msg(SCI_GOTOPOS, parameters.dot);
+ interface.ssm(SCI_GOTOPOS, parameters.dot);
return;
}
re = g_regex_new(re_pattern, (GRegexCompileFlags)flags,
(GRegexMatchFlags)0, NULL);
g_free(re_pattern);
if (!re) {
- editor_msg(SCI_GOTOPOS, parameters.dot);
+ interface.ssm(SCI_GOTOPOS, parameters.dot);
return;
}
- buffer = (const gchar *)editor_msg(SCI_GETCHARACTERPOINTER);
+ buffer = (const gchar *)interface.ssm(SCI_GETCHARACTERPOINTER);
g_regex_match_full(re, buffer, (gssize)parameters.to, parameters.from,
(GRegexMatchFlags)0, &info, NULL);
@@ -1428,9 +1428,9 @@ StateSearch::process(const gchar *str, gint new_chars __attribute__((unused)))
if (matched_from >= 0 && matched_to >= 0) {
/* match success */
search_reg->integer = SUCCESS;
- editor_msg(SCI_SETSEL, matched_from, matched_to);
+ interface.ssm(SCI_SETSEL, matched_from, matched_to);
} else {
- editor_msg(SCI_GOTOPOS, parameters.dot);
+ interface.ssm(SCI_GOTOPOS, parameters.dot);
}
g_regex_unref(re);
@@ -1456,7 +1456,7 @@ StateSearch::done(const gchar *str)
expressions.push(search_reg->integer);
else if (IS_FAILURE(search_reg->integer) &&
!expressions.find_op(Expressions::OP_LOOP) /* not in loop */)
- message_display(GTK_MESSAGE_ERROR, "Search string not found!");
+ interface.msg(Interface::MSG_ERROR, "Search string not found!");
return &States::start;
}
diff --git a/parser.h b/parser.h
index e9ef59b..e7bbd1e 100644
--- a/parser.h
+++ b/parser.h
@@ -6,6 +6,9 @@
#include "sciteco.h"
+/* TECO uses only lower 7 bits for commands */
+#define MAX_TRANSITIONS 127
+
class State {
protected:
/* static transitions */
diff --git a/qbuffers.cpp b/qbuffers.cpp
index b9afbd6..f12ed3c 100644
--- a/qbuffers.cpp
+++ b/qbuffers.cpp
@@ -11,11 +11,10 @@
#include <glib/gprintf.h>
#include <glib/gstdio.h>
-#include "gtk-info-popup.h"
-
#include <Scintilla.h>
#include "sciteco.h"
+#include "interface.h"
#include "undo.h"
#include "parser.h"
#include "expressions.h"
@@ -45,7 +44,7 @@ static QRegister *register_argument = NULL;
static inline void
current_save_dot(void)
{
- gint dot = editor_msg(SCI_GETCURRENTPOS);
+ gint dot = interface.ssm(SCI_GETCURRENTPOS);
if (ring.current)
ring.current->dot = dot;
@@ -68,9 +67,9 @@ QRegister::set_string(const gchar *str)
edit();
dot = 0;
- editor_msg(SCI_BEGINUNDOACTION);
- editor_msg(SCI_SETTEXT, 0, (sptr_t)str);
- editor_msg(SCI_ENDUNDOACTION);
+ interface.ssm(SCI_BEGINUNDOACTION);
+ interface.ssm(SCI_SETTEXT, 0, (sptr_t)str);
+ interface.ssm(SCI_ENDUNDOACTION);
current_edit();
}
@@ -99,9 +98,9 @@ QRegister::get_string(void)
current_save_dot();
edit();
- size = editor_msg(SCI_GETLENGTH) + 1;
+ size = interface.ssm(SCI_GETLENGTH) + 1;
str = (gchar *)g_malloc(size);
- editor_msg(SCI_GETTEXT, size, (sptr_t)str);
+ interface.ssm(SCI_GETTEXT, size, (sptr_t)str);
current_edit();
@@ -122,10 +121,10 @@ QRegister::load(const gchar *filename)
if (!g_file_get_contents(filename, &contents, &size, NULL))
return false;
- editor_msg(SCI_BEGINUNDOACTION);
- editor_msg(SCI_CLEARALL);
- editor_msg(SCI_APPENDTEXT, size, (sptr_t)contents);
- editor_msg(SCI_ENDUNDOACTION);
+ interface.ssm(SCI_BEGINUNDOACTION);
+ interface.ssm(SCI_CLEARALL);
+ interface.ssm(SCI_APPENDTEXT, size, (sptr_t)contents);
+ interface.ssm(SCI_ENDUNDOACTION);
g_free(contents);
@@ -164,16 +163,16 @@ Buffer::load(const gchar *filename)
gsize size;
edit();
- editor_msg(SCI_CLEARALL);
+ interface.ssm(SCI_CLEARALL);
/* FIXME: prevent excessive allocations by reading file into buffer */
if (!g_file_get_contents(filename, &contents, &size, NULL))
return false;
- editor_msg(SCI_APPENDTEXT, size, (sptr_t)contents);
+ interface.ssm(SCI_APPENDTEXT, size, (sptr_t)contents);
g_free(contents);
- editor_msg(SCI_GOTOPOS, 0);
- editor_msg(SCI_SETSAVEPOINT);
+ interface.ssm(SCI_GOTOPOS, 0);
+ interface.ssm(SCI_SETSAVEPOINT);
set_filename(filename);
@@ -186,12 +185,12 @@ Buffer::close(void)
LIST_REMOVE(this, buffers);
if (filename)
- message_display(GTK_MESSAGE_INFO,
- "Removed file \"%s\" from the ring",
- filename);
+ interface.msg(Interface::MSG_INFO,
+ "Removed file \"%s\" from the ring",
+ filename);
else
- message_display(GTK_MESSAGE_INFO,
- "Removed unnamed file from the ring.");
+ interface.msg(Interface::MSG_INFO,
+ "Removed unnamed file from the ring.");
}
void
@@ -243,19 +242,19 @@ Ring::edit(const gchar *filename)
if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
buffer->load(filename);
- message_display(GTK_MESSAGE_INFO,
- "Added file \"%s\" to ring", filename);
+ interface.msg(Interface::MSG_INFO,
+ "Added file \"%s\" to ring", filename);
} else {
buffer->edit();
buffer->set_filename(filename);
if (filename)
- message_display(GTK_MESSAGE_INFO,
- "Added new file \"%s\" to ring",
- filename);
+ interface.msg(Interface::MSG_INFO,
+ "Added new file \"%s\" to ring",
+ filename);
else
- message_display(GTK_MESSAGE_INFO,
- "Added new unnamed file to ring.");
+ interface.msg(Interface::MSG_INFO,
+ "Added new unnamed file to ring.");
}
}
@@ -307,9 +306,9 @@ public:
attributes);
#endif
} else {
- message_display(GTK_MESSAGE_WARNING,
- "Unable to restore save point file \"%s\"",
- savepoint);
+ interface.msg(Interface::MSG_WARNING,
+ "Unable to restore save point file \"%s\"",
+ savepoint);
}
}
};
@@ -341,9 +340,9 @@ make_savepoint(Buffer *buffer)
#endif
undo.push(token);
} else {
- message_display(GTK_MESSAGE_WARNING,
- "Unable to create save point file \"%s\"",
- savepoint);
+ interface.msg(Interface::MSG_WARNING,
+ "Unable to create save point file \"%s\"",
+ savepoint);
g_free(savepoint);
}
}
@@ -372,8 +371,8 @@ Ring::save(const gchar *filename)
undo.push(new UndoTokenRemoveFile(filename));
}
- buffer = (const gchar *)editor_msg(SCI_GETCHARACTERPOINTER);
- size = editor_msg(SCI_GETLENGTH);
+ buffer = (const gchar *)interface.ssm(SCI_GETCHARACTERPOINTER);
+ size = interface.ssm(SCI_GETLENGTH);
if (!g_file_set_contents(filename, buffer, size, NULL))
return false;
@@ -397,7 +396,7 @@ Ring::close(void)
{
Buffer *buffer = current;
- buffer->dot = editor_msg(SCI_GETCURRENTPOS);
+ buffer->dot = interface.ssm(SCI_GETCURRENTPOS);
buffer->close();
current = buffer->next() ? : first();
/* transfer responsibility to UndoToken object */
@@ -481,12 +480,11 @@ StateEditFile::initial(void)
if (id == 0) {
for (Buffer *cur = ring.first(); cur; cur = cur->next())
- gtk_info_popup_add_filename(filename_popup,
- GTK_INFO_POPUP_FILE,
- cur->filename ? : "(Unnamed)",
- cur == ring.current);
+ interface.popup_add_filename(Interface::POPUP_FILE,
+ cur->filename ? : "(Unnamed)",
+ cur == ring.current);
- gtk_widget_show(GTK_WIDGET(filename_popup));
+ interface.popup_show();
}
}
@@ -665,10 +663,10 @@ StateCopyToQReg::got_register(QRegister *reg)
expressions.eval();
if (expressions.args() <= 1) {
- from = editor_msg(SCI_GETCURRENTPOS);
- sptr_t line = editor_msg(SCI_LINEFROMPOSITION, from) +
+ from = interface.ssm(SCI_GETCURRENTPOS);
+ sptr_t line = interface.ssm(SCI_LINEFROMPOSITION, from) +
expressions.pop_num_calc();
- len = editor_msg(SCI_POSITIONFROMLINE, line) - from;
+ len = interface.ssm(SCI_POSITIONFROMLINE, line) - from;
if (len < 0) {
from += len;
@@ -683,7 +681,7 @@ StateCopyToQReg::got_register(QRegister *reg)
tr.chrg.cpMin = from;
tr.chrg.cpMax = from + len;
tr.lpstrText = (char *)g_malloc(len + 1);
- editor_msg(SCI_GETTEXTRANGE, 0, (sptr_t)&tr);
+ interface.ssm(SCI_GETTEXTRANGE, 0, (sptr_t)&tr);
reg->undo_set_string();
reg->set_string(tr.lpstrText);
diff --git a/sciteco.h b/sciteco.h
index 37f1af4..9cf3205 100644
--- a/sciteco.h
+++ b/sciteco.h
@@ -1,26 +1,14 @@
#ifndef __SCITECO_H
#define __SCITECO_H
-#include <stdarg.h>
-
#include <glib.h>
-#include <gtk/gtk.h>
-#include "gtk-info-popup.h"
-#include <Scintilla.h>
+#include "interface.h"
extern gchar *cmdline;
extern bool quit_requested;
-extern GtkInfoPopup *filename_popup;
-
-void message_display(GtkMessageType type,
- const gchar *fmt, ...) G_GNUC_PRINTF(2, 3);
-
void cmdline_keypress(gchar key);
-void cmdline_display(const gchar *cmdline);
-
-sptr_t editor_msg(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0);
#define IS_CTL(C) ((C) < ' ')
#define CTL_ECHO(C) ((C) | 0x40)
@@ -35,9 +23,6 @@ typedef gint64 tecoBool;
#define IS_SUCCESS(X) ((X) < 0)
#define IS_FAILURE(X) (!IS_SUCCESS(X))
-/* TECO uses only lower 7 bits for commands */
-#define MAX_TRANSITIONS 127
-
namespace String {
static inline void
@@ -62,13 +47,13 @@ namespace Validate {
static inline bool
pos(gint n)
{
- return n >= 0 && n <= editor_msg(SCI_GETLENGTH);
+ return n >= 0 && n <= interface.ssm(SCI_GETLENGTH);
}
static inline bool
line(gint n)
{
- return n >= 0 && n < editor_msg(SCI_GETLINECOUNT);
+ return n >= 0 && n < interface.ssm(SCI_GETLINECOUNT);
}
} /* namespace Validate */
diff --git a/undo.cpp b/undo.cpp
index c6b30ff..da0b593 100644
--- a/undo.cpp
+++ b/undo.cpp
@@ -6,6 +6,7 @@
#include <Scintilla.h>
#include "sciteco.h"
+#include "interface.h"
#include "undo.h"
UndoStack undo;
@@ -13,7 +14,7 @@ UndoStack undo;
void
UndoTokenMessage::run(void)
{
- editor_msg(iMessage, wParam, lParam);
+ interface.ssm(iMessage, wParam, lParam);
}
void