Browse CVS Repository
Diff of /shiki/shiki/shiki.c
Parent Directory
| Revision Log
| Revision Graph
| Patch
| 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 |
|
|
| 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 |
/* ソースコードの色分け */ |
/* ソースコードの色分け */ |
| 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 |
/* バッファにテキストが挿入された */ |
/* バッファにテキストが挿入された */ |
| 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 |
|
|
| 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 |
/* 対応するタブ情報を大域テーブルに保存しておく */ |
/* 対応するタブ情報を大域テーブルに保存しておく */ |
| 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 |
|
|
| |