Develop and Download Open Source Software

Browse CVS Repository

Annotation of /shiki/shiki/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (hide annotations) (download) (as text)
Wed Nov 29 04:37:23 2006 UTC (17 years, 4 months ago) by aloha
Branch: MAIN
Changes since 1.8: +145 -3 lines
File MIME type: text/x-csrc
bug fix (C-x C-s) and add no-or-yes-p API

1 aloha 1.1 /* vim: set encoding=utf8:
2     *
3     * buffer.c
4     *
5     * This file is part of Shiki.
6     *
7     * Copyright(C)2006 WAKATSUKI toshihiro
8     *
9     * Permission is hereby granted, free of charge, to any person obtaining a
10     * copy of this software and associated documentation files (the "Software"),
11     * to deal in the Software without restriction, including without limitation
12     * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13     * and/or sell copies of the Software, and to permit persons to whom the
14     * Software is furnished to do so, subject to the following conditions:
15     *
16     * The above copyright notice and this permission notice shall be included in
17     * all copies or substantial portions of the Software.
18     *
19     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25     * SOFTWARE.
26     *
27 aloha 1.9 * $Id: buffer.c,v 1.8 2006/11/28 16:29:22 aloha Exp $
28 aloha 1.1 */
29     #include"shiki.h"
30 aloha 1.2
31 aloha 1.9 ScmClass *ShikiBufferClass;
32     extern void Scm_Init_xyzzylisp(ScmModule *module);
33    
34 aloha 1.7 /* GtkTextBuffer ��������������������� ShikiBuffer ��������������������� */
35     static gint compBuffer(gconstpointer a, gconstpointer b) {
36     return ((ShikiBuffer *)a)->text_buffer == b ? 0 : b - a;
37     }
38 aloha 1.3
39 aloha 1.7 static GList *get_ShikiBufferListElement_By_GtkTextBuffer(GtkTextBuffer *b) {
40     return g_list_find_custom(Shiki_EDITOR_BUFFER_LIST, b, compBuffer);
41 aloha 1.3 }
42 aloha 1.4
43 aloha 1.9 static void buffer_print(ScmObj obj, ScmPort *out, ScmWriteContext *ctx) {
44     GtkTextBuffer *b = SHIKI_BUFFER_UNBOX(obj);
45     GList *l = g_list_find_custom(Shiki_EDITOR_BUFFER_LIST, b, compBuffer);
46     if(l)
47     Scm_Printf(out, "#<buffer: %s>", ((ShikiBuffer *)(l->data))->name);
48     else
49     Scm_Printf(out, "#<deleted buffer: %p>", b);
50     }
51    
52     static void buffer_cleanup(ScmObj obj)
53     {
54     g_object_unref(SHIKI_BUFFER_UNBOX(obj));
55     }
56    
57     /* ������������������������������������������������������������������������������������������ */
58     static gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, GtkTextBuffer *buffer){
59     /* delete-event ������������������������FALSE ��������������������������������������������� */
60     return Shiki_need_buffer_save_p(buffer) && !Shiki_yes_or_no_p("��������������������������������������������������������������������������� ?");
61     }
62    
63     /* ��������������������������������������������� */
64     static void insert_text_handler(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *str, gint len) {
65     /* Undo ��������������������������� */
66     ShikiUndoInfo *undoInfo = g_malloc(sizeof(ShikiUndoInfo));
67     g_return_if_fail(undoInfo != NULL);
68     undoInfo->action = SHIKI_UNDO_INSERT;
69     undoInfo->str = g_strdup(str);
70     undoInfo->strlen = len;
71     undoInfo->start = gtk_text_iter_get_offset(iter);
72     undoInfo->end = undoInfo->start + undoInfo->strlen;
73     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
74     }
75    
76     /* ��������������������������������������������������������������� */
77     static void update_modeline_label() {
78     static gchar label[1024];
79     GtkTextIter p;
80     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
81    
82     g_snprintf(label, 1024, "--%s- %-10s (Gauche Interaction) [%s] L%d:%d ",
83     gtk_text_buffer_get_modified(Shiki_CURRENT_TEXT_BUFFER) ? "**" : "--",
84     Shiki_CURRENT_BASENAME,
85     Shiki_CURRENT_CES,
86     gtk_text_iter_get_line(&p) + 1,
87     gtk_text_iter_get_line_offset (&p) + 1);
88     gtk_label_set_text(GTK_LABEL(Shiki_EDITOR_MODELINE_LABEL), label);
89     }
90    
91     /* ������������������������������������������������ */
92     static void delete_range_handler(GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end) {
93     /* Undo ��������������������������� */
94     ShikiUndoInfo *undoInfo = g_malloc(sizeof(ShikiUndoInfo));
95     g_return_if_fail(undoInfo != NULL);
96     undoInfo->action = SHIKI_UNDO_DELETE;
97     undoInfo->str = gtk_text_buffer_get_text(buffer, start, end, FALSE);
98     undoInfo->start = gtk_text_iter_get_offset(start);
99     undoInfo->end = gtk_text_iter_get_offset(end);
100     undoInfo->strlen = end - start;
101     Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
102     }
103    
104     /* ��������������������������������������� (������������) ��������� */
105     GtkTextBuffer *Shiki_new_buffer_create(gchar *filename) {
106     /*-------------------- ������������������������ ----------------------------------*/
107     /* ShikiBuffer ������������������������������������������������������������������ */
108     ShikiBuffer *tabinfo = g_malloc(sizeof(ShikiBuffer));
109     tabinfo->locale = "Gtk Default (utf8)";
110     tabinfo->undoInfoList = NULL;
111     tabinfo->filename = filename;
112     tabinfo->name = g_path_get_basename(filename);
113     tabinfo->tabpage_label = g_strndup(tabinfo->name, 7);
114     tabinfo->env = Scm_MakeModule(NULL, FALSE);
115    
116     ShikiBufferClass = Scm_MakeForeignPointerClass(SCM_MODULE(tabinfo->env),
117     "<buffer>", buffer_print, buffer_cleanup,
118     SCM_FOREIGN_POINTER_KEEP_IDENTITY
119     |
120     SCM_FOREIGN_POINTER_MAP_NULL);
121    
122     /* xyzzy lisp ��������������� */
123     Scm_Init_xyzzylisp(SCM_MODULE(tabinfo->env));
124    
125     /* ������������������������������ (������������������������) ��������� */
126     tabinfo->tabpage = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
127     gtk_scrolled_window_set_policy (tabinfo->tabpage, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
128    
129     /* ��������������������������������������������������������������������������������������� */
130     tabinfo->text_view = GTK_TEXT_VIEW(gtk_text_view_new());
131     gtk_text_view_set_wrap_mode(tabinfo->text_view, GTK_WRAP_WORD);
132     tabinfo->text_buffer = gtk_text_view_get_buffer(tabinfo->text_view);
133     gtk_widget_set_size_request(GTK_WIDGET(tabinfo->text_view), 680, 700);
134    
135     gtk_container_add(GTK_CONTAINER(tabinfo->tabpage), GTK_WIDGET(tabinfo->text_view));
136     g_signal_connect(tabinfo->text_buffer, "mark_set", G_CALLBACK(update_modeline_label), tabinfo->text_view);
137     g_signal_connect(tabinfo->text_buffer, "insert-text", G_CALLBACK(insert_text_handler), NULL);
138     g_signal_connect(tabinfo->text_buffer, "delete-range", G_CALLBACK(delete_range_handler), NULL);
139    
140     /* ������������������������������������������������������������������������������������������������������ */
141     tabinfo->delete_handler_id = g_signal_connect(Shiki_EDITOR_WINDOW, "delete_event", G_CALLBACK(delete_event_handler), tabinfo->text_buffer);
142    
143     /* ������������������������ */
144    
145     /* ������������������������������������������������ */
146     gtk_text_buffer_create_tag(tabinfo->text_buffer, "parent_emphasis_background", "background", "green", NULL);
147    
148     /* ������������������������������������������ */
149     gtk_text_buffer_create_tag(tabinfo->text_buffer, "keyword_highlighting", "foreground", "blue", NULL);
150     /* ������ */
151     gtk_text_buffer_create_tag(tabinfo->text_buffer, "function_highlighting", "foreground", "red", NULL);
152     /* ������������ */
153     gtk_text_buffer_create_tag (tabinfo->text_buffer, "comment_highlighting", "foreground", "purple", NULL);
154     /* ��������� */
155     gtk_text_buffer_create_tag (tabinfo->text_buffer, "string_highlighting", "foreground", "orange", NULL);
156     /* ������������������������������������������ */
157     gtk_notebook_append_page(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(tabinfo->tabpage), gtk_label_new(tabinfo->tabpage_label));
158     /* ������������������������������������������������������������������ */
159     Shiki_EDITOR_BUFFER_LIST = g_list_append(Shiki_EDITOR_BUFFER_LIST, tabinfo);
160    
161     gtk_widget_show_all(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
162     /* ��������������������������������� */
163     gtk_notebook_set_current_page(Shiki_EDITOR_NOTEBOOK, g_list_length(Shiki_EDITOR_BUFFER_LIST) - 1);
164     //Shiki_CURRENT_TAB_INFO = tabinfo;
165     return tabinfo->text_buffer;
166     }
167    
168 aloha 1.7 void Shiki_delete_buffer(GtkTextBuffer *buffer) {
169     /* ��������������������������������������������������������������������������������������������������� */
170     /* ���������������������Scheme ������������������������ Gtk ������������������������������������������������ */
171     GList *bufListElem = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
172     ShikiBuffer *tabInfo = bufListElem->data;
173     gint bufNum = g_list_position(Shiki_EDITOR_BUFFER_LIST, bufListElem);
174    
175     /* ��������� 1 ��������������������������������������������������� */
176     if(g_list_length(Shiki_EDITOR_BUFFER_LIST) == 1)
177 aloha 1.4 return;
178 aloha 1.7 /* ��������������������������������������������������������������������������������������������� */
179     g_signal_handler_disconnect(Shiki_EDITOR_WINDOW, tabInfo->delete_handler_id);
180     Shiki_EDITOR_BUFFER_LIST = g_list_delete_link(Shiki_EDITOR_BUFFER_LIST, bufListElem);
181     gtk_widget_destroy(GTK_WIDGET(tabInfo->tabpage));
182     g_free(tabInfo->tabpage_label);
183     g_free(tabInfo->name);
184     g_free(tabInfo->filename);
185     g_free(tabInfo);
186     gtk_notebook_remove_page(Shiki_EDITOR_NOTEBOOK, bufNum);
187     /* ��������������� */
188     gtk_widget_queue_draw(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
189     }
190    
191     GtkTextBuffer *Shiki_find_buffer(const gchar *name) {
192     GList *l;
193     for(l = Shiki_EDITOR_BUFFER_LIST; l != NULL; l = l->next)
194     if(strcmp(((ShikiBuffer *)l->data)->name, name) == 0)
195     return ((ShikiBuffer *)l->data)->text_buffer;
196     return NULL;
197     }
198    
199     gchar *Shiki_buffer_substring(gint start, gint end) {
200     if(start >= end)
201     return NULL;
202     else {
203     GtkTextIter s, e;
204     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &s, start);
205     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &e, end);
206    
207     return gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &s, &e, FALSE);
208     }
209     }
210    
211     void Shiki_delete_region(gint start, gint end) {
212     if(start >= end)
213     return;
214     else {
215     GtkTextIter s, e;
216     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &s, start);
217     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &e, end);
218 aloha 1.4
219 aloha 1.7 return gtk_text_buffer_delete(Shiki_CURRENT_TEXT_BUFFER, &s, &e);
220     }
221 aloha 1.4 }
222    
223     gint Shiki_point() {
224     GtkTextIter p;
225     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
226     return gtk_text_iter_get_offset(&p);
227     }
228    
229     gint Shiki_point_max() {
230     GtkTextIter p;
231     gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
232     return gtk_text_iter_get_offset(&p);
233     }
234    
235     gint Shiki_point_min() {
236     return 0;
237     }
238    
239     void Shiki_goto_char(gint offset) {
240     GtkTextIter p;
241     gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &p, offset);
242     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
243     }
244    
245     void Shiki_forward_char() {
246     GtkTextIter p;
247     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
248     gtk_text_iter_forward_char(&p);
249     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
250     }
251    
252     void Shiki_backward_char() {
253     GtkTextIter p;
254     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
255     gtk_text_iter_backward_char(&p);
256     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
257     }
258    
259     void Shiki_goto_line(gint line) {
260     GtkTextIter p;
261     gtk_text_buffer_get_iter_at_line(Shiki_CURRENT_TEXT_BUFFER, &p, line);
262     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
263     }
264    
265     void Shiki_goto_bol() {
266     GtkTextIter p;
267     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
268     gtk_text_buffer_get_iter_at_line_offset(Shiki_CURRENT_TEXT_BUFFER, &p, gtk_text_iter_get_line(&p), 0);
269     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
270     }
271    
272     void Shiki_goto_eol() {
273     GtkTextIter p;
274     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
275     gtk_text_iter_forward_to_line_end(&p);
276     gtk_text_iter_backward_char(&p);
277     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
278     }
279 aloha 1.5
280 aloha 1.7 void Shiki_forward_line(gint count) {
281     GtkTextIter p;
282     gint i;
283     gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
284    
285     if(count >= 0) {
286     for(i = count; i != 0; i--)
287     gtk_text_view_forward_display_line(Shiki_CURRENT_TEXT_VIEW, &p);
288     } else {
289     for(i = count; i != 0; i++)
290     gtk_text_view_backward_display_line(Shiki_CURRENT_TEXT_VIEW, &p);
291     }
292     gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
293 aloha 1.5 }
294    
295     const char *Shiki_buffer_name(GtkTextBuffer *buffer) {
296     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
297     if(l)
298     return ((ShikiBuffer *)(l->data))->name;
299     else
300     return NULL;
301     }
302    
303 aloha 1.6 gboolean Shiki_deleted_buffer_p(GtkTextBuffer *buffer) {
304     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
305     if(l)
306     return FALSE;
307     else
308     return TRUE;
309     }
310    
311 aloha 1.5 GtkTextBuffer *Shiki_get_next_buffer(GtkTextBuffer *buffer) {
312     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
313     if(l && l->next)
314     return ((ShikiBuffer *)(l->next->data))->text_buffer;
315     else
316     return NULL;
317     }
318    
319     GtkTextBuffer *Shiki_get_previous_buffer(GtkTextBuffer *buffer) {
320     GList *l = get_ShikiBufferListElement_By_GtkTextBuffer(buffer);
321     if(l && l->prev)
322     return ((ShikiBuffer *)(l->prev->data))->text_buffer;
323     else
324     return NULL;
325     }
326    
327     ScmObj Shiki_buffer_list() {
328     GList *l;
329     GtkTextBuffer *b;
330     ScmObj bl = SCM_NIL;
331    
332     for(l = Shiki_EDITOR_BUFFER_LIST; l != NULL; l = l->next) {
333     b= ((ShikiBuffer *)(l->data))->text_buffer;
334     bl = Scm_Cons(SHIKI_BUFFER_BOX(g_object_ref(b)), bl);
335     }
336     return bl;
337     }
338 aloha 1.7
339     void Shiki_erase_buffer(GtkTextBuffer *buffer) {
340     GtkTextIter start, end;
341     gtk_text_buffer_get_start_iter(buffer, &start);
342     gtk_text_buffer_get_end_iter(buffer, &end);
343     gtk_text_buffer_delete(buffer, &start, &end);
344     }
345    
346     const gchar *Shiki_file_name_dialog(const gchar *msg) {
347    
348     GtkWidget *dialog = gtk_file_selection_new(msg);
349     gint resp = gtk_dialog_run(GTK_DIALOG(dialog));
350     const gchar *filename = NULL;
351    
352     if(resp == GTK_RESPONSE_OK)
353     filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(dialog));
354    
355     gtk_widget_destroy(dialog);
356     return filename;
357     }
358    
359     gboolean Shiki_yes_or_no_p(const gchar *msg) {
360     GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
361     GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
362     GTK_BUTTONS_YES_NO, msg);
363 aloha 1.9 gint resp;
364     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
365     resp = gtk_dialog_run(GTK_DIALOG(dialog));
366     gtk_widget_destroy(dialog);
367     if(GTK_RESPONSE_YES == resp)
368     return TRUE;
369     return FALSE;
370     }
371    
372     gboolean Shiki_no_or_yes_p(const gchar *msg) {
373     GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
374     GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
375     GTK_BUTTONS_YES_NO, msg);
376     gint resp;
377     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_NO);
378     resp = gtk_dialog_run(GTK_DIALOG(dialog));
379 aloha 1.7 gtk_widget_destroy(dialog);
380     if(GTK_RESPONSE_YES == resp)
381     return TRUE;
382     return FALSE;
383     }
384 aloha 1.8
385     gboolean Shiki_need_buffer_save_p(GtkTextBuffer *buffer) {
386     return gtk_text_buffer_get_modified(buffer);
387     }
388    
389     /* ������������ */
390     void Shiki_kill_buffer(GtkTextBuffer *buffer) {
391     if(!Shiki_need_buffer_save_p(buffer) || Shiki_yes_or_no_p("��������������������������������������������������������������������������� ?"))
392     Shiki_delete_buffer(buffer);
393     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26