geevi: set window default size
[geevi.git] / move.c
blob933447f8e6b7e3003766cabca5b1b60915b2bd68
1 #include <ctype.h>
2 #include <gtk/gtk.h>
3 #include "geevi.h"
5 static int line_length(GtkTextIter *orig)
7 GtkTextIter iter = *orig;
8 while (!gtk_text_iter_ends_line(&iter))
9 gtk_text_iter_forward_char(&iter);
10 return gtk_text_iter_get_line_offset(&iter);
13 static void jump(GtkTextIter *iter, int c)
15 char name[2];
16 GtkTextMark *mark;
17 GtkTextBuffer *buffer = gtk_text_iter_get_buffer(iter);
18 name[0] = c;
19 name[1] = '\0';
20 mark = gtk_text_buffer_get_mark(buffer, name);
21 if (mark)
22 gtk_text_buffer_get_iter_at_mark(buffer, iter, mark);
25 /* where: 0, 1, 2 for top, center, buttom respectively */
26 static void recenter(GtkTextView *view, int where, GtkTextIter *iter)
28 GdkRectangle rect;
29 int y;
30 gtk_text_view_get_visible_rect(view, &rect);
31 switch (where) {
32 case 1:
33 y = rect.y + rect.height / 2;
34 break;
35 case 2:
36 y = rect.y + rect.height;
37 break;
38 default:
39 y = rect.y;
41 gtk_text_view_get_iter_at_location(view, iter, 0, y);
44 static void search(struct movement *mm, GtkTextIter *iter)
46 GtkTextIter start, end;
47 int found = 0;
48 start = end = *iter;
49 if (mm->count > 0) {
50 gtk_text_iter_forward_char(&start);
51 found = gtk_text_iter_forward_search(&start, mm->arg.s, 0,
52 &start, &end, NULL);
53 } else {
54 gtk_text_iter_backward_char(&start);
55 found = gtk_text_iter_backward_search(&end, mm->arg.s, 0,
56 &start, &end, NULL);
58 if (found)
59 *iter = start;
62 static gboolean ischar(gunichar c, void *data)
64 struct movement *mm = data;
65 return c == mm->arg.c;
68 static void cfind(struct movement *mm, GtkTextIter *iter)
70 GtkTextIter cur = *iter;
71 GtkTextIter bol = *iter;
72 GtkTextIter eol = *iter;
73 int found = 0;
74 gtk_text_iter_forward_to_line_end(&eol);
75 gtk_text_iter_set_line_offset(&bol, 0);
76 if (mm->count > 0) {
77 gtk_text_iter_forward_char(&cur);
78 found = gtk_text_iter_forward_find_char(&cur, ischar,
79 mm, NULL);
80 } else {
81 gtk_text_iter_backward_char(&cur);
82 found = gtk_text_iter_backward_find_char(&cur, ischar,
83 mm, NULL);
85 if (found && gtk_text_iter_compare(&bol, &cur) <= 0 &&
86 gtk_text_iter_compare(&eol, &cur) >= 0)
87 *iter = cur;
90 void moveiter(GtkTextView *view, struct movement *mm,
91 GtkTextIter *iter, GtkTextIter *start)
93 GtkTextIter orig;
94 int length;
95 int offset = -1;
96 switch (mm->kind) {
97 case MM_LINE:
98 offset = gtk_text_iter_get_line_offset(iter);
99 gtk_text_iter_forward_lines(iter, mm->count);
100 break;
101 case MM_CHAR:
102 orig = *iter;
103 gtk_text_view_move_visually(view, iter, mm->count);
104 if (gtk_text_iter_get_line(iter) !=
105 gtk_text_iter_get_line(&orig))
106 *iter = orig;
107 break;
108 case MM_EOL:
109 gtk_text_iter_forward_to_line_end(iter);
110 break;
111 case MM_WORDEND:
112 if (gtk_text_iter_forward_char(iter) &&
113 gtk_text_iter_forward_word_end(iter))
114 gtk_text_iter_backward_char(iter);
115 break;
116 case MM_WORDSTART:
117 if (mm->count > 0) {
118 if (!isspace(gtk_text_iter_get_char(iter)))
119 gtk_text_iter_forward_word_end(iter);
120 if (gtk_text_iter_forward_word_end(iter))
121 gtk_text_iter_backward_word_start(iter);
123 if (mm->count < 0)
124 gtk_text_iter_backward_word_start(iter);
125 break;
126 case MM_FIRST:
127 gtk_text_iter_set_line_offset(iter, 0);
128 break;
129 case MM_FIRSTNB:
130 gtk_text_iter_set_line_offset(iter, 0);
131 while (isspace(gtk_text_iter_get_char(iter)) &&
132 !gtk_text_iter_ends_line(iter) &&
133 gtk_text_iter_forward_char(iter))
135 break;
136 case MM_GOTOLINE:
137 gtk_text_iter_forward_to_end(iter);
138 gtk_text_iter_set_line_offset(iter, 0);
139 break;
140 case MM_WHOLELINE:
141 gtk_text_iter_set_line_offset(start, 0);
142 gtk_text_iter_forward_to_line_end(iter);
143 break;
144 case MM_MARK:
145 jump(iter, mm->arg.m);
146 break;
147 case MM_TOP:
148 recenter(view, 0, iter);
149 break;
150 case MM_CENTER:
151 recenter(view, 1, iter);
152 break;
153 case MM_BOTTOM:
154 recenter(view, 2, iter);
155 break;
156 case MM_SEARCH:
157 search(mm, iter);
158 break;
159 case MM_CFIND:
160 cfind(mm, iter);
161 break;
163 if (offset == -1)
164 offset = gtk_text_iter_get_line_offset(iter);
165 length = line_length(iter);
166 if (offset > length)
167 offset = length;
168 if (mm->eolfix && offset == length)
169 offset--;
170 if (offset < 0 || !length)
171 offset = 0;
172 gtk_text_iter_set_line_offset(iter, offset);
173 if (mm->onemore)
174 gtk_text_iter_forward_char(iter);