From 2998ce6daad7f77598e3734797da30125e64c58e Mon Sep 17 00:00:00 2001 From: Valentin Batz Date: Sat, 27 Aug 2005 22:06:34 +0000 Subject: [PATCH] Implementation of the meta-[cult] (capitalize words, upcase word, downcase word, transpose words) key-bindings from the TODO by Peder Stray git-svn-id: http://svn.irssi.org/repos/irssi/trunk@3963 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- TODO | 2 - docs/help/in/bind.in | 4 ++ src/fe-text/gui-entry.c | 117 +++++++++++++++++++++++++++++++++++++ src/fe-text/gui-entry.h | 5 ++ src/fe-text/gui-readline.c | 28 +++++++++ 5 files changed, 154 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 6654d7e0..bc2cef99 100644 --- a/TODO +++ b/TODO @@ -349,8 +349,6 @@ - /BIND -deletes should be saved in config - ^W (and some others) don't update cut buffer. - default binds: M-d, M-y - - capitalize-word (meta-c), downcase-word (meta-l), - transpose-words (meta-t), upcase-word (meta-u) - /PASSWORD command that asks you to type the password to entry line and would hide it with asterisks, good if people spy on you :) - ^R-like history search diff --git a/docs/help/in/bind.in b/docs/help/in/bind.in index 51e0c0d0..9b71a121 100644 --- a/docs/help/in/bind.in +++ b/docs/help/in/bind.in @@ -93,6 +93,10 @@ Command can be one of: refresh_screen yank_from_cutbuffer - "Undelete" line transpose_characters - Swap current and previous character + transpose_words - Swap current and previous word + capitalize_word - Capitalize word from current position + downcase_word - Downcase word from current position + upcase_word - Upcase word from current position escape_char - Insert the next character exactly as-is to input line insert_text - Insert data to entry line, data may contain $variables. stop_irc - Send SIGSTOP to client (^Z) diff --git a/src/fe-text/gui-entry.c b/src/fe-text/gui-entry.c index 0b59220c..b9332c5e 100644 --- a/src/fe-text/gui-entry.c +++ b/src/fe-text/gui-entry.c @@ -576,6 +576,123 @@ void gui_entry_transpose_chars(GUI_ENTRY_REC *entry) gui_entry_draw(entry); } +void gui_entry_transpose_words(GUI_ENTRY_REC *entry) +{ + int spos1, epos1, spos2, epos2; + + /* find last position */ + epos2 = entry->pos; + while (epos2 < entry->text_len && !i_isalnum(entry->text[epos2])) + epos2++; + while (epos2 < entry->text_len && i_isalnum(entry->text[epos2])) + epos2++; + + /* find other position */ + spos2 = epos2; + while (spos2 > 0 && !i_isalnum(entry->text[spos2-1])) + spos2--; + while (spos2 > 0 && i_isalnum(entry->text[spos2-1])) + spos2--; + + epos1 = spos2; + while (epos1 > 0 && !i_isalnum(entry->text[epos1-1])) + epos1--; + + spos1 = epos1; + while (spos1 > 0 && i_isalnum(entry->text[spos1-1])) + spos1--; + + /* do wordswap if any found */ + if (spos1 < epos1 && epos1 < spos2 && spos2 < epos2) { + unichar *first, *sep, *second; + int i; + + first = (unichar *) g_malloc( (epos1 - spos1) * sizeof(unichar) ); + sep = (unichar *) g_malloc( (spos2 - epos1) * sizeof(unichar) ); + second = (unichar *) g_malloc( (epos2 - spos2) * sizeof(unichar) ); + + for (i = spos1; i < epos1; i++) + first[i-spos1] = entry->text[i]; + for (i = epos1; i < spos2; i++) + sep[i-epos1] = entry->text[i]; + for (i = spos2; i < epos2; i++) + second[i-spos2] = entry->text[i]; + + entry->pos = spos1; + for (i = 0; i < epos2-spos2; i++) + entry->text[entry->pos++] = second[i]; + for (i = 0; i < spos2-epos1; i++) + entry->text[entry->pos++] = sep[i]; + for (i = 0; i < epos1-spos1; i++) + entry->text[entry->pos++] = first[i]; + + g_free(first); + g_free(sep); + g_free(second); + + } + + gui_entry_redraw_from(entry, spos1); + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); +} + +void gui_entry_capitalize_word(GUI_ENTRY_REC *entry) +{ + int pos = entry->pos; + while (pos < entry->text_len && !g_unichar_isalnum(entry->text[pos])) + pos++; + + if (pos < entry->text_len) { + entry->text[pos] = g_unichar_toupper(entry->text[pos]); + pos++; + } + + while (pos < entry->text_len && g_unichar_isalnum(entry->text[pos])) { + entry->text[pos] = g_unichar_tolower(entry->text[pos]); + pos++; + } + + gui_entry_redraw_from(entry, entry->pos); + entry->pos = pos; + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); +} + +void gui_entry_downcase_word(GUI_ENTRY_REC *entry) +{ + int pos = entry->pos; + while (pos < entry->text_len && !g_unichar_isalnum(entry->text[pos])) + pos++; + + while (pos < entry->text_len && g_unichar_isalnum(entry->text[pos])) { + entry->text[pos] = g_unichar_tolower(entry->text[pos]); + pos++; + } + + gui_entry_redraw_from(entry, entry->pos); + entry->pos = pos; + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); +} + +void gui_entry_upcase_word(GUI_ENTRY_REC *entry) +{ + int pos = entry->pos; + while (pos < entry->text_len && !g_unichar_isalnum(entry->text[pos])) + pos++; + + while (pos < entry->text_len && g_unichar_isalnum(entry->text[pos])) { + entry->text[pos] = g_unichar_toupper(entry->text[pos]); + pos++; + } + + gui_entry_redraw_from(entry, entry->pos); + entry->pos = pos; + gui_entry_fix_cursor(entry); + gui_entry_draw(entry); +} + int gui_entry_get_pos(GUI_ENTRY_REC *entry) { g_return_val_if_fail(entry != NULL, 0); diff --git a/src/fe-text/gui-entry.h b/src/fe-text/gui-entry.h index 85cacb90..0c65aae7 100644 --- a/src/fe-text/gui-entry.h +++ b/src/fe-text/gui-entry.h @@ -45,6 +45,11 @@ void gui_entry_erase_word(GUI_ENTRY_REC *entry, int to_space); void gui_entry_erase_next_word(GUI_ENTRY_REC *entry, int to_space); void gui_entry_transpose_chars(GUI_ENTRY_REC *entry); +void gui_entry_transpose_words(GUI_ENTRY_REC *entry); + +void gui_entry_capitalize_word(GUI_ENTRY_REC *entry); +void gui_entry_downcase_word(GUI_ENTRY_REC *entry); +void gui_entry_upcase_word(GUI_ENTRY_REC *entry); int gui_entry_get_pos(GUI_ENTRY_REC *entry); void gui_entry_set_pos(GUI_ENTRY_REC *entry, int pos); diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index 06ce0148..57d1ed59 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -668,6 +668,25 @@ static void key_transpose_characters(void) gui_entry_transpose_chars(active_entry); } +static void key_transpose_words(void) +{ + gui_entry_transpose_words(active_entry); +} + +static void key_capitalize_word(void) +{ + gui_entry_capitalize_word(active_entry); +} + +static void key_downcase_word(void) +{ + gui_entry_downcase_word(active_entry); +} +static void key_upcase_word(void) +{ + gui_entry_upcase_word(active_entry); +} + static void key_delete_character(void) { if (gui_entry_get_pos(active_entry) < active_entry->text_len) { @@ -1095,6 +1114,10 @@ void gui_readline_init(void) key_bind("erase_to_end_of_line", "", "^K", NULL, (SIGNAL_FUNC) key_erase_to_end_of_line); key_bind("yank_from_cutbuffer", "", "^Y", NULL, (SIGNAL_FUNC) key_yank_from_cutbuffer); key_bind("transpose_characters", "Swap current and previous character", "^T", NULL, (SIGNAL_FUNC) key_transpose_characters); + key_bind("transpose_words", "Swap current and previous word", NULL, NULL, (SIGNAL_FUNC) key_transpose_words); + key_bind("capitalize_word", "Capitalize word", NULL, NULL, (SIGNAL_FUNC) key_capitalize_word); + key_bind("downcase_word", "Downcase word", NULL, NULL, (SIGNAL_FUNC) key_downcase_word); + key_bind("upcase_word", "Upcase word", NULL, NULL, (SIGNAL_FUNC) key_upcase_word); /* line transmitting */ key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line); @@ -1177,6 +1200,11 @@ void gui_readline_deinit(void) key_unbind("erase_to_end_of_line", (SIGNAL_FUNC) key_erase_to_end_of_line); key_unbind("yank_from_cutbuffer", (SIGNAL_FUNC) key_yank_from_cutbuffer); key_unbind("transpose_characters", (SIGNAL_FUNC) key_transpose_characters); + key_unbind("transpose_words", (SIGNAL_FUNC) key_transpose_words); + + key_unbind("capitalize_word", (SIGNAL_FUNC) key_capitalize_word); + key_unbind("downcase_word", (SIGNAL_FUNC) key_downcase_word); + key_unbind("upcase_word", (SIGNAL_FUNC) key_upcase_word); key_unbind("send_line", (SIGNAL_FUNC) key_send_line); key_unbind("word_completion", (SIGNAL_FUNC) key_word_completion);