Develop and Download Open Source Software

Browse CVS Repository

Contents of /shiki/shiki/shiki.c

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


Revision 1.62 - (show annotations) (download) (as text)
Thu Nov 30 14:45:49 2006 UTC (17 years, 4 months ago) by aloha
Branch: MAIN
Changes since 1.61: +7 -33 lines
File MIME type: text/x-csrc
add undo API

1 /* vim: set encoding=utf8:
2 *
3 * shiki.c
4 *
5 * This file is main file 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 * $Id: shiki.c,v 1.61 2006/11/29 14:58:27 aloha Exp $
28 */
29
30 #include"shiki.h"
31
32 /* ������������������������������������������������������������������������������������������������������������������������������ */
33 ShikiEditorType Shiki_editor;
34
35 static gchar *R5RS_keywords[] = {"and", "begin", "case", "cond-expand", "cond", "define-accessor", "define-class", "defined?", "define-generic", "define", "define-macro", "define-method", "define-module", "define-private", "define-public", "define-reader-ctor", "define-syntax", "define-syntax-macro", "defmacro", "defmacro*-public", "delay", "do", "else", "fluid-let", "if", "lambda", "let", "let*", "letrec", "letrec-syntax", "let-syntax", "or", "quasiquote", "quote", "set!", "syntax-rules", "unquote", NULL};
36
37 static gchar *R5RS_functions[] = {"*", "+", "-", "/", "<", ">", "<=", ">=", "?", "`", "=", "abs", "acos", "angle", "append", "apply", "asin", "assoc", "assq", "assv", "atan", "boolean?", "caaar", "caadr", "caar", "cadar", "caddr", "cadr", "call/cc", "call-with-current-continuation", "call-with-input-file", "call-with-output-file", "call-with-values", "car", "catch", "cdaar", "cdadr", "cdar", "cddar", "cdddr", "cddr", "cdr", "ceiling", "char-alphabetic?", "char-ci>=?", "char-ci>?", "char-ci=?", "char-ci<=?", "char-ci<?", "char-downcase", "char->integer", "char>=?", "char>?", "char=?", "char?", "char-lower-case?", "char<=?", "char<?", "char-numeric?", "char-ready?", "char-upcase", "char-upper-case?", "char-whitespace?", "close-input-port", "close-output-port", "complex?", "cons", "cos", "current-input-port", "current-output-port", "delete-file", "display", "dynamic-wind", "eof-object?", "eq?", "equal?", "eqv?", "eval", "even?", "exact->inexact", "exact?", "exit", "exp", "expt", "file-exists?", "file-or-directory-modify-seconds", "floor", "force", "for-each", "gcd", "gensym", "getenv", "get-output-string", "imag-part", "inexact?", "input-port?", "integer->char", "integer?", "lcm", "length", "list->string", "list->vector", "list", "list?", "list-ref", "list-tail", "load", "log", "magnitude", "make-polar", "make-rectangular", "make-string", "make-vector", "map", "max", "member", "memq", "memv", "min", "modulo", "negative?", "newline", "nil", "not", "null?", "number->string", "number?", "odd?", "open-input-file", "open-input-string", "open-output-file", "open-output-string", "output-port?", "pair?", "peek-char", "port?", "positive?", "procedure?", "quotient", "rational?", "read-char", "read", "read-line", "real?", "real-part", "remainder", "reverse", "reverse!", "round", "set-car!", "set-cdr!", "sin", "sqrt", "string-append", "string-ci>=?", "string-ci>?", "string-ci=?", "string-ci<=?", "string-ci<?", "string-copy", "string-fill!", "string>=?", "string>?", "string->list", "string->number", "string->symbol", "string", "string=?", "string?", "string-length", "string<=?", "string<?", "string-ref", "string-set!", "substring", "symbol->string", "symbol?", "system", "tan", "truncate", "values", "vector-fill!", "vector->list", "vector", "vector?", "vector-length", "vector-ref", "vector-set!", "with-input-from-file", "with-output-to-file", "write-char", "write", "zero", NULL};
38
39 static GHashTable *keywords_hash = NULL;
40
41 typedef enum {
42 R5RS_KEYWORD_COLOR = 1,
43 R5RS_FUNCTION_COLOR,
44 GAUCHE_KEYWORD_COLOR,
45 GAUCHE_FUNCTION_COLOR
46 } HIGHILIGHT_COLOR;
47
48 GdkColor COLOR_BLACK;
49 GdkColor COLOR_GREEN;
50
51 /* ������������������ */
52
53 /* foo_bar_handler() ������������������������������������������������������ */
54 static void kill_buffer_handler();
55 static void append_default_tabpage_handler();
56
57 /* ������������������ */
58 static void save_file();
59 static void save_file_as();
60
61 /* ������������������������������ */
62 static gchar* get_all_buffer_contents(GtkTextBuffer *buffer);
63 static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer);
64 static void clear_current_buffer_handler();
65 static void search_current_buffer();
66
67 /* Gauche ��� S ��������������������������������������������������������������������������� */
68 static gchar *eval_cstring_by_gauche(gchar *s);
69 static gchar *load_cstring_by_gauche(gchar *s);
70 static void load_buffer_by_gauche();
71 static void load_region_by_gauche();
72 static void load_scheme_file_by_gauche();
73 static gboolean is_kakko_or_kokka(gunichar ch, gpointer);
74 static gboolean is_kakko(gunichar ch, gpointer);
75 static gboolean is_kokka(gunichar ch, gpointer);
76 static gboolean search_sexp(GtkTextIter *start, GtkTextIter *end);
77 static gboolean search_sexp_kokka(GtkTextIter *end);
78 static gboolean search_last_sexp(GtkTextIter *start, GtkTextIter *end);
79 static gboolean search_last_sexp_kakko(GtkTextIter *start);
80 static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer);
81 static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data);
82 static gboolean is_double_quote(gunichar ch, gpointer user_data);
83 static gboolean is_scheme_delimita_p(gunichar ch, gpointer user_data);
84 static void scheme_keyword_highlighting_current_buffer();
85
86 /* ������ */
87 static void select_font();
88 static void font_selection_ok(GtkWidget *button, GtkWidget *font_dialog);
89 static void switch_tabpage_handler(GtkNotebook *notebook, GtkNotebookPage *page, guint pagenum) ;
90 static void tabsborder_on_off(GtkButton *button, GtkNotebook *notebook);
91 static void rotate_tab_position(GtkButton *button, GtkNotebook *notebook);
92
93 /* ������������������������ */
94 static gboolean signal_key_press_handler(GtkWidget *notebook, GdkEventKey *event, gpointer contextid);
95 static gboolean signal_key_release_handler(GtkWidget *notebook, GdkEventKey *event, gpointer contextid);
96
97 /* ������������������ */
98 static void open_online_help();
99 static void about_this_application();
100
101 /* ������������������������ */
102 static void Shiki_editor_window_init(int argc, char **argv);
103
104 /* ������������������������������ */
105 static void clear_current_buffer_handler() {
106 Shiki_erase_buffer(Shiki_CURRENT_TEXT_BUFFER);
107 }
108
109 static void destroy_handler(GtkWidget *button, GtkWidget *widget) {gtk_widget_destroy(widget);}
110
111 static void toggled_handler(GtkToggleButton *togglebutton, gboolean *flag) {
112 *flag = !*flag;
113 }
114
115 static void replace_current_buffer() {
116 GtkWidget *dialog = gtk_dialog_new_with_buttons ("������������������", GTK_WINDOW(Shiki_EDITOR_WINDOW), GTK_DIALOG_DESTROY_WITH_PARENT, NULL);
117 GtkWidget *table = gtk_table_new(7, 3, FALSE);
118 GtkWidget *find_label = gtk_label_new("������ : ");
119 GtkWidget *find = gtk_entry_new();
120 GtkWidget *rep_label = gtk_label_new("������ : ");
121 GtkWidget *replace = gtk_entry_new();
122 GtkWidget *check1 = gtk_check_button_new_with_label("���������������������������������");
123 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1), TRUE);
124 GtkWidget *check2 = gtk_check_button_new_with_label("���������������������������");
125 GtkWidget *check3 = gtk_check_button_new_with_label("������������");
126 GtkWidget *check4 = gtk_check_button_new_with_label("���������������������������������������������");
127 GtkWidget *check5 = gtk_check_button_new_with_label("���������������������������");
128 GtkWidget *interactive = gtk_button_new_with_label ("������������");
129 GtkWidget *all = gtk_button_new_with_label ("������������");
130 GtkWidget *cancel = gtk_button_new_with_label ("���������������");
131 gboolean f1 = TRUE, f2, f3, f4, f5;
132 f2 = f3 = f4 = f5 = FALSE;
133 g_signal_connect (check1, "toggled", G_CALLBACK (toggled_handler), &f1);
134 g_signal_connect (check2, "toggled", G_CALLBACK (toggled_handler), &f2);
135 g_signal_connect (check3, "toggled", G_CALLBACK (toggled_handler), &f3);
136 g_signal_connect (check4, "toggled", G_CALLBACK (toggled_handler), &f4);
137 g_signal_connect (check5, "toggled", G_CALLBACK (toggled_handler), &f5);
138
139 g_signal_connect (G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
140 g_signal_connect (G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_handler), dialog);
141 gtk_table_set_row_spacings(GTK_TABLE(table), 10);
142 gtk_table_set_col_spacings(GTK_TABLE(table), 10);
143 gtk_container_border_width (GTK_CONTAINER (dialog), 10);
144
145 gtk_table_attach_defaults (GTK_TABLE(table), find_label, 0, 1, 0, 1);
146 gtk_table_attach_defaults (GTK_TABLE(table), find, 1, 2, 0, 1);
147 gtk_table_attach_defaults (GTK_TABLE(table), interactive, 2, 3, 0, 1);
148
149 gtk_table_attach_defaults (GTK_TABLE(table), rep_label, 0, 1, 1, 2);
150 gtk_table_attach_defaults (GTK_TABLE(table), replace, 1, 2, 1, 2);
151 gtk_table_attach_defaults (GTK_TABLE(table), all, 2, 3, 1, 2);
152
153 gtk_table_attach_defaults (GTK_TABLE(table), check1, 1, 2, 2, 3);
154 gtk_table_attach_defaults (GTK_TABLE(table), cancel, 2, 3, 2, 3);
155
156 gtk_table_attach_defaults (GTK_TABLE(table), check2, 1, 2, 3, 4);
157 gtk_table_attach_defaults (GTK_TABLE(table), check3, 1, 2, 4, 5);
158 gtk_table_attach_defaults (GTK_TABLE(table), check4, 1, 2, 5, 6);
159 gtk_table_attach_defaults (GTK_TABLE(table), check5, 1, 2, 6, 7);
160
161 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
162 gtk_widget_show_all(table);
163 gtk_dialog_run(GTK_DIALOG(dialog));
164 }
165
166 static void search_current_buffer() {
167 GtkWidget *dialog = gtk_dialog_new_with_buttons ("������������������", GTK_WINDOW(Shiki_EDITOR_WINDOW), GTK_DIALOG_DESTROY_WITH_PARENT, NULL);
168 GtkWidget *table = gtk_table_new(6, 3, FALSE);
169 GtkWidget *label = gtk_label_new("������ : ");
170 GtkWidget *input = gtk_entry_new();
171 GtkWidget *check1 = gtk_check_button_new_with_label("���������������������������������");
172 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1), TRUE);
173 GtkWidget *check2 = gtk_check_button_new_with_label("���������������������������");
174 GtkWidget *check3 = gtk_check_button_new_with_label("������������");
175 GtkWidget *check4 = gtk_check_button_new_with_label("���������������������������������������������");
176 GtkWidget *check5 = gtk_check_button_new_with_label("���������������������������������");
177 GtkWidget *prev = gtk_button_new_with_label ("���������");
178 GtkWidget *next = gtk_button_new_with_label ("���������");
179 GtkWidget *cancel = gtk_button_new_with_label ("���������������");
180 gboolean f1 = TRUE, f2, f3, f4, f5;
181 f2 = f3 = f4 = f5 = FALSE;
182 g_signal_connect (check1, "toggled", G_CALLBACK (toggled_handler), &f1);
183 g_signal_connect (check2, "toggled", G_CALLBACK (toggled_handler), &f2);
184 g_signal_connect (check3, "toggled", G_CALLBACK (toggled_handler), &f3);
185 g_signal_connect (check4, "toggled", G_CALLBACK (toggled_handler), &f4);
186 g_signal_connect (check5, "toggled", G_CALLBACK (toggled_handler), &f5);
187
188 g_signal_connect (G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL);
189 g_signal_connect (G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_handler), dialog);
190 gtk_table_set_row_spacings(GTK_TABLE(table), 10);
191 gtk_table_set_col_spacings(GTK_TABLE(table), 10);
192 gtk_container_border_width (GTK_CONTAINER (dialog), 10);
193 gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 1, 0, 1);
194 gtk_table_attach_defaults (GTK_TABLE(table), input, 1, 2, 0, 1);
195 gtk_table_attach_defaults (GTK_TABLE(table), prev, 2, 3, 0, 1);
196 gtk_table_attach_defaults (GTK_TABLE(table), check1, 1, 2, 1, 2);
197 gtk_table_attach_defaults (GTK_TABLE(table), check2, 1, 2, 2, 3);
198 gtk_table_attach_defaults (GTK_TABLE(table), check3, 1, 2, 3, 4);
199 gtk_table_attach_defaults (GTK_TABLE(table), check4, 1, 2, 4, 5);
200 gtk_table_attach_defaults (GTK_TABLE(table), check5, 1, 2, 5, 6);
201 gtk_table_attach_defaults (GTK_TABLE(table), next, 2, 3, 1, 2);
202 gtk_table_attach_defaults (GTK_TABLE(table), cancel, 2, 3, 2, 3);
203 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
204 gtk_widget_show_all(table);
205 gtk_dialog_run(GTK_DIALOG(dialog));
206 }
207
208 static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data) {
209 return ch != '(' && ch != ')' && !g_unichar_isspace(ch);
210 }
211
212 static gboolean is_double_quote(gunichar ch, gpointer user_data) {
213 return ch == '\"';
214 }
215
216 static gboolean is_scheme_delimita_p(gunichar ch, gpointer user_data) {
217 return ch == ' ' || ch == '(' || ch == ')' || ch == '\"' || g_unichar_isspace(ch);
218 }
219
220 /* ������������������������������ */
221 static void scheme_keyword_highlighting_current_buffer() {
222 GtkTextIter s, e;
223 HIGHILIGHT_COLOR c;
224 gchar *word;
225 gboolean is_comment, is_string;
226 gunichar ch;
227
228 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &s);
229
230 /* ��������� Scheme ������������������������������ */
231 while(TRUE) {
232 is_comment = FALSE;
233 is_string = FALSE;
234 if((ch = gtk_text_iter_get_char(&s)) != ';' && ch != '\"')
235 gtk_text_iter_forward_find_char(&s, is_not_scheme_delimita_p, NULL, NULL);
236 e = s;
237 if(gtk_text_iter_get_char(&s) == ';') {
238 gtk_text_iter_forward_line(&e);
239 gtk_text_iter_backward_char(&e);
240 is_comment = TRUE;
241 } else if(gtk_text_iter_get_char(&s) == '\"') {
242 while(TRUE) {
243 gtk_text_iter_forward_find_char(&e, is_double_quote, NULL, NULL);
244 gtk_text_iter_backward_char(&e);
245 if(gtk_text_iter_get_char(&e) != '\\') {
246 is_string = TRUE;
247 gtk_text_iter_forward_char(&e);
248 gtk_text_iter_forward_char(&e);
249 break;
250 }
251 gtk_text_iter_forward_char(&e);
252 gtk_text_iter_forward_char(&e);
253 }
254
255 } else
256 gtk_text_iter_forward_find_char(&e, is_scheme_delimita_p, NULL, NULL);
257
258 word = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &s, &e, FALSE);
259
260 /* ������������������������������������������������������������ */
261 if(is_comment) /* ������������ */
262 gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", &s, &e);
263 else if(is_string) /* ��������� */
264 gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "string_highlighting", &s, &e);
265 else if(R5RS_KEYWORD_COLOR == (c = GPOINTER_TO_INT(g_hash_table_lookup(keywords_hash, word)))) /* R5RS ��������������� */
266 gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "keyword_highlighting", &s, &e);
267 else if(R5RS_FUNCTION_COLOR == c) /* R5RS ������ */
268 gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "function_highlighting", &s, &e);
269
270 /* XXX : get_text() ������������������������������������������������������������������������������������������������������ GtkTextBuffer ������ const gchar * ������������������������������ */
271 g_free(word);
272
273 if(gtk_text_iter_is_end(&e)) break;
274 s = e;
275 }
276 }
277
278 /* ������������������������������������������������������������ */
279 static void switch_tabpage_handler(GtkNotebook *notebook, GtkNotebookPage *page, guint pagenum) {
280 /* ��������������������������������������������������������������������� */
281 Shiki_CURRENT_TAB_INFO = (ShikiBuffer *)g_list_nth_data(Shiki_EDITOR_BUFFER_LIST, pagenum);
282
283 /* ������������������������������������ */
284 Shiki_CURRENT_TAB_NUM = pagenum;
285
286 /* ������������������������������������������������������ */
287 if(!Shiki_CURRENT_TAB_INFO) return;
288 gtk_window_set_title (GTK_WINDOW(Shiki_EDITOR_WINDOW), Shiki_CURRENT_FILENAME);
289
290 Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER);
291 }
292
293 /* ��������������������� */
294 static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) {
295 GtkTextIter start, end;
296
297 /* ������������������������������������ */
298 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &start);
299 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &end);
300 gtk_text_buffer_remove_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "parent_emphasis_background", &start, &end);
301
302 if(event->state & GDK_CONTROL_MASK && event->state & GDK_MOD1_MASK) {
303 switch(event->keyval) {
304 case GDK_at : /* C-M-SPC */
305 { GtkTextIter start, end;
306 if(!search_sexp(&start, &end)) return FALSE;
307 gtk_text_buffer_select_range(Shiki_CURRENT_TEXT_BUFFER, &start, &end);
308 }
309 break;
310 case GDK_space : /* C-M-SPC */
311 { GtkTextIter start, end;
312 if(!search_last_sexp(&start, &end)) return FALSE;
313 gtk_text_buffer_select_range(Shiki_CURRENT_TEXT_BUFFER, &start, &end);
314 }
315 break;
316 }
317 } else if(event->state & GDK_CONTROL_MASK) {
318 switch(event->keyval) {
319 case GDK_f : /* Ctrl + f : forward */
320 Shiki_forward_char();
321 break;
322 case GDK_b : /* Ctrl + b : backward */
323 Shiki_backward_char();
324 break;
325 case GDK_n : /* Ctrl + n : next line */
326 Shiki_forward_line(1);
327 break;
328 case GDK_p : /* Ctrl + p : previous line */
329 Shiki_forward_line(-1);
330 break;
331 case GDK_h :
332 { GtkTextIter p;
333 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
334 gtk_text_buffer_backspace(Shiki_CURRENT_TEXT_BUFFER, &p, FALSE, TRUE);
335 }
336 break;
337
338 case GDK_e : /* Ctrl + e : eval-expression */
339 {
340 gchar *code, *result;
341 GtkTextIter start, end;
342
343 if(!search_sexp(&start, &end)) return FALSE;
344
345 code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
346 result = eval_cstring_by_gauche(code);
347 g_free(code);
348
349 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
350
351 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
352 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, result, -1);
353 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
354 }
355 break;
356
357 case GDK_j : /* Ctrl + j : eval-last-sexp */
358 {
359 gchar *code, *result;
360 GtkTextIter start, end;
361
362 if(!search_last_sexp(&start, &end)) return FALSE;
363
364 code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
365 result = eval_cstring_by_gauche(code);
366 g_free(code);
367
368 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
369
370 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
371 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, result, -1);
372 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1);
373 }
374 break;
375
376 case GDK_underscore : /* Ctrl + _ : Undo */
377 Shiki_undo();
378 break;
379
380 case GDK_t : /* Ctrl + t : ��������������� */
381 append_default_tabpage_handler();
382 break;
383
384 case GDK_k : /* Ctrl + k : ������������������ */
385 kill_buffer_handler();
386 break;
387
388 case GDK_w : /* Ctrl + w : ��������� */
389 gtk_text_buffer_cut_clipboard(Shiki_CURRENT_TEXT_BUFFER, Shiki_EDITOR_CLIPBOARD, TRUE);
390 break;
391
392 case GDK_y : /* Ctrl + y : ��������� */
393 {GtkTextIter p;
394 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER,&p, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
395 gtk_text_buffer_paste_clipboard(Shiki_CURRENT_TEXT_BUFFER, Shiki_EDITOR_CLIPBOARD, &p, TRUE);
396 }
397 break;
398 }
399 }
400 return FALSE;
401 }
402
403 static void append_default_tabpage_handler() {
404 Shiki_new_buffer_create(g_strdup("*scratch*"));
405 }
406
407 /* ������������������������������������������ (������������) ��������� */
408 static void kill_buffer_handler() {
409 Shiki_kill_buffer(Shiki_CURRENT_TEXT_BUFFER);
410 }
411
412 /* ������������������������������������ */
413 static void load_buffer_by_gauche() {
414 GtkTextIter p;
415 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
416 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, "\n\n", -1);
417 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(get_all_buffer_contents(Shiki_CURRENT_TEXT_BUFFER)), -1);
418 }
419
420 /* ������������������������ */
421 static void load_scheme_file_by_gauche() {
422 gchar *contents, *text = NULL;
423 gsize br, bw, len;
424 GError *err = NULL;
425 const gchar *filename = Shiki_file_name_dialog("File Selection");
426 GtkTextIter p;
427
428 if(!filename) return;
429
430 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
431 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, "\n\n", -1);
432
433 if(g_file_get_contents(filename, &contents, &len, NULL)) {
434 if(!(text = g_locale_to_utf8(contents, -1, &br, &bw, &err)))
435 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(text), -1);
436 else
437 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(contents), -1);
438 }
439 g_free(text); g_free(contents);
440 }
441
442 /* gauche ������������������������������������ */
443 static gchar *load_cstring_by_gauche(gchar *s) {
444 gchar *msg;
445
446 ScmObj result, error;
447 /* ��������������������������������� */
448 ScmObj is = Scm_MakeInputStringPort(SCM_STRING(SCM_MAKE_STR_COPYING(s)), TRUE);
449 /* ������������������������������ */
450 ScmObj os = Scm_MakeOutputStringPort(TRUE);
451
452 Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*input*")), is);
453 Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
454 /* Scheme ��������������������������������������������������������������������������������� S ��������������������������������������������������������������������������� *error* ������������������ */
455 result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (load-from-port *input*) (current-module)))", SCM_OBJ(Shiki_CURRENT_BUFFER_ENV));
456
457 error = Scm_GlobalVariableRef(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
458
459 /* ��������������������������������������������������������� */
460 if (!SCM_FALSEP(error))
461 Scm_Write(error, os, SCM_WRITE_DISPLAY);
462 else
463 Scm_Write(result, os, SCM_WRITE_DISPLAY);
464
465 msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
466 /* ������������������ */
467 Scm_ClosePort(SCM_PORT(is));
468 Scm_ClosePort(SCM_PORT(os));
469
470 return msg;
471 }
472
473 static void font_selection_ok(GtkWidget *button, GtkWidget *font_dialog) {
474 gchar *font_name = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font_dialog));
475 if(font_name) {
476 GtkRcStyle *style = gtk_rc_style_new ();
477 pango_font_description_free(style->font_desc);
478 style->font_desc = pango_font_description_from_string(font_name);
479 gtk_widget_modify_style (GTK_WIDGET(Shiki_CURRENT_TEXT_VIEW), style);
480 gtk_rc_style_unref (style);
481 g_free (font_name);
482 }
483 }
484
485 /* ������������������������������������������������������ */
486 static void select_font(){
487 GtkWidget *font_dialog = gtk_font_selection_dialog_new("Font Selection Dialog");
488 g_signal_connect (GTK_FONT_SELECTION_DIALOG (font_dialog)->ok_button, "clicked", G_CALLBACK(font_selection_ok), font_dialog);
489 gtk_dialog_run(GTK_DIALOG(font_dialog));
490 gtk_widget_destroy(font_dialog);
491 }
492
493 /* ������������������������������������������ */
494 static void about_this_application() {
495 GtkAboutDialog *about = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
496 const gchar *authors[] = {
497 "������������ (���������) <alohakun@gmail.com>\n",
498 "Contribute : tkng ������",
499 "(http://d.hatena.ne.jp/tkng/20061113)", NULL
500 };
501 gtk_about_dialog_set_authors(about, authors);
502 gtk_about_dialog_set_copyright(about, "Copyright(C)2006 WAKATSUKI Toshihiro");
503 gtk_about_dialog_set_name(about, "��� (SHIKI)");
504 gtk_about_dialog_set_website_label(about, "���������30������������������������������������������������������������Blog");
505 gtk_about_dialog_set_website(about, "http://alohakun.blog7.fc2.com/blog-category-29.html");
506 gtk_dialog_run(GTK_DIALOG(about));
507 gtk_widget_destroy(GTK_WIDGET(about));
508 }
509
510 /* ��������� */
511 static void dummy_handler() {
512 GtkWidget *dummy = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
513 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
514 "Sorry... This Button is Dummy.");
515 gtk_dialog_run(GTK_DIALOG(dummy));
516 gtk_widget_destroy(dummy);
517 }
518
519 /* ��������������������������������������������������������������� */
520 static gchar* get_all_buffer_contents(GtkTextBuffer *buffer) {
521 GtkTextIter start, end;
522 gtk_text_buffer_get_start_iter(buffer, &start);
523 gtk_text_buffer_get_end_iter(buffer, &end);
524 return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
525 }
526
527 /* buffer ������������������������ filename ��������� */
528 static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer) {
529 gchar *contents, *text;
530 gsize br, bw;
531 GError *err = NULL;
532
533 if(!filename) return FALSE;
534 contents = get_all_buffer_contents(buffer);
535 text = g_locale_from_utf8(contents, -1, &br, &bw, &err);
536 /* ��������������������������������� */
537 g_file_set_contents(filename, text, -1, NULL);
538 gtk_text_buffer_set_modified(buffer, FALSE);
539 Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER);
540 g_free(contents); g_free(text);
541 return TRUE;
542 }
543
544 /* ��������������������������������������������������������������������� */
545 static void save_file() {
546
547 /* ��������������������������������������� */
548 if(strcmp("*help*", Shiki_CURRENT_TAB_TITLE) == 0) return;
549
550 /* ������������������������������������ */
551 if(!gtk_text_buffer_get_modified(Shiki_CURRENT_TEXT_BUFFER)) return;
552
553 /* ������������������������������������������������������������������������������������������������������ */
554 if(strcmp("*scratch*", Shiki_CURRENT_FILENAME) == 0) {
555 const gchar *filename = Shiki_file_name_dialog("Save File As ...");
556 if(!filename) return;
557 if(!save_text_buffer(filename, Shiki_CURRENT_TEXT_BUFFER)) return;
558 gtk_notebook_set_tab_label_text(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(Shiki_CURRENT_TAB), filename);
559 gtk_window_set_title (GTK_WINDOW(Shiki_EDITOR_WINDOW), filename);
560 } else
561 save_text_buffer(Shiki_CURRENT_TAB_TITLE, Shiki_CURRENT_TEXT_BUFFER);
562 }
563
564 /* ��������������������������������������������������������������������������� */
565 static void save_file_as() {
566 const gchar *filename = Shiki_file_name_dialog("Save File As ...");
567
568 if(!filename) return;
569 if(!save_text_buffer(filename, Shiki_CURRENT_TEXT_BUFFER)) return;
570
571 gtk_notebook_set_tab_label_text(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(Shiki_CURRENT_TAB), filename);
572 gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename);
573 }
574
575 /* gauche ��������������������������������� */
576 static gchar *eval_cstring_by_gauche(gchar *s) {
577 gchar *msg;
578
579 ScmObj result, error;
580 /* ������������������������������ */
581 ScmObj os = Scm_MakeOutputStringPort(TRUE);
582
583 /* Scheme ��������������������������������������� */
584 /* http://alohakun.blog7.fc2.com/blog-entry-517.html */
585 Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*input*")), SCM_MAKE_STR_COPYING(s));
586 Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE);
587
588 result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (read-from-string *input*) (current-module)))", SCM_OBJ(Shiki_CURRENT_BUFFER_ENV));
589
590 error = Scm_GlobalVariableRef(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), 0);
591
592 /* ��������������������������������������������������������� */
593 if (!SCM_FALSEP(error))
594 Scm_Write(error, os, SCM_WRITE_DISPLAY);
595 else
596 Scm_Write(result, os, SCM_WRITE_DISPLAY);
597
598 msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os))));
599 /* ������������������ */
600 Scm_ClosePort(SCM_PORT(os));
601
602 return msg;
603 }
604
605 /* ������������������������������������������������������������������ S ��������������� (������������) */
606 static void load_region_by_gauche() {
607
608 GtkTextIter start, end, p;
609 gchar *code;
610 gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
611 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, "\n\n", -1);
612
613 /* ������������������������������������������������������������ */
614 if(gtk_text_buffer_get_selection_bounds(Shiki_CURRENT_TEXT_BUFFER, &start, &end)) {
615 code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE);
616 gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &p, load_cstring_by_gauche(code), -1);
617 g_free(code);
618 }
619 }
620
621 // GtkTextCharPredicate
622 static gboolean is_kakko_or_kokka(gunichar ch, gpointer p) {
623 return ch == '(' || ch == ')';
624 }
625 static gboolean is_kakko(gunichar ch, gpointer p) {return ch == '(';}
626 static gboolean is_kokka(gunichar ch, gpointer p) {return ch == ')';}
627
628 /* ��������������������� '(' ��������������� ')' ������������������ (S ���) ��������������� */
629 static gboolean search_sexp(GtkTextIter *start, GtkTextIter *end) {
630
631 /* ������������������������������ */
632 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, start, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
633
634 if(gtk_text_iter_get_char(start) != '(')
635 gtk_text_iter_forward_find_char(start, is_kakko, NULL, NULL);
636
637 *end = *start;
638
639 /* ��������������������������������� S ������������������ */
640 if(!search_sexp_kokka(end)) return FALSE;
641 gtk_text_iter_forward_char(end);
642 return TRUE;
643 }
644
645 static gboolean search_sexp_kokka(GtkTextIter *end) {
646 gint nest_level = 0;
647
648 /* ������������ ')' ��������� */
649 while(1) {
650 if(!gtk_text_iter_forward_find_char(end, is_kakko_or_kokka, NULL, NULL))
651 return FALSE;
652
653 if(gtk_text_iter_get_char(end) == '(')
654 nest_level++;
655 else {
656 if(!nest_level)
657 break;
658 else
659 nest_level--;
660 }
661 }
662 return TRUE;
663 }
664
665 /* ��������������������� ')' ��������������� '(' ������������������ (S ���) ��������������� */
666 static gboolean search_last_sexp(GtkTextIter *start, GtkTextIter *end) {
667
668 /* ������������������������������ */
669 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
670
671 gtk_text_iter_backward_char(end);
672
673 if(gtk_text_iter_get_char(end) != ')')
674 gtk_text_iter_backward_find_char(end, is_kokka, NULL, NULL);
675 *start = *end;
676 gtk_text_iter_forward_char(end);
677
678 /* ��������������������������������� S ������������������ */
679 if(!search_last_sexp_kakko(start)) return FALSE;
680
681 return TRUE;
682 }
683
684 /* ')' ��������������� '(' ������������������ (S ���) ��������������� */
685 static gboolean search_last_sexp_kakko(GtkTextIter *start) {
686 gint nest_level = 0;
687 /* ��������������������������������������� ')' ��������� */
688 while(1) {
689 if(!gtk_text_iter_backward_find_char(start, is_kakko_or_kokka, NULL, NULL))
690 return FALSE;
691
692 if(gtk_text_iter_get_char(start) == ')')
693 nest_level++;
694 else {
695 if(!nest_level)
696 break;
697 else
698 nest_level--;
699 }
700 }
701 return TRUE;
702 }
703
704 /* ������������������������������������������������ */
705 static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer) {
706 gint nest_level = 0;
707 GtkTextIter start, end;
708 gtk_text_buffer_get_start_iter(buffer, &start);
709 if(gtk_text_iter_get_char(&start) == '(') nest_level++;
710
711 /* ��������������������� (= end) ��������� */
712 gtk_text_buffer_get_iter_at_mark(buffer,&end, gtk_text_buffer_get_insert(buffer));
713
714 while(1) {
715 /* end ������ '(' ��� ')' ��������������������������������������������� */
716 if(!gtk_text_iter_forward_find_char(&start, is_kakko_or_kokka, NULL, &end))
717 return nest_level;
718
719 if(gtk_text_iter_get_char(&start) == '(')
720 nest_level++;
721 else
722 nest_level--;
723 }
724 }
725
726 /* ��������������������������������� on/off */
727 static void tabsborder_on_off(GtkButton *button, GtkNotebook *notebook) {
728 gint tval = FALSE;
729 gint bval = FALSE;
730 if(notebook->show_tabs == FALSE)
731 tval = TRUE;
732 if(notebook->show_border == FALSE)
733 bval = TRUE;
734
735 gtk_notebook_set_show_tabs(notebook, tval);
736 gtk_notebook_set_show_border(notebook, bval);
737 }
738
739 /* ������������������������ */
740 static void rotate_tab_position(GtkButton *button, GtkNotebook *notebook ) {
741 gtk_notebook_set_tab_pos(notebook, (notebook->tab_pos + 1) % 4);
742 }
743
744 /* ��������������������� */
745 static gboolean signal_key_release_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) {
746 static gint metakey_pressed = 0;
747 static gint controlx_pressed = 0;
748
749 if(event->keyval == GDK_parenright && event->state & GDK_SHIFT_MASK) {
750 GtkTextIter start, end;
751
752 /* ������������������������������ */
753 gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER));
754
755 start = end;
756 gtk_text_iter_backward_char(&start);
757
758 /* ��������������������������������� S ������������������ */
759 if(!search_last_sexp_kakko(&start)) return FALSE;
760
761 gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "parent_emphasis_background", &start, &end);
762 }
763
764 /* ������������������������������������������������������������������������������������������������ (���������������) ������������������ */
765 if(event->keyval == GDK_Return) {
766 gint indentWidth = get_parent_nest_level_at_cursor(Shiki_CURRENT_TEXT_BUFFER) * SCM_INT_VALUE(Scm_GlobalVariableRef(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*indent-width*")), 0)), i;
767 static gchar *indent = " ";
768 for(i = 0; i < indentWidth; i++)
769 gtk_text_buffer_insert_at_cursor(Shiki_CURRENT_TEXT_BUFFER, indent, -1);
770 }
771
772 /* C-x */
773 if(event->keyval == GDK_x && event->state & GDK_CONTROL_MASK) {
774 controlx_pressed++;
775 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-x -");
776 } else if(event->state & GDK_CONTROL_MASK) {
777
778 if(controlx_pressed > 0) {
779 switch(event->keyval) {
780 case GDK_c :/* C-x C-c : ������ */
781 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-c");
782 {/* "delete-event" ��������������������������������������� �� ������������������������������������ */
783 GdkEvent ev;
784
785 ev.any.type = GDK_DELETE;
786 ev.any.window = Shiki_EDITOR_WINDOW->window;
787 ev.any.send_event = FALSE;
788 gdk_event_put (&ev);
789 }
790 break;
791
792 case GDK_f : /* C-x C-f : ������������������ */
793 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-f");
794 Shiki_open_file_dialog();
795 break;
796
797 case GDK_s : /* C-x C-s : ������������������ */
798 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-s");
799 save_file();
800 break;
801
802 case GDK_w : /* C-x C-w : ������������������������ */
803 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "C-w");
804 save_file_as();
805 break;
806 }
807 controlx_pressed = 0;
808 }
809
810 switch(event->keyval) {
811 case GDK_g :/* C-g : ��������������� */
812 metakey_pressed = 0;
813 controlx_pressed = 0;
814
815 gtk_statusbar_push(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), GPOINTER_TO_INT(contextid), "Quit");
816 break;
817 }
818
819 }
820 return FALSE;
821 }
822 static void open_online_help() {
823 GtkTextIter p;
824 Shiki_new_buffer_create(g_strdup("*help*"));
825 gtk_text_buffer_set_text(Shiki_CURRENT_TEXT_BUFFER,
826 "������������������������������������������\n"
827 "$ ./shiki [file1 file2 ....]\n\n"
828 "[���������������������������] ��������������������� (C-x C-f)\n"
829 "[������������������������������������������] ��������������������� (C-x C-s)\n"
830 "[���������������������������������������������] ��������������������������� (C-x C-w)\n"
831 "[���������������������] ��������������� gauche ������������\n"
832 "[��������������� (���������) ���������������] ��������� on/off\n"
833 "[������ (���������) ���������������] ������������������������\n"
834 "[������������������] ��������������������������� (C-t)\n"
835 "[���������������������������] ������������ (C-_)\n"
836 "[���������������������] ������������������������\n"
837 "\n"
838 "(��� : ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Undo ������������������)\n"
839 "\n"
840 "[�� ������������] ������������������������ (C-k)\n"
841 "[A ������������] ���������������������\n"
842 "[���������������������������] Scheme ������������������������\n"
843 "[���������������������������������] ���������������������������������������\n"
844 "[��������� (?) ������������] ���������������������������������������\n"
845 "[info ������������] ���������������������������������������������������\n"
846 "\n"
847 "C-f : ��� ��������� (forward)\n"
848 "C-b : ��� ��������� (backward)\n"
849 "C-n : ��� ��������� (next line)\n"
850 "C-p : ��� ��������� (previous line)\n"
851 "\n"
852 "C-h : ���������������������\n"
853 "C-w : ���������\n"
854 "C-y : ��������� (������������)\n"
855 "\n"
856 "C-e : ��������������������� S ������������ (eval-expression)\n"
857 "C-j : ��������������������� S ������������ (eval-last-sexp)\n"
858 "(emacs/xyzzy ��� *scratch* ���������������������)\n"
859 "\n"
860 "C-M-@ : ��������������������� S ������������ (mark-sexp)\n"
861 "C-M-SPC : ��������������������� S ������������ (mark-last-sexp)\n"
862 "C-x C-c : ��������������������������� �� ���������������������������������\n"
863 "\n"
864 "������������ API\n"
865 "(clear-current-buffer) : ��������������������������������� (������������)\n"
866 , -1);
867 gtk_text_buffer_set_modified(Shiki_CURRENT_TEXT_BUFFER, FALSE);
868 /* ������������������������������ */
869 gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &p);
870 gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p);
871 }
872
873 /* ��������������������������������������� */
874 static void Shiki_editor_window_init(int argc, char **argv) {
875 GtkWidget *vbox, *toolbar, *modeline_bg = gtk_event_box_new();
876 GtkToolItem *icon;
877 GtkIconSize iconsize;
878 GtkTooltips *toolbar_tips = gtk_tooltips_new();
879 /* ��������������������������������������������������������������������������������� */
880 GtkToolItem *oicon, *sicon, *saicon, *eicon;
881
882 gint contextid, i;
883
884 /* ������������������������������������������������������������������������������ */
885 keywords_hash = g_hash_table_new(g_str_hash, g_str_equal);
886 i = 0;
887 while(R5RS_keywords[i] != NULL)
888 g_hash_table_insert(keywords_hash, R5RS_keywords[i++], GINT_TO_POINTER(R5RS_KEYWORD_COLOR));
889 i = 0;
890 while(R5RS_functions[i] != NULL)
891 g_hash_table_insert(keywords_hash, R5RS_functions[i++], GINT_TO_POINTER(R5RS_FUNCTION_COLOR));
892
893 /* ������������ */
894 Shiki_EDITOR_WINDOW = gtk_window_new(GTK_WINDOW_TOPLEVEL);
895 g_signal_connect(G_OBJECT(Shiki_EDITOR_WINDOW), "destroy", G_CALLBACK(gtk_main_quit), NULL);
896
897 /* ������������������������������������������������������������ */
898 Shiki_EDITOR_CLIPBOARD = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
899
900 /* ������������������������������������ */
901 vbox = gtk_vbox_new(FALSE, 0);
902 /* ��������������������� */
903 toolbar = gtk_toolbar_new();
904 gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
905
906 Shiki_EDITOR_NOTEBOOK = GTK_NOTEBOOK(gtk_notebook_new());
907 g_signal_connect(G_OBJECT(Shiki_EDITOR_NOTEBOOK), "switch-page", GTK_SIGNAL_FUNC(switch_tabpage_handler), NULL);
908
909 /* ������������������������������������������������ */
910 gtk_toolbar_set_style(GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
911 iconsize = gtk_toolbar_get_icon_size (GTK_TOOLBAR (toolbar));
912
913 /* ������������������ */
914
915 /* ������������������ */
916 oicon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_OPEN, iconsize), "");
917 /* ������������������������������������������������������������������������������������ */
918 g_signal_connect(G_OBJECT(oicon), "clicked", G_CALLBACK(Shiki_open_file_dialog), NULL);
919 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(oicon));
920 gtk_tool_item_set_tooltip(oicon, toolbar_tips, "���������������������������",
921 "���������������������������������������������������������������������������������������");
922
923 /* ������������������ */
924 sicon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_SAVE, iconsize), "");
925 /* ������������������������������������������������������������������������������������ */
926 g_signal_connect(G_OBJECT(sicon), "clicked", G_CALLBACK(save_file), NULL);
927 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(sicon));
928 gtk_tool_item_set_tooltip(sicon, toolbar_tips, "������������������������������",
929 "������������������������������������������������������������������������������������������������������������������������������������");
930
931 /* ��������������������������� */
932 saicon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, iconsize), "");
933 /* ������������������������������������������������������������������������������������������������������������������ */
934 g_signal_connect(G_OBJECT(saicon), "clicked", G_CALLBACK(save_file_as), NULL);
935 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(saicon));
936 gtk_tool_item_set_tooltip(saicon, toolbar_tips, "������������������������������������",
937 "");
938
939 /* ������������������ */
940 eicon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_EXECUTE, iconsize), "");
941 /* ������������������������������������������ libgauche ������������������ */
942 g_signal_connect(G_OBJECT(eicon), "clicked", G_CALLBACK(load_region_by_gauche), NULL);
943 gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET(eicon));
944 gtk_tool_item_set_tooltip(eicon, toolbar_tips, "��������������� S ������������������������ (load-region-lisp)",
945 "Scheme (gauche) ������������������ S ������������������������");
946
947 gtk_container_add(GTK_CONTAINER(Shiki_EDITOR_WINDOW), vbox);
948 gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
949
950 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_NEW, iconsize), "");
951 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(append_default_tabpage_handler), NULL);
952 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
953 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������������", "");
954
955 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_UNDO, iconsize), "");
956 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(Shiki_undo), NULL);
957 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
958 gtk_tool_item_set_tooltip(icon, toolbar_tips, "Undo","");
959
960 /* XXX : TODO */
961 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_REDO, iconsize), "");
962 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(dummy_handler), NULL);
963 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
964 gtk_tool_item_set_tooltip(icon, toolbar_tips, "Redo", "");
965
966 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_FIND, iconsize), "");
967 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(search_current_buffer), NULL);
968 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
969 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������", "");
970
971
972 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE, iconsize), "");
973 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(replace_current_buffer), NULL);
974 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
975 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������", "");
976
977 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_REFRESH, iconsize), "");
978 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(dummy_handler), NULL);
979 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
980 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������", "");
981
982 /* TODO ������������ */
983
984 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_DELETE, iconsize), "");
985 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(clear_current_buffer_handler), NULL);
986 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
987 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������������",
988 "���������������������������������������������������������������������");
989
990 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_CLOSE, iconsize), "");
991 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(kill_buffer_handler), NULL);
992 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
993 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������������",
994 "���������������������������������������������������������������");
995
996 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_CONNECT, iconsize), "");
997 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(load_scheme_file_by_gauche), NULL);
998 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
999 gtk_tool_item_set_tooltip(icon, toolbar_tips, "Scheme ������������������������", "");
1000
1001 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_CONVERT, iconsize), "");
1002 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(load_buffer_by_gauche), G_OBJECT(Shiki_EDITOR_NOTEBOOK));
1003 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1004 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������", "");
1005
1006 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_SPELL_CHECK, iconsize), "");
1007 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(scheme_keyword_highlighting_current_buffer), NULL);
1008 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1009 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������������������������", "");
1010
1011
1012 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, iconsize), "");
1013 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(open_online_help), NULL);
1014 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1015 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������", "");
1016
1017 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_BOLD, iconsize), "");
1018 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(select_font), NULL);
1019 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1020 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������", "");
1021
1022 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_APPLY, iconsize), "");
1023 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(tabsborder_on_off), G_OBJECT(Shiki_EDITOR_NOTEBOOK));
1024 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1025 gtk_tool_item_set_tooltip(icon, toolbar_tips, "��������� on/off", "");
1026
1027 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, iconsize), "");
1028 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(rotate_tab_position), G_OBJECT(Shiki_EDITOR_NOTEBOOK));
1029 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1030 gtk_tool_item_set_tooltip(icon, toolbar_tips, "���������������������", "");
1031
1032 icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, iconsize), "");
1033 g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(about_this_application), NULL);
1034 gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon));
1035 gtk_tool_item_set_tooltip(icon, toolbar_tips, "������������������������������������������", "");
1036
1037 /* ������������������������ */
1038 Shiki_EDITOR_MODELINE_LABEL = gtk_label_new(NULL);
1039 gtk_container_add(GTK_CONTAINER (modeline_bg), Shiki_EDITOR_MODELINE_LABEL);
1040
1041 gdk_color_parse("black", &COLOR_BLACK);
1042 gdk_color_parse("green", &COLOR_GREEN);
1043
1044 gtk_widget_modify_fg(Shiki_EDITOR_MODELINE_LABEL, GTK_STATE_NORMAL, &COLOR_GREEN);
1045 gtk_widget_modify_bg(modeline_bg, GTK_STATE_NORMAL, &COLOR_BLACK);
1046
1047 gtk_box_pack_start(GTK_BOX(vbox), modeline_bg, TRUE, TRUE, 0);
1048
1049 /* C-x C-s ��������������������������������������������������������������������������������������� */
1050 Shiki_EDITOR_STATUSBAR = gtk_statusbar_new();
1051 gtk_box_pack_start(GTK_BOX(vbox), Shiki_EDITOR_STATUSBAR, TRUE, TRUE, 0);
1052 contextid = gtk_statusbar_get_context_id(GTK_STATUSBAR(Shiki_EDITOR_STATUSBAR), "");
1053
1054 /* ������������������������������������������������ */
1055 g_signal_connect(G_OBJECT(Shiki_EDITOR_NOTEBOOK), "key-press-event", G_CALLBACK (signal_key_press_handler), GINT_TO_POINTER(contextid));
1056 g_signal_connect(G_OBJECT(Shiki_EDITOR_NOTEBOOK), "key-release-event", G_CALLBACK (signal_key_release_handler), GINT_TO_POINTER(contextid));
1057
1058 /* ��������������������������������������������� */
1059 if(argc >= 2) {
1060 int i;
1061 for(i = 1; i < argc; i++)
1062 Shiki_create_file_buffer(argv[i]);
1063 } else /* ������������������������������������������������������������������ */
1064 open_online_help(Shiki_EDITOR_NOTEBOOK);
1065
1066 gtk_widget_grab_focus(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
1067 gtk_widget_show_all(Shiki_EDITOR_WINDOW);
1068 }
1069
1070 int main(int argc, char *argv[]) {
1071 /* ������������������������������������ */
1072 Shiki_EDITOR_DEFAULT_LOCALE = g_locale_to_utf8(gtk_set_locale(), -1, NULL, NULL, NULL);
1073 gtk_init(&argc, &argv);
1074 GC_INIT(); Scm_Init(GAUCHE_SIGNATURE);
1075 Scm_Load("gauche-init.scm", 0);
1076 Shiki_editor_window_init(argc, argv);
1077 gtk_main();
1078 Scm_Exit(0);
1079 return 0;
1080 }

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