Disable Qt4 interface if KDE4 is used.
[mp-5.x.git] / mp_move.mpsl
blob3d576036b231a8420e2c6eb697656699edc678d5
1 /*
3     Minimum Profit 5.x
4     A Programmer's Text Editor
6     Movement.
8     Copyright (C) 1991-2007 Angel Ortega <angel@triptico.com>
10     This program is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     as published by the Free Software Foundation; either version 2
13     of the License, or (at your option) any later version.
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24     http://www.triptico.com
28 /** editor actions **/
30 mp.actions['move_left']         = sub (d) { mp.move(d, mp.move_left); };
31 mp.actions['move_right']        = sub (d) { mp.move(d, mp.move_right); };
32 mp.actions['move_up']           = sub (d) { mp.move(d, mp.move_up); };
33 mp.actions['move_down']         = sub (d) { mp.move(d, mp.move_down); };
34 mp.actions['move_pgup']         = sub (d) { mp.move(d, mp.move_pgup); };
35 mp.actions['move_pgdn']         = sub (d) { mp.move(d, mp.move_pgdn); };
36 mp.actions['move_bol']          = sub (d) { mp.move(d, mp.move_bol); };
37 mp.actions['move_eol']          = sub (d) { mp.move(d, mp.move_eol); };
38 mp.actions['move_bof']          = sub (d) { mp.move(d, mp.move_bof); };
39 mp.actions['move_eof']          = sub (d) { mp.move(d, mp.move_eof); };
40 mp.actions['move_word_left']    = sub (d) { mp.move(d, mp.move_word_left); };
41 mp.actions['move_word_right']   = sub (d) { mp.move(d, mp.move_word_right); };
43 mp.actions['goto']              = sub (d) {
44         local y = mp.form( [
45                 { 'label'       => L("Line to go to:"),
46                   'type'        => 'text',
47                   'history'     => 'goto' }
48                 ]);
50         if (y != NULL && y[0] >= 1) {
51                 d.txt.x = 0;
52                 mp.set_y(d, y[0] - 1);
53         }
56 mp.actions['move_to_mouse_position']    = sub (d) {
58         /* move the cursor there */
59         mp.move_to_coords_xy(d, mp.mouse_x, mp.mouse_y);
61         /* mouse click always unmarks */
62         mp.unmark(d);
65 mp.actions['move_mouse_wheel_up']       = sub (d) {
66         mp.move(d, sub (d) {
67                 mp.move_up(d);
68                 mp.move_up(d);
69                 mp.move_up(d);
70                 mp.move_up(d);
71         });
74 mp.actions['move_mouse_wheel_down']     = sub (d) {
75         mp.move(d, sub(d) {
76                 mp.move_down(d);
77                 mp.move_down(d);
78                 mp.move_down(d);
79                 mp.move_down(d);
80         });
83 mp.actions['document_list'] = sub (d) {
85         local r = mp.form( [
86                 { 'label'       =>      L("Document list"),
87                   'type'        =>      'list',
88                   'list'        =>      mp.get_doc_names(60),
89                   'value'       =>      mp.active_i
90                 } ]
91         );
93         if (r[0] != NULL)
94                 mp.active_i = r[0];
97 /** default key bindings **/
99 mp.keycodes['cursor-left']              = "move_left";
100 mp.keycodes['cursor-right']             = "move_right";
101 mp.keycodes['cursor-up']                = "move_up";
102 mp.keycodes['cursor-down']              = "move_down";
103 mp.keycodes['page-up']                  = "move_pgup";
104 mp.keycodes['page-down']                = "move_pgdn";
105 mp.keycodes['home']                     = "move_bol";
106 mp.keycodes['end']                      = "move_eol";
107 mp.keycodes['ctrl-home']                = "move_bof";
108 mp.keycodes['ctrl-end']                 = "move_eof";
109 mp.keycodes['ctrl-cursor-left']         = "move_word_left";
110 mp.keycodes['ctrl-cursor-right']        = "move_word_right";
111 mp.keycodes['ctrl-g']                   = "goto";
112 mp.keycodes['mouse-left-button']        = "move_to_mouse_position";
113 mp.keycodes['mouse-right-button']       = "move_to_mouse_position";
114 mp.keycodes['mouse-middle-button']      = "move_to_mouse_position";
115 mp.keycodes['mouse-wheel-up']           = "move_mouse_wheel_up";
116 mp.keycodes['mouse-wheel-down']         = "move_mouse_wheel_down";
118 /** action descriptions **/
120 mp.actdesc['move_left']                 = LL("Character left");
121 mp.actdesc['move_right']                = LL("Character right");
122 mp.actdesc['move_up']                   = LL("Line up");
123 mp.actdesc['move_down']                 = LL("Line down");
124 mp.actdesc['move_pgup']                 = LL("Page up");
125 mp.actdesc['move_pgdn']                 = LL("Page down");
126 mp.actdesc['move_bol']                  = LL("Beginning of line");
127 mp.actdesc['move_eol']                  = LL("End of line");
128 mp.actdesc['move_bof']                  = LL("Beginning of document");
129 mp.actdesc['move_eof']                  = LL("End of document");
130 mp.actdesc['move_word_left']            = LL("Word left");
131 mp.actdesc['move_word_right']           = LL("Word right");
132 mp.actdesc['goto']                      = LL("Go to line...");
133 mp.actdesc['move_to_mouse_position']    = LL("Move cursor to mouse click");
134 mp.actdesc['move_mouse_wheel_down']     = LL("Mouse wheel up");
135 mp.actdesc['move_mouse_wheel_up']       = LL("Mouse wheel down");
136 mp.actdesc['document_list']             = LL("Document list");
138 /** code **/
140 sub mp.move(doc, func)
141 /* wrapper for movement functions, with possible shift selection */
143         if (func != NULL) {
144                 if (mp.shift_pressed) {
145                         /* shift pressed? move selecting */
146                         if (doc.txt.mark == NULL)
147                                 mp.mark(doc);
149                         func(doc);
150                         mp.mark(doc);
151                 }
152                 else
153                         func(doc);
154         }
156         return doc;
160 sub mp.split_by_words(s, r)
161 /* splits a string by words */
163         /* if no special-purpose regex set, take global one */
164         if (r == NULL)
165                 r = mp.word_regex;
167         return regex(r ~ 'g', s);
171 sub mp.split_line_by_words(doc, r)
172 /* splits current line by words and returns a three element array containing
173    the list of words, the list of offsets and the current position */
175         local txt, l, w, c, ol, oc, p;
177         txt = doc.txt;
178         l = txt.lines[txt.y];
179         ol = [];
180         oc = [];
181         p = -1;
183         /* if no special-purpose regex set, take global one */
184         if (r == NULL)
185                 r = mp.word_regex;
187         while ((w = regex(r, l, c[0] + c[1])) != NULL) {
188                 /* store the word */
189                 push(ol, w);
191                 /* get coordinates */
192                 c = regex();
194                 /* push the starting column */
195                 push(oc, c[0]);
197                 /* if matching coords are between the cursor, store it */
198                 if (c[0] <= txt.x && c[0] + c[1] >= txt.x)
199                         p = size(ol) - 1;
200         }
202         /* it txt.x is still further than the last match, it means
203            that the 'current' position is beyond the last word */
204         if (txt.x > c[0] + c[1])
205                 p = size(ol);
207         /* return the list of words, the list of
208            coordinates and the current one */
209         return [ ol, oc, p ];
213 sub mp.get_word(doc, r)
214 /* returns the word under the cursor */
216         local l = mp.split_line_by_words(doc, r);
218         /* no word over cursor? */
219         if (l[2] == -1)
220                 return NULL;
222         return l[0][l[2]];
226 sub mp.get_range(doc, bx, by, ex, ey, v)
227 /* gets a range or characters from a document */
229         local txt = doc.txt;
231         local r = [];
233         if (by == ey) {
234                 local w;
236                 /* block is just one line; take the inside
237                    part and push it onto the clipboard */
239                 w = splice(txt.lines[by], NULL, bx, ex - bx);
241                 push(r, w[1]);
242         }
243         else {
244                 local w, n;
246                 /* block has more than one line */
248                 n = by;
249                 if (v == 0) {
250                         /* use normal selection block */
252                         /* take from the beginning to the end of the first line */
253                         w = splice(txt.lines[n], NULL, bx, -1);
255                         push(r, w[1] || '');
256                         n++;
258                         /* take the central lines */
259                         while (n < ey)
260                                 push(r, txt.lines[n++]);
262                         /* take the last line */
263                         w = splice(txt.lines[n], NULL, 0, ex);
264                         push(r, w[1] || '');
265                 }
266                 else {
267                         /* use vertical selection block */
268                         while (n <= ey) {
269                                 w = splice(txt.lines[n++], NULL, bx, ex - bx + 1);
270                                 local l = w[1];
271                                 local p = ex - bx - size(l);
273                                 /* pad out to end of block line */
274                                 while (p-- >= 0)
275                                         l = l ~ " ";
277                                 push(r, l);
278                         }
279                 }
280         }
282         return r;
286 sub mp.set_x(doc, x)
287 /* sets the x position */
289         local txt = doc.txt;
291         if (x < 0) {
292                 /* cursor moved left of the bol; effective cursor up + eol */
293                 if (txt.y > 0) {
294                         /* one line up */
295                         txt.y--;
297                         /* set x to the end of the line */
298                         txt.x = size(txt.lines[txt.y]);
299                 }
300         }
301         else {
302                 /* test if moved beyond end of line */
303                 if (x > size(txt.lines[txt.y])) {
304                         if (txt.y < size(txt.lines) - 1) {
305                                 /* cursor moved right of eol;
306                                    effective cursor down + bol */
307                                 txt.x = 0;
308                                 txt.y++;
309                         }
310                 }
311                 else
312                         txt.x = x;
313         }
315         return doc;
319 sub mp.set_y(doc, y)
320 /* sets the y position */
322         local txt = doc.txt;
323         local vx;
325         /* get current visual x position */
326         vx = mp.x2vx(txt.lines[txt.y], txt.x);
328         /* set boundaries */
329         if (y < 0)
330                 y = 0;
331         if (y >= size(txt.lines))
332                 y = size(txt.lines) - 1;
334         /* move there */
335         txt.y = y;
337         /* adjust new x to match previously one */
338         txt.x = mp.vx2x(txt.lines[txt.y], vx);
340         return doc;
344 sub mp.move_up(doc)
345 /* moves one line up */
347         mp.set_y(doc, doc.txt.y - 1);
351 sub mp.move_down(doc)
352 /* moves one line down */
354         mp.set_y(doc, doc.txt.y + 1);
358 sub mp.move_pgup(doc)
359 /* moves one page up */
361         mp.set_y(doc, doc.txt.y - mp.window.ty);
365 sub mp.move_pgdn(doc)
366 /* moves one page down */
368         mp.set_y(doc, doc.txt.y + mp.window.ty);
372 sub mp.move_left(doc)
373 /* moves one char left */
375         if (doc.txt.x + doc.txt.y)
376                 mp.set_x(doc, doc.txt.x - 1);
378         return doc;
382 sub mp.move_right(doc)
383 /* moves one char right */
385         mp.set_x(doc, doc.txt.x + 1);
389 sub mp.move_bol(doc)
390 /* moves to the beginning of the line */
392         doc.txt.x = 0;
393         return doc;
397 sub mp.move_eol(doc)
398 /* moves to the end of the line */
400         doc.txt.x = size(doc.txt.lines[doc.txt.y]);
401         return doc;
405 sub mp.move_bof(doc)
406 /* moves to the beginning of the file */
408         doc.txt.x = 0;
409         doc.txt.y = 0;
410         return doc;
414 sub mp.move_eof(doc)
415 /* moves to the end of the file */
417         doc.txt.y = size(doc.txt.lines) - 1;
418         mp.move_eol(doc);
422 sub mp.move_word_left(doc)
423 /* moves a word to the left */
425         local txt = doc.txt;
427         while (1) {
428                 /* split by words */
429                 local l = mp.split_line_by_words(doc);
431                 /* get current word */
432                 local i = l[2];
434                 if (i >= 0) {
435                         /* if it's not at the beginning of a word,
436                            move there and go */
437                         if (i < size(l[1]) && txt.x != l[1][i]) {
438                                 txt.x = l[1][i];
439                                 break;
440                         }
442                         /* go to previous word */
443                         i = l[2] - 1;
445                         /* if that position exists, move there */
446                         if (i >= 0) {
447                                 txt.x = l[1][i];
448                                 break;
449                         }
450                 }
452                 /* no lines up? exit */
453                 if (txt.y == 0)
454                         break;
456                 txt.y--;
457                 txt.x = size(txt.lines[txt.y]);
458         }
460         return doc;
464 sub mp.move_word_right(doc)
465 /* moves a word to the right */
467         local txt = doc.txt;
469         while (txt.y < size(txt.lines) - 1) {
470                 /* split by words */
471                 local l = mp.split_line_by_words(doc);
473                 /* get next position */
474                 local i = l[2] + 1;
476                 /* if that position exists, move there */
477                 if (i < size(l[1])) {
478                         txt.x = l[1][i];
479                         break;
480                 }
482                 /* try next line */
483                 txt.y++;
484                 txt.x = 0;
485         }
487         return doc;
491 sub mp.move_to_coords_xy(doc, x, y)
492 /* move the cursor to the character on the visual coords x and y */
494         /* set y */
495         mp.set_y(doc, doc.txt.vy + y);
497         /* calculate the real position in that line
498            where the mouse click seem to be */
499         x = mp.vx2x(doc.txt.lines[doc.txt.y], doc.txt.vx + x);
501         /* move there */
502         mp.set_x(doc, x);