Skip to content

Commit

Permalink
Initial Add of keypress handler for ctrl+shift+right/left arrow keys …
Browse files Browse the repository at this point in the history
…to change default behvior of selecting word-after-whitespace, should stop at beginning of word. buffer_select_to_next_char() and buffer_select_to_prev_char() 80% finished.
  • Loading branch information
David C. Rankin committed Aug 28, 2017
1 parent 0dfffa5 commit 1cb7218
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 8 deletions.
8 changes: 8 additions & 0 deletions gtk_appdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ g_print ("app->exename : %s\n"
app->appshort = APPSHORT; /* short name, e.g. "GTKwrite" */
app->comment = g_strdup ("// ");

app->ctrl_shift_right_fix = TRUE; /* Use custom key-handler */

app->new_pos = NULL; /* Goto mark, no sep init */

app->printsettings = NULL; /* initialize print settings */
Expand Down Expand Up @@ -236,6 +238,10 @@ static void context_read_keyfile (kwinst *app)
"pgudmvscsr", &err);
if (chk_key_ok (&err)) app->pgudmvscsr = bv;

bv = g_key_file_get_boolean (app->keyfile, "editor",
"ctrl_shift_right_fix", &err);
if (chk_key_ok (&err)) app->ctrl_shift_right_fix = bv;

bv = g_key_file_get_boolean (app->keyfile, "editor",
"indentwspc", &err);
if (chk_key_ok (&err)) app->indentwspc = bv;
Expand Down Expand Up @@ -352,6 +358,8 @@ static void context_write_keyfile (kwinst *app)
g_key_file_set_boolean (app->keyfile, "editor", "dynwrap", app->dynwrap);
g_key_file_set_boolean (app->keyfile, "editor", "wraptxtcsr", app->wraptxtcsr);
g_key_file_set_boolean (app->keyfile, "editor", "pgudmvscsr", app->pgudmvscsr);
g_key_file_set_boolean (app->keyfile, "editor", "ctrl_shift_right_fix",
app->ctrl_shift_right_fix);
g_key_file_set_boolean (app->keyfile, "editor", "indentwspc", app->indentwspc);
g_key_file_set_boolean (app->keyfile, "editor", "indentmixd", app->indentmixd);
g_key_file_set_boolean (app->keyfile, "editor", "indentauto", app->indentauto);
Expand Down
15 changes: 9 additions & 6 deletions gtk_appdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#define HAVEMSWIN 1
#endif

#define VER "0.1.7"
#define VER "0.1.8"
#define SITE "https://www.rankinlawfirm.com"
#define LICENSE "gpl-2.0.txt"
#define CFGDIR "gtkwrite"
Expand Down Expand Up @@ -179,14 +179,12 @@ typedef struct {
gboolean trimendws;
// gboolean tabkeyindt; /* TODO: tab key indents */

/* text view status */
GtkTextMark *markfrom, /* operation from mark */
*selstart, /* selection start/end */
*selend;

gchar *comment; /* comment string */
GtkWidget *cmtentry; /* comment entry */

/* custom key handler flags */
gboolean ctrl_shift_right_fix; /* select only whitespace or char */

/* find replace dailog data */
GtkWidget *findrepwin; /* main window */
GtkWidget *entryfind; /* find entry combo */
Expand Down Expand Up @@ -220,6 +218,11 @@ typedef struct {
gboolean findcbchgd; /* find combo box changed */
gboolean replcbchgd; /* replace combo box changed */

/* find/replace placeholders - TODO move to find/replace data struct */
GtkTextMark *markfrom, /* operation from mark */
*selstart, /* selection start/end */
*selend;

/* find replace results */
gboolean txtfound; /* prev search found text */
GtkTextMark *last_pos; /* position of last match in buf */
Expand Down
161 changes: 161 additions & 0 deletions gtk_filebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,155 @@ gboolean buffer_deselect_all (kwinst *app)
return TRUE;
}

/** buffer_select_to_next_char selects from cursor to next non-ws char.
* this corrects the gtk_text_view default selection of whitespace
* plus the next word on the ctrl+shift+right-arrow combination
*
* TODO: implement ctrl+shift+left-arrow event handler to undo this
* handler. (currently starts at beginning and backs up rather than
* starting at end an back-tracking). This fixes the most annoying
* aspect of the default gtk key combination handling. Make optional
* for now in settings->editing.
*/
gboolean buffer_select_to_next_char (GtkTextBuffer *buf)
{
GtkTextIter start, end;
gunichar c;

/* check existing selection, set start = end, otherwise
* get iter at cursor position ("Insert" mark), set end = start
*/
if (!gtk_text_buffer_get_selection_bounds (buf, &start, &end)) {
gtk_text_buffer_get_iter_at_mark (buf, &start,
gtk_text_buffer_get_insert (buf));
end = start;
}

/* get char and check if whitespace or non-whitespace */
c = gtk_text_iter_get_char (&end);
if (c == ' ' || c == '\t') {
/* read contiguous whitespace to next word */
while (c == ' ' || c == '\t') {
if (!gtk_text_iter_forward_char (&end))
break;
c = gtk_text_iter_get_char (&end);
}
}
else {
/* read contiguous non-whitespace */
while (c != ' ' && c != '\t') {
if (!gtk_text_iter_forward_char (&end))
break;
c = gtk_text_iter_get_char (&end);
}
/* read contiguous whitespace to next word */
while (c == ' ' || c == '\t') {
if (!gtk_text_iter_forward_char (&end))
break;
c = gtk_text_iter_get_char (&end);
}
}

/* select range */
gtk_text_buffer_select_range (buf, &start, &end);

return TRUE;
}

gboolean buffer_select_to_prev_char (GtkTextBuffer *buf)
{
GtkTextIter start, end;
gunichar c;

/* check existing selection, set start = end, otherwise
* get iter at cursor position ("Insert" mark), set end = start
*/
if (!gtk_text_buffer_get_selection_bounds (buf, &start, &end)) {
gtk_text_buffer_get_iter_at_mark (buf, &start,
gtk_text_buffer_get_insert (buf));
end = start;
}

/* reduce end until equal to start, then move start */
if (gtk_text_iter_compare (&start, &end) < 0) {
g_print ("start < end\n");
gtk_text_iter_backward_char (&end);

/* get char and check if whitespace or non-whitespace */
c = gtk_text_iter_get_char (&end);
if (c == ' ' || c == '\t') {
/* read contiguous whitespace to next word */
while (c == ' ' || c == '\t') {
if (!gtk_text_iter_backward_char (&end) ||
gtk_text_iter_equal (&start, &end))
break;
c = gtk_text_iter_get_char (&end);
}
}
else {
/* read contiguous non-whitespace */
while (c != ' ' && c != '\t') {
if (!gtk_text_iter_backward_char (&end) ||
gtk_text_iter_equal (&start, &end))
goto swapiters;
c = gtk_text_iter_get_char (&end);
}
/* read contiguous whitespace to next word */
while (c == ' ' || c == '\t') {
if (!gtk_text_iter_backward_char (&end) ||
gtk_text_iter_equal (&start, &end))
goto swapiters;
c = gtk_text_iter_get_char (&end);
}
swapiters:;
}
if (!gtk_text_iter_equal (&start, &end);
gtk_text_iter_forward_char (&end);

}
else { /* no selection or selection toward beginning of file */
/* TODO change start to end below and include
* gtk_text_iter_forward_char after each loop
* to make sure next loop executes correctly.
* method has promise, work ok until you erase existing selection.
*/
g_print ("start >= end\n");
gtk_text_iter_backward_char (&start);

/* get char and check if whitespace or non-whitespace */
c = gtk_text_iter_get_char (&start);
if (c == ' ' || c == '\t') {
/* read contiguous whitespace to next word */
while (c == ' ' || c == '\t') {
if (!gtk_text_iter_backward_char (&start))
break;
c = gtk_text_iter_get_char (&start);
}
}
else {
/* read contiguous non-whitespace */
while (c != ' ' && c != '\t') {
if (!gtk_text_iter_backward_char (&start))
break;
c = gtk_text_iter_get_char (&start);
}
/* read contiguous whitespace to next word */
while (c == ' ' || c == '\t') {
if (!gtk_text_iter_backward_char (&start))
break;
c = gtk_text_iter_get_char (&start);
}
}
gtk_text_iter_forward_char (&start);

}

/* select range */
gtk_text_buffer_select_range (buf, &start, &end);

return TRUE;
}

void buffer_comment_lines (kwinst *app,
GtkTextIter *start,
GtkTextIter *end)
Expand Down Expand Up @@ -533,6 +682,7 @@ void buffer_uncomment_lines (kwinst *app,
gtk_text_buffer_delete_mark (buffer, end_mark);
}

/** callback for ibar_handle_quit, handling save, exit or cancel. */
void ib_handle_quit (GtkInfoBar *bar, gint response_id, kwinst *app)
{
switch (response_id) {
Expand Down Expand Up @@ -575,6 +725,11 @@ void ib_handle_quit (GtkInfoBar *bar, gint response_id, kwinst *app)
app->ibflags = 0;
}

/** ibar_handle_quit catches File->Close and on_window_delete_event.
* checks gtk_text_buffer_get_modified and presents an infobar
* prompting for save (Yes, No, Cancel). callback ib_handle_quit
* receives the response_id from the user choice and acts accordingly.
*/
void ibar_handle_quit (kwinst *app)
{
ibbtndef btndef[] = { { .btntext = "_Yes", .response_id = GTK_RESPONSE_YES },
Expand Down Expand Up @@ -606,6 +761,9 @@ void ibar_handle_quit (kwinst *app)

}

/** presents dialog on quit if file modified
* (replaced by ibar_handle_quit)
*/
gboolean buffer_chk_save_on_exit (GtkTextBuffer *buffer)
{
if (!buffer) return FALSE;
Expand All @@ -617,6 +775,9 @@ gboolean buffer_chk_save_on_exit (GtkTextBuffer *buffer)
return FALSE;
}

/** presents dialog on quit (or WM_CLOSE) if file modified
* (replaced by ibar_handle_quit)
*/
void buffer_handle_quit (kwinst *app)
{
/* check changed, prompt yes/no */
Expand Down
2 changes: 2 additions & 0 deletions gtk_filebuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ void file_open (kwinst *app, gchar *filename);
void buffer_insert_file (kwinst *app, gchar *filename);
gboolean buffer_select_all (kwinst *app);
gboolean buffer_deselect_all (kwinst *app);
gboolean buffer_select_to_next_char (GtkTextBuffer *buf);
gboolean buffer_select_to_prev_char (GtkTextBuffer *buf);
void buffer_comment_lines (kwinst *app,
GtkTextIter *start,
GtkTextIter *end);
Expand Down
17 changes: 16 additions & 1 deletion gtk_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ GtkWidget *create_settings_dlg (kwinst *app)
GtkWidget *chksmarthe; /* checkbox - smart home/end */
GtkWidget *chkwraptxtcsr; /* checkbox - wrap text cursor */
GtkWidget *chkpgudmvscsr; /* checkbox - PgUp/PgDn moves cursor */
GtkWidget *chkcsrtarrow; /* checkbox - use ctrl_shift_right_fix */
GtkWidget *chkwinrestore; /* checkbox - restore window size */
GtkWidget *chkexpandtab; /* checkbox - insert spaces for tab */
GtkWidget *chksmartbs; /* checkbox - smart backspace */
Expand Down Expand Up @@ -204,7 +205,7 @@ GtkWidget *create_settings_dlg (kwinst *app)
gtk_widget_show (frame);

/* table inside frame */
table = gtk_table_new (3, 2, TRUE);
table = gtk_table_new (4, 2, TRUE);
gtk_table_set_row_spacings (GTK_TABLE (table), 5);
gtk_table_set_col_spacings (GTK_TABLE (table), 3);
gtk_container_set_border_width (GTK_CONTAINER (table), 5);
Expand All @@ -227,6 +228,12 @@ GtkWidget *create_settings_dlg (kwinst *app)
gtk_table_attach_defaults (GTK_TABLE (table), chkpgudmvscsr, 0, 1, 2, 3);
gtk_widget_show (chkpgudmvscsr);

chkcsrtarrow = gtk_check_button_new_with_mnemonic ("Ctrl + Shift + _Right-Arrow fix");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chkcsrtarrow),
app->ctrl_shift_right_fix);
gtk_table_attach_defaults (GTK_TABLE (table), chkcsrtarrow, 0, 1, 3, 4);
gtk_widget_show (chkcsrtarrow);

/* pack frame into notebook vbox */
gtk_box_pack_start (GTK_BOX (vboxnb), frame, FALSE, FALSE, 0);

Expand Down Expand Up @@ -615,6 +622,9 @@ GtkWidget *create_settings_dlg (kwinst *app)
g_signal_connect (chkpgudmvscsr, "toggled",
G_CALLBACK (chkpgudmvscsr_toggled), app);

g_signal_connect (chkcsrtarrow, "toggled",
G_CALLBACK (chkcsrtarrow_toggled), app);

#ifdef HAVESOURCEVIEW
g_signal_connect (chklinehghlt, "toggled",
G_CALLBACK (chklinehghlt_toggled), app);
Expand Down Expand Up @@ -741,6 +751,11 @@ void chkpgudmvscsr_toggled (GtkWidget *widget, kwinst *app)
app->pgudmvscsr = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
}

void chkcsrtarrow_toggled (GtkWidget *widget, kwinst *app)
{
app->ctrl_shift_right_fix = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
}

#ifdef HAVESOURCEVIEW
void chklinehghlt_toggled (GtkWidget *widget, kwinst *app)
{
Expand Down
1 change: 1 addition & 0 deletions gtk_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void chkshowdwrap_toggled (GtkWidget *widget, kwinst *app);
void chksmarthe_toggled (GtkWidget *widget, kwinst *app);
void chkwraptxtcsr_toggled (GtkWidget *widget, kwinst *app);
void chkpgudmvscsr_toggled (GtkWidget *widget, kwinst *app);
void chkcsrtarrow_toggled (GtkWidget *widget, kwinst *app);
void chkwinrestore_toggled (GtkWidget *widget, kwinst *app);
void chkexpandtab_toggled (GtkWidget *widget, kwinst *app);
void chksmartbs_toggled (GtkWidget *widget, kwinst *app);
Expand Down
11 changes: 10 additions & 1 deletion gtk_windef.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,17 @@ gboolean on_keypress (GtkWidget *widget, GdkEventKey *event, kwinst *app)
event->state & GDK_CONTROL_MASK &&
event->state & GDK_SHIFT_MASK) {
switch (event->keyval) {
case GDK_KEY_Left:
if (app->ctrl_shift_right_fix) {
g_print ("key pressed: %s\n", "ctrl + shift + Right->Arrow");
return buffer_select_to_prev_char (GTK_TEXT_BUFFER(app->buffer));
}
break;
case GDK_KEY_Right:
g_print ("key pressed: %s\n", "ctrl + shift + Right->Arrow");
if (app->ctrl_shift_right_fix) {
// g_print ("key pressed: %s\n", "ctrl + shift + Right->Arrow");
return buffer_select_to_next_char (GTK_TEXT_BUFFER(app->buffer));
}
break;
}
return FALSE; /* return - only process ctrl + shift events */
Expand Down

0 comments on commit 1cb7218

Please sign in to comment.