diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-12-04 17:29:01 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2012-12-04 22:07:08 +0100 |
commit | d8a316514c03d85b771a9dce4a8a51b875d955b3 (patch) | |
tree | 8966c29db767a155848f6d90f76771ce5b9de32e /src/ring.h | |
parent | b120616b6da52e951097f69ad267de06081d218a (diff) | |
download | sciteco-d8a316514c03d85b771a9dce4a8a51b875d955b3.tar.gz |
autoconf preparation: move everything into src/ subdir
Diffstat (limited to 'src/ring.h')
-rw-r--r-- | src/ring.h | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/ring.h b/src/ring.h new file mode 100644 index 0000000..da4f322 --- /dev/null +++ b/src/ring.h @@ -0,0 +1,246 @@ +#ifndef __RING_H +#define __RING_H + +#include <string.h> +#include <bsd/sys/queue.h> + +#include <glib.h> +#include <glib/gprintf.h> +#include <glib/gstdio.h> + +#include <Scintilla.h> + +#include "sciteco.h" +#include "interface.h" +#include "undo.h" +#include "qregisters.h" +#include "parser.h" + +/* + * Auxiliary functions + */ +static inline bool +is_glob_pattern(const gchar *str) +{ + return strchr(str, '*') || strchr(str, '?'); +} + +/* + * Get absolute/full version of a possibly relative path. + * Works with existing and non-existing paths (in the latter case, + * heuristics may be applied.) + */ +gchar *get_absolute_path(const gchar *path); + +/* + * Classes + */ + +class Buffer { + class UndoTokenClose : public UndoToken { + Buffer *buffer; + + public: + UndoTokenClose(Buffer *_buffer) + : UndoToken(), buffer(_buffer) {} + + void run(void); + }; + +public: + TAILQ_ENTRY(Buffer) buffers; + + gchar *filename; + gint dot; + + gint savepoint_id; + + bool dirty; + +private: + typedef void document; + document *doc; + +public: + Buffer() : filename(NULL), dot(0), savepoint_id(0), dirty(false) + { + doc = (document *)interface.ssm(SCI_CREATEDOCUMENT); + } + ~Buffer() + { + interface.ssm(SCI_RELEASEDOCUMENT, 0, (sptr_t)doc); + g_free(filename); + } + + inline Buffer *& + next(void) + { + return TAILQ_NEXT(this, buffers); + } + inline Buffer *& + prev(void) + { + TAILQ_HEAD(Head, Buffer); + + return TAILQ_PREV(this, Head, buffers); + } + + inline void + set_filename(const gchar *filename) + { + gchar *resolved = get_absolute_path(filename); + g_free(Buffer::filename); + Buffer::filename = resolved; + interface.info_update(this); + } + + inline void + edit(void) + { + interface.ssm(SCI_SETDOCPOINTER, 0, (sptr_t)doc); + interface.ssm(SCI_GOTOPOS, dot); + interface.info_update(this); + } + inline void + undo_edit(void) + { + interface.undo_info_update(this); + undo.push_msg(SCI_GOTOPOS, dot); + undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)doc); + } + + bool load(const gchar *filename); + + inline void + undo_close(void) + { + undo.push(new UndoTokenClose(this)); + } +}; + +extern class Ring { + /* + * Emitted after a buffer close + * The pointer is the only remaining reference to the buffer! + */ + class UndoTokenEdit : public UndoToken { + Ring *ring; + Buffer *buffer; + + public: + UndoTokenEdit(Ring *_ring, Buffer *_buffer) + : UndoToken(), ring(_ring), buffer(_buffer) {} + ~UndoTokenEdit() + { + if (buffer) + delete buffer; + } + + void run(void); + }; + + class UndoTokenRemoveFile : public UndoToken { + gchar *filename; + + public: + UndoTokenRemoveFile(const gchar *_filename) + : filename(g_strdup(_filename)) {} + ~UndoTokenRemoveFile() + { + g_free(filename); + } + + void + run(void) + { + g_unlink(filename); + } + }; + + TAILQ_HEAD(Head, Buffer) head; + +public: + Buffer *current; + + Ring() : current(NULL) + { + TAILQ_INIT(&head); + } + ~Ring(); + + inline Buffer * + first(void) + { + return TAILQ_FIRST(&head); + } + inline Buffer * + last(void) + { + return TAILQ_LAST(&head, Head); + } + + Buffer *find(const gchar *filename); + Buffer *find(gint64 id); + + void dirtify(void); + bool is_any_dirty(void); + + bool edit(gint64 id); + void edit(const gchar *filename); + inline void + undo_edit(void) + { + current->dot = interface.ssm(SCI_GETCURRENTPOS); + undo.push_var(current); + current->undo_edit(); + } + + bool save(const gchar *filename); + + void close(Buffer *buffer); + void close(void); + inline void + undo_close(void) + { + current->undo_close(); + } +} ring; + +/* + * Command states + */ + +class StateEditFile : public StateExpectString { +private: + bool allowFilename; + + void do_edit(const gchar *filename) throw (Error); + void do_edit(gint64 id) throw (Error); + + void initial(void) throw (Error); + State *done(const gchar *str) throw (Error); +}; + +class StateSaveFile : public StateExpectString { +private: + State *done(const gchar *str) throw (Error); +}; + +namespace States { + extern StateEditFile editfile; + extern StateSaveFile savefile; +} + +/* FIXME: clean up current_save_dot() usage */ +static inline void +current_save_dot(void) +{ + gint dot = interface.ssm(SCI_GETCURRENTPOS); + + if (ring.current) + ring.current->dot = dot; + else if (QRegisters::current) + QRegisters::current->dot = dot; +} + +#endif |