Develop and Download Open Source Software

Browse CVS Repository

Diff of /shiki/shiki/shiki.c

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

revision 1.34 by aloha, Fri Nov 17 13:04:08 2006 UTC revision 1.35 by aloha, Sat Nov 18 13:11:33 2006 UTC
# Line 55  typedef struct { Line 55  typedef struct {
55  } ShikiTabInfo;  } ShikiTabInfo;
56    
57  /* エディタ全体に関する情報と,現在表示されているタブ情報へのキャッシュを管理する構造体 */  /* エディタ全体に関する情報と,現在表示されているタブ情報へのキャッシュを管理する構造体 */
58  struct {  static struct {
59    GtkWidget     *editor_window;    GtkWidget     *editor_window;
60    GtkClipboard  *clipboard;    GtkClipboard  *clipboard;
61    GtkNotebook   *notebook;    GtkNotebook   *notebook;
# Line 85  struct { Line 85  struct {
85  #define Shiki_CURRENT_FILENAME       (shiki_editor.current_tabpage_info)->filename  #define Shiki_CURRENT_FILENAME       (shiki_editor.current_tabpage_info)->filename
86  #define Shiki_CURRENT_BUFFER_ENV     (shiki_editor.current_tabpage_info)->env  #define Shiki_CURRENT_BUFFER_ENV     (shiki_editor.current_tabpage_info)->env
87    
88    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};
89    
90    static gchar *R5RS_functions[] = {
91    "*", "+", "-", "/", "<", ">", "<=", ">=", "?", "`", "=", "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};
92    
93    static GHashTable *keywords_hash = NULL;
94    
95    typedef enum {
96      R5RS_KEYWORD_COLOR = 1,
97      R5RS_FUNCTION_COLOR,
98      GAUCHE_KEYWORD_COLOR,
99      GAUCHE_FUNCTION_COLOR
100    } HIGHILIGHT_COLOR;
101    
102  /* プロトタイプ */  /* プロトタイプ */
103    
104  /* タブの生成と削除 : 基本的に,ShikiTabInfo の中身に格納する情報を増やしたかったら,この 2 つの関数だけを変更すれば良い (ようにする…) */  /* タブの生成と削除 : 基本的に,ShikiTabInfo の中身に格納する情報を増やしたかったら,この 2 つの関数だけを変更すれば良い (ようにする…) */
# Line 160  static void about_this_application(); Line 174  static void about_this_application();
174  /* エディタの初期化 */  /* エディタの初期化 */
175  static void shiki_editor_window_init(int argc, char **argv);  static void shiki_editor_window_init(int argc, char **argv);
176    
177    static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data) {
178      return ch != '(' && ch != ')' && !g_unichar_isspace(ch);
179    }
180    
181    static gboolean is_scheme_delimita_p(gunichar ch, gpointer user_data) {
182      return ch == ' ' || ch == '(' || ch == ')' || g_unichar_isspace(ch);
183    }
184    
185    /* ソースコードの色分け */
186    static void scheme_keyword_highlighting_current_buffer() {
187      GtkTextIter s, e;
188      HIGHILIGHT_COLOR c;
189      gchar *word;
190    
191      if(!keywords_hash) {
192        keywords_hash = g_hash_table_new(g_str_hash, g_str_equal);
193        int i = 0;
194        while(R5RS_keywords[i] != NULL)
195          g_hash_table_insert(keywords_hash, R5RS_keywords[i++], GINT_TO_POINTER(R5RS_KEYWORD_COLOR));
196        i = 0;
197        while(R5RS_functions[i] != NULL)
198          g_hash_table_insert(keywords_hash, R5RS_functions[i++], GINT_TO_POINTER(R5RS_FUNCTION_COLOR));
199      }
200      gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &s);
201      gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &e);
202      gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "default_background", &s, &e);
203      gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "default_foreground", &s, &e);
204    
205      gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &s);
206    
207      /* 簡単な Scheme レキシカルアナライザ */
208      while(TRUE) {
209        gboolean is_comment = FALSE;
210        if(gtk_text_iter_get_char(&s) != ';')
211          gtk_text_iter_forward_find_char(&s, is_not_scheme_delimita_p, NULL, NULL);
212        e = s;
213        if(gtk_text_iter_get_char(&s) == ';') {
214          gtk_text_iter_forward_line(&e);
215          gtk_text_iter_backward_char(&e);
216          is_comment = TRUE;
217        } else
218          gtk_text_iter_forward_find_char(&e, is_scheme_delimita_p, NULL, NULL);
219        
220        word = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &s, &e, FALSE);
221        if(is_comment)
222          gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", &s, &e);
223        /* 切り取った文字列がキーワードならば色を付ける */
224        else if(R5RS_KEYWORD_COLOR == (c = GPOINTER_TO_INT(g_hash_table_lookup(keywords_hash, word))))
225          gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "keyword_highlighting", &s, &e);
226        else if(R5RS_FUNCTION_COLOR == c)
227          gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "function_highlighting", &s, &e);
228    
229        g_free(word);
230    
231        if(gtk_text_iter_is_end(&e)) break;
232        s = e;
233      }
234      /* XXX : 正規表現を試している途中
235         static ScmRegexp *rx = NULL;
236         gchar *buf = get_all_buffer_contents(Shiki_CURRENT_TEXT_BUFFER);
237         ScmString *input = SCM_STRING(SCM_MAKE_STR(buf));
238         ScmRegMatch *regmatch;
239         ScmObj n, s, e;
240         GtkTextIter start, end;
241         if(!rx) {
242         rx = SCM_REGEXP(Scm_RegComp(SCM_STRING(SCM_MAKE_STR(";. - #[\x0d\x0a]*")), 0));
243         g_return_if_fail(SCM_REGEXPP(rx));
244         }
245         regmatch = SCM_REGMATCH(Scm_RegExec(rx, input));
246         if(!SCM_REGMATCHP(regmatch))
247         return;
248    
249         gtk_text_buffer_create_tag (Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", "foreground", "red", NULL);
250    
251         n = Scm_MakeInteger(0);
252         s = Scm_RegMatchStart(regmatch, n);
253         e = Scm_RegMatchEnd(regmatch, n);
254         gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &start, SCM_INT_VALUE(s));
255         gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &end, SCM_INT_VALUE(e));
256         gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", &start, &end);
257      //g_print("start : %ld, end : %ld", SCM_INT_VALUE(start), SCM_INT_VALUE(end));
258      Scm_RegMatchDump(regmatch);
259      g_free(buf);
260      */
261    }
262    
263  /* バッファにテキストが挿入された */  /* バッファにテキストが挿入された */
264  static void insert_text_handler(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *str, gint len) {  static void insert_text_handler(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *str, gint len) {
265    /* Undo のための情報を記録 */    /* Undo のための情報を記録 */
# Line 171  static void insert_text_handler(GtkTextB Line 271  static void insert_text_handler(GtkTextB
271    undoInfo->start  = gtk_text_iter_get_offset(iter);    undoInfo->start  = gtk_text_iter_get_offset(iter);
272    undoInfo->end    = undoInfo->start + undoInfo->strlen;    undoInfo->end    = undoInfo->start + undoInfo->strlen;
273    Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);    Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
274    g_print("insert : %s, len : %d, start : %d, end : %d\n", undoInfo->str, undoInfo->strlen, undoInfo->start, undoInfo->end);    /* g_print("insert : %s, len : %d, start : %d, end : %d\n", undoInfo->str, undoInfo->strlen, undoInfo->start, undoInfo->end); */
275  }  }
276    
277  /* バッファからテキストが消去された */  /* バッファからテキストが消去された */
# Line 185  static void delete_range_handler(GtkText Line 285  static void delete_range_handler(GtkText
285    undoInfo->end    = gtk_text_iter_get_offset(end);    undoInfo->end    = gtk_text_iter_get_offset(end);
286    undoInfo->strlen = end - start;    undoInfo->strlen = end - start;
287    Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);    Shiki_CURRENT_UNDO_INFO_LIST = g_list_prepend(Shiki_CURRENT_UNDO_INFO_LIST, undoInfo);
288    g_print("delete : %s %d\n", undoInfo->str, undoInfo->strlen);    /* g_print("delete : %s %d\n", undoInfo->str, undoInfo->strlen); */
289  }  }
290    
291  /* タブが切り替わる時のイベントハンドリング */  /* タブが切り替わる時のイベントハンドリング */
# Line 338  static void append_tabpage(gchar *filena Line 438  static void append_tabpage(gchar *filena
438    tabinfo->filename      = filename;    tabinfo->filename      = filename;
439    tabinfo->tabpage_label = g_path_get_basename(filename);    tabinfo->tabpage_label = g_path_get_basename(filename);
440    tabinfo->env           = Scm_MakeModule(NULL, FALSE);    tabinfo->env           = Scm_MakeModule(NULL, FALSE);
441      
442    g_return_if_fail(tabinfo->env != SCM_FALSE);    g_return_if_fail(tabinfo->env != SCM_FALSE);
443    
444    /* スクロールウィンドウ (タブの中身の大外) を作る */    /* スクロールウィンドウ (タブの中身の大外) を作る */
# Line 359  static void append_tabpage(gchar *filena Line 459  static void append_tabpage(gchar *filena
459    tabinfo->delete_handler_id = g_signal_connect(Shiki_EDITOR_WINDOW, "delete_event", G_CALLBACK(delete_event_handler), tabinfo->text_buffer);    tabinfo->delete_handler_id = g_signal_connect(Shiki_EDITOR_WINDOW, "delete_event", G_CALLBACK(delete_event_handler), tabinfo->text_buffer);
460    
461    /* 様々な初期化処理 */    /* 様々な初期化処理 */
462      /* デフォルトの背景色と文字の色 */
463      gtk_text_buffer_create_tag(tabinfo->text_buffer, "default_background", "background", "black", NULL);
464      gtk_text_buffer_create_tag(tabinfo->text_buffer, "default_foreground", "foreground", "green", NULL);
465    /* 括弧の強調表示のためのタグを作る */    /* 括弧の強調表示のためのタグを作る */
466    gtk_text_buffer_create_tag (tabinfo->text_buffer, "parent_emphasis_background", "background", "green", NULL);    gtk_text_buffer_create_tag(tabinfo->text_buffer, "parent_emphasis_background", "background", "pink", NULL);
467    
468      /* キーワードハイライティング */
469      gtk_text_buffer_create_tag(tabinfo->text_buffer, "keyword_highlighting", "foreground", "blue", NULL);
470      /* 関数 */
471      gtk_text_buffer_create_tag(tabinfo->text_buffer, "function_highlighting", "foreground", "red", NULL);
472      /* コメント */
473      gtk_text_buffer_create_tag (tabinfo->text_buffer, "comment_highlighting", "foreground", "orange", NULL);
474    
475    /* タブをノートブックに登録する */    /* タブをノートブックに登録する */
476    gtk_notebook_append_page(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(tabinfo->tabpage), gtk_label_new(tabinfo->tabpage_label));    gtk_notebook_append_page(Shiki_EDITOR_NOTEBOOK, GTK_WIDGET(tabinfo->tabpage), gtk_label_new(tabinfo->tabpage_label));
# Line 680  static void open_file(gchar *filename) { Line 790  static void open_file(gchar *filename) {
790      gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename);      gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename);
791      gtk_widget_show_all(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));      gtk_widget_show_all(GTK_WIDGET(Shiki_EDITOR_NOTEBOOK));
792      g_free(contents); g_free(text); g_free(filename);      g_free(contents); g_free(text); g_free(filename);
793    
794        /* キーワードを色分けする */
795        scheme_keyword_highlighting_current_buffer();
796    } else    } else
797      g_printerr("Get file contents error !\n");      g_printerr("Get file contents error !\n");
798  }  }

Legend:
Removed from v.1.34  
changed lines
  Added in v.1.35

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