aboutsummaryrefslogtreecommitdiffhomepage
path: root/qbuffers.h
blob: 0f1c16e3500a5eb150d96cfb09f43e2fadcedf4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#ifndef __QBUFFERS_H
#define __QBUFFERS_H

#include <bsd/sys/queue.h>

#include <glib.h>
#include <glib/gprintf.h>

#include <Scintilla.h>

#include "sciteco.h"
#include "undo.h"
#include "parser.h"

class Buffer {
	class UndoTokenClose : public UndoToken {
		Buffer *buffer;

	public:
		UndoTokenClose(Buffer *_buffer)
			      : UndoToken(), buffer(_buffer) {}

		void
		run(void)
		{
			buffer->close();
			delete buffer;
		}
	};

public:
	LIST_ENTRY(Buffer) buffers;

	gchar *filename;
	gint dot;

private:
	typedef void document;
	document *doc;

public:
	Buffer() : filename(NULL), dot(0)
	{
		doc = (document *)editor_msg(SCI_CREATEDOCUMENT);
	}
	~Buffer()
	{
		editor_msg(SCI_RELEASEDOCUMENT, 0, (sptr_t)doc);
		g_free(filename);
	}

	inline void
	set_filename(const gchar *filename)
	{
		g_free(Buffer::filename);
		Buffer::filename = filename ? g_strdup(filename) : NULL;
	}

	inline void
	edit(void)
	{
		editor_msg(SCI_SETDOCPOINTER, 0, (sptr_t)doc);
		editor_msg(SCI_GOTOPOS, dot);
	}
	inline void
	undo_edit(void)
	{
		undo.push_msg(SCI_GOTOPOS, dot);
		undo.push_msg(SCI_SETDOCPOINTER, 0, (sptr_t)doc);
	}

	bool load(const gchar *filename);

	void close(void);
	inline void
	undo_close(void)
	{
		undo.push(new UndoTokenClose(this));
	}
};

extern class Ring {
	LIST_HEAD(Head, Buffer) head;
	Buffer *current;

public:
	Ring() : current(NULL)
	{
		LIST_INIT(&head);
	}
	~Ring();

	Buffer *find(const gchar *filename);

	bool edit(const gchar *filename);
	inline void
	undo_edit(void)
	{
		current->dot = editor_msg(SCI_GETCURRENTPOS);

		undo.push_var<Buffer*>(current);
		current->undo_edit();
	}

	void close(void);
	inline void
	undo_close(void)
	{
		current->undo_close();
	}
} ring;

/*
 * Command states
 */

class StateFile : public StateExpectString {
private:
	void do_edit(const gchar *filename);

	State *done(const gchar *str);
};

#endif