| 29 |
#include<gtk/gtk.h> |
#include<gtk/gtk.h> |
| 30 |
#include<gdk/gdkkeysyms.h> |
#include<gdk/gdkkeysyms.h> |
| 31 |
|
|
| 32 |
#define INDENT_WIDTH 2 |
static gint editor_indent_width = 2; |
|
|
|
| 33 |
static GtkWidget *editor_window; |
static GtkWidget *editor_window; |
| 34 |
|
|
| 35 |
/* テキストバッファから全ての文字列を取り出す */ |
/* テキストバッファから全ての文字列を取り出す */ |
| 440 |
/* キーが押された */ |
/* キーが押された */ |
| 441 |
static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer p) { |
static gboolean signal_key_press_handler (GtkWidget *notebook, GdkEventKey *event, gpointer p) { |
| 442 |
GtkTextBuffer *buffer = get_text_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
GtkTextBuffer *buffer = get_text_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
|
//static gint metakey_pressed = 0; |
|
|
static gint controlx_pressed = 0; |
|
| 443 |
GtkTextIter start, end; |
GtkTextIter start, end; |
| 444 |
|
|
| 445 |
/* 括弧の対応の強調を無効に */ |
/* 括弧の対応の強調を無効に */ |
| 447 |
gtk_text_buffer_get_end_iter(buffer, &end); |
gtk_text_buffer_get_end_iter(buffer, &end); |
| 448 |
gtk_text_buffer_remove_tag_by_name(buffer, "parent_emphasis_background", &start, &end); |
gtk_text_buffer_remove_tag_by_name(buffer, "parent_emphasis_background", &start, &end); |
| 449 |
|
|
| 450 |
/* C-x */ |
if(event->state & GDK_CONTROL_MASK) { |
| 451 |
if(event->keyval == GDK_x && event->state & GDK_CONTROL_MASK) { |
switch(event->keyval) { |
| 452 |
controlx_pressed++; |
case GDK_f : /* Ctrl + f : forward */ |
| 453 |
g_print("C-x "); |
forward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
| 454 |
} else if(event->state & GDK_CONTROL_MASK) { |
break; |
| 455 |
if(controlx_pressed > 0) { |
case GDK_b : /* Ctrl + b : backward */ |
| 456 |
g_print("C-%s\n", event->string); |
backward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
| 457 |
switch(event->keyval) { |
break; |
| 458 |
case GDK_c :/* C-x C-c : 終了 */ |
case GDK_n : /* Ctrl + n : next line */ |
| 459 |
{/* "delete-event" を発生させる.ウィンドウの × ボタンが押されたのと同じ */ |
line_forward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
| 460 |
GdkEvent ev; |
break; |
| 461 |
|
case GDK_p : /* Ctrl + p : previous line */ |
| 462 |
ev.any.type = GDK_DELETE; |
line_backward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
| 463 |
ev.any.window = editor_window->window; |
break; |
|
ev.any.send_event = FALSE; |
|
|
gdk_event_put (&ev); |
|
|
} |
|
|
break; |
|
|
|
|
|
case GDK_f : /* C-x C-f : ファイル開く */ |
|
|
open_file_from_notebook(GTK_NOTEBOOK(notebook)); |
|
|
g_print("C-f\n"); |
|
|
break; |
|
|
|
|
|
case GDK_s : /* C-x C-s : ファイル保存 */ |
|
|
save_file_from_notebook(GTK_NOTEBOOK(notebook)); |
|
|
break; |
|
|
|
|
|
case GDK_w : /* C-x C-w : ファイル別名保存 */ |
|
|
save_file_as_from_notebook(GTK_NOTEBOOK(notebook)); |
|
|
break; |
|
|
} |
|
|
controlx_pressed = 0; |
|
|
} else { |
|
|
switch(event->keyval) { |
|
|
case GDK_f : /* Ctrl + f : forward */ |
|
|
forward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
|
|
break; |
|
|
case GDK_b : /* Ctrl + b : backward */ |
|
|
backward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
|
|
break; |
|
|
case GDK_n : /* Ctrl + n : next line */ |
|
|
line_forward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
|
|
break; |
|
|
case GDK_p : /* Ctrl + p : previous line */ |
|
|
line_backward_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
|
|
break; |
|
| 464 |
|
|
| 465 |
case GDK_j : /* Ctrl + j : カーソル手前の S 式の評価 */ |
case GDK_j : /* Ctrl + j : カーソル手前の S 式の評価 */ |
| 466 |
{ |
{ |
| 467 |
gchar *code; |
gchar *code; |
| 468 |
GtkTextIter start, end; |
GtkTextIter start, end; |
| 469 |
|
|
| 470 |
/* カーソルの位置を取得 */ |
/* カーソルの位置を取得 */ |
| 471 |
gtk_text_buffer_get_iter_at_mark(buffer, &end, gtk_text_buffer_get_insert(buffer)); |
gtk_text_buffer_get_iter_at_mark(buffer, &end, gtk_text_buffer_get_insert(buffer)); |
| 472 |
|
|
| 473 |
gtk_text_iter_backward_find_char(&end, is_kokka, NULL, NULL); |
gtk_text_iter_backward_find_char(&end, is_kokka, NULL, NULL); |
| 474 |
start = end; |
start = end; |
| 475 |
gtk_text_iter_forward_char(&end); |
gtk_text_iter_forward_char(&end); |
| 476 |
|
|
| 477 |
/* カーソル位置の前にある S 式を切り出す */ |
/* カーソル位置の前にある S 式を切り出す */ |
| 478 |
if(!search_sexp_string(&start)) return FALSE; |
if(!search_sexp_string(&start)) return FALSE; |
| 479 |
|
|
| 480 |
code = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
code = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); |
| 481 |
gtk_text_buffer_insert(buffer, &end, "\n\n", -1); |
gtk_text_buffer_insert(buffer, &end, "\n\n", -1); |
| 482 |
gtk_text_buffer_insert(buffer, &end, eval_cstring_by_gauche(code), -1); |
gtk_text_buffer_insert(buffer, &end, eval_cstring_by_gauche(code), -1); |
| 483 |
g_free(code); |
g_free(code); |
| 484 |
} |
} |
| 485 |
break; |
break; |
| 486 |
|
|
| 487 |
case GDK_t : /* Ctrl + t : タブを開く */ |
case GDK_t : /* Ctrl + t : タブを開く */ |
| 488 |
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_scrolled_text_buffer(), gtk_label_new("*scratch*")); |
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_scrolled_text_buffer(), gtk_label_new("*scratch*")); |
| 489 |
gtk_widget_show_all(GTK_WIDGET(notebook)); |
gtk_widget_show_all(GTK_WIDGET(notebook)); |
| 490 |
break; |
break; |
| 491 |
|
|
| 492 |
case GDK_k : /* Ctrl + k : タブを閉じる */ |
case GDK_k : /* Ctrl + k : タブを閉じる */ |
| 493 |
remove_tabpage(GTK_NOTEBOOK(notebook)); |
remove_tabpage(GTK_NOTEBOOK(notebook)); |
| 494 |
break; |
break; |
|
} |
|
| 495 |
} |
} |
| 496 |
} |
} |
| 497 |
return FALSE; |
return FALSE; |
| 501 |
static gboolean signal_key_release_handler (GtkWidget *notebook, GdkEventKey *event, gpointer p) { |
static gboolean signal_key_release_handler (GtkWidget *notebook, GdkEventKey *event, gpointer p) { |
| 502 |
|
|
| 503 |
GtkTextBuffer *buffer = get_text_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
GtkTextBuffer *buffer = get_text_buffer_from_current_tabpage(GTK_NOTEBOOK(notebook)); |
| 504 |
|
//static gint metakey_pressed = 0; |
| 505 |
|
static gint controlx_pressed = 0; |
| 506 |
|
|
| 507 |
if(event->keyval == GDK_parenright && event->state & GDK_SHIFT_MASK) { |
if(event->keyval == GDK_parenright && event->state & GDK_SHIFT_MASK) { |
| 508 |
GtkTextIter start, end; |
GtkTextIter start, end; |
| 521 |
|
|
| 522 |
/* 改行されるたびに,自動的に括弧のネストの深さに応じた数のスペース (インデント) が行頭に入る */ |
/* 改行されるたびに,自動的に括弧のネストの深さに応じた数のスペース (インデント) が行頭に入る */ |
| 523 |
if(event->keyval == GDK_Return) { |
if(event->keyval == GDK_Return) { |
| 524 |
gint indentWidth = get_parent_nest_level_at_cursor(buffer) * INDENT_WIDTH; |
gint indentWidth = get_parent_nest_level_at_cursor(buffer) * editor_indent_width; |
| 525 |
gchar *indent = g_strnfill(indentWidth, ' '); |
gchar *indent = g_strnfill(indentWidth, ' '); |
| 526 |
gtk_text_buffer_insert_at_cursor(buffer, indent, -1); |
gtk_text_buffer_insert_at_cursor(buffer, indent, -1); |
| 527 |
g_free(indent); |
g_free(indent); |
| 528 |
} |
} |
| 529 |
|
|
| 530 |
|
/* C-x */ |
| 531 |
|
if(event->keyval == GDK_x && event->state & GDK_CONTROL_MASK) { |
| 532 |
|
controlx_pressed++; |
| 533 |
|
g_print("C-x "); |
| 534 |
|
} else if(event->state & GDK_CONTROL_MASK) { |
| 535 |
|
if(controlx_pressed > 0) { |
| 536 |
|
switch(event->keyval) { |
| 537 |
|
case GDK_c :/* C-x C-c : 終了 */ |
| 538 |
|
g_print("C-c\n"); |
| 539 |
|
{/* "delete-event" を発生させる.ウィンドウの × ボタンが押されたのと同じ */ |
| 540 |
|
GdkEvent ev; |
| 541 |
|
|
| 542 |
|
ev.any.type = GDK_DELETE; |
| 543 |
|
ev.any.window = editor_window->window; |
| 544 |
|
ev.any.send_event = FALSE; |
| 545 |
|
gdk_event_put (&ev); |
| 546 |
|
} |
| 547 |
|
break; |
| 548 |
|
|
| 549 |
|
case GDK_f : /* C-x C-f : ファイル開く */ |
| 550 |
|
g_print("C-f\n"); |
| 551 |
|
open_file_from_notebook(GTK_NOTEBOOK(notebook)); |
| 552 |
|
break; |
| 553 |
|
|
| 554 |
|
case GDK_s : /* C-x C-s : ファイル保存 */ |
| 555 |
|
g_print("C-s\n"); |
| 556 |
|
save_file_from_notebook(GTK_NOTEBOOK(notebook)); |
| 557 |
|
break; |
| 558 |
|
|
| 559 |
|
case GDK_w : /* C-x C-w : ファイル別名保存 */ |
| 560 |
|
g_print("C-w\n"); |
| 561 |
|
save_file_as_from_notebook(GTK_NOTEBOOK(notebook)); |
| 562 |
|
break; |
| 563 |
|
} |
| 564 |
|
controlx_pressed = 0; |
| 565 |
|
} |
| 566 |
|
} |
| 567 |
return FALSE; |
return FALSE; |
| 568 |
} |
} |
| 569 |
|
|
| 619 |
gtk_tool_item_set_tooltip(saicon, toolbar_tips, "バッファを別名保存します", |
gtk_tool_item_set_tooltip(saicon, toolbar_tips, "バッファを別名保存します", |
| 620 |
""); |
""); |
| 621 |
|
|
|
|
|
| 622 |
/* バッファ実行 */ |
/* バッファ実行 */ |
| 623 |
eicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-execute", iconsize), ""); |
eicon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-execute", iconsize), ""); |
| 624 |
/* バッファを実行ボタンに libgauche を関連付ける */ |
/* バッファを実行ボタンに libgauche を関連付ける */ |
| 641 |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-apply", iconsize), "append"); |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-apply", iconsize), "append"); |
| 642 |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(tabsborder_on_off), G_OBJECT(notebook)); |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(tabsborder_on_off), G_OBJECT(notebook)); |
| 643 |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
| 644 |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "タブの on/off", |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "タブの on/off", ""); |
|
""); |
|
| 645 |
|
|
| 646 |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-preferences", iconsize), "append"); |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-preferences", iconsize), "append"); |
| 647 |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(rotate_tab_position), G_OBJECT( notebook)); |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(rotate_tab_position), G_OBJECT( notebook)); |
| 648 |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
| 649 |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "タブの位置の設定", |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "タブの位置の設定", ""); |
|
""); |
|
| 650 |
|
|
| 651 |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-add", iconsize), "append"); |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-add", iconsize), "append"); |
| 652 |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(append_tabpage), G_OBJECT( notebook)); |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(append_tabpage), G_OBJECT( notebook)); |
| 653 |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
gtk_container_add(GTK_CONTAINER (toolbar), GTK_WIDGET(icon)); |
| 654 |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "新規バッファを開きます", |
gtk_tool_item_set_tooltip(icon, toolbar_tips, "新規バッファを開きます", ""); |
|
""); |
|
| 655 |
|
|
| 656 |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-close", iconsize), "remove"); |
icon = gtk_tool_button_new(gtk_image_new_from_stock ("gtk-close", iconsize), "remove"); |
| 657 |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(remove_tabpage_handler), G_OBJECT( notebook)); |
g_signal_connect(G_OBJECT(icon), "clicked", G_CALLBACK(remove_tabpage_handler), G_OBJECT( notebook)); |