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.35 by aloha, Sat Nov 18 13:11:33 2006 UTC revision 1.36 by aloha, Sat Nov 18 16:01:20 2006 UTC
# Line 87  static struct { Line 87  static struct {
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};  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[] = {  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};
 "*", "+", "-", "/", "<", ">", "<=", ">=", "?", "`", "=", "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};  
91    
92  static GHashTable *keywords_hash = NULL;  static GHashTable *keywords_hash = NULL;
93    
# Line 175  static void about_this_application(); Line 174  static void about_this_application();
174  static void shiki_editor_window_init(int argc, char **argv);  static void shiki_editor_window_init(int argc, char **argv);
175    
176  static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data) {  static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data) {
177    return ch != '(' && ch != ')' && !g_unichar_isspace(ch);    return ch != '(' && ch != ')' &&  !g_unichar_isspace(ch);
178    }
179    
180    static gboolean is_double_quote(gunichar ch, gpointer user_data) {
181      return ch == '\"';
182  }  }
183    
184  static gboolean is_scheme_delimita_p(gunichar ch, gpointer user_data) {  static gboolean is_scheme_delimita_p(gunichar ch, gpointer user_data) {
185    return ch == ' ' || ch == '(' || ch == ')' || g_unichar_isspace(ch);    return ch == ' ' || ch == '(' || ch == ')' || ch == '\"' || g_unichar_isspace(ch);
186  }  }
187    
188  /* ソースコードの色分け */  /* ソースコードの色分け */
# Line 187  static void scheme_keyword_highlighting_ Line 190  static void scheme_keyword_highlighting_
190    GtkTextIter s, e;    GtkTextIter s, e;
191    HIGHILIGHT_COLOR c;    HIGHILIGHT_COLOR c;
192    gchar *word;    gchar *word;
193      gboolean is_comment, is_string;
194    if(!keywords_hash) {    gunichar ch;
     keywords_hash = g_hash_table_new(g_str_hash, g_str_equal);  
     int i = 0;  
     while(R5RS_keywords[i] != NULL)  
       g_hash_table_insert(keywords_hash, R5RS_keywords[i++], GINT_TO_POINTER(R5RS_KEYWORD_COLOR));  
     i = 0;  
     while(R5RS_functions[i] != NULL)  
       g_hash_table_insert(keywords_hash, R5RS_functions[i++], GINT_TO_POINTER(R5RS_FUNCTION_COLOR));  
   }  
   gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &s);  
   gtk_text_buffer_get_end_iter(Shiki_CURRENT_TEXT_BUFFER, &e);  
   gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "default_background", &s, &e);  
   gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "default_foreground", &s, &e);  
195    
196    gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &s);    gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &s);
197    
198    /* 簡単な Scheme レキシカルアナライザ */    /* 簡単な Scheme レキシカルアナライザ */
199    while(TRUE) {    while(TRUE) {
200      gboolean is_comment = FALSE;      is_comment = FALSE;
201      if(gtk_text_iter_get_char(&s) != ';')      is_string = FALSE;
202        if((ch = gtk_text_iter_get_char(&s)) != ';' && ch != '\"')
203        gtk_text_iter_forward_find_char(&s, is_not_scheme_delimita_p, NULL, NULL);        gtk_text_iter_forward_find_char(&s, is_not_scheme_delimita_p, NULL, NULL);
204      e = s;      e = s;
205      if(gtk_text_iter_get_char(&s) == ';') {      if(gtk_text_iter_get_char(&s) == ';') {
206        gtk_text_iter_forward_line(&e);        gtk_text_iter_forward_line(&e);
207        gtk_text_iter_backward_char(&e);        gtk_text_iter_backward_char(&e);
208        is_comment = TRUE;        is_comment = TRUE;
209        } else if(gtk_text_iter_get_char(&s) == '\"') {
210          while(TRUE) {
211            gtk_text_iter_forward_find_char(&e, is_double_quote, NULL, NULL);
212            gtk_text_iter_backward_char(&e);
213            if(gtk_text_iter_get_char(&e) != '\\') {
214              is_string = TRUE;
215              gtk_text_iter_forward_char(&e);
216              gtk_text_iter_forward_char(&e);
217              break;
218            }
219            gtk_text_iter_forward_char(&e);
220            gtk_text_iter_forward_char(&e);
221          }
222    
223      } else      } else
224        gtk_text_iter_forward_find_char(&e, is_scheme_delimita_p, NULL, NULL);        gtk_text_iter_forward_find_char(&e, is_scheme_delimita_p, NULL, NULL);
225            
226      word = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &s, &e, FALSE);      word = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &s, &e, FALSE);
227      if(is_comment)  
228        /* 対応する色をそれぞれトークン部分につける */
229        if(is_comment) /* コメント */
230        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", &s, &e);        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", &s, &e);
231      /* 切り取った文字列がキーワードならば色を付ける */      else if(is_string) /* 文字列 */
232      else if(R5RS_KEYWORD_COLOR == (c = GPOINTER_TO_INT(g_hash_table_lookup(keywords_hash, word))))        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "string_highlighting", &s, &e);    
233        else if(R5RS_KEYWORD_COLOR == (c = GPOINTER_TO_INT(g_hash_table_lookup(keywords_hash, word)))) /* R5RS キーワード */
234        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "keyword_highlighting", &s, &e);        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "keyword_highlighting", &s, &e);
235      else if(R5RS_FUNCTION_COLOR == c)      else if(R5RS_FUNCTION_COLOR == c) /* R5RS 関数 */
236        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "function_highlighting", &s, &e);        gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "function_highlighting", &s, &e);
237    
238      g_free(word);      /* XXX : get_text() でいちいち文字列がアロケートされるから,非常に効率が悪いと思うけど… GtkTextBuffer から const gchar * が取れれば良いのに… */
239        g_free(word);
240    
241      if(gtk_text_iter_is_end(&e)) break;      if(gtk_text_iter_is_end(&e)) break;
242      s = e;      s = e;
243    }    }
   /* XXX : 正規表現を試している途中  
      static ScmRegexp *rx = NULL;  
      gchar *buf = get_all_buffer_contents(Shiki_CURRENT_TEXT_BUFFER);  
      ScmString *input = SCM_STRING(SCM_MAKE_STR(buf));  
      ScmRegMatch *regmatch;  
      ScmObj n, s, e;  
      GtkTextIter start, end;  
      if(!rx) {  
      rx = SCM_REGEXP(Scm_RegComp(SCM_STRING(SCM_MAKE_STR(";. - #[\x0d\x0a]*")), 0));  
      g_return_if_fail(SCM_REGEXPP(rx));  
      }  
      regmatch = SCM_REGMATCH(Scm_RegExec(rx, input));  
      if(!SCM_REGMATCHP(regmatch))  
      return;  
   
      gtk_text_buffer_create_tag (Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", "foreground", "red", NULL);  
   
      n = Scm_MakeInteger(0);  
      s = Scm_RegMatchStart(regmatch, n);  
      e = Scm_RegMatchEnd(regmatch, n);  
      gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &start, SCM_INT_VALUE(s));  
      gtk_text_buffer_get_iter_at_offset(Shiki_CURRENT_TEXT_BUFFER, &end, SCM_INT_VALUE(e));  
      gtk_text_buffer_apply_tag_by_name(Shiki_CURRENT_TEXT_BUFFER, "comment_highlighting", &start, &end);  
   //g_print("start : %ld, end : %ld", SCM_INT_VALUE(start), SCM_INT_VALUE(end));  
   Scm_RegMatchDump(regmatch);  
   g_free(buf);  
   */  
244  }  }
245    
246  /* バッファにテキストが挿入された */  /* バッファにテキストが挿入された */
# Line 459  static void append_tabpage(gchar *filena Line 442  static void append_tabpage(gchar *filena
442    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);
443    
444    /* 様々な初期化処理 */    /* 様々な初期化処理 */
445    /* デフォルトの背景色と文字の色 */  
   gtk_text_buffer_create_tag(tabinfo->text_buffer, "default_background", "background", "black", NULL);  
   gtk_text_buffer_create_tag(tabinfo->text_buffer, "default_foreground", "foreground", "green", NULL);  
446    /* 括弧の強調表示のためのタグを作る */    /* 括弧の強調表示のためのタグを作る */
447    gtk_text_buffer_create_tag(tabinfo->text_buffer, "parent_emphasis_background", "background", "pink", NULL);    gtk_text_buffer_create_tag(tabinfo->text_buffer, "parent_emphasis_background", "background", "pink", NULL);
448    
# Line 470  static void append_tabpage(gchar *filena Line 451  static void append_tabpage(gchar *filena
451    /* 関数 */    /* 関数 */
452    gtk_text_buffer_create_tag(tabinfo->text_buffer, "function_highlighting", "foreground", "red", NULL);    gtk_text_buffer_create_tag(tabinfo->text_buffer, "function_highlighting", "foreground", "red", NULL);
453    /* コメント */    /* コメント */
454    gtk_text_buffer_create_tag (tabinfo->text_buffer, "comment_highlighting", "foreground", "orange", NULL);    gtk_text_buffer_create_tag (tabinfo->text_buffer, "comment_highlighting", "foreground", "purple", NULL);
455      /* 文字列 */
456      gtk_text_buffer_create_tag (tabinfo->text_buffer, "string_highlighting", "foreground", "orange", NULL);
457    /* タブをノートブックに登録する */    /* タブをノートブックに登録する */
458    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));
459    /* 対応するタブ情報を大域テーブルに保存しておく */    /* 対応するタブ情報を大域テーブルに保存しておく */
# Line 1135  static void shiki_editor_window_init(int Line 1117  static void shiki_editor_window_init(int
1117    /* 「開く」「保存」「別名保存」「選択領域を実行」アイコン */    /* 「開く」「保存」「別名保存」「選択領域を実行」アイコン */
1118    GtkToolItem *oicon, *sicon, *saicon, *eicon;    GtkToolItem *oicon, *sicon, *saicon, *eicon;
1119    
1120    gint contextid;    gint contextid, i;
1121    
1122      /* ハイライティングキーワードのハッシュテーブルを初期化 */
1123      keywords_hash = g_hash_table_new(g_str_hash, g_str_equal);
1124      i = 0;
1125      while(R5RS_keywords[i] != NULL)
1126        g_hash_table_insert(keywords_hash, R5RS_keywords[i++], GINT_TO_POINTER(R5RS_KEYWORD_COLOR));
1127      i = 0;
1128      while(R5RS_functions[i] != NULL)
1129        g_hash_table_insert(keywords_hash, R5RS_functions[i++], GINT_TO_POINTER(R5RS_FUNCTION_COLOR));
1130    
1131    /* 窓を作る */    /* 窓を作る */
1132    Shiki_EDITOR_WINDOW = gtk_window_new(GTK_WINDOW_TOPLEVEL);    Shiki_EDITOR_WINDOW = gtk_window_new(GTK_WINDOW_TOPLEVEL);

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

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