4 A Programmer's Text Editor
8 Copyright (C) 1991-2011 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['unmark'] = sub (d) { mp.unmark(d); };
31 mp.actions['mark'] = sub (d) { mp.mark(d); };
32 mp.actions['mark_vertical'] = sub (d) { mp.mark_vertical(d); };
34 mp.actions['copy_mark'] = sub (d) {
43 mp.actions['paste_mark'] = sub (d) {
52 mp.actions['cut_mark'] = sub (d) {
61 mp.actions['delete_mark'] = sub (d) {
70 mp.actions['mouse_drag_mark'] = sub (d) {
71 /* no selection yet? move to initial click and mark */
72 if (d.txt.mark == NULL)
75 /* move to drag position */
76 mp.move_to_coords_xy(d, mp.mouse_to_x, mp.mouse_to_y);
84 mp.actions['mark_all'] = sub (d) {
96 mp.actions['cut_lines_with_string'] = sub (d, str) {
101 'label' => L("Cut lines containing:"),
103 'history' => 'cut_lines_with_string'
115 mp.cut_lines_with_string(d, str);
123 /** default key bindings **/
125 mp.keycodes['f8'] = "unmark";
126 mp.keycodes['f9'] = "mark";
127 mp.keycodes['ctrl-b'] = "mark_vertical";
128 mp.keycodes['ctrl-c'] = "copy_mark";
129 mp.keycodes['ctrl-v'] = "paste_mark";
130 mp.keycodes['ctrl-x'] = "cut_mark";
131 mp.keycodes['mouse-drag'] = "mouse_drag_mark";
133 /** action descriptions **/
135 mp.actdesc['unmark'] = LL("Unmark block");
136 mp.actdesc['mark'] = LL("Mark beginning/end of block");
137 mp.actdesc['mark_vertical'] = LL("Mark vertical block");
138 mp.actdesc['copy_mark'] = LL("Copy block");
139 mp.actdesc['paste_mark'] = LL("Paste block");
140 mp.actdesc['cut_mark'] = LL("Cut block");
141 mp.actdesc['delete_mark'] = LL("Delete block");
142 mp.actdesc['mouse_drag_mark'] = LL("Mark using mouse dragging");
143 mp.actdesc['mark_all'] = LL("Mark all");
144 mp.actdesc['cut_lines_with_string'] = LL("Cut lines containing a string...");
150 /* unmarks the block */
152 /* just destroy the mark */
160 /* marks the start or end of the block */
164 if (txt.mark == NULL) {
165 /* no mark; create one */
167 txt.mark.ax = txt.mark.bx = txt.mark.ex = txt.x;
168 txt.mark.ay = txt.mark.by = txt.mark.ey = txt.y;
169 txt.mark.vertical = 0;
170 txt.mark.incomplete = 1;
173 /* mark exists; extend current one */
174 if (txt.mark.vertical == 0) {
175 /* normal selection */
176 if (txt.y < txt.mark.ay ||
177 (txt.y == txt.mark.ay && txt.x < txt.mark.ax)) {
178 /* move the beginning of the block */
181 txt.mark.ex = txt.mark.ax;
182 txt.mark.ey = txt.mark.ay;
185 /* move the end of the block */
188 txt.mark.bx = txt.mark.ax;
189 txt.mark.by = txt.mark.ay;
193 /* vertical selection */
194 txt.mark.by = txt.mark.ay;
196 if (txt.y < txt.mark.ay) {
198 txt.mark.ey = txt.mark.ay;
201 txt.mark.bx = txt.mark.ax;
203 if (txt.x < txt.mark.ax) {
205 txt.mark.ex = txt.mark.ax;
209 txt.mark.incomplete = 0;
216 sub mp.mark_vertical(doc)
217 /* start vertical block selection */
220 doc.txt.mark.vertical = 1;
226 sub mp.get_active_area(doc)
227 /* returns the active area: the selection or the full document */
231 if ((m = doc.txt.mark) == NULL)
232 return doc.txt.lines;
234 return mp.get_range(doc, m.bx, m.by, m.ex, m.ey, m.vertical);
239 * mp.copy - Copies the selected block or a string to the clipboard
240 * @doc: the source of the copy
242 * If @doc is a document, it copies to the clipboard the content of the
243 * selected block, if one exists. If @doc is an array or scalar, it copies
244 * that data directly into it.
250 mp.clipboard = mp.get_active_area(doc);
251 mp.clipboard_vertical = doc.txt.mark.vertical;
253 mp.drv.clip_to_sys();
258 doc = split(doc, "\n");
261 mp.clipboard_vertical = 0;
262 mp.drv.clip_to_sys();
269 sub mp.delete_mark(doc)
270 /* deletes current selection */
275 if (txt.mark != NULL) {
276 /* deletes the range */
277 if (txt.mark.bx != txt.mark.ex || txt.mark.by != txt.mark.ey)
278 mp.delete_range(doc, txt.mark.bx, txt.mark.by,
279 txt.mark.ex, txt.mark.ey, txt.mark.vertical);
289 /* cut (copy + delete) selected mark */
293 mp.drv.clip_to_sys();
300 * mp.paste - Pastes from the clipboard into a text or as a value
301 * @doc: the destination of the copy
303 * If @doc is NULL, returns the content of the clipboard as a
304 * scalar string; if it's not, is assumed to be a document and
305 * pastes the content of the clipboard into the cursor position.
309 mp.drv.sys_to_clip();
312 return join(mp.clipboard, "\n");
314 if (size(mp.clipboard) == 0)
317 local t = mp.config.auto_indent;
318 mp.config.auto_indent = 0;
320 /* is there a block? replace it */
321 if (doc.txt.mark != NULL) {
323 doc.txt.x = doc.txt.mark.bx;
324 doc.txt.y = doc.txt.mark.by;
326 /* and delete the block */
330 if (mp.clipboard_vertical == 0) {
331 /* normal selection in clipboard */
332 mp.insert(doc, mp.clipboard);
335 /* vertical selection in clipboard */
337 local s = size(mp.clipboard);
342 /* pad out to current x position */
343 e = txt.x - size(txt.lines[txt.y]);
346 txt.lines[txt.y] = txt.lines[txt.y] ~ " ";
348 /* insert this line of the clipboard */
349 w = splice(txt.lines[txt.y], mp.clipboard[i++], txt.x, 0);
350 txt.lines[txt.y++] = w[0];
356 mp.config.auto_indent = t;
363 * mp.cut_lines_with_string - Cuts all lines matching a string
365 * @str: the string to be matched
367 * Cuts all lines from the document that matches @str, that is
368 * a regular expression. The deleted lines are left in the clipboard.
369 * If a block is selected, only lines inside it are cut.
371 sub mp.cut_lines_with_string(doc, str)
376 if (str == NULL || str eq '')
379 str = '/' ~ str ~ '/';
384 /* create a temporary work document */
385 p = mp.create('<wrk>', mp.clipboard);
393 while (p.txt.y < size(p.txt.lines) - 1) {
394 local l = p.txt.lines[p.txt.y];
396 if (regex(l, str) != NULL) {
404 /* if p is the working document, move content back to doc */
405 if (p.name eq '<wrk>')
406 mp.insert(doc, p.txt.lines);
409 mp.drv.clip_to_sys();