Skip to content

Commit

Permalink
Add delete modifier and multipliers
Browse files Browse the repository at this point in the history
  • Loading branch information
polachok committed Jul 16, 2012
1 parent 513a9dc commit cf3dda0
Showing 1 changed file with 85 additions and 18 deletions.
103 changes: 85 additions & 18 deletions vi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,116 @@
* gcc -shared -fPIC `pkg-config gtk+-x11-2.0 --cflags --libs` -o libvi.so vi.c
* GTK_MODULES=$PWD/libvi.so <app>
*/
#include <string.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

enum { INSERT, NORMAL };
enum { Insert, Normal };
enum { Move, Delete };
enum { No, Yes, More };
enum { Char, Word, Line };

static int mode = INSERT;
static int mode = Insert;

gint
vi_mode(GtkWidget *widget, GdkEventKey *event) {
static int m = 1; /* command multiplier */
static int mod = Move;
static int obj;
static int handled = Yes;
static int count = 0;
int k;
static const char *commands[] = { "move-cursor",
"delete-from-cursor" };
static const struct {
int character;
int word;
int line;
int paragraph;
} objs[] = {
{ GTK_MOVEMENT_LOGICAL_POSITIONS,
GTK_MOVEMENT_WORDS,
GTK_MOVEMENT_DISPLAY_LINES,
GTK_MOVEMENT_PARAGRAPH_ENDS },
{ GTK_DELETE_CHARS,
GTK_DELETE_WORD_ENDS,
GTK_DELETE_DISPLAY_LINE_ENDS,
GTK_DELETE_PARAGRAPH_ENDS },
};

if (event->type != GDK_KEY_PRESS)
return TRUE;
switch(event->keyval) {
handled = Yes;
switch (event->keyval) {
case GDK_0:
case GDK_1:
case GDK_2:
case GDK_3:
case GDK_4:
case GDK_5:
case GDK_6:
case GDK_7:
case GDK_8:
case GDK_9:
handled = More;
if (count == 0)
m = 0;
k = event->keyval - GDK_0;
m = m * 10 + k;
count++;
return TRUE;
break;
default:
count = 0;
}

switch (event->keyval) {
case GDK_d:
mod = Delete;
handled = More;
return TRUE;
break;
case GDK_b:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_WORDS, -1, 0);
obj = objs[mod].word;
m = -abs(m);
break;
case GDK_w:
obj = objs[mod].word;
break;
case GDK_h:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_LOGICAL_POSITIONS, -1, 0);
obj = objs[mod].character;
m = -abs(m);
break;
case GDK_l:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_LOGICAL_POSITIONS, 1, 0);
obj = objs[mod].character;
break;
case GDK_i:
mode = INSERT;
mode = Insert;
break;
case GDK_j:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_DISPLAY_LINES, 1, 0);
obj = objs[mod].line;
break;
case GDK_k:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_DISPLAY_LINES, -1, 0);
break;
case GDK_w:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_WORDS, 1, 0);
obj = objs[mod].line;
m = -abs(m);
break;
case GDK_asciicircum:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_PARAGRAPH_ENDS, -1, 0);
obj = objs[mod].paragraph;
m = -1;
break;
case GDK_dollar:
g_signal_emit_by_name(G_OBJECT(widget), "move-cursor", GTK_MOVEMENT_PARAGRAPH_ENDS, 1, 0);
obj = objs[mod].paragraph;
m = 1;
break;
default:
handled = No;
return TRUE;
}
if (handled == Yes) {
g_signal_emit_by_name(G_OBJECT(widget), commands[mod],
obj, m, 0);
m = 1;
mod = Move;
}
return TRUE;
}

Expand All @@ -53,11 +120,11 @@ snooper(GtkWidget *widget, GdkEventKey *event, gpointer data) {
widget = gtk_window_get_focus(widget);
if (!GTK_IS_TEXT_VIEW(widget) && !GTK_IS_ENTRY(widget))
return FALSE;
if (mode == NORMAL && vi_mode(widget, event))
if (mode == Normal && vi_mode(widget, event))
return TRUE;
if (mode == INSERT && event->keyval == GDK_Escape) {
if (mode == Insert && event->keyval == GDK_Escape) {
if (event->type == GDK_KEY_PRESS)
mode = NORMAL;
mode = Normal;
return TRUE;
}
return FALSE;
Expand Down

0 comments on commit cf3dda0

Please sign in to comment.