aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/document.cpp71
-rw-r--r--src/document.h53
-rw-r--r--src/interface-gtk.cpp2
-rw-r--r--src/interface-ncurses.cpp67
-rw-r--r--src/interface-ncurses.h51
-rw-r--r--src/interface.cpp114
-rw-r--r--src/interface.h80
-rw-r--r--src/main.cpp50
-rw-r--r--src/parser.cpp26
-rw-r--r--src/qregisters.cpp107
-rw-r--r--src/qregisters.h25
-rw-r--r--src/ring.cpp12
-rw-r--r--src/ring.h20
-rw-r--r--src/search.cpp14
-rw-r--r--src/spawn.cpp4
-rw-r--r--src/undo.cpp6
-rw-r--r--src/undo.h23
18 files changed, 475 insertions, 252 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 60346bd..4833b6e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,7 +33,7 @@ libsciteco_base_a_SOURCES = main.cpp sciteco.h \
goto.cpp goto.h \
rbtree.cpp rbtree.h \
symbols.cpp symbols.h \
- interface.h
+ interface.cpp interface.h
nodist_libsciteco_base_a_SOURCES =
if INTERFACE_GTK
diff --git a/src/document.cpp b/src/document.cpp
index ff2ce2b..8ed5007 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -30,76 +30,43 @@
namespace SciTECO {
-static inline void
-set_representations(void)
-{
- static const char *reps[] = {
- "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G",
- "^H", "TAB" /* ^I */, "LF" /* ^J */, "^K", "^L", "CR" /* ^M */, "^N", "^O",
- "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
- "^X", "^Y", "^Z", "$" /* ^[ */, "^\\", "^]", "^^", "^_"
- };
-
- for (guint cc = 0; cc < G_N_ELEMENTS(reps); cc++) {
- gchar buf[] = {(gchar)cc, '\0'};
- interface.ssm(SCI_SETREPRESENTATION,
- (uptr_t)buf, (sptr_t)reps[cc]);
- }
-}
-
-class UndoSetRepresentations : public UndoToken {
-public:
- void
- run(void)
- {
- set_representations();
- }
-};
-
void
-Document::edit(void)
+Document::edit(ViewCurrent *view)
{
- if (!is_initialized())
- doc = (SciDoc)interface.ssm(SCI_CREATEDOCUMENT);
+ maybe_create_document();
- interface.ssm(SCI_SETDOCPOINTER, 0, (sptr_t)doc);
- interface.ssm(SCI_SETFIRSTVISIBLELINE, first_line);
- interface.ssm(SCI_SETXOFFSET, xoffset);
- interface.ssm(SCI_SETSEL, anchor, (sptr_t)dot);
+ view->ssm(SCI_SETDOCPOINTER, 0, (sptr_t)doc);
+ view->ssm(SCI_SETFIRSTVISIBLELINE, first_line);
+ view->ssm(SCI_SETXOFFSET, xoffset);
+ view->ssm(SCI_SETSEL, anchor, (sptr_t)dot);
/*
* Default TECO-style character representations.
* They are reset on EVERY SETDOCPOINTER call by Scintilla.
*/
- set_representations();
+ view->set_representations();
}
void
-Document::undo_edit(void)
+Document::undo_edit(ViewCurrent *view)
{
- if (!is_initialized())
- doc = (SciDoc)interface.ssm(SCI_CREATEDOCUMENT);
+ maybe_create_document();
- /*
- * see above: set TECO-style character representations
- * NOTE: could be done with push_msg() but that requires
- * making the entire mapping static constant
- */
- undo.push(new UndoSetRepresentations());
+ view->undo_set_representations();
- undo.push_msg(SCI_SETSEL, anchor, (sptr_t)dot);
- undo.push_msg(SCI_SETXOFFSET, xoffset);
- undo.push_msg(SCI_SETFIRSTVISIBLELINE, first_line);
- undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)doc);
+ view->undo_ssm(SCI_SETSEL, anchor, (sptr_t)dot);
+ view->undo_ssm(SCI_SETXOFFSET, xoffset);
+ view->undo_ssm(SCI_SETFIRSTVISIBLELINE, first_line);
+ view->undo_ssm(SCI_SETDOCPOINTER, 0, (sptr_t)doc);
}
void
-Document::update(void)
+Document::update(ViewCurrent *view)
{
- anchor = interface.ssm(SCI_GETANCHOR);
- dot = interface.ssm(SCI_GETCURRENTPOS);
- first_line = interface.ssm(SCI_GETFIRSTVISIBLELINE);
- xoffset = interface.ssm(SCI_GETXOFFSET);
+ anchor = view->ssm(SCI_GETANCHOR);
+ dot = view->ssm(SCI_GETCURRENTPOS);
+ first_line = view->ssm(SCI_GETFIRSTVISIBLELINE);
+ xoffset = view->ssm(SCI_GETXOFFSET);
}
/*
diff --git a/src/document.h b/src/document.h
index 81700b4..763db7a 100644
--- a/src/document.h
+++ b/src/document.h
@@ -36,7 +36,10 @@ class Document {
typedef const void *SciDoc;
SciDoc doc;
- /* updated/restored only when required */
+ /*
+ * The so called "parameters".
+ * Updated/restored only when required
+ */
gint anchor, dot;
gint first_line, xoffset;
@@ -47,8 +50,15 @@ public:
}
virtual ~Document()
{
- if (is_initialized())
- interface.ssm(SCI_RELEASEDOCUMENT, 0, (sptr_t)doc);
+ /*
+ * Cannot release document here, since we must
+ * do it on the same view that created it.
+ * We also cannot call get_create_document_view()
+ * since it is virtual.
+ * So we must demand that deriving classes call
+ * release_document() from their destructors.
+ */
+ g_assert(doc == NULL);
}
inline bool
@@ -57,10 +67,10 @@ public:
return doc != NULL;
}
- void edit(void);
- void undo_edit(void);
+ void edit(ViewCurrent *view);
+ void undo_edit(ViewCurrent *view);
- void update(void);
+ void update(ViewCurrent *view);
inline void
update(const Document &from)
{
@@ -92,6 +102,37 @@ public:
undo.push_var(doc);
undo_reset();
}
+
+protected:
+ inline void
+ release_document(void)
+ {
+ if (is_initialized()) {
+ ViewCurrent *view = get_create_document_view();
+ view->ssm(SCI_RELEASEDOCUMENT, 0, (sptr_t)doc);
+ doc = NULL;
+ }
+ }
+
+private:
+ /*
+ * Must be implemented by derived class.
+ * Documents must be released on the same view
+ * as they were created.
+ * Since we do not want to save this view
+ * per document, it must instead be returned by
+ * this method.
+ */
+ virtual ViewCurrent *get_create_document_view(void) = 0;
+
+ inline void
+ maybe_create_document(void)
+ {
+ if (!is_initialized()) {
+ ViewCurrent *view = get_create_document_view();
+ doc = (SciDoc)view->ssm(SCI_CREATEDOCUMENT);
+ }
+ }
};
} /* namespace SciTECO */
diff --git a/src/interface-gtk.cpp b/src/interface-gtk.cpp
index 2b47019..b49a5fb 100644
--- a/src/interface-gtk.cpp
+++ b/src/interface-gtk.cpp
@@ -97,8 +97,6 @@ InterfaceGtk::main(int &argc, char **&argv)
gtk_widget_grab_focus(cmdline_widget);
- ssm(SCI_SETFOCUS, TRUE);
-
cmdline_update("");
}
diff --git a/src/interface-ncurses.cpp b/src/interface-ncurses.cpp
index a956fdf..bb88af1 100644
--- a/src/interface-ncurses.cpp
+++ b/src/interface-ncurses.cpp
@@ -56,6 +56,34 @@ static void scintilla_notify(Scintilla *sci, int idFrom,
#define SCI_COLOR_ATTR(f, b) \
((chtype)COLOR_PAIR(SCI_COLOR_PAIR(f, b)))
+ViewNCurses::ViewNCurses()
+{
+ WINDOW *window;
+
+ /* NOTE: Scintilla initializes color pairs */
+ sci = scintilla_new(scintilla_notify);
+ window = get_window();
+
+ /*
+ * Window must have dimension before it can be
+ * positioned.
+ * Perhaps it's better to leave the window
+ * unitialized and set the position in
+ * InterfaceNCurses::show_view().
+ */
+ wresize(window, 1, 1);
+ /* Set up window position: never changes */
+ mvwin(window, 1, 0);
+
+ initialize();
+}
+
+ViewNCurses::~ViewNCurses()
+{
+ delwin(get_window());
+ scintilla_delete(sci);
+}
+
void
InterfaceNCurses::main(int &argc, char **&argv)
{
@@ -69,19 +97,11 @@ InterfaceNCurses::main(int &argc, char **&argv)
info_window = newwin(1, 0, 0, 0);
info_current = g_strdup(PACKAGE_NAME);
- /* NOTE: Scintilla initializes color pairs */
- sci = scintilla_new(scintilla_notify);
- sci_window = scintilla_get_window(sci);
- wresize(sci_window, LINES - 3, COLS);
- mvwin(sci_window, 1, 0);
-
msg_window = newwin(1, 0, LINES - 2, 0);
cmdline_window = newwin(0, 0, LINES - 1, 0);
cmdline_current = NULL;
- ssm(SCI_SETFOCUS, TRUE);
-
draw_info();
/* scintilla will be refreshed in event loop */
msg_clear();
@@ -140,7 +160,8 @@ InterfaceNCurses::resize_all_windows(void)
getmaxyx(stdscr, lines, cols);
wresize(info_window, 1, cols);
- wresize(sci_window, lines - 3, cols);
+ wresize(current_view->get_window(),
+ lines - 3, cols);
wresize(msg_window, 1, cols);
mvwin(msg_window, lines - 2, 0);
wresize(cmdline_window, 1, cols);
@@ -195,6 +216,23 @@ InterfaceNCurses::msg_clear(void)
}
void
+InterfaceNCurses::show_view(View *view)
+{
+ int lines, cols; /* screen dimensions */
+
+ /* We know that `view` is a ViewNCurses */
+ current_view = (ViewNCurses *)view;
+
+ /*
+ * screen size might have changed since
+ * this view's WINDOW was last active
+ */
+ getmaxyx(stdscr, lines, cols);
+ wresize(current_view->get_window(),
+ lines - 3, cols);
+}
+
+void
InterfaceNCurses::draw_info(void)
{
if (isendwin()) /* batch mode */
@@ -343,8 +381,8 @@ InterfaceNCurses::popup_clear(void)
redrawwin(info_window);
wrefresh(info_window);
- redrawwin(sci_window);
- scintilla_refresh(sci);
+ redrawwin(current_view->get_window());
+ current_view->refresh();
redrawwin(msg_window);
wrefresh(msg_window);
@@ -432,7 +470,7 @@ event_loop_iter()
sigint_occurred = FALSE;
- scintilla_refresh(interface.sci);
+ interface.current_view->refresh();
if (interface.popup.window)
wrefresh(interface.popup.window);
}
@@ -441,7 +479,7 @@ void
InterfaceNCurses::event_loop(void)
{
/* initial refresh: window might have been changed in batch mode */
- scintilla_refresh(sci);
+ current_view->refresh();
draw_info();
#ifdef EMSCRIPTEN
@@ -465,9 +503,6 @@ InterfaceNCurses::~InterfaceNCurses()
if (info_window)
delwin(info_window);
g_free(info_current);
- /* also deletes curses window */
- if (sci)
- scintilla_delete(sci);
if (cmdline_window)
delwin(cmdline_window);
g_free(cmdline_current);
diff --git a/src/interface-ncurses.h b/src/interface-ncurses.h
index f1003de..647b1ef 100644
--- a/src/interface-ncurses.h
+++ b/src/interface-ncurses.h
@@ -31,19 +31,44 @@
namespace SciTECO {
+typedef class ViewNCurses : public View {
+ Scintilla *sci;
+
+public:
+ ViewNCurses();
+ ~ViewNCurses();
+
+ inline void
+ refresh(void)
+ {
+ scintilla_refresh(sci);
+ }
+
+ inline WINDOW *
+ get_window(void)
+ {
+ return scintilla_get_window(sci);
+ }
+
+ inline sptr_t
+ ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0)
+ {
+ return scintilla_send_message(sci, iMessage, wParam, lParam);
+ }
+} ViewCurrent;
+
typedef class InterfaceNCurses : public Interface {
SCREEN *screen;
FILE *screen_tty;
- Scintilla *sci;
-
WINDOW *info_window;
gchar *info_current;
- WINDOW *sci_window;
WINDOW *msg_window;
WINDOW *cmdline_window;
gchar *cmdline_current;
+ ViewNCurses *current_view;
+
struct Popup {
WINDOW *window;
GSList *list;
@@ -57,13 +82,12 @@ typedef class InterfaceNCurses : public Interface {
public:
InterfaceNCurses() : screen(NULL),
screen_tty(NULL),
- sci(NULL),
info_window(NULL),
info_current(NULL),
- sci_window(NULL),
msg_window(NULL),
cmdline_window(NULL),
- cmdline_current(NULL) {}
+ cmdline_current(NULL),
+ current_view(NULL) {}
~InterfaceNCurses();
void main(int &argc, char **&argv);
@@ -71,10 +95,23 @@ public:
void vmsg(MessageType type, const gchar *fmt, va_list ap);
void msg_clear(void);
+ void show_view(View *view);
+ inline View *
+ get_current_view(void)
+ {
+ return current_view;
+ }
+
inline sptr_t
ssm(unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0)
{
- return scintilla_send_message(sci, iMessage, wParam, lParam);
+ return current_view->ssm(iMessage, wParam, lParam);
+ }
+ inline void
+ undo_ssm(unsigned int iMessage,
+ uptr_t wParam = 0, sptr_t lParam = 0)
+ {
+ current_view->undo_ssm(iMessage, wParam, lParam);
}
void info_update(QRegister *reg);
diff --git a/src/interface.cpp b/src/interface.cpp
new file mode 100644
index 0000000..aecba4e
--- /dev/null
+++ b/src/interface.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012-2014 Robin Haberkorn
+ *
+ * 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+
+#include <Scintilla.h>
+#include <SciLexer.h>
+
+#include "sciteco.h"
+#include "interface.h"
+
+namespace SciTECO {
+
+void
+View::set_representations(void)
+{
+ static const char *reps[] = {
+ "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G",
+ "^H", "TAB" /* ^I */, "LF" /* ^J */, "^K", "^L", "CR" /* ^M */, "^N", "^O",
+ "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
+ "^X", "^Y", "^Z", "$" /* ^[ */, "^\\", "^]", "^^", "^_"
+ };
+
+ for (guint cc = 0; cc < G_N_ELEMENTS(reps); cc++) {
+ gchar buf[] = {(gchar)cc, '\0'};
+ ssm(SCI_SETREPRESENTATION, (uptr_t)buf, (sptr_t)reps[cc]);
+ }
+}
+
+void
+View::initialize(void)
+{
+ ssm(SCI_SETFOCUS, TRUE);
+
+ ssm(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK);
+ ssm(SCI_SETCARETFORE, 0xFFFFFF);
+
+ /*
+ * FIXME: Default styles should probably be set interface-based
+ * (system defaults)
+ */
+ ssm(SCI_STYLESETFORE, STYLE_DEFAULT, 0xFFFFFF);
+ ssm(SCI_STYLESETBACK, STYLE_DEFAULT, 0x000000);
+ ssm(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)"Courier");
+ ssm(SCI_STYLECLEARALL);
+
+ ssm(SCI_STYLESETBACK, STYLE_LINENUMBER, 0x000000);
+}
+
+void
+Interface::UndoTokenShowView::run(void)
+{
+ /*
+ * Implementing this here allows us to reference
+ * `interface`
+ */
+ interface.show_view(view);
+}
+
+void
+Interface::stdio_vmsg(MessageType type, const gchar *fmt, va_list ap)
+{
+ gchar buf[255];
+
+ g_vsnprintf(buf, sizeof(buf), fmt, 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;
+ }
+}
+
+void
+Interface::process_notify(SCNotification *notify)
+{
+#ifdef DEBUG
+ g_printf("SCINTILLA NOTIFY: code=%d\n", notify->nmhdr.code);
+#endif
+}
+
+} /* namespace SciTECO */
diff --git a/src/interface.h b/src/interface.h
index e2d24de..f7bec85 100644
--- a/src/interface.h
+++ b/src/interface.h
@@ -34,6 +34,65 @@ class QRegister;
class Buffer;
extern sig_atomic_t sigint_occurred;
+class View {
+ class UndoTokenMessage : public UndoToken {
+ View *view;
+
+ unsigned int iMessage;
+ uptr_t wParam;
+ sptr_t lParam;
+
+ public:
+ UndoTokenMessage(View *_view, unsigned int _iMessage,
+ uptr_t _wParam = 0, sptr_t _lParam = 0)
+ : UndoToken(), view(_view),
+ iMessage(_iMessage),
+ wParam(_wParam), lParam(_lParam) {}
+
+ void
+ run(void)
+ {
+ view->ssm(iMessage, wParam, lParam);
+ }
+ };
+
+ class UndoTokenSetRepresentations : public UndoToken {
+ View *view;
+
+ public:
+ UndoTokenSetRepresentations(View *_view)
+ : view(_view) {}
+
+ void
+ run(void)
+ {
+ view->set_representations();
+ }
+ };
+
+public:
+ virtual ~View() {}
+
+ virtual sptr_t ssm(unsigned int iMessage,
+ uptr_t wParam = 0, sptr_t lParam = 0) = 0;
+ inline void
+ undo_ssm(unsigned int iMessage,
+ uptr_t wParam = 0, sptr_t lParam = 0)
+ {
+ undo.push(new UndoTokenMessage(this, iMessage, wParam, lParam));
+ }
+
+ void set_representations(void);
+ inline void
+ undo_set_representations(void)
+ {
+ undo.push(new UndoTokenSetRepresentations(this));
+ }
+
+protected:
+ void initialize(void);
+};
+
/*
* Base class for all user interfaces - used mereley as a class interface.
* The actual instance of the interface has the platform-specific type
@@ -43,8 +102,19 @@ extern sig_atomic_t sigint_occurred;
* There's only one Interface* instance in the system.
*/
class Interface {
+ class UndoTokenShowView : public UndoToken {
+ View *view;
+
+ public:
+ UndoTokenShowView(View *_view)
+ : view(_view) {}
+
+ void run(void);
+ };
+
template <class Type>
class UndoTokenInfoUpdate : public UndoToken {
+ /* FIXME: can be implement this in interface.cpp - avoid saving iface */
Interface *iface;
Type *obj;
@@ -86,8 +156,18 @@ public:
}
virtual void msg_clear(void) {}
+ virtual void show_view(View *view) = 0;
+ inline void
+ undo_show_view(View *view)
+ {
+ undo.push(new UndoTokenShowView(view));
+ }
+ virtual View *get_current_view(void) = 0;
+
virtual sptr_t ssm(unsigned int iMessage,
uptr_t wParam = 0, sptr_t lParam = 0) = 0;
+ virtual void undo_ssm(unsigned int iMessage,
+ uptr_t wParam = 0, sptr_t lParam = 0) = 0;
virtual void info_update(QRegister *reg) = 0;
virtual void info_update(Buffer *buffer) = 0;
diff --git a/src/main.cpp b/src/main.cpp
index ed46747..a713964 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,7 +19,6 @@
#include "config.h"
#endif
-#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -30,9 +29,6 @@
#include <glib/gprintf.h>
#include <glib/gstdio.h>
-#include <Scintilla.h>
-#include <SciLexer.h>
-
#include "sciteco.h"
#include "cmdline.h"
#include "interface.h"
@@ -88,37 +84,6 @@ static void sigint_handler(int signal);
}
void
-Interface::stdio_vmsg(MessageType type, const gchar *fmt, va_list ap)
-{
- gchar buf[255];
-
- g_vsnprintf(buf, sizeof(buf), fmt, 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;
- }
-}
-
-void
-Interface::process_notify(SCNotification *notify)
-{
-#ifdef DEBUG
- g_printf("SCINTILLA NOTIFY: code=%d\n", notify->nmhdr.code);
-#endif
-}
-
-void
String::get_coord(const gchar *str, gint pos,
gint &line, gint &column)
{
@@ -321,19 +286,12 @@ main(int argc, char **argv)
interface.main(argc, argv);
/* remaining arguments are arguments to the munged file */
- interface.ssm(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK);
- interface.ssm(SCI_SETCARETFORE, 0xFFFFFF);
-
/*
- * FIXME: Default styles should probably be set interface-based
- * (system defaults)
+ * QRegister view must be initialized only now
+ * (after Curses initialization)
*/
- interface.ssm(SCI_STYLESETFORE, STYLE_DEFAULT, 0xFFFFFF);
- interface.ssm(SCI_STYLESETBACK, STYLE_DEFAULT, 0x000000);
- interface.ssm(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)"Courier");
- interface.ssm(SCI_STYLECLEARALL);
-
- interface.ssm(SCI_STYLESETBACK, STYLE_LINENUMBER, 0x000000);
+ QRegisters::view = new ViewCurrent();
+ // FIXME: view should be deallocated */
/* search string and status register */
QRegisters::globals.insert("_");
diff --git a/src/parser.cpp b/src/parser.cpp
index f839840..61d43cc 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -512,7 +512,7 @@ StateStart::insert_integer(tecoInt v)
ring.dirtify();
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
}
tecoInt
@@ -554,7 +554,7 @@ StateStart::move_chars(tecoInt n)
interface.ssm(SCI_GOTOPOS, pos + n);
if (current_doc_must_undo())
- undo.push_msg(SCI_GOTOPOS, pos);
+ interface.undo_ssm(SCI_GOTOPOS, pos);
return SUCCESS;
}
@@ -570,7 +570,7 @@ StateStart::move_lines(tecoInt n)
interface.ssm(SCI_GOTOLINE, line);
if (current_doc_must_undo())
- undo.push_msg(SCI_GOTOPOS, pos);
+ interface.undo_ssm(SCI_GOTOPOS, pos);
return SUCCESS;
}
@@ -619,9 +619,9 @@ StateStart::delete_words(tecoInt n)
return FAILURE;
}
- undo.push_msg(SCI_GOTOPOS, pos);
+ interface.undo_ssm(SCI_GOTOPOS, pos);
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
ring.dirtify();
return SUCCESS;
@@ -1008,7 +1008,7 @@ StateStart::custom(gchar chr)
interface.ssm(SCI_ENDUNDOACTION);
/* must always support undo on global register */
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
break;
case '}':
@@ -1063,8 +1063,8 @@ StateStart::custom(gchar chr)
v = expressions.pop_num_calc(1, 0);
if (Validate::pos(v)) {
if (current_doc_must_undo())
- undo.push_msg(SCI_GOTOPOS,
- interface.ssm(SCI_GETCURRENTPOS));
+ interface.undo_ssm(SCI_GOTOPOS,
+ interface.ssm(SCI_GETCURRENTPOS));
interface.ssm(SCI_GOTOPOS, v);
if (eval_colon())
@@ -1202,7 +1202,7 @@ StateStart::custom(gchar chr)
}
if (v < 0) {
if (current_doc_must_undo())
- undo.push_msg(SCI_GOTOPOS, pos);
+ interface.undo_ssm(SCI_GOTOPOS, pos);
if (eval_colon())
expressions.push(SUCCESS);
} else {
@@ -1366,8 +1366,8 @@ StateStart::custom(gchar chr)
break;
if (current_doc_must_undo()) {
- undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS));
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS));
+ interface.undo_ssm(SCI_UNDO);
}
interface.ssm(SCI_BEGINUNDOACTION);
@@ -2077,7 +2077,7 @@ StateInsert::initial(void)
ring.dirtify();
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
}
void
@@ -2091,7 +2091,7 @@ StateInsert::process(const gchar *str, gint new_chars)
ring.dirtify();
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
}
State *
diff --git a/src/qregisters.cpp b/src/qregisters.cpp
index fa95c80..981db88 100644
--- a/src/qregisters.cpp
+++ b/src/qregisters.cpp
@@ -59,6 +59,7 @@ namespace States {
namespace QRegisters {
QRegisterTable *locals = NULL;
QRegister *current = NULL;
+ ViewCurrent *view = NULL;
void
undo_edit(void)
@@ -73,26 +74,19 @@ namespace QRegisters {
static QRegister *register_argument = NULL;
-static inline void
-current_edit(void)
-{
- if (ring.current)
- ring.current->edit();
- else if (QRegisters::current)
- QRegisters::current->edit();
-}
-
void
QRegisterData::set_string(const gchar *str)
{
- edit();
+ string.edit(QRegisters::view);
string.reset();
- interface.ssm(SCI_BEGINUNDOACTION);
- interface.ssm(SCI_SETTEXT, 0, (sptr_t)(str ? : ""));
- interface.ssm(SCI_ENDUNDOACTION);
+ QRegisters::view->ssm(SCI_BEGINUNDOACTION);
+ QRegisters::view->ssm(SCI_SETTEXT, 0,
+ (sptr_t)(str ? : ""));
+ QRegisters::view->ssm(SCI_ENDUNDOACTION);
- current_edit();
+ if (QRegisters::current)
+ QRegisters::current->string.edit(QRegisters::view);
}
void
@@ -104,30 +98,34 @@ QRegisterData::undo_set_string(void)
if (!must_undo)
return;
- if (ring.current)
- ring.current->undo_edit();
- else if (QRegisters::current)
- QRegisters::current->undo_edit();
+ if (QRegisters::current)
+ QRegisters::current->string.undo_edit(QRegisters::view);
string.undo_reset();
- undo.push_msg(SCI_UNDO);
+ QRegisters::view->undo_ssm(SCI_UNDO);
- undo_edit();
+ string.undo_edit(QRegisters::view);
}
void
QRegisterData::append_string(const gchar *str)
{
- if (!str)
+ /*
+ * NOTE: Will not create undo action
+ * if string is empty
+ */
+ if (!str || !*str)
return;
- edit();
+ string.edit(QRegisters::view);
- interface.ssm(SCI_BEGINUNDOACTION);
- interface.ssm(SCI_APPENDTEXT, strlen(str), (sptr_t)str);
- interface.ssm(SCI_ENDUNDOACTION);
+ QRegisters::view->ssm(SCI_BEGINUNDOACTION);
+ QRegisters::view->ssm(SCI_APPENDTEXT,
+ strlen(str), (sptr_t)str);
+ QRegisters::view->ssm(SCI_ENDUNDOACTION);
- current_edit();
+ if (QRegisters::current)
+ QRegisters::current->string.edit(QRegisters::view);
}
gchar *
@@ -140,13 +138,14 @@ QRegisterData::get_string(void)
return g_strdup("");
current_doc_update();
- edit();
+ string.edit(QRegisters::view);
- size = interface.ssm(SCI_GETLENGTH) + 1;
+ size = QRegisters::view->ssm(SCI_GETLENGTH) + 1;
str = (gchar *)g_malloc(size);
- interface.ssm(SCI_GETTEXT, size, (sptr_t)str);
+ QRegisters::view->ssm(SCI_GETTEXT, size, (sptr_t)str);
- current_edit();
+ if (QRegisters::current)
+ QRegisters::current->string.edit(QRegisters::view);
return str;
}
@@ -154,20 +153,26 @@ QRegisterData::get_string(void)
void
QRegisterData::edit(void)
{
- string.edit();
+ string.edit(QRegisters::view);
+ interface.show_view(QRegisters::view);
}
void
QRegisterData::undo_edit(void)
{
- if (must_undo)
- string.undo_edit();
+ if (!must_undo)
+ return;
+
+ string.undo_edit(QRegisters::view);
+ interface.undo_show_view(QRegisters::view);
}
void
QRegister::edit(void)
{
- string.edit();
+ /* NOTE: could call QRegisterData::edit() */
+ string.edit(QRegisters::view);
+ interface.show_view(QRegisters::view);
interface.info_update(this);
}
@@ -178,7 +183,9 @@ QRegister::undo_edit(void)
return;
interface.undo_info_update(this);
- string.undo_edit();
+ /* NOTE: could call QRegisterData::undo_edit() */
+ string.undo_edit(QRegisters::view);
+ interface.undo_show_view(QRegisters::view);
}
void
@@ -213,17 +220,18 @@ QRegister::load(const gchar *filename)
if (!g_file_get_contents(filename, &contents, &size, &gerror))
throw GlibError(gerror);
- edit();
+ string.edit(QRegisters::view);
string.reset();
- interface.ssm(SCI_BEGINUNDOACTION);
- interface.ssm(SCI_CLEARALL);
- interface.ssm(SCI_APPENDTEXT, size, (sptr_t)contents);
- interface.ssm(SCI_ENDUNDOACTION);
+ QRegisters::view->ssm(SCI_BEGINUNDOACTION);
+ QRegisters::view->ssm(SCI_CLEARALL);
+ QRegisters::view->ssm(SCI_APPENDTEXT, size, (sptr_t)contents);
+ QRegisters::view->ssm(SCI_ENDUNDOACTION);
g_free(contents);
- current_edit();
+ if (QRegisters::current)
+ QRegisters::current->string.edit(QRegisters::view);
}
tecoInt
@@ -245,23 +253,20 @@ QRegisterBufferInfo::get_integer(void)
gchar *
QRegisterBufferInfo::get_string(void)
{
- gchar *filename = ring.current ? ring.current->filename : NULL;
-
- return g_strdup(filename ? : "");
+ return g_strdup(ring.current ? ring.current->filename : "");
}
void
QRegisterBufferInfo::edit(void)
{
- gchar *filename = ring.current ? ring.current->filename : NULL;
-
QRegister::edit();
- interface.ssm(SCI_BEGINUNDOACTION);
- interface.ssm(SCI_SETTEXT, 0, (sptr_t)(filename ? : ""));
- interface.ssm(SCI_ENDUNDOACTION);
+ QRegisters::view->ssm(SCI_BEGINUNDOACTION);
+ QRegisters::view->ssm(SCI_SETTEXT, 0,
+ (sptr_t)(ring.current ? ring.current->filename : ""));
+ QRegisters::view->ssm(SCI_ENDUNDOACTION);
- undo.push_msg(SCI_UNDO);
+ QRegisters::view->undo_ssm(SCI_UNDO);
}
QRegisterTable::QRegisterTable(bool _undo) : RBTree(), must_undo(_undo)
@@ -648,7 +653,7 @@ StateGetQRegString::got_register(QRegister &reg)
interface.ssm(SCI_ENDUNDOACTION);
ring.dirtify();
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
}
g_free(str);
diff --git a/src/qregisters.h b/src/qregisters.h
index 556ce7b..e0e8520 100644
--- a/src/qregisters.h
+++ b/src/qregisters.h
@@ -34,6 +34,11 @@
namespace SciTECO {
+namespace QRegisters {
+ /* constructed after Interface.main() in main() */
+ extern ViewCurrent *view;
+}
+
/*
* Classes
*/
@@ -41,7 +46,21 @@ namespace SciTECO {
class QRegisterData {
protected:
tecoInt integer;
- Document string;
+
+ class QRegisterString : public Document {
+ public:
+ ~QRegisterString()
+ {
+ release_document();
+ }
+
+ private:
+ ViewCurrent *
+ get_create_document_view(void)
+ {
+ return QRegisters::view;
+ }
+ } string;
public:
/*
@@ -70,9 +89,9 @@ public:
}
inline void
- update_string(void)
+ update_string()
{
- string.update();
+ string.update(QRegisters::view);
}
virtual void set_string(const gchar *str);
diff --git a/src/ring.cpp b/src/ring.cpp
index f7dc3bf..25a46ce 100644
--- a/src/ring.cpp
+++ b/src/ring.cpp
@@ -137,12 +137,10 @@ Buffer::load(const gchar *filename)
if (!g_file_get_contents(filename, &contents, &size, &gerror))
throw GlibError(gerror);
- edit();
-
- interface.ssm(SCI_BEGINUNDOACTION);
- interface.ssm(SCI_CLEARALL);
- interface.ssm(SCI_APPENDTEXT, size, (sptr_t)contents);
- interface.ssm(SCI_ENDUNDOACTION);
+ ssm(SCI_BEGINUNDOACTION);
+ ssm(SCI_CLEARALL);
+ ssm(SCI_APPENDTEXT, size, (sptr_t)contents);
+ ssm(SCI_ENDUNDOACTION);
g_free(contents);
@@ -263,6 +261,7 @@ Ring::edit(const gchar *filename)
undo_close();
if (filename && g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
+ buffer->edit();
buffer->load(filename);
interface.msg(Interface::MSG_INFO,
@@ -489,7 +488,6 @@ Ring::close(void)
{
Buffer *buffer = current;
- buffer->update();
close(buffer);
current = buffer->next() ? : buffer->prev();
/* transfer responsibility to UndoToken object */
diff --git a/src/ring.h b/src/ring.h
index 8fc148c..00284cb 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -30,7 +30,6 @@
#include "sciteco.h"
#include "interface.h"
#include "undo.h"
-#include "document.h"
#include "qregisters.h"
#include "parser.h"
@@ -56,7 +55,7 @@ gchar *get_absolute_path(const gchar *path);
* Classes
*/
-class Buffer : public Document {
+class Buffer : private ViewCurrent {
class UndoTokenClose : public UndoToken {
Buffer *buffer;
@@ -74,8 +73,12 @@ public:
gint savepoint_id;
bool dirty;
- Buffer() : Document(),
- filename(NULL), savepoint_id(0), dirty(false) {}
+ Buffer() : ViewCurrent(),
+ filename(NULL), savepoint_id(0), dirty(false)
+ {
+ set_representations();
+ }
+
~Buffer()
{
g_free(filename);
@@ -106,14 +109,14 @@ public:
inline void
edit(void)
{
- Document::edit();
+ interface.show_view(this);
interface.info_update(this);
}
inline void
undo_edit(void)
{
interface.undo_info_update(this);
- Document::undo_edit();
+ interface.undo_show_view(this);
}
void load(const gchar *filename);
@@ -198,7 +201,6 @@ public:
inline void
undo_edit(void)
{
- current->update();
undo.push_var(QRegisters::current);
undo.push_var(current)->undo_edit();
}
@@ -243,9 +245,7 @@ namespace States {
static inline void
current_doc_update(void)
{
- if (ring.current)
- ring.current->update();
- else if (QRegisters::current)
+ if (QRegisters::current)
QRegisters::current->update_string();
}
diff --git a/src/search.cpp b/src/search.cpp
index bd0802e..16706ee 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -421,9 +421,9 @@ StateSearch::process(const gchar *str, gint new_chars)
gint count = parameters.count;
if (current_doc_must_undo())
- undo.push_msg(SCI_SETSEL,
- interface.ssm(SCI_GETANCHOR),
- interface.ssm(SCI_GETCURRENTPOS));
+ interface.undo_ssm(SCI_SETSEL,
+ interface.ssm(SCI_GETANCHOR),
+ interface.ssm(SCI_GETCURRENTPOS));
search_reg->undo_set_integer();
search_reg->set_integer(FAILURE);
@@ -510,7 +510,7 @@ StateSearch::done(const gchar *str)
/* workaround: preserve selection (also on rubout) */
gint anchor = interface.ssm(SCI_GETANCHOR);
if (current_doc_must_undo())
- undo.push_msg(SCI_SETANCHOR, anchor);
+ interface.undo_ssm(SCI_SETANCHOR, anchor);
search_reg->undo_set_string();
search_reg->set_string(str);
@@ -661,7 +661,7 @@ StateSearchKill::done(const gchar *str)
gint anchor = interface.ssm(SCI_GETANCHOR);
if (current_doc_must_undo())
- undo.push_msg(SCI_GOTOPOS, dot);
+ interface.undo_ssm(SCI_GOTOPOS, dot);
interface.ssm(SCI_GOTOPOS, anchor);
interface.ssm(SCI_DELETERANGE,
@@ -674,7 +674,7 @@ StateSearchKill::done(const gchar *str)
ring.dirtify();
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
return &States::start;
}
@@ -708,7 +708,7 @@ StateSearchDelete::done(const gchar *str)
ring.dirtify();
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
}
return &States::start;
diff --git a/src/spawn.cpp b/src/spawn.cpp
index 9e8f620..e346950 100644
--- a/src/spawn.cpp
+++ b/src/spawn.cpp
@@ -316,7 +316,7 @@ StateExecuteCommand::done(const gchar *str)
if (!register_argument) {
if (current_doc_must_undo())
- undo.push_msg(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS));
+ interface.undo_ssm(SCI_GOTOPOS, interface.ssm(SCI_GETCURRENTPOS));
interface.ssm(SCI_GOTOPOS, ctx.to);
}
@@ -331,7 +331,7 @@ StateExecuteCommand::done(const gchar *str)
(ctx.from != ctx.to || ctx.text_added)) {
/* undo action is only effective if it changed anything */
if (current_doc_must_undo())
- undo.push_msg(SCI_UNDO);
+ interface.undo_ssm(SCI_UNDO);
interface.ssm(SCI_SCROLLCARET);
ring.dirtify();
}
diff --git a/src/undo.cpp b/src/undo.cpp
index 55df610..d123a7c 100644
--- a/src/undo.cpp
+++ b/src/undo.cpp
@@ -39,12 +39,6 @@ namespace SciTECO {
UndoStack undo;
void
-UndoTokenMessage::run(void)
-{
- interface.ssm(iMessage, wParam, lParam);
-}
-
-void
UndoStack::push(UndoToken *token)
{
if (enabled) {
diff --git a/src/undo.h b/src/undo.h
index 5cc3b3a..b4742c3 100644
--- a/src/undo.h
+++ b/src/undo.h
@@ -23,8 +23,6 @@
#include <glib.h>
#include <glib/gprintf.h>
-#include <Scintilla.h>
-
#ifdef DEBUG
#include "parser.h"
#endif
@@ -42,20 +40,6 @@ public:
virtual void run() = 0;
};
-class UndoTokenMessage : public UndoToken {
- unsigned int iMessage;
- uptr_t wParam;
- sptr_t lParam;
-
-public:
- UndoTokenMessage(unsigned int _iMessage,
- uptr_t _wParam = 0, sptr_t _lParam = 0)
- : UndoToken(), iMessage(_iMessage),
- wParam(_wParam), lParam(_lParam) {}
-
- void run(void);
-};
-
template <typename Type>
class UndoTokenVariable : public UndoToken {
Type *ptr;
@@ -140,13 +124,6 @@ public:
void push(UndoToken *token);
- inline void
- push_msg(unsigned int iMessage,
- uptr_t wParam = 0, sptr_t lParam = 0)
- {
- push(new UndoTokenMessage(iMessage, wParam, lParam));
- }
-
template <typename Type>
inline Type &
push_var(Type &variable, Type value)