mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
Fix #126: Allow (simplistic) word movement and deletion.
* Ctrl-Alt-d: Delete word * Ctrl-Alt-h: Delete previous word * Alt-f: Forward one word * Alt-b: Backwards one word
This commit is contained in:
parent
00e48fdcf7
commit
f7eeaec60f
3 changed files with 136 additions and 6 deletions
|
@ -485,9 +485,13 @@ Rofi supports the following keybindings:
|
||||||
* `Ctrl-a`: Beginning of line
|
* `Ctrl-a`: Beginning of line
|
||||||
* `Ctrl-e`: End of line
|
* `Ctrl-e`: End of line
|
||||||
* `Ctrl-f, Right`: Forward one character
|
* `Ctrl-f, Right`: Forward one character
|
||||||
|
* `Alt-f`: Forward one word
|
||||||
* `Ctrl-b, Left`: Back one character
|
* `Ctrl-b, Left`: Back one character
|
||||||
|
* `Alt-b`: Back one word
|
||||||
* `Ctrl-d, Delete`: Delete character
|
* `Ctrl-d, Delete`: Delete character
|
||||||
|
* `Ctrl-Alt-d': Delete word
|
||||||
* `Ctrl-h, Backspace`: Backspace (delete previous character)
|
* `Ctrl-h, Backspace`: Backspace (delete previous character)
|
||||||
|
* `Ctrl-Alt-h`: Delete previous word
|
||||||
* `Ctrl-j,Ctrl-m,Enter`: Accept entry
|
* `Ctrl-j,Ctrl-m,Enter`: Accept entry
|
||||||
* `Ctrl-n,Down`: Select next entry
|
* `Ctrl-n,Down`: Select next entry
|
||||||
* `Ctrl-p,Up`: Select previous entry
|
* `Ctrl-p,Up`: Select previous entry
|
||||||
|
|
|
@ -599,12 +599,20 @@ Rofi supports the following keybindings:
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
\fB\fCCtrl\-f, Right\fR: Forward one character
|
\fB\fCCtrl\-f, Right\fR: Forward one character
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
|
\fB\fCAlt\-f\fR: Forward one word
|
||||||
|
.IP \(bu 2
|
||||||
\fB\fCCtrl\-b, Left\fR: Back one character
|
\fB\fCCtrl\-b, Left\fR: Back one character
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
|
\fB\fCAlt\-b\fR: Back one word
|
||||||
|
.IP \(bu 2
|
||||||
\fB\fCCtrl\-d, Delete\fR: Delete character
|
\fB\fCCtrl\-d, Delete\fR: Delete character
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
|
`Ctrl\-Alt\-d': Delete word
|
||||||
|
.IP \(bu 2
|
||||||
\fB\fCCtrl\-h, Backspace\fR: Backspace (delete previous character)
|
\fB\fCCtrl\-h, Backspace\fR: Backspace (delete previous character)
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
|
\fB\fCCtrl\-Alt\-h\fR: Delete previous word
|
||||||
|
.IP \(bu 2
|
||||||
\fB\fCCtrl\-j,Ctrl\-m,Enter\fR: Accept entry
|
\fB\fCCtrl\-j,Ctrl\-m,Enter\fR: Accept entry
|
||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
\fB\fCCtrl\-n,Down\fR: Select next entry
|
\fB\fCCtrl\-n,Down\fR: Select next entry
|
||||||
|
|
130
source/textbox.c
130
source/textbox.c
|
@ -329,6 +329,82 @@ void textbox_cursor_dec ( textbox *tb )
|
||||||
textbox_cursor ( tb, index );
|
textbox_cursor ( tb, index );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move word right
|
||||||
|
void textbox_cursor_inc_word ( textbox *tb )
|
||||||
|
{
|
||||||
|
// Find word boundaries, with pango_Break?
|
||||||
|
gchar *c = &( tb->text[tb->cursor] );
|
||||||
|
while ( ( c = g_utf8_next_char ( c ) ) ) {
|
||||||
|
gunichar uc = g_utf8_get_char ( c );
|
||||||
|
GUnicodeBreakType bt = g_unichar_break_type ( uc );
|
||||||
|
if ( (
|
||||||
|
bt == G_UNICODE_BREAK_ALPHABETIC ||
|
||||||
|
bt == G_UNICODE_BREAK_HEBREW_LETTER ||
|
||||||
|
bt == G_UNICODE_BREAK_NUMERIC ||
|
||||||
|
bt == G_UNICODE_BREAK_QUOTATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( ( c = g_utf8_next_char ( c ) ) ) {
|
||||||
|
gunichar uc = g_utf8_get_char ( c );
|
||||||
|
GUnicodeBreakType bt = g_unichar_break_type ( uc );
|
||||||
|
if ( !(
|
||||||
|
bt == G_UNICODE_BREAK_ALPHABETIC ||
|
||||||
|
bt == G_UNICODE_BREAK_HEBREW_LETTER ||
|
||||||
|
bt == G_UNICODE_BREAK_NUMERIC ||
|
||||||
|
bt == G_UNICODE_BREAK_QUOTATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int index = c - tb->text;
|
||||||
|
textbox_cursor ( tb, index );
|
||||||
|
}
|
||||||
|
// move word left
|
||||||
|
void textbox_cursor_dec_word ( textbox *tb )
|
||||||
|
{
|
||||||
|
// Find word boundaries, with pango_Break?
|
||||||
|
gchar *n;
|
||||||
|
gchar *c = &( tb->text[tb->cursor] );
|
||||||
|
while ( ( c = g_utf8_prev_char ( c ) ) && c != tb->text ) {
|
||||||
|
gunichar uc = g_utf8_get_char ( c );
|
||||||
|
GUnicodeBreakType bt = g_unichar_break_type ( uc );
|
||||||
|
if ( (
|
||||||
|
bt == G_UNICODE_BREAK_ALPHABETIC ||
|
||||||
|
bt == G_UNICODE_BREAK_HEBREW_LETTER ||
|
||||||
|
bt == G_UNICODE_BREAK_NUMERIC ||
|
||||||
|
bt == G_UNICODE_BREAK_QUOTATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( c != tb->text ) {
|
||||||
|
while ( ( n = g_utf8_prev_char ( c ) ) ) {
|
||||||
|
gunichar uc = g_utf8_get_char ( n );
|
||||||
|
GUnicodeBreakType bt = g_unichar_break_type ( uc );
|
||||||
|
if ( !(
|
||||||
|
bt == G_UNICODE_BREAK_ALPHABETIC ||
|
||||||
|
bt == G_UNICODE_BREAK_HEBREW_LETTER ||
|
||||||
|
bt == G_UNICODE_BREAK_NUMERIC ||
|
||||||
|
bt == G_UNICODE_BREAK_QUOTATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = n;
|
||||||
|
if ( n == tb->text ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int index = c - tb->text;
|
||||||
|
textbox_cursor ( tb, index );
|
||||||
|
}
|
||||||
|
|
||||||
// end of line
|
// end of line
|
||||||
void textbox_cursor_end ( textbox *tb )
|
void textbox_cursor_end ( textbox *tb )
|
||||||
{
|
{
|
||||||
|
@ -381,6 +457,26 @@ void textbox_cursor_bkspc ( textbox *tb )
|
||||||
textbox_cursor_del ( tb );
|
textbox_cursor_del ( tb );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void textbox_cursor_bkspc_word ( textbox *tb )
|
||||||
|
{
|
||||||
|
if ( tb->cursor > 0 ) {
|
||||||
|
int cursor = tb->cursor;
|
||||||
|
textbox_cursor_dec_word ( tb );
|
||||||
|
if ( cursor > tb->cursor ) {
|
||||||
|
textbox_delete ( tb, tb->cursor, cursor - tb->cursor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void textbox_cursor_del_word ( textbox *tb )
|
||||||
|
{
|
||||||
|
if ( tb->cursor >= 0 ) {
|
||||||
|
int cursor = tb->cursor;
|
||||||
|
textbox_cursor_inc_word ( tb );
|
||||||
|
if ( cursor < tb->cursor ) {
|
||||||
|
textbox_delete ( tb, cursor, tb->cursor - cursor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handle a keypress in edit mode
|
// handle a keypress in edit mode
|
||||||
// 0 = unhandled
|
// 0 = unhandled
|
||||||
|
@ -413,12 +509,7 @@ int textbox_keypress ( textbox *tb, XEvent *ev )
|
||||||
textbox_cursor_inc ( tb );
|
textbox_cursor_inc ( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Delete or Ctrl-D
|
|
||||||
else if ( key == XK_Delete ||
|
|
||||||
( ( ev->xkey.state & ControlMask ) && key == XK_d ) ) {
|
|
||||||
textbox_cursor_del ( tb );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// Ctrl-U: Kill from the beginning to the end of the line.
|
// Ctrl-U: Kill from the beginning to the end of the line.
|
||||||
else if ( ( ev->xkey.state & ControlMask ) && key == XK_u ) {
|
else if ( ( ev->xkey.state & ControlMask ) && key == XK_u ) {
|
||||||
textbox_text ( tb, "" );
|
textbox_text ( tb, "" );
|
||||||
|
@ -434,6 +525,33 @@ int textbox_keypress ( textbox *tb, XEvent *ev )
|
||||||
textbox_cursor_end ( tb );
|
textbox_cursor_end ( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// Ctrl-Alt-h
|
||||||
|
else if ( ( ev->xkey.state & ControlMask ) &&
|
||||||
|
( ev->xkey.state & Mod1Mask ) && key == XK_h ) {
|
||||||
|
textbox_cursor_bkspc_word ( tb );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Ctrl-Alt-d
|
||||||
|
else if ( ( ev->xkey.state & ControlMask ) &&
|
||||||
|
( ev->xkey.state & Mod1Mask ) && key == XK_d ) {
|
||||||
|
textbox_cursor_del_word ( tb );
|
||||||
|
return 1;
|
||||||
|
} // Delete or Ctrl-D
|
||||||
|
else if ( key == XK_Delete ||
|
||||||
|
( ( ev->xkey.state & ControlMask ) && key == XK_d ) ) {
|
||||||
|
textbox_cursor_del ( tb );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Alt-B
|
||||||
|
else if ( ( ev->xkey.state & Mod1Mask ) && key == XK_b ) {
|
||||||
|
textbox_cursor_dec_word ( tb );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Alt-F
|
||||||
|
else if ( ( ev->xkey.state & Mod1Mask ) && key == XK_f ) {
|
||||||
|
textbox_cursor_inc_word ( tb );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
// BackSpace, Ctrl-h
|
// BackSpace, Ctrl-h
|
||||||
else if ( key == XK_BackSpace ||
|
else if ( key == XK_BackSpace ||
|
||||||
( ( ev->xkey.state & ControlMask ) && key == XK_h ) ) {
|
( ( ev->xkey.state & ControlMask ) && key == XK_h ) ) {
|
||||||
|
|
Loading…
Reference in a new issue