| 62 |
static gchar* get_all_buffer_contents(GtkTextBuffer *buffer); |
static gchar* get_all_buffer_contents(GtkTextBuffer *buffer); |
| 63 |
static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer); |
static gboolean save_text_buffer(const gchar *filename, GtkTextBuffer *buffer); |
| 64 |
static void clear_current_buffer_handler(); |
static void clear_current_buffer_handler(); |
|
static void search_current_buffer(); |
|
| 65 |
|
|
| 66 |
/* Gauche と S 式操作やインデント・キーワードハイライティング関連 */ |
/* Gauche と S 式操作やインデント・キーワードハイライティング関連 */ |
|
static gchar *eval_cstring_by_gauche(gchar *s); |
|
| 67 |
static gchar *load_cstring_by_gauche(gchar *s); |
static gchar *load_cstring_by_gauche(gchar *s); |
| 68 |
static void load_buffer_by_gauche(); |
static void load_buffer_by_gauche(); |
| 69 |
static void load_region_by_gauche(); |
static void load_region_by_gauche(); |
| 70 |
static void load_scheme_file_by_gauche(); |
static void load_scheme_file_by_gauche(); |
|
static gboolean is_kakko_or_kokka(gunichar ch, gpointer); |
|
|
static gboolean is_kakko(gunichar ch, gpointer); |
|
|
static gboolean is_kokka(gunichar ch, gpointer); |
|
|
static gboolean search_sexp(GtkTextIter *start, GtkTextIter *end); |
|
|
static gboolean search_sexp_kokka(GtkTextIter *end); |
|
|
static gboolean search_last_sexp(GtkTextIter *start, GtkTextIter *end); |
|
|
static gboolean search_last_sexp_kakko(GtkTextIter *start); |
|
| 71 |
static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer); |
static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer); |
| 72 |
static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data); |
static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data); |
| 73 |
static gboolean is_double_quote(gunichar ch, gpointer user_data); |
static gboolean is_double_quote(gunichar ch, gpointer user_data); |
| 97 |
Shiki_erase_buffer(Shiki_CURRENT_TEXT_BUFFER); |
Shiki_erase_buffer(Shiki_CURRENT_TEXT_BUFFER); |
| 98 |
} |
} |
| 99 |
|
|
|
static void destroy_handler(GtkWidget *button, GtkWidget *widget) {gtk_widget_destroy(widget);} |
|
|
|
|
|
static void toggled_handler(GtkToggleButton *togglebutton, gboolean *flag) { |
|
|
*flag = !*flag; |
|
|
} |
|
|
|
|
|
static void replace_current_buffer() { |
|
|
GtkWidget *dialog = gtk_dialog_new_with_buttons ("文字列の置換", GTK_WINDOW(Shiki_EDITOR_WINDOW), GTK_DIALOG_DESTROY_WITH_PARENT, NULL); |
|
|
GtkWidget *table = gtk_table_new(7, 3, FALSE); |
|
|
GtkWidget *find_label = gtk_label_new("検索 : "); |
|
|
GtkWidget *find = gtk_entry_new(); |
|
|
GtkWidget *rep_label = gtk_label_new("置換 : "); |
|
|
GtkWidget *replace = gtk_entry_new(); |
|
|
GtkWidget *check1 = gtk_check_button_new_with_label("大文字小文字を区別する"); |
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1), TRUE); |
|
|
GtkWidget *check2 = gtk_check_button_new_with_label("単語単位で検索する"); |
|
|
GtkWidget *check3 = gtk_check_button_new_with_label("正規表現"); |
|
|
GtkWidget *check4 = gtk_check_button_new_with_label("エスケープシーケンスを理解する"); |
|
|
GtkWidget *check5 = gtk_check_button_new_with_label("バッファの先頭から"); |
|
|
GtkWidget *interactive = gtk_button_new_with_label ("確認あり"); |
|
|
GtkWidget *all = gtk_button_new_with_label ("全て置換"); |
|
|
GtkWidget *cancel = gtk_button_new_with_label ("キャンセル"); |
|
|
gboolean f1 = TRUE, f2, f3, f4, f5; |
|
|
f2 = f3 = f4 = f5 = FALSE; |
|
|
g_signal_connect (check1, "toggled", G_CALLBACK (toggled_handler), &f1); |
|
|
g_signal_connect (check2, "toggled", G_CALLBACK (toggled_handler), &f2); |
|
|
g_signal_connect (check3, "toggled", G_CALLBACK (toggled_handler), &f3); |
|
|
g_signal_connect (check4, "toggled", G_CALLBACK (toggled_handler), &f4); |
|
|
g_signal_connect (check5, "toggled", G_CALLBACK (toggled_handler), &f5); |
|
|
|
|
|
g_signal_connect (G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL); |
|
|
g_signal_connect (G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_handler), dialog); |
|
|
gtk_table_set_row_spacings(GTK_TABLE(table), 10); |
|
|
gtk_table_set_col_spacings(GTK_TABLE(table), 10); |
|
|
gtk_container_border_width (GTK_CONTAINER (dialog), 10); |
|
|
|
|
|
gtk_table_attach_defaults (GTK_TABLE(table), find_label, 0, 1, 0, 1); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), find, 1, 2, 0, 1); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), interactive, 2, 3, 0, 1); |
|
|
|
|
|
gtk_table_attach_defaults (GTK_TABLE(table), rep_label, 0, 1, 1, 2); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), replace, 1, 2, 1, 2); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), all, 2, 3, 1, 2); |
|
|
|
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check1, 1, 2, 2, 3); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), cancel, 2, 3, 2, 3); |
|
|
|
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check2, 1, 2, 3, 4); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check3, 1, 2, 4, 5); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check4, 1, 2, 5, 6); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check5, 1, 2, 6, 7); |
|
|
|
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); |
|
|
gtk_widget_show_all(table); |
|
|
gtk_dialog_run(GTK_DIALOG(dialog)); |
|
|
} |
|
|
|
|
|
static void search_current_buffer() { |
|
|
GtkWidget *dialog = gtk_dialog_new_with_buttons ("文字列の検索", GTK_WINDOW(Shiki_EDITOR_WINDOW), GTK_DIALOG_DESTROY_WITH_PARENT, NULL); |
|
|
GtkWidget *table = gtk_table_new(6, 3, FALSE); |
|
|
GtkWidget *label = gtk_label_new("検索 : "); |
|
|
GtkWidget *input = gtk_entry_new(); |
|
|
GtkWidget *check1 = gtk_check_button_new_with_label("大文字小文字を区別する"); |
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check1), TRUE); |
|
|
GtkWidget *check2 = gtk_check_button_new_with_label("単語単位で検索する"); |
|
|
GtkWidget *check3 = gtk_check_button_new_with_label("正規表現"); |
|
|
GtkWidget *check4 = gtk_check_button_new_with_label("エスケープシーケンスを理解する"); |
|
|
GtkWidget *check5 = gtk_check_button_new_with_label("見つからなければ戻って"); |
|
|
GtkWidget *prev = gtk_button_new_with_label ("上検索"); |
|
|
GtkWidget *next = gtk_button_new_with_label ("下検索"); |
|
|
GtkWidget *cancel = gtk_button_new_with_label ("キャンセル"); |
|
|
gboolean f1 = TRUE, f2, f3, f4, f5; |
|
|
f2 = f3 = f4 = f5 = FALSE; |
|
|
g_signal_connect (check1, "toggled", G_CALLBACK (toggled_handler), &f1); |
|
|
g_signal_connect (check2, "toggled", G_CALLBACK (toggled_handler), &f2); |
|
|
g_signal_connect (check3, "toggled", G_CALLBACK (toggled_handler), &f3); |
|
|
g_signal_connect (check4, "toggled", G_CALLBACK (toggled_handler), &f4); |
|
|
g_signal_connect (check5, "toggled", G_CALLBACK (toggled_handler), &f5); |
|
|
|
|
|
g_signal_connect (G_OBJECT(dialog), "delete_event", G_CALLBACK(gtk_widget_destroy), NULL); |
|
|
g_signal_connect (G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_handler), dialog); |
|
|
gtk_table_set_row_spacings(GTK_TABLE(table), 10); |
|
|
gtk_table_set_col_spacings(GTK_TABLE(table), 10); |
|
|
gtk_container_border_width (GTK_CONTAINER (dialog), 10); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 1, 0, 1); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), input, 1, 2, 0, 1); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), prev, 2, 3, 0, 1); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check1, 1, 2, 1, 2); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check2, 1, 2, 2, 3); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check3, 1, 2, 3, 4); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check4, 1, 2, 4, 5); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), check5, 1, 2, 5, 6); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), next, 2, 3, 1, 2); |
|
|
gtk_table_attach_defaults (GTK_TABLE(table), cancel, 2, 3, 2, 3); |
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); |
|
|
gtk_widget_show_all(table); |
|
|
gtk_dialog_run(GTK_DIALOG(dialog)); |
|
|
} |
|
|
|
|
| 100 |
static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data) { |
static gboolean is_not_scheme_delimita_p(gunichar ch, gpointer user_data) { |
| 101 |
return ch != '(' && ch != ')' && !g_unichar_isspace(ch); |
return ch != '(' && ch != ')' && !g_unichar_isspace(ch); |
| 102 |
} |
} |
| 182 |
Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER); |
Shiki_update_modeline(Shiki_CURRENT_TEXT_BUFFER); |
| 183 |
} |
} |
| 184 |
|
|
| 185 |
|
/* GtkTextCharPredicate */ |
| 186 |
|
static gboolean is_kakko_or_kokka(gunichar ch, gpointer p) { |
| 187 |
|
return ch == '(' || ch == ')'; |
| 188 |
|
} |
| 189 |
|
static gboolean is_kakko(gunichar ch, gpointer p) {return ch == '(';} |
| 190 |
|
static gboolean is_kokka(gunichar ch, gpointer p) {return ch == ')';} |
| 191 |
|
|
| 192 |
|
static gboolean search_sexp_kokka(GtkTextIter *end) { |
| 193 |
|
gint nest_level = 0; |
| 194 |
|
|
| 195 |
|
/* 対応する ')' を探す */ |
| 196 |
|
while(1) { |
| 197 |
|
if(!gtk_text_iter_forward_find_char(end, is_kakko_or_kokka, NULL, NULL)) |
| 198 |
|
return FALSE; |
| 199 |
|
|
| 200 |
|
if(gtk_text_iter_get_char(end) == '(') |
| 201 |
|
nest_level++; |
| 202 |
|
else { |
| 203 |
|
if(!nest_level) |
| 204 |
|
break; |
| 205 |
|
else |
| 206 |
|
nest_level--; |
| 207 |
|
} |
| 208 |
|
} |
| 209 |
|
return TRUE; |
| 210 |
|
} |
| 211 |
|
|
| 212 |
|
/* カーソル以降の '(' に対応する ')' までの文字列 (S 式) を切り出す */ |
| 213 |
|
static gboolean search_sexp(GtkTextIter *start, GtkTextIter *end) { |
| 214 |
|
|
| 215 |
|
/* カーソルの位置を取得 */ |
| 216 |
|
gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, start, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER)); |
| 217 |
|
|
| 218 |
|
if(gtk_text_iter_get_char(start) != '(') |
| 219 |
|
gtk_text_iter_forward_find_char(start, is_kakko, NULL, NULL); |
| 220 |
|
|
| 221 |
|
*end = *start; |
| 222 |
|
|
| 223 |
|
/* カーソル位置の前にある S 式を切り出す */ |
| 224 |
|
if(!search_sexp_kokka(end)) return FALSE; |
| 225 |
|
gtk_text_iter_forward_char(end); |
| 226 |
|
return TRUE; |
| 227 |
|
} |
| 228 |
|
|
| 229 |
|
/* ')' に対応する '(' までの文字列 (S 式) を切り出す */ |
| 230 |
|
static gboolean search_last_sexp_kakko(GtkTextIter *start) { |
| 231 |
|
gint nest_level = 0; |
| 232 |
|
/* ネストレベルを計算しながら ')' を探す */ |
| 233 |
|
while(1) { |
| 234 |
|
if(!gtk_text_iter_backward_find_char(start, is_kakko_or_kokka, NULL, NULL)) |
| 235 |
|
return FALSE; |
| 236 |
|
|
| 237 |
|
if(gtk_text_iter_get_char(start) == ')') |
| 238 |
|
nest_level++; |
| 239 |
|
else { |
| 240 |
|
if(!nest_level) |
| 241 |
|
break; |
| 242 |
|
else |
| 243 |
|
nest_level--; |
| 244 |
|
} |
| 245 |
|
} |
| 246 |
|
return TRUE; |
| 247 |
|
} |
| 248 |
|
|
| 249 |
|
/* カーソル以前の ')' に対応する '(' までの文字列 (S 式) を切り出す */ |
| 250 |
|
static gboolean search_last_sexp(GtkTextIter *start, GtkTextIter *end) { |
| 251 |
|
|
| 252 |
|
/* カーソルの位置を取得 */ |
| 253 |
|
gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER)); |
| 254 |
|
|
| 255 |
|
gtk_text_iter_backward_char(end); |
| 256 |
|
|
| 257 |
|
if(gtk_text_iter_get_char(end) != ')') |
| 258 |
|
gtk_text_iter_backward_find_char(end, is_kokka, NULL, NULL); |
| 259 |
|
*start = *end; |
| 260 |
|
gtk_text_iter_forward_char(end); |
| 261 |
|
|
| 262 |
|
/* カーソル位置の前にある S 式を切り出す */ |
| 263 |
|
if(!search_last_sexp_kakko(start)) return FALSE; |
| 264 |
|
|
| 265 |
|
return TRUE; |
| 266 |
|
} |
| 267 |
|
|
| 268 |
/* キーが押された */ |
/* キーが押された */ |
| 269 |
static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) { |
static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer contextid) { |
| 270 |
GtkTextIter start, end; |
GtkTextIter start, end; |
| 311 |
break; |
break; |
| 312 |
|
|
| 313 |
case GDK_e : /* Ctrl + e : eval-expression */ |
case GDK_e : /* Ctrl + e : eval-expression */ |
| 314 |
{ |
Shiki_eval_expression(); |
|
gchar *code, *result; |
|
|
GtkTextIter start, end; |
|
|
|
|
|
if(!search_sexp(&start, &end)) return FALSE; |
|
|
|
|
|
code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE); |
|
|
result = eval_cstring_by_gauche(code); |
|
|
g_free(code); |
|
|
|
|
|
gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER)); |
|
|
|
|
|
gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1); |
|
|
gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, result, -1); |
|
|
gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1); |
|
|
} |
|
| 315 |
break; |
break; |
| 316 |
|
|
| 317 |
case GDK_j : /* Ctrl + j : eval-last-sexp */ |
case GDK_j : /* Ctrl + j : eval-last-sexp */ |
| 318 |
{ |
Shiki_eval_last_sexp(); |
|
gchar *code, *result; |
|
|
GtkTextIter start, end; |
|
|
|
|
|
if(!search_last_sexp(&start, &end)) return FALSE; |
|
|
|
|
|
code = gtk_text_buffer_get_text(Shiki_CURRENT_TEXT_BUFFER, &start, &end, FALSE); |
|
|
result = eval_cstring_by_gauche(code); |
|
|
g_free(code); |
|
|
|
|
|
gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, &end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER)); |
|
|
|
|
|
gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1); |
|
|
gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, result, -1); |
|
|
gtk_text_buffer_insert(Shiki_CURRENT_TEXT_BUFFER, &end, "\n", -1); |
|
|
} |
|
| 319 |
break; |
break; |
| 320 |
|
|
| 321 |
case GDK_underscore : /* Ctrl + _ : Undo */ |
case GDK_underscore : /* Ctrl + _ : Undo */ |
| 517 |
gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename); |
gtk_window_set_title (GTK_WINDOW (Shiki_EDITOR_WINDOW), filename); |
| 518 |
} |
} |
| 519 |
|
|
|
/* gauche を起動して文字列を評価 */ |
|
|
static gchar *eval_cstring_by_gauche(gchar *s) { |
|
|
gchar *msg; |
|
|
|
|
|
ScmObj result, error; |
|
|
/* 出力文字列ポート開く */ |
|
|
ScmObj os = Scm_MakeOutputStringPort(TRUE); |
|
|
|
|
|
/* Scheme レベルでエラーハンドリング */ |
|
|
/* http://alohakun.blog7.fc2.com/blog-entry-517.html */ |
|
|
Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*input*")), SCM_MAKE_STR_COPYING(s)); |
|
|
Scm_Define(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), SCM_FALSE); |
|
|
|
|
|
result = Scm_EvalCString("(guard (e (else (set! *error* e) #f)) (eval (read-from-string *input*) (current-module)))", SCM_OBJ(Shiki_CURRENT_BUFFER_ENV)); |
|
|
|
|
|
error = Scm_GlobalVariableRef(SCM_MODULE(Shiki_CURRENT_BUFFER_ENV), SCM_SYMBOL(SCM_INTERN("*error*")), 0); |
|
|
|
|
|
/* 文字列を評価した結果をポートに書き込む */ |
|
|
if (!SCM_FALSEP(error)) |
|
|
Scm_Write(error, os, SCM_WRITE_DISPLAY); |
|
|
else |
|
|
Scm_Write(result, os, SCM_WRITE_DISPLAY); |
|
|
|
|
|
msg = Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os)))); |
|
|
/* ポート閉じる */ |
|
|
Scm_ClosePort(SCM_PORT(os)); |
|
|
|
|
|
return msg; |
|
|
} |
|
|
|
|
| 520 |
/* 緑ボタンのハンドリング.バッファの選択範囲の S 式をロード (逐次評価) */ |
/* 緑ボタンのハンドリング.バッファの選択範囲の S 式をロード (逐次評価) */ |
| 521 |
static void load_region_by_gauche() { |
static void load_region_by_gauche() { |
| 522 |
|
|
| 533 |
} |
} |
| 534 |
} |
} |
| 535 |
|
|
|
// GtkTextCharPredicate |
|
|
static gboolean is_kakko_or_kokka(gunichar ch, gpointer p) { |
|
|
return ch == '(' || ch == ')'; |
|
|
} |
|
|
static gboolean is_kakko(gunichar ch, gpointer p) {return ch == '(';} |
|
|
static gboolean is_kokka(gunichar ch, gpointer p) {return ch == ')';} |
|
|
|
|
|
/* カーソル以降の '(' に対応する ')' までの文字列 (S 式) を切り出す */ |
|
|
static gboolean search_sexp(GtkTextIter *start, GtkTextIter *end) { |
|
|
|
|
|
/* カーソルの位置を取得 */ |
|
|
gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, start, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER)); |
|
|
|
|
|
if(gtk_text_iter_get_char(start) != '(') |
|
|
gtk_text_iter_forward_find_char(start, is_kakko, NULL, NULL); |
|
|
|
|
|
*end = *start; |
|
|
|
|
|
/* カーソル位置の前にある S 式を切り出す */ |
|
|
if(!search_sexp_kokka(end)) return FALSE; |
|
|
gtk_text_iter_forward_char(end); |
|
|
return TRUE; |
|
|
} |
|
|
|
|
|
static gboolean search_sexp_kokka(GtkTextIter *end) { |
|
|
gint nest_level = 0; |
|
|
|
|
|
/* 対応する ')' を探す */ |
|
|
while(1) { |
|
|
if(!gtk_text_iter_forward_find_char(end, is_kakko_or_kokka, NULL, NULL)) |
|
|
return FALSE; |
|
|
|
|
|
if(gtk_text_iter_get_char(end) == '(') |
|
|
nest_level++; |
|
|
else { |
|
|
if(!nest_level) |
|
|
break; |
|
|
else |
|
|
nest_level--; |
|
|
} |
|
|
} |
|
|
return TRUE; |
|
|
} |
|
|
|
|
|
/* カーソル以前の ')' に対応する '(' までの文字列 (S 式) を切り出す */ |
|
|
static gboolean search_last_sexp(GtkTextIter *start, GtkTextIter *end) { |
|
|
|
|
|
/* カーソルの位置を取得 */ |
|
|
gtk_text_buffer_get_iter_at_mark(Shiki_CURRENT_TEXT_BUFFER, end, gtk_text_buffer_get_insert(Shiki_CURRENT_TEXT_BUFFER)); |
|
|
|
|
|
gtk_text_iter_backward_char(end); |
|
|
|
|
|
if(gtk_text_iter_get_char(end) != ')') |
|
|
gtk_text_iter_backward_find_char(end, is_kokka, NULL, NULL); |
|
|
*start = *end; |
|
|
gtk_text_iter_forward_char(end); |
|
|
|
|
|
/* カーソル位置の前にある S 式を切り出す */ |
|
|
if(!search_last_sexp_kakko(start)) return FALSE; |
|
|
|
|
|
return TRUE; |
|
|
} |
|
|
|
|
|
/* ')' に対応する '(' までの文字列 (S 式) を切り出す */ |
|
|
static gboolean search_last_sexp_kakko(GtkTextIter *start) { |
|
|
gint nest_level = 0; |
|
|
/* ネストレベルを計算しながら ')' を探す */ |
|
|
while(1) { |
|
|
if(!gtk_text_iter_backward_find_char(start, is_kakko_or_kokka, NULL, NULL)) |
|
|
return FALSE; |
|
|
|
|
|
if(gtk_text_iter_get_char(start) == ')') |
|
|
nest_level++; |
|
|
else { |
|
|
if(!nest_level) |
|
|
break; |
|
|
else |
|
|
nest_level--; |
|
|
} |
|
|
} |
|
|
return TRUE; |
|
|
} |
|
|
|
|
| 536 |
/* カーソル位置のネストレベルを返す */ |
/* カーソル位置のネストレベルを返す */ |
| 537 |
static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer) { |
static gint get_parent_nest_level_at_cursor(GtkTextBuffer *buffer) { |
| 538 |
gint nest_level = 0; |
gint nest_level = 0; |
| 700 |
/* カーソル位置を先頭に */ |
/* カーソル位置を先頭に */ |
| 701 |
gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &p); |
gtk_text_buffer_get_start_iter(Shiki_CURRENT_TEXT_BUFFER, &p); |
| 702 |
gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p); |
gtk_text_buffer_place_cursor(Shiki_CURRENT_TEXT_BUFFER, &p); |
| 703 |
|
gtk_text_view_set_editable(Shiki_CURRENT_TEXT_VIEW, FALSE); |
| 704 |
} |
} |
| 705 |
|
|
| 706 |
/* エディタの編集画面の初期化 */ |
/* エディタの編集画面の初期化 */ |
| 797 |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "Redo", ""); |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "Redo", ""); |
| 798 |
|
|
| 799 |
icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_FIND, iconsize), ""); |
icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_FIND, iconsize), ""); |
| 800 |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(search_current_buffer), NULL); |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(Shiki_search_buffer), NULL); |
| 801 |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
| 802 |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "検索", ""); |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "検索", ""); |
| 803 |
|
|
| 804 |
|
|
| 805 |
icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE, iconsize), ""); |
icon = gtk_tool_button_new(gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE, iconsize), ""); |
| 806 |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(replace_current_buffer), NULL); |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(Shiki_replace_buffer), NULL); |
| 807 |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
| 808 |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "置換", ""); |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "置換", ""); |
| 809 |
|
|