blob: 52e46f012945f173bfa59e289eeb9140009d7970 [file] [log] [blame]
Chris Allegretta11b00112000-08-06 21:13:45 +00001/* $Id$ */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002/**************************************************************************
3 * winio.c *
4 * *
Jordi Mallach8ae57892002-01-04 17:57:40 +00005 * Copyright (C) 1999-2002 Chris Allegretta *
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00006 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
Chris Allegretta3a24f3f2001-10-24 11:33:54 +00008 * the Free Software Foundation; either version 2, or (at your option) *
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00009 * any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
19 * *
20 **************************************************************************/
21
Chris Allegretta6efda542001-04-28 18:03:52 +000022#include "config.h"
23
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000024#include <stdarg.h>
25#include <string.h>
Chris Allegrettadba37ae2000-07-07 05:13:09 +000026#include <stdlib.h>
Chris Allegretta8a0de3b2000-11-24 20:45:14 +000027#include <unistd.h>
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000028#include "proto.h"
29#include "nano.h"
30
31#ifndef NANO_SMALL
32#include <libintl.h>
33#define _(string) gettext(string)
34#else
35#define _(string) (string)
36#endif
37
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +000038
39/* winio.c statics */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000040static int statblank = 0; /* Number of keystrokes left after
Chris Allegretta88520c92001-05-05 17:45:54 +000041 we call statusbar(), before we
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000042 actually blank the statusbar */
Robert Siemborskid8510b22000-06-06 23:04:06 +000043
44/* Local Function Prototypes for only winio.c */
45inline int get_page_from_virtual(int virtual);
46inline int get_page_start_virtual(int page);
47inline int get_page_end_virtual(int page);
48
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000049/* Window I/O */
50
51int do_first_line(void)
52{
53 current = fileage;
54 placewewant = 0;
55 current_x = 0;
Chris Allegretta234a34d2000-07-29 04:33:38 +000056 edit_update(current, CENTER);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000057 return 1;
58}
59
60int do_last_line(void)
61{
62 current = filebot;
63 placewewant = 0;
64 current_x = 0;
Chris Allegretta234a34d2000-07-29 04:33:38 +000065 edit_update(current, CENTER);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000066 return 1;
67}
68
Chris Allegretta88520c92001-05-05 17:45:54 +000069/* Like xplustabs, but for a specific index of a specific filestruct */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000070int xpt(filestruct * fileptr, int index)
71{
72 int i, tabs = 0;
73
74 if (fileptr == NULL || fileptr->data == NULL)
75 return 0;
76
77 for (i = 0; i < index && fileptr->data[i] != 0; i++) {
78 tabs++;
79
80 if (fileptr->data[i] == NANO_CONTROL_I) {
Chris Allegretta6d690a32000-08-03 22:51:21 +000081 if (tabs % tabsize == 0);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000082 else
Chris Allegretta6d690a32000-08-03 22:51:21 +000083 tabs += tabsize - (tabs % tabsize);
Chris Allegretta4da1fc62000-06-21 03:00:43 +000084 } else if (fileptr->data[i] & 0x80)
Chris Allegretta88520c92001-05-05 17:45:54 +000085 /* Make 8 bit chars only 1 column! */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000086 ;
Chris Allegretta2598c662002-03-28 01:59:34 +000087 else if (fileptr->data[i] < 32 || fileptr->data[i] == 127)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +000088 tabs++;
89 }
90
91 return tabs;
92}
93
94
95/* Return the actual place on the screen of current->data[current_x], which
96 should always be > current_x */
97int xplustabs(void)
98{
99 return xpt(current, current_x);
100}
101
102
Robert Siemborskid8510b22000-06-06 23:04:06 +0000103/* Return what current_x should be, given xplustabs() for the line,
104 * given a start position in the filestruct's data */
105int actual_x_from_start(filestruct * fileptr, int xplus, int start)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000106{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000107 int i, tot = 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000108
109 if (fileptr == NULL || fileptr->data == NULL)
110 return 0;
111
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000112 for (i = start; tot <= xplus && fileptr->data[i] != 0; i++, tot++)
Robert Siemborskid8510b22000-06-06 23:04:06 +0000113 if (fileptr->data[i] == NANO_CONTROL_I) {
Chris Allegretta6d690a32000-08-03 22:51:21 +0000114 if (tot % tabsize == 0)
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000115 tot++;
116 else
Chris Allegretta6d690a32000-08-03 22:51:21 +0000117 tot += tabsize - (tot % tabsize);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000118 } else if (fileptr->data[i] & 0x80)
119 tot++; /* Make 8 bit chars only 1 column (again) */
120 else if (fileptr->data[i] < 32)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000121 tot += 2;
122
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000123#ifdef DEBUG
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000124 fprintf(stderr, _("actual_x_from_start for xplus=%d returned %d\n"),
125 xplus, i);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000126#endif
Robert Siemborskid8510b22000-06-06 23:04:06 +0000127 return i - start;
128}
129
130/* Opposite of xplustabs */
Chris Allegretta6efda542001-04-28 18:03:52 +0000131int actual_x(filestruct * fileptr, int xplus)
Robert Siemborskid8510b22000-06-06 23:04:06 +0000132{
133 return actual_x_from_start(fileptr, xplus, 0);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000134}
135
136/* a strlen with tabs factored in, similar to xplustabs() */
Chris Allegrettad4fa0d32002-03-05 19:55:55 +0000137int strnlenpt(char *buf, int size)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000138{
139 int i, tabs = 0;
140
141 if (buf == NULL)
142 return 0;
143
Chris Allegrettad4fa0d32002-03-05 19:55:55 +0000144 for (i = 0; i < size; i++) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000145 tabs++;
146
147 if (buf[i] == NANO_CONTROL_I) {
Chris Allegretta6d690a32000-08-03 22:51:21 +0000148 if (tabs % tabsize == 0);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000149 else
Chris Allegretta6d690a32000-08-03 22:51:21 +0000150 tabs += tabsize - (tabs % tabsize);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000151 } else if (buf[i] & 0x80)
Chris Allegretta88520c92001-05-05 17:45:54 +0000152 /* Make 8 bit chars only 1 column! */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000153 ;
154 else if (buf[i] < 32)
155 tabs++;
156 }
157
158 return tabs;
159}
160
Chris Allegrettad4fa0d32002-03-05 19:55:55 +0000161int strlenpt(char *buf)
162{
163 return strnlenpt(buf, strlen(buf));
164}
165
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000166
Chris Allegretta88520c92001-05-05 17:45:54 +0000167/* resets current_y, based on the position of current, and puts the cursor at
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000168 (current_y, current_x) */
169void reset_cursor(void)
170{
171 filestruct *ptr = edittop;
172 int x;
173
174 current_y = 0;
175
176 while (ptr != current && ptr != editbot && ptr->next != NULL) {
177 ptr = ptr->next;
178 current_y++;
179 }
180
181 x = xplustabs();
182 if (x <= COLS - 2)
Robert Siemborskid8510b22000-06-06 23:04:06 +0000183 wmove(edit, current_y, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000184 else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000185 wmove(edit, current_y, x -
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000186 get_page_start_virtual(get_page_from_virtual(x)));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000187
188}
189
190void blank_bottombars(void)
191{
192 int i = no_help()? 3 : 1;
193
194 for (; i <= 2; i++)
195 mvwaddstr(bottomwin, i, 0, hblank);
196
197}
198
199void blank_edit(void)
200{
201 int i;
202 for (i = 0; i <= editwinrows - 1; i++)
203 mvwaddstr(edit, i, 0, hblank);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000204}
205
206
207void blank_statusbar(void)
208{
209 mvwaddstr(bottomwin, 0, 0, hblank);
210}
211
212void blank_statusbar_refresh(void)
213{
214 blank_statusbar();
215 wrefresh(bottomwin);
216}
217
218void check_statblank(void)
219{
220
221 if (statblank > 1)
222 statblank--;
223 else if (statblank == 1 && !ISSET(CONSTUPDATE)) {
224 statblank--;
225 blank_statusbar_refresh();
226 }
227}
228
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000229/* Repaint the statusbar when getting a character in nanogetstr */
230void nanoget_repaint(char *buf, char *inputbuf, int x)
231{
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000232 int len = strlen(buf);
233 int wid = COLS - len;
234
Chris Allegretta8ce24132001-04-30 11:28:46 +0000235#ifdef ENABLE_COLOR
236 color_on(bottomwin, COLOR_STATUSBAR);
Chris Allegrettab3655b42001-10-22 03:15:31 +0000237#else
238 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000239#endif
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000240 blank_statusbar();
Chris Allegretta8ce24132001-04-30 11:28:46 +0000241
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000242 if (x <= COLS - 1) {
243 /* Black magic */
244 buf[len - 1] = ' ';
Chris Allegretta31925e42000-11-02 04:40:39 +0000245
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000246 mvwaddstr(bottomwin, 0, 0, buf);
247 waddnstr(bottomwin, inputbuf, wid);
248 wmove(bottomwin, 0, (x % COLS));
Chris Allegretta598106e2002-01-19 01:59:37 +0000249 } else {
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000250 /* Black magic */
251 buf[len - 1] = '$';
Chris Allegretta31925e42000-11-02 04:40:39 +0000252
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000253 mvwaddstr(bottomwin, 0, 0, buf);
254 waddnstr(bottomwin, &inputbuf[wid * ((x - len) / (wid))], wid);
255 wmove(bottomwin, 0, ((x - len) % wid) + len);
256 }
Chris Allegretta8ce24132001-04-30 11:28:46 +0000257
258#ifdef ENABLE_COLOR
259 color_off(bottomwin, COLOR_STATUSBAR);
Chris Allegrettab3655b42001-10-22 03:15:31 +0000260#else
261 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000262#endif
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000263}
264
Chris Allegretta88520c92001-05-05 17:45:54 +0000265/* Get the input from the kb; this should only be called from statusq */
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000266int nanogetstr(int allowtabs, char *buf, char *def, shortcut *s,
Chris Allegretta2084acc2001-11-29 03:43:08 +0000267 int start_x, int list)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000268{
Chris Allegretta9caa1932002-02-15 20:08:05 +0000269 int kbinput = 0, x = 0, xend, slen;
Chris Allegrettabe77c612000-11-24 14:00:16 +0000270 int x_left = 0, inputlen, tabbed = 0;
Chris Allegretta31925e42000-11-02 04:40:39 +0000271 char *inputbuf;
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000272 shortcut *t;
Rocco Corsi06aca1c2001-01-11 05:30:31 +0000273#ifndef DISABLE_TABCOMP
Chris Allegrettabe77c612000-11-24 14:00:16 +0000274 int shift = 0;
275#endif
Chris Allegretta598106e2002-01-19 01:59:37 +0000276
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000277 slen = length_of_list(s);
Chris Allegretta88b09152001-05-17 11:35:43 +0000278 inputbuf = charalloc(strlen(def) + 1);
Chris Allegretta31925e42000-11-02 04:40:39 +0000279 inputbuf[0] = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000280
281 x_left = strlen(buf);
282 x = strlen(def) + x_left;
283
Chris Allegrettab3655b42001-10-22 03:15:31 +0000284#if !defined(DISABLE_HELP) || !defined(DISABLE_MOUSE)
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000285 currshortcut = s;
Chris Allegretta6fe61492001-05-21 12:56:25 +0000286#endif
287
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000288 /* Get the input! */
Chris Allegretta31925e42000-11-02 04:40:39 +0000289 if (strlen(def) > 0)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000290 strcpy(inputbuf, def);
Chris Allegretta31925e42000-11-02 04:40:39 +0000291
292 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000293
Chris Allegretta022b96f2000-11-14 17:47:58 +0000294 /* Make sure any editor screen updates are displayed before getting input */
295 wrefresh(edit);
296
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000297 while ((kbinput = wgetch(bottomwin)) != 13) {
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000298 for (t = s; t != NULL; t = t->next) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000299#ifdef DEBUG
300 fprintf(stderr, _("Aha! \'%c\' (%d)\n"), kbinput, kbinput);
301#endif
302
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000303 if (kbinput == t->val && kbinput < 32) {
Chris Allegretta5bf51d32000-11-16 06:01:10 +0000304
Chris Allegrettab3655b42001-10-22 03:15:31 +0000305#ifndef DISABLE_HELP
306 /* Have to do this here, it would be too late to do it in statusq */
Chris Allegretta598106e2002-01-19 01:59:37 +0000307 if (kbinput == NANO_HELP_KEY || kbinput == NANO_HELP_FKEY) {
Chris Allegrettab3655b42001-10-22 03:15:31 +0000308 do_help();
309 break;
310 }
311#endif
312
Chris Allegretta5bf51d32000-11-16 06:01:10 +0000313 /* We shouldn't discard the answer it gave, just because
314 we hit a keystroke, GEEZ! */
315 answer = mallocstrcpy(answer, inputbuf);
Chris Allegretta92d2bab2000-11-02 14:53:46 +0000316 free(inputbuf);
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000317 return t->val;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000318 }
319 }
320 xend = strlen(buf) + strlen(inputbuf);
321
Chris Allegretta04d848e2000-11-05 17:54:41 +0000322 if (kbinput != '\t')
323 tabbed = 0;
324
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000325 switch (kbinput) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000326
Chris Allegretta598106e2002-01-19 01:59:37 +0000327 /* Stuff we want to equate with <enter>, ASCII 13 */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000328 case 343:
Chris Allegrettaf9b6c9b2000-10-18 19:35:59 +0000329 ungetch(13); /* Enter on iris-ansi $TERM, sometimes */
330 break;
Chris Allegretta598106e2002-01-19 01:59:37 +0000331 /* Stuff we want to ignore */
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000332#ifdef PDCURSES
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000333 case 541:
334 case 542:
Chris Allegretta598106e2002-01-19 01:59:37 +0000335 case 543: /* Right ctrl again */
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000336 case 544:
Chris Allegretta598106e2002-01-19 01:59:37 +0000337 case 545: /* Right alt again */
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000338 break;
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000339#endif
Chris Allegretta84de5522001-04-12 14:51:48 +0000340#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000341#ifdef NCURSES_MOUSE_VERSION
342 case KEY_MOUSE:
343 do_mouse();
344 break;
345#endif
346#endif
Chris Allegretta658399a2001-06-14 02:54:22 +0000347 case NANO_HOME_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000348 case KEY_HOME:
349 x = x_left;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000350 break;
Chris Allegretta658399a2001-06-14 02:54:22 +0000351 case NANO_END_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000352 case KEY_END:
353 x = x_left + strlen(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000354 break;
355 case KEY_RIGHT:
Chris Allegretta35dac582001-03-21 15:07:20 +0000356 case NANO_FORWARD_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000357
358 if (x < xend)
359 x++;
360 wmove(bottomwin, 0, x);
361 break;
362 case NANO_CONTROL_D:
363 if (strlen(inputbuf) > 0 && (x - x_left) != strlen(inputbuf)) {
364 memmove(inputbuf + (x - x_left),
365 inputbuf + (x - x_left) + 1,
366 strlen(inputbuf) - (x - x_left) - 1);
367 inputbuf[strlen(inputbuf) - 1] = 0;
368 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000369 break;
370 case NANO_CONTROL_K:
371 case NANO_CONTROL_U:
372 *inputbuf = 0;
373 x = x_left;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000374 break;
375 case KEY_BACKSPACE:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000376 case 127:
377 case NANO_CONTROL_H:
378 if (strlen(inputbuf) > 0) {
379 if (x == (x_left + strlen(inputbuf)))
380 inputbuf[strlen(inputbuf) - 1] = 0;
381 else if (x - x_left) {
382 memmove(inputbuf + (x - x_left) - 1,
383 inputbuf + (x - x_left),
384 strlen(inputbuf) - (x - x_left));
385 inputbuf[strlen(inputbuf) - 1] = 0;
386 }
387 }
Chris Allegretta04d848e2000-11-05 17:54:41 +0000388 if (x > strlen(buf))
389 x--;
Chris Allegretta04d848e2000-11-05 17:54:41 +0000390 break;
Rocco Corsi06aca1c2001-01-11 05:30:31 +0000391#ifndef DISABLE_TABCOMP
Chris Allegretta04d848e2000-11-05 17:54:41 +0000392 case NANO_CONTROL_I:
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000393 if (allowtabs) {
Chris Allegretta442f2c52000-11-14 17:46:06 +0000394 shift = 0;
Chris Allegretta598106e2002-01-19 01:59:37 +0000395 inputbuf = input_tab(inputbuf, (x - x_left),
396 &tabbed, &shift, &list);
Chris Allegretta442f2c52000-11-14 17:46:06 +0000397 x += shift;
Chris Allegrettae434b452001-01-27 19:25:00 +0000398 if (x - x_left > strlen(inputbuf))
399 x = strlen(inputbuf) + x_left;
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000400 }
Chris Allegretta04d848e2000-11-05 17:54:41 +0000401 break;
Chris Allegrettabe77c612000-11-24 14:00:16 +0000402#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000403 case KEY_LEFT:
Chris Allegretta35dac582001-03-21 15:07:20 +0000404 case NANO_BACK_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000405 if (x > strlen(buf))
406 x--;
407 wmove(bottomwin, 0, x);
408 break;
409 case KEY_UP:
410 case KEY_DOWN:
411 break;
412
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000413 case KEY_DC:
414 goto do_deletekey;
415
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000416 case 27:
417 switch (kbinput = wgetch(edit)) {
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000418 case 'O':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000419 switch (kbinput = wgetch(edit)) {
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000420 case 'F':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000421 x = x_left + strlen(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000422 break;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000423 case 'H':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000424 x = x_left;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000425 break;
426 }
427 break;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000428 case '[':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000429 switch (kbinput = wgetch(edit)) {
430 case 'C':
431 if (x < xend)
432 x++;
433 wmove(bottomwin, 0, x);
434 break;
435 case 'D':
436 if (x > strlen(buf))
437 x--;
438 wmove(bottomwin, 0, x);
439 break;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000440 case '1':
441 case '7':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000442 x = x_left;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000443 goto skip_tilde;
444 case '3':
445 do_deletekey:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000446 if (strlen(inputbuf) > 0
447 && (x - x_left) != strlen(inputbuf)) {
448 memmove(inputbuf + (x - x_left),
449 inputbuf + (x - x_left) + 1,
450 strlen(inputbuf) - (x - x_left) - 1);
451 inputbuf[strlen(inputbuf) - 1] = 0;
452 }
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000453 goto skip_tilde;
454 case '4':
455 case '8':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000456 x = x_left + strlen(inputbuf);
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000457 goto skip_tilde;
458 skip_tilde:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000459 nodelay(edit, TRUE);
460 kbinput = wgetch(edit);
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000461 if (kbinput == '~' || kbinput == ERR)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000462 kbinput = -1;
463 nodelay(edit, FALSE);
464 break;
465 }
Chris Allegretta658399a2001-06-14 02:54:22 +0000466 default:
467
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000468 for (t = s; t != NULL; t = t->next) {
Chris Allegretta658399a2001-06-14 02:54:22 +0000469#ifdef DEBUG
Chris Allegretta598106e2002-01-19 01:59:37 +0000470 fprintf(stderr, _("Aha! \'%c\' (%d)\n"), kbinput,
471 kbinput);
Chris Allegretta658399a2001-06-14 02:54:22 +0000472#endif
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000473 if (kbinput == t->val || kbinput == t->val - 32) {
Chris Allegretta658399a2001-06-14 02:54:22 +0000474
475 /* We hit an Alt key. Do like above. We don't
476 just ungetch the letter and let it get caught
477 above cause that screws the keypad... */
478 answer = mallocstrcpy(answer, inputbuf);
479 free(inputbuf);
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000480 return t->val;
Chris Allegretta658399a2001-06-14 02:54:22 +0000481 }
482 }
483
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000484 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000485 break;
486
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000487 default:
Chris Allegretta658399a2001-06-14 02:54:22 +0000488
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000489 if (kbinput < 32)
490 break;
Chris Allegretta31925e42000-11-02 04:40:39 +0000491
492 inputlen = strlen(inputbuf);
493 inputbuf = nrealloc(inputbuf, inputlen + 2);
494
Chris Allegretta598106e2002-01-19 01:59:37 +0000495 memmove(&inputbuf[x - x_left + 1],
496 &inputbuf[x - x_left], inputlen - (x - x_left) + 1);
Chris Allegretta31925e42000-11-02 04:40:39 +0000497 inputbuf[x - x_left] = kbinput;
498
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000499 x++;
500
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000501#ifdef DEBUG
502 fprintf(stderr, _("input \'%c\' (%d)\n"), kbinput, kbinput);
503#endif
504 }
Chris Allegretta386e0512001-10-02 02:57:26 +0000505 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000506 wrefresh(bottomwin);
507 }
508
Chris Allegretta31925e42000-11-02 04:40:39 +0000509 answer = mallocstrcpy(answer, inputbuf);
Chris Allegretta92d2bab2000-11-02 14:53:46 +0000510 free(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000511
Chris Allegrettac1049ac2001-08-17 00:03:46 +0000512 /* In pico mode, just check for a blank answer here */
Chris Allegretta598106e2002-01-19 01:59:37 +0000513 if (((ISSET(PICO_MODE)) && !strcmp(answer, "")))
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000514 return -2;
515 else
516 return 0;
517}
518
519void horizbar(WINDOW * win, int y)
520{
521 wattron(win, A_REVERSE);
522 mvwaddstr(win, 0, 0, hblank);
523 wattroff(win, A_REVERSE);
524}
525
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000526void titlebar(char *path)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000527{
528 int namelen, space;
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000529 char *what = path;
530
531 if (path == NULL)
532 what = filename;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000533
Chris Allegretta8ce24132001-04-30 11:28:46 +0000534#ifdef ENABLE_COLOR
535 color_on(topwin, COLOR_TITLEBAR);
536 mvwaddstr(topwin, 0, 0, hblank);
537#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000538 horizbar(topwin, 0);
539 wattron(topwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000540#endif
541
542
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000543 mvwaddstr(topwin, 0, 3, VERMSG);
544
545 space = COLS - strlen(VERMSG) - strlen(VERSION) - 21;
546
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000547 namelen = strlen(what);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000548
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000549 if (!strcmp(what, ""))
Chris Allegretta17dcb722001-01-20 21:40:07 +0000550 mvwaddstr(topwin, 0, COLS / 2 - 6, _("New Buffer"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000551 else {
552 if (namelen > space) {
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000553 if (path == NULL)
554 waddstr(topwin, _(" File: ..."));
555 else
556 waddstr(topwin, _(" DIR: ..."));
557 waddstr(topwin, &what[namelen - space]);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000558 } else {
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000559 if (path == NULL)
Chris Allegretta598106e2002-01-19 01:59:37 +0000560 mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1),
561 _("File: "));
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000562 else
Chris Allegretta598106e2002-01-19 01:59:37 +0000563 mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1),
564 _(" DIR: "));
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000565 waddstr(topwin, what);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000566 }
567 }
568 if (ISSET(MODIFIED))
569 mvwaddstr(topwin, 0, COLS - 10, _("Modified"));
Chris Allegretta8ce24132001-04-30 11:28:46 +0000570
571
572#ifdef ENABLE_COLOR
573 color_off(topwin, COLOR_TITLEBAR);
574#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000575 wattroff(topwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000576#endif
577
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000578 wrefresh(topwin);
579 reset_cursor();
580}
581
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000582void onekey(char *keystroke, char *desc, int len)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000583{
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000584 int i;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000585
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000586 wattron(bottomwin, A_REVERSE);
587 waddstr(bottomwin, keystroke);
588 wattroff(bottomwin, A_REVERSE);
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000589 waddch(bottomwin, ' ');
590 waddnstr(bottomwin, desc, len - 3);
591 for (i = strlen(desc); i < len - 3; i++)
592 waddch(bottomwin, ' ');
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000593}
594
595void clear_bottomwin(void)
596{
597 if (ISSET(NO_HELP))
598 return;
599
600 mvwaddstr(bottomwin, 1, 0, hblank);
601 mvwaddstr(bottomwin, 2, 0, hblank);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000602}
603
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000604void bottombars(shortcut *s)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000605{
Chris Allegrettabc72e362002-02-16 20:03:44 +0000606 int i, j, numcols;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000607 char keystr[10];
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000608 shortcut *t;
609 int slen;
610
611 if (s == main_list)
612 slen = MAIN_VISIBLE;
613 else
614 slen = length_of_list(s);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000615
616 if (ISSET(NO_HELP))
617 return;
618
Chris Allegretta598106e2002-01-19 01:59:37 +0000619#ifdef ENABLE_COLOR
Chris Allegretta8ce24132001-04-30 11:28:46 +0000620 color_on(bottomwin, COLOR_BOTTOMBARS);
Chris Allegretta66577ac2002-01-05 02:03:29 +0000621 if (!colors[COLOR_BOTTOMBARS - FIRST_COLORNUM].set ||
Chris Allegretta598106e2002-01-19 01:59:37 +0000622 colors[COLOR_BOTTOMBARS - FIRST_COLORNUM].fg != COLOR_BLACK)
623 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000624#endif
625
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000626 /* Determine how many extra spaces are needed to fill the bottom of the screen */
Chris Allegretta96eef732001-08-25 16:41:37 +0000627 if (slen < 2)
Chris Allegrettabc72e362002-02-16 20:03:44 +0000628 numcols = 6;
Chris Allegretta96eef732001-08-25 16:41:37 +0000629 else
Chris Allegrettabc72e362002-02-16 20:03:44 +0000630 numcols = (slen + (slen % 2)) / 2;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000631
632 clear_bottomwin();
Chris Allegretta658399a2001-06-14 02:54:22 +0000633
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000634 t = s;
Chris Allegrettabc72e362002-02-16 20:03:44 +0000635 for (i = 0; i < numcols; i++) {
636 for (j = 0; j <= 1; j++) {
Chris Allegretta658399a2001-06-14 02:54:22 +0000637
Chris Allegrettabc72e362002-02-16 20:03:44 +0000638 wmove(bottomwin, 1 + j, i * ((COLS - 1) / numcols));
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000639
Chris Allegrettabc72e362002-02-16 20:03:44 +0000640 if (t->val < 97)
641 snprintf(keystr, 10, "^%c", t->val + 64);
642 else
643 snprintf(keystr, 10, "M-%c", t->val - 32);
Chris Allegretta658399a2001-06-14 02:54:22 +0000644
Chris Allegrettabc72e362002-02-16 20:03:44 +0000645 onekey(keystr, t->desc, (COLS - 1) / numcols);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000646
Chris Allegrettabc72e362002-02-16 20:03:44 +0000647 if (t->next == NULL)
648 break;
649 t = t->next;
650 }
Chris Allegrettaa8c22572002-02-15 19:17:02 +0000651
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000652 }
653
Chris Allegretta598106e2002-01-19 01:59:37 +0000654#ifdef ENABLE_COLOR
Chris Allegretta8ce24132001-04-30 11:28:46 +0000655 color_off(bottomwin, COLOR_BOTTOMBARS);
656#endif
657
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000658 wrefresh(bottomwin);
659
660}
661
662/* If modified is not already set, set it and update titlebar */
663void set_modified(void)
664{
665 if (!ISSET(MODIFIED)) {
666 SET(MODIFIED);
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000667 titlebar(NULL);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000668 wrefresh(topwin);
669 }
670}
671
Robert Siemborski9d584552000-07-08 00:41:29 +0000672/* And so start the display update routines */
673/* Given a column, this returns the "page" it is on */
674/* "page" in the case of the display columns, means which set of 80 */
Chris Allegretta88520c92001-05-05 17:45:54 +0000675/* characters is viewable (e.g.: page 1 shows from 1 to COLS) */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000676inline int get_page_from_virtual(int virtual)
677{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000678 int page = 2;
679
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000680 if (virtual <= COLS - 2)
681 return 1;
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000682 virtual -= (COLS - 2);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000683
684 while (virtual > COLS - 2 - 7) {
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000685 virtual -= (COLS - 2 - 7);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000686 page++;
687 }
688
689 return page;
690}
691
Robert Siemborski9d584552000-07-08 00:41:29 +0000692/* The inverse of the above function */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000693inline int get_page_start_virtual(int page)
694{
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000695 int virtual;
696 virtual = --page * (COLS - 7);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000697 if (page)
698 virtual -= 2 * page - 1;
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000699 return virtual;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000700}
701
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000702inline int get_page_end_virtual(int page)
703{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000704 return get_page_start_virtual(page) + COLS - 1;
705}
706
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000707#ifndef NANO_SMALL
Robert Siemborski9d584552000-07-08 00:41:29 +0000708/* This takes care of the case where there is a mark that covers only */
709/* the current line. */
710
Chris Allegretta88520c92001-05-05 17:45:54 +0000711/* It expects a line with no tab characters (i.e.: the type that edit_add */
Robert Siemborski9d584552000-07-08 00:41:29 +0000712/* deals with */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000713void add_marked_sameline(int begin, int end, filestruct * fileptr, int y,
714 int virt_cur_x, int this_page)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000715{
Robert Siemborski9d584552000-07-08 00:41:29 +0000716 /*
717 * The general idea is to break the line up into 3 sections: before
718 * the mark, the mark, and after the mark. We then paint each in
Chris Allegretta88520c92001-05-05 17:45:54 +0000719 * turn (for those that are currently visible, of course)
Robert Siemborski9d584552000-07-08 00:41:29 +0000720 *
721 * 3 start points: 0 -> begin, begin->end, end->strlen(data)
722 * in data : pre sel post
723 */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000724 int this_page_start = get_page_start_virtual(this_page),
Robert Siemborski53875912000-06-16 04:25:30 +0000725 this_page_end = get_page_end_virtual(this_page);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000726
Robert Siemborskid8510b22000-06-06 23:04:06 +0000727 /* likewise, 3 data lengths */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000728 int pre_data_len = begin, sel_data_len = end - begin, post_data_len = 0; /* Determined from the other two */
Robert Siemborskid8510b22000-06-06 23:04:06 +0000729
730 /* now fix the start locations & lengths according to the cursor's
Chris Allegretta88520c92001-05-05 17:45:54 +0000731 * position (i.e.: our page) */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000732 if (pre_data_len < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000733 pre_data_len = 0;
734 else
735 pre_data_len -= this_page_start;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000736
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000737 if (begin < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000738 begin = this_page_start;
739
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000740 if (end < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000741 end = this_page_start;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000742
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000743 if (begin > this_page_end)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000744 begin = this_page_end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000745
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000746 if (end > this_page_end)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000747 end = this_page_end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000748
Robert Siemborski9d584552000-07-08 00:41:29 +0000749 /* Now calculate the lengths */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000750 sel_data_len = end - begin;
751 post_data_len = this_page_end - end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000752
Chris Allegretta8ce24132001-04-30 11:28:46 +0000753#ifdef ENABLE_COLOR
754 color_on(edit, COLOR_MARKER);
755#else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000756 wattron(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +0000757#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000758
Robert Siemborskia9addc72000-06-17 06:06:35 +0000759 mvwaddnstr(edit, y, begin - this_page_start,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000760 &fileptr->data[begin], sel_data_len);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000761
762#ifdef ENABLE_COLOR
763 color_off(edit, COLOR_MARKER);
764#else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000765 wattroff(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +0000766#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000767
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000768}
769#endif
770
Robert Siemborski9d584552000-07-08 00:41:29 +0000771/* edit_add takes care of the job of actually painting a line into the
772 * edit window.
773 *
774 * Called only from update_line. Expects a converted-to-not-have-tabs
Robert Siemborski53875912000-06-16 04:25:30 +0000775 * line */
776void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000777 int virt_mark_beginx, int this_page)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000778{
Chris Allegretta08893e02001-11-29 02:42:27 +0000779
Chris Allegretta7dd77682001-12-08 19:52:28 +0000780#ifdef ENABLE_COLOR
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000781 colortype *tmpcolor = NULL;
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000782 int k, paintlen;
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000783 filestruct *e, *s;
784 regoff_t ematch, smatch;
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000785#endif
786
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000787 /* Just paint the string in any case (we'll add color or reverse on
Chris Allegretta598106e2002-01-19 01:59:37 +0000788 just the text that needs it */
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000789 mvwaddnstr(edit, yval, 0, &fileptr->data[start],
Chris Allegretta598106e2002-01-19 01:59:37 +0000790 get_page_end_virtual(this_page) - start + 1);
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000791
Chris Allegretta7dd77682001-12-08 19:52:28 +0000792#ifdef ENABLE_COLOR
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000793 if (colorstrings != NULL)
Chris Allegretta598106e2002-01-19 01:59:37 +0000794 for (tmpcolor = colorstrings; tmpcolor != NULL;
795 tmpcolor = tmpcolor->next) {
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000796
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000797 if (tmpcolor->end == NULL) {
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000798
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000799 /* First, highlight all single-line regexes */
800 k = start;
Chris Allegretta3533a342002-03-24 23:19:32 +0000801 regcomp(&color_regexp, tmpcolor->start, 0);
802 while (!regexec(&color_regexp, &fileptr->data[k], 1,
803 colormatches, 0)) {
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000804
Chris Allegretta3533a342002-03-24 23:19:32 +0000805 if (colormatches[0].rm_eo - colormatches[0].rm_so < 1) {
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000806 statusbar("Refusing 0 length regex match");
807 break;
808 }
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000809#ifdef DEBUG
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000810 fprintf(stderr, "Match! (%d chars) \"%s\"\n",
Chris Allegretta3533a342002-03-24 23:19:32 +0000811 colormatches[0].rm_eo - colormatches[0].rm_so,
812 &fileptr->data[k + colormatches[0].rm_so]);
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000813#endif
Chris Allegretta3533a342002-03-24 23:19:32 +0000814 if (colormatches[0].rm_so < COLS - 1) {
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000815 if (tmpcolor->bright)
816 wattron(edit, A_BOLD);
817 wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
818
Chris Allegretta3533a342002-03-24 23:19:32 +0000819 if (colormatches[0].rm_eo + k <= COLS)
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000820 paintlen =
Chris Allegretta3533a342002-03-24 23:19:32 +0000821 colormatches[0].rm_eo - colormatches[0].rm_so;
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000822 else
Chris Allegretta3533a342002-03-24 23:19:32 +0000823 paintlen = COLS - k - colormatches[0].rm_so - 1;
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000824
Chris Allegretta3533a342002-03-24 23:19:32 +0000825 mvwaddnstr(edit, yval, colormatches[0].rm_so + k,
826 &fileptr->data[k + colormatches[0].rm_so],
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000827 paintlen);
828
829 }
830
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000831 if (tmpcolor->bright)
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000832 wattroff(edit, A_BOLD);
833 wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000834
Chris Allegretta3533a342002-03-24 23:19:32 +0000835 k += colormatches[0].rm_eo;
Chris Allegretta598106e2002-01-19 01:59:37 +0000836
837 }
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000838 }
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000839 /* Now, if there's an 'end' somewhere below, and a 'start'
840 somewhere above, things get really fun. We have to look
841 down for an end, make sure there's not a start before
842 the end after us, and then look up for a start,
843 and see if there's an end after the start, before us :) */
844 else {
845
846 s = fileptr;
847 while (s != NULL) {
Chris Allegretta3533a342002-03-24 23:19:32 +0000848 regcomp(&color_regexp, tmpcolor->start, 0);
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000849 if (!regexec
Chris Allegretta3533a342002-03-24 23:19:32 +0000850 (&color_regexp, s->data, 1, colormatches, 0))
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000851 break;
852 s = s->prev;
853 }
854
855 if (s != NULL) {
856 /* We found a start, mark it */
Chris Allegretta3533a342002-03-24 23:19:32 +0000857 smatch = colormatches[0].rm_so;
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000858
859 e = s;
860 while (e != NULL && e != fileptr) {
Chris Allegretta3533a342002-03-24 23:19:32 +0000861 regcomp(&color_regexp, tmpcolor->end, 0);
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000862 if (!regexec
Chris Allegretta3533a342002-03-24 23:19:32 +0000863 (&color_regexp, e->data, 1, colormatches, 0))
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000864 break;
865 e = e->next;
866 }
867
868 if (e != fileptr)
869 continue; /* There's an end before us */
870 else { /* Keep looking for an end */
871 while (e != NULL) {
Chris Allegretta3533a342002-03-24 23:19:32 +0000872 regcomp(&color_regexp, tmpcolor->end, 0);
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000873 if (!regexec
Chris Allegretta3533a342002-03-24 23:19:32 +0000874 (&color_regexp, e->data, 1, colormatches,
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000875 0))
876 break;
877 e = e->next;
878 }
879
880 if (e == NULL)
881 continue; /* There's no start before the end :) */
882 else { /* Okay, we found an end, mark it! */
Chris Allegretta3533a342002-03-24 23:19:32 +0000883 ematch = colormatches[0].rm_eo;
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000884
885 while (e != NULL) {
Chris Allegretta3533a342002-03-24 23:19:32 +0000886 regcomp(&color_regexp, tmpcolor->end, 0);
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000887 if (!regexec
Chris Allegretta3533a342002-03-24 23:19:32 +0000888 (&color_regexp, e->data, 1,
889 colormatches, 0))
Chris Allegretta6c1e6612002-01-19 16:52:34 +0000890 break;
891 e = e->next;
892 }
893
894 if (e == NULL)
895 continue; /* No end, oh well :) */
896
897 /* Didn't find another end, we must be in the
898 middle of a highlighted bit */
899
900 if (tmpcolor->bright)
901 wattron(edit, A_BOLD);
902
903 wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
904
905 if (s == fileptr && e == fileptr)
906 mvwaddnstr(edit, yval, start + smatch,
907 &fileptr->data[start + smatch],
908 ematch - smatch);
909 else if (s == fileptr)
910 mvwaddnstr(edit, yval, start + smatch,
911 &fileptr->data[start + smatch],
912 COLS - smatch);
913 else if (e == fileptr)
914 mvwaddnstr(edit, yval, start,
915 &fileptr->data[start],
916 ematch - start);
917 else
918 mvwaddnstr(edit, yval, start,
919 &fileptr->data[start],
920 COLS);
921
922 if (tmpcolor->bright)
923 wattroff(edit, A_BOLD);
924
925 wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
926
927 }
928
929 }
930
931 /* Else go to the next string, yahoo! =) */
932 }
933
934 }
935
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000936 }
Chris Allegretta598106e2002-01-19 01:59:37 +0000937#endif /* ENABLE_COLOR */
Chris Allegretta7dd77682001-12-08 19:52:28 +0000938#ifndef NANO_SMALL
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000939
Chris Allegretta88520c92001-05-05 17:45:54 +0000940 /* There are quite a few cases that could take place; we'll deal
Robert Siemborski9d584552000-07-08 00:41:29 +0000941 * with them each in turn */
Chris Allegretta598106e2002-01-19 01:59:37 +0000942 if (ISSET(MARK_ISSET) &&
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000943 !((fileptr->lineno > mark_beginbuf->lineno
Chris Allegretta598106e2002-01-19 01:59:37 +0000944 && fileptr->lineno > current->lineno)
945 || (fileptr->lineno < mark_beginbuf->lineno
946 && fileptr->lineno < current->lineno))) {
Chris Allegretta88520c92001-05-05 17:45:54 +0000947 /* If we get here we are on a line that is at least
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000948 * partially selected. The lineno checks above determined
949 * that */
950 if (fileptr != mark_beginbuf && fileptr != current) {
951 /* We are on a completely marked line, paint it all
952 * inverse */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000953#ifdef ENABLE_COLOR
954 color_on(edit, COLOR_MARKER);
955#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000956 wattron(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +0000957#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000958
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000959 mvwaddnstr(edit, yval, 0, fileptr->data, COLS);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000960
961#ifdef ENABLE_COLOR
962 color_off(edit, COLOR_MARKER);
963#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000964 wattroff(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +0000965#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000966
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000967 } else if (fileptr == mark_beginbuf && fileptr == current) {
968 /* Special case, we're still on the same line we started
969 * marking -- so we call our helper function */
970 if (virt_cur_x < virt_mark_beginx) {
971 /* To the right of us is marked */
972 add_marked_sameline(virt_cur_x, virt_mark_beginx,
973 fileptr, yval, virt_cur_x, this_page);
974 } else {
975 /* To the left of us is marked */
976 add_marked_sameline(virt_mark_beginx, virt_cur_x,
977 fileptr, yval, virt_cur_x, this_page);
978 }
979 } else if (fileptr == mark_beginbuf) {
980 /*
Chris Allegretta88520c92001-05-05 17:45:54 +0000981 * We're updating the line that was first marked,
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000982 * but we're not currently on it. So we want to
Robert Siemborskia0238ed2001-03-31 21:46:43 +0000983 * figure out which half to invert based on our
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000984 * relative line numbers.
985 *
Chris Allegretta88520c92001-05-05 17:45:54 +0000986 * I.e. if we're above the "beginbuf" line, we want to
987 * mark the left side. Otherwise, we're below, so we
988 * mark the right.
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000989 */
990 int target;
991
Chris Allegretta8ce24132001-04-30 11:28:46 +0000992 if (mark_beginbuf->lineno > current->lineno) {
993#ifdef ENABLE_COLOR
994 color_on(edit, COLOR_MARKER);
995#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000996 wattron(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +0000997#endif /* ENABLE_COLOR */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000998
Chris Allegretta2fa11b82001-12-02 04:55:44 +0000999 target =
Chris Allegretta598106e2002-01-19 01:59:37 +00001000 (virt_mark_beginx <
1001 COLS - 1) ? virt_mark_beginx : COLS - 1;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001002
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001003 mvwaddnstr(edit, yval, 0, fileptr->data, target);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001004
1005#ifdef ENABLE_COLOR
1006 color_off(edit, COLOR_MARKER);
1007#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001008 wattroff(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001009#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +00001010
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001011
Chris Allegretta8ce24132001-04-30 11:28:46 +00001012 }
Robert Siemborskid8510b22000-06-06 23:04:06 +00001013
Chris Allegretta8ce24132001-04-30 11:28:46 +00001014 if (mark_beginbuf->lineno < current->lineno) {
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001015#ifdef ENABLE_COLOR
1016 color_on(edit, COLOR_MARKER);
1017#else
1018 wattron(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001019#endif /* ENABLE_COLOR */
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001020
1021 target = (COLS - 1) - virt_mark_beginx;
1022
1023 if (target < 0)
1024 target = 0;
1025
1026 mvwaddnstr(edit, yval, virt_mark_beginx,
Chris Allegretta598106e2002-01-19 01:59:37 +00001027 &fileptr->data[virt_mark_beginx], target);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001028
1029#ifdef ENABLE_COLOR
1030 color_off(edit, COLOR_MARKER);
1031#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001032 wattroff(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001033#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +00001034
1035 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001036
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001037 } else if (fileptr == current) {
Chris Allegretta88520c92001-05-05 17:45:54 +00001038 /* We're on the cursor's line, but it's not the first
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001039 * one we marked. Similar to the previous logic. */
1040 int this_page_start = get_page_start_virtual(this_page),
1041 this_page_end = get_page_end_virtual(this_page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001042
Chris Allegretta8ce24132001-04-30 11:28:46 +00001043 if (mark_beginbuf->lineno < current->lineno) {
1044
1045#ifdef ENABLE_COLOR
1046 color_on(edit, COLOR_MARKER);
1047#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001048 wattron(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001049#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +00001050
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001051 if (virt_cur_x > COLS - 2) {
1052 mvwaddnstr(edit, yval, 0,
Chris Allegretta598106e2002-01-19 01:59:37 +00001053 &fileptr->data[this_page_start],
1054 virt_cur_x - this_page_start);
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001055 } else
1056 mvwaddnstr(edit, yval, 0, fileptr->data, virt_cur_x);
1057
1058#ifdef ENABLE_COLOR
1059 color_off(edit, COLOR_MARKER);
1060#else
1061 wattroff(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001062#endif /* ENABLE_COLOR */
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001063
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001064 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001065
Chris Allegretta8ce24132001-04-30 11:28:46 +00001066 if (mark_beginbuf->lineno > current->lineno) {
1067
1068#ifdef ENABLE_COLOR
1069 color_on(edit, COLOR_MARKER);
1070#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001071 wattron(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001072#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +00001073
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001074 if (virt_cur_x > COLS - 2)
1075 mvwaddnstr(edit, yval, virt_cur_x - this_page_start,
Chris Allegretta598106e2002-01-19 01:59:37 +00001076 &fileptr->data[virt_cur_x],
1077 this_page_end - virt_cur_x);
Chris Allegretta2fa11b82001-12-02 04:55:44 +00001078 else
1079 mvwaddnstr(edit, yval, virt_cur_x,
Chris Allegretta598106e2002-01-19 01:59:37 +00001080 &fileptr->data[virt_cur_x],
1081 COLS - virt_cur_x);
Robert Siemborskid8510b22000-06-06 23:04:06 +00001082
Chris Allegretta8ce24132001-04-30 11:28:46 +00001083#ifdef ENABLE_COLOR
1084 color_off(edit, COLOR_MARKER);
1085#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001086 wattroff(edit, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001087#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +00001088
1089 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001090 }
Chris Allegretta08893e02001-11-29 02:42:27 +00001091 }
Chris Allegretta08893e02001-11-29 02:42:27 +00001092#endif
1093
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001094}
1095
1096/*
Robert Siemborski9d584552000-07-08 00:41:29 +00001097 * Just update one line in the edit buffer. Basically a wrapper for
1098 * edit_add
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001099 *
Chris Allegretta88520c92001-05-05 17:45:54 +00001100 * index gives us a place in the string to update starting from.
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001101 * Likely args are current_x or 0.
1102 */
1103void update_line(filestruct * fileptr, int index)
1104{
1105 filestruct *filetmp;
Robert Siemborski53875912000-06-16 04:25:30 +00001106 int line = 0, col = 0;
1107 int virt_cur_x = current_x, virt_mark_beginx = mark_beginx;
1108 char *realdata, *tmp;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001109 int i, pos, len, page;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001110
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001111 if (!fileptr)
1112 return;
Robert Siemborski53154a72000-06-18 00:11:03 +00001113
Robert Siemborski53875912000-06-16 04:25:30 +00001114 /* First, blank out the line (at a minimum) */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001115 for (filetmp = edittop; filetmp != fileptr && filetmp != editbot;
1116 filetmp = filetmp->next)
1117 line++;
1118
1119 mvwaddstr(edit, line, 0, hblank);
1120
Chris Allegretta88520c92001-05-05 17:45:54 +00001121 /* Next, convert all the tabs to spaces, so everything else is easy */
Robert Siemborski53875912000-06-16 04:25:30 +00001122 index = xpt(fileptr, index);
1123
1124 realdata = fileptr->data;
1125 len = strlen(realdata);
Chris Allegretta88b09152001-05-17 11:35:43 +00001126 fileptr->data = charalloc(xpt(fileptr, len) + 1);
Robert Siemborski53875912000-06-16 04:25:30 +00001127
1128 pos = 0;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001129 for (i = 0; i < len; i++) {
1130 if (realdata[i] == '\t') {
Robert Siemborski53875912000-06-16 04:25:30 +00001131 do {
1132 fileptr->data[pos++] = ' ';
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001133 if (i < current_x)
1134 virt_cur_x++;
1135 if (i < mark_beginx)
1136 virt_mark_beginx++;
Chris Allegretta6d690a32000-08-03 22:51:21 +00001137 } while (pos % tabsize);
Robert Siemborski53875912000-06-16 04:25:30 +00001138 /* must decrement once to account for tab-is-one-character */
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001139 if (i < current_x)
1140 virt_cur_x--;
1141 if (i < mark_beginx)
1142 virt_mark_beginx--;
Chris Allegretta2598c662002-03-28 01:59:34 +00001143 } else if (realdata[i] == 127) {
1144 /* Treat control characters as ^symbol (ASCII 1 - 31, 127) */
1145 fileptr->data[pos++] = '^';
1146 fileptr->data[pos++] = '?';
Chris Allegretta3c57e502001-12-19 16:20:43 +00001147 } else if (realdata[i] >= 1 && realdata[i] <= 31) {
Chris Allegretta6306a112000-09-02 07:55:41 +00001148 fileptr->data[pos++] = '^';
1149 fileptr->data[pos++] = realdata[i] + 64;
Robert Siemborski53875912000-06-16 04:25:30 +00001150 } else {
1151 fileptr->data[pos++] = realdata[i];
1152 }
1153 }
1154
1155 fileptr->data[pos] = '\0';
1156
1157 /* Now, Paint the line */
1158 if (current == fileptr && index > COLS - 2) {
Robert Siemborskia9addc72000-06-17 06:06:35 +00001159 /* This handles when the current line is beyond COLS */
Chris Allegretta88520c92001-05-05 17:45:54 +00001160 /* It requires figuring out what page we're on */
Robert Siemborskia9addc72000-06-17 06:06:35 +00001161 page = get_page_from_virtual(index);
Robert Siemborskid8510b22000-06-06 23:04:06 +00001162 col = get_page_start_virtual(page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001163
Robert Siemborskia9addc72000-06-17 06:06:35 +00001164 edit_add(filetmp, line, col, virt_cur_x, virt_mark_beginx, page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001165 mvwaddch(edit, line, 0, '$');
1166
Chris Allegrettafb62f732000-12-05 11:36:41 +00001167 if (strlenpt(fileptr->data) > get_page_end_virtual(page) + 1)
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001168 mvwaddch(edit, line, COLS - 1, '$');
Robert Siemborskid8510b22000-06-06 23:04:06 +00001169 } else {
Robert Siemborskia9addc72000-06-17 06:06:35 +00001170 /* It's not the current line means that it's at x=0 and page=1 */
1171 /* If it is the current line, then we're in the same boat */
1172 edit_add(filetmp, line, 0, virt_cur_x, virt_mark_beginx, 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001173
Robert Siemborski53875912000-06-16 04:25:30 +00001174 if (strlenpt(&filetmp->data[col]) > COLS)
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001175 mvwaddch(edit, line, COLS - 1, '$');
Robert Siemborskid8510b22000-06-06 23:04:06 +00001176 }
Robert Siemborski53875912000-06-16 04:25:30 +00001177
1178 /* Clean up our mess */
1179 tmp = fileptr->data;
1180 fileptr->data = realdata;
1181 free(tmp);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001182}
1183
1184void center_cursor(void)
1185{
1186 current_y = editwinrows / 2;
1187 wmove(edit, current_y, current_x);
1188}
1189
1190/* Refresh the screen without changing the position of lines */
1191void edit_refresh(void)
1192{
Chris Allegrettaed022162000-08-03 16:54:11 +00001193 static int noloop = 0;
Chris Allegretta3d0739c2002-01-07 14:41:32 +00001194 int nlines = 0, i = 0, currentcheck = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001195 filestruct *temp, *hold = current;
1196
1197 if (current == NULL)
1198 return;
1199
1200 temp = edittop;
1201
Chris Allegretta3d0739c2002-01-07 14:41:32 +00001202 while (nlines <= editwinrows - 1 && nlines <= totlines && temp != NULL) {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001203 hold = temp;
1204 update_line(temp, current_x);
Chris Allegretta95b0b522000-07-28 02:58:06 +00001205 if (temp == current)
1206 currentcheck = 1;
1207
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001208 temp = temp->next;
Chris Allegretta3d0739c2002-01-07 14:41:32 +00001209 nlines++;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001210 }
Chris Allegrettaed022162000-08-03 16:54:11 +00001211 /* If noloop == 1, then we already did an edit_update without finishing
1212 this function. So we don't run edit_update again */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001213 if (!currentcheck && !noloop) { /* Then current has run off the screen... */
Chris Allegrettada721be2000-07-31 01:26:42 +00001214 edit_update(current, CENTER);
Chris Allegrettaed022162000-08-03 16:54:11 +00001215 noloop = 1;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001216 } else if (noloop)
Chris Allegrettaed022162000-08-03 16:54:11 +00001217 noloop = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001218
Chris Allegretta3d0739c2002-01-07 14:41:32 +00001219 if (nlines <= editwinrows - 1)
1220 while (nlines <= editwinrows - 1) {
1221 mvwaddstr(edit, nlines, i, hblank);
1222 nlines++;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001223 }
1224 if (temp == NULL)
1225 editbot = hold;
1226 else
1227 editbot = temp;
Chris Allegrettab3655b42001-10-22 03:15:31 +00001228
1229 /* What the hell are we expecting to update the screen if this isn't
Chris Allegretta598106e2002-01-19 01:59:37 +00001230 here? luck?? */
Chris Allegrettab3655b42001-10-22 03:15:31 +00001231 wrefresh(edit);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001232}
1233
1234/*
Chris Allegretta88520c92001-05-05 17:45:54 +00001235 * Same as above, but touch the window first, so everything is redrawn.
Chris Allegrettaf1d33d32000-08-19 03:53:39 +00001236 */
1237void edit_refresh_clearok(void)
1238{
1239 clearok(edit, TRUE);
1240 edit_refresh();
1241 clearok(edit, FALSE);
1242}
1243
1244/*
Chris Allegretta88520c92001-05-05 17:45:54 +00001245 * Nice generic routine to update the edit buffer, given a pointer to the
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001246 * file struct =)
1247 */
Chris Allegretta2d7893d2001-07-11 02:08:33 +00001248void edit_update(filestruct * fileptr, int topmidbotnone)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001249{
Robert Siemborski29e9a762000-07-05 03:16:04 +00001250 int i = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001251 filestruct *temp;
1252
1253 if (fileptr == NULL)
1254 return;
1255
1256 temp = fileptr;
Chris Allegretta2d7893d2001-07-11 02:08:33 +00001257 if (topmidbotnone == TOP);
1258 else if (topmidbotnone == NONE)
1259 for (i = 0; i <= current_y - 1 && temp->prev != NULL; i++)
1260 temp = temp->prev;
1261 else if (topmidbotnone == BOTTOM)
Chris Allegretta234a34d2000-07-29 04:33:38 +00001262 for (i = 0; i <= editwinrows - 1 && temp->prev != NULL; i++)
1263 temp = temp->prev;
1264 else
1265 for (i = 0; i <= editwinrows / 2 && temp->prev != NULL; i++)
1266 temp = temp->prev;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001267
Robert Siemborski29e9a762000-07-05 03:16:04 +00001268 edittop = temp;
1269 fix_editbot();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001270
1271 edit_refresh();
1272}
1273
Chris Allegretta88520c92001-05-05 17:45:54 +00001274/* This function updates current, based on where current_y is; reset_cursor
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001275 does the opposite */
1276void update_cursor(void)
1277{
1278 int i = 0;
1279
1280#ifdef DEBUG
1281 fprintf(stderr, _("Moved to (%d, %d) in edit buffer\n"), current_y,
1282 current_x);
1283#endif
1284
1285 current = edittop;
1286 while (i <= current_y - 1 && current->next != NULL) {
1287 current = current->next;
1288 i++;
1289 }
1290
1291#ifdef DEBUG
1292 fprintf(stderr, _("current->data = \"%s\"\n"), current->data);
1293#endif
1294
1295}
1296
1297/*
1298 * Ask a question on the statusbar. Answer will be stored in answer
1299 * global. Returns -1 on aborted enter, -2 on a blank string, and 0
Chris Allegretta88520c92001-05-05 17:45:54 +00001300 * otherwise, the valid shortcut key caught. Def is any editable text we
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001301 * want to put up by default.
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001302 *
1303 * New arg tabs tells whether or not to allow tab completion.
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001304 */
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001305int statusq(int tabs, shortcut *s, char *def, char *msg, ...)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001306{
1307 va_list ap;
1308 char foo[133];
Chris Allegretta9caa1932002-02-15 20:08:05 +00001309 int ret;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001310
Chris Allegretta2084acc2001-11-29 03:43:08 +00001311#ifndef DISABLE_TABCOMP
Chris Allegrettaa16e4e92002-01-05 18:59:54 +00001312 int list = 0;
Chris Allegretta2084acc2001-11-29 03:43:08 +00001313#endif
1314
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001315 bottombars(s);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001316
1317 va_start(ap, msg);
1318 vsnprintf(foo, 132, msg, ap);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001319 va_end(ap);
Chris Allegrettaa4d21622000-07-08 23:57:03 +00001320 strncat(foo, ": ", 132);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001321
Chris Allegretta8ce24132001-04-30 11:28:46 +00001322#ifdef ENABLE_COLOR
1323 color_on(bottomwin, COLOR_STATUSBAR);
1324#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001325 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001326#endif
1327
1328
Chris Allegretta2084acc2001-11-29 03:43:08 +00001329#ifndef DISABLE_TABCOMP
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001330 ret = nanogetstr(tabs, foo, def, s, (strlen(foo) + 3), list);
Chris Allegretta2084acc2001-11-29 03:43:08 +00001331#else
1332 /* if we've disabled tab completion, the value of list won't be
1333 used at all, so it's safe to use 0 (NULL) as a placeholder */
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001334 ret = nanogetstr(tabs, foo, def, s, (strlen(foo) + 3), 0);
Chris Allegretta2084acc2001-11-29 03:43:08 +00001335#endif
Chris Allegretta8ce24132001-04-30 11:28:46 +00001336
1337#ifdef ENABLE_COLOR
1338 color_off(bottomwin, COLOR_STATUSBAR);
1339#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001340 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001341#endif
1342
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001343
1344 switch (ret) {
1345
1346 case NANO_FIRSTLINE_KEY:
1347 do_first_line();
1348 break;
1349 case NANO_LASTLINE_KEY:
1350 do_last_line();
1351 break;
1352 case NANO_CANCEL_KEY:
Chris Allegretta2084acc2001-11-29 03:43:08 +00001353#ifndef DISABLE_TABCOMP
1354 /* if we've done tab completion, there might be a list of
1355 filename matches on the edit window at this point; make sure
1356 they're cleared off */
1357 if (list)
1358 edit_refresh();
1359#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001360 return -1;
1361 default:
Chris Allegretta5b1faac2000-11-16 19:55:30 +00001362 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001363 }
1364
1365#ifdef DEBUG
1366 fprintf(stderr, _("I got \"%s\"\n"), answer);
1367#endif
1368
1369 return ret;
1370}
1371
1372/*
1373 * Ask a simple yes/no question on the statusbar. Returns 1 for Y, 0 for
1374 * N, 2 for All (if all is non-zero when passed in) and -1 for abort (^C)
1375 */
1376int do_yesno(int all, int leavecursor, char *msg, ...)
1377{
1378 va_list ap;
1379 char foo[133];
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001380 int kbinput, ok = -1, i;
1381 char *yesstr; /* String of yes characters accepted */
1382 char *nostr; /* Same for no */
1383 char *allstr; /* And all, surprise! */
1384 char shortstr[5]; /* Temp string for above */
Chris Allegretta84de5522001-04-12 14:51:48 +00001385#ifndef DISABLE_MOUSE
Chris Allegretta235ab192001-04-12 13:24:40 +00001386#ifdef NCURSES_MOUSE_VERSION
1387 MEVENT mevent;
1388#endif
1389#endif
1390
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001391
1392 /* Yes, no and all are strings of any length. Each string consists of
Chris Allegretta598106e2002-01-19 01:59:37 +00001393 all characters accepted as a valid character for that value.
1394 The first value will be the one displayed in the shortcuts. */
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001395 yesstr = _("Yy");
1396 nostr = _("Nn");
1397 allstr = _("Aa");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001398
1399 /* Write the bottom of the screen */
1400 clear_bottomwin();
Chris Allegretta8ce24132001-04-30 11:28:46 +00001401
1402#ifdef ENABLE_COLOR
1403 color_on(bottomwin, COLOR_BOTTOMBARS);
1404#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001405
Jordi Mallach0b0fc492000-06-23 01:00:13 +00001406 /* Remove gettext call for keybindings until we clear the thing up */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001407 if (!ISSET(NO_HELP)) {
1408 wmove(bottomwin, 1, 0);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001409
1410 snprintf(shortstr, 3, " %c", yesstr[0]);
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001411 onekey(shortstr, _("Yes"), 16);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001412
1413 if (all) {
1414 snprintf(shortstr, 3, " %c", allstr[0]);
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001415 onekey(shortstr, _("All"), 16);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001416 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001417 wmove(bottomwin, 2, 0);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001418
1419 snprintf(shortstr, 3, " %c", nostr[0]);
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001420 onekey(shortstr, _("No"), 16);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001421
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001422 onekey("^C", _("Cancel"), 16);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001423 }
1424 va_start(ap, msg);
1425 vsnprintf(foo, 132, msg, ap);
1426 va_end(ap);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001427
1428#ifdef ENABLE_COLOR
1429 color_off(bottomwin, COLOR_BOTTOMBARS);
1430 color_on(bottomwin, COLOR_STATUSBAR);
1431#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001432 wattron(bottomwin, A_REVERSE);
Chris Allegretta598106e2002-01-19 01:59:37 +00001433#endif /* ENABLE_COLOR */
Chris Allegretta8ce24132001-04-30 11:28:46 +00001434
1435 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001436 mvwaddstr(bottomwin, 0, 0, foo);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001437
1438#ifdef ENABLE_COLOR
1439 color_off(bottomwin, COLOR_STATUSBAR);
1440#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001441 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001442#endif
1443
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001444 wrefresh(bottomwin);
1445
1446 if (leavecursor == 1)
1447 reset_cursor();
1448
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001449 while (ok == -1) {
1450 kbinput = wgetch(edit);
1451
1452 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00001453#ifndef DISABLE_MOUSE
Chris Allegretta235ab192001-04-12 13:24:40 +00001454#ifdef NCURSES_MOUSE_VERSION
1455 case KEY_MOUSE:
1456
1457 /* Look ma! We get to duplicate lots of code from do_mouse!! */
1458 if (getmouse(&mevent) == ERR)
1459 break;
1460 if (!wenclose(bottomwin, mevent.y, mevent.x) || ISSET(NO_HELP))
1461 break;
1462 mevent.y -= editwinrows + 3;
1463 if (mevent.y < 0)
1464 break;
1465 else {
1466
1467 /* Rather than a bunch of if statements, set up a matrix
1468 of possible return keystrokes based on the x and y values */
1469 if (all) {
1470 char yesnosquare[2][2] = {
Chris Allegretta598106e2002-01-19 01:59:37 +00001471 {yesstr[0], allstr[0]},
1472 {nostr[0], NANO_CONTROL_C}
1473 };
Chris Allegretta235ab192001-04-12 13:24:40 +00001474
Chris Allegretta598106e2002-01-19 01:59:37 +00001475 ungetch(yesnosquare[mevent.y][mevent.x / (COLS / 6)]);
Chris Allegretta235ab192001-04-12 13:24:40 +00001476 } else {
1477 char yesnosquare[2][2] = {
1478 {yesstr[0], '\0'},
Chris Allegretta598106e2002-01-19 01:59:37 +00001479 {nostr[0], NANO_CONTROL_C}
1480 };
Chris Allegretta235ab192001-04-12 13:24:40 +00001481
Chris Allegretta598106e2002-01-19 01:59:37 +00001482 ungetch(yesnosquare[mevent.y][mevent.x / (COLS / 6)]);
Chris Allegretta235ab192001-04-12 13:24:40 +00001483 }
1484 }
1485 break;
1486#endif
1487#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001488 case NANO_CONTROL_C:
1489 ok = -2;
1490 break;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001491 default:
1492
Chris Allegretta88520c92001-05-05 17:45:54 +00001493 /* Look for the kbinput in the yes, no and (optimally) all str */
Chris Allegretta598106e2002-01-19 01:59:37 +00001494 for (i = 0; yesstr[i] != 0 && yesstr[i] != kbinput; i++);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001495 if (yesstr[i] != 0) {
Chris Allegrettaea620fe2001-02-18 05:39:41 +00001496 ok = 1;
Chris Allegretta598106e2002-01-19 01:59:37 +00001497 break;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001498 }
1499
Chris Allegretta598106e2002-01-19 01:59:37 +00001500 for (i = 0; nostr[i] != 0 && nostr[i] != kbinput; i++);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001501 if (nostr[i] != 0) {
1502 ok = 0;
Chris Allegretta598106e2002-01-19 01:59:37 +00001503 break;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001504 }
1505
1506 if (all) {
Chris Allegretta598106e2002-01-19 01:59:37 +00001507 for (i = 0; allstr[i] != 0 && allstr[i] != kbinput; i++);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001508 if (allstr[i] != 0) {
1509 ok = 2;
Chris Allegretta598106e2002-01-19 01:59:37 +00001510 break;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001511 }
1512 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001513 }
1514 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001515
1516 /* Then blank the screen */
1517 blank_statusbar_refresh();
1518
1519 if (ok == -2)
1520 return -1;
1521 else
1522 return ok;
1523}
1524
1525void statusbar(char *msg, ...)
1526{
1527 va_list ap;
1528 char foo[133];
1529 int start_x = 0;
1530
1531 va_start(ap, msg);
1532 vsnprintf(foo, 132, msg, ap);
1533 va_end(ap);
1534
Chris Allegretta17dcb722001-01-20 21:40:07 +00001535 start_x = COLS / 2 - strlen(foo) / 2 - 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001536
1537 /* Blank out line */
1538 blank_statusbar();
1539
1540 wmove(bottomwin, 0, start_x);
1541
Chris Allegretta8ce24132001-04-30 11:28:46 +00001542#ifdef ENABLE_COLOR
1543 color_on(bottomwin, COLOR_STATUSBAR);
1544#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001545 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001546#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001547
1548 waddstr(bottomwin, "[ ");
1549 waddstr(bottomwin, foo);
1550 waddstr(bottomwin, " ]");
Chris Allegretta8ce24132001-04-30 11:28:46 +00001551
1552#ifdef ENABLE_COLOR
1553 color_off(bottomwin, COLOR_STATUSBAR);
1554#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001555 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001556#endif
1557
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001558 wrefresh(bottomwin);
1559
1560 if (ISSET(CONSTUPDATE))
1561 statblank = 1;
1562 else
1563 statblank = 25;
1564}
1565
1566void display_main_list(void)
1567{
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001568 bottombars(main_list);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001569}
1570
1571int total_refresh(void)
1572{
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001573 clearok(edit, TRUE);
1574 clearok(topwin, TRUE);
1575 clearok(bottomwin, TRUE);
1576 wnoutrefresh(edit);
1577 wnoutrefresh(topwin);
1578 wnoutrefresh(bottomwin);
1579 doupdate();
1580 clearok(edit, FALSE);
1581 clearok(topwin, FALSE);
1582 clearok(bottomwin, FALSE);
Chris Allegrettaf1d33d32000-08-19 03:53:39 +00001583 edit_refresh();
Chris Allegrettaf4b96012001-01-03 07:11:47 +00001584 titlebar(NULL);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001585 return 1;
1586}
1587
1588void previous_line(void)
1589{
1590 if (current_y > 0)
1591 current_y--;
1592}
1593
Chris Allegretta2084acc2001-11-29 03:43:08 +00001594int do_cursorpos(int constant)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001595{
1596 filestruct *fileptr;
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001597 float linepct = 0.0, bytepct = 0.0, colpct = 0.0;
Chris Allegretta14b3ca92002-01-25 21:59:02 +00001598 long i = 0, j = 0;
Chris Allegretta2084acc2001-11-29 03:43:08 +00001599 static long old_i = -1, old_totsize = -1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001600
1601 if (current == NULL || fileage == NULL)
1602 return 0;
1603
Chris Allegretta2084acc2001-11-29 03:43:08 +00001604 if (old_i == -1)
1605 old_i = i;
1606
1607 if (old_totsize == -1)
1608 old_totsize = totsize;
1609
Chris Allegrettaf3a07b22002-03-29 15:15:38 +00001610 colpct = 100 * (xplustabs() + 1) / (xpt(current, strlen(current->data)) + 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001611
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001612 for (fileptr = fileage; fileptr != current && fileptr != NULL;
1613 fileptr = fileptr->next)
1614 i += strlen(fileptr->data) + 1;
Chris Allegretta14b3ca92002-01-25 21:59:02 +00001615
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001616 if (fileptr == NULL)
1617 return -1;
Chris Allegretta14b3ca92002-01-25 21:59:02 +00001618
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001619 i += current_x;
Chris Allegretta14b3ca92002-01-25 21:59:02 +00001620
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001621 j = totsize;
Chris Allegretta14b3ca92002-01-25 21:59:02 +00001622
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001623 if (totsize > 0)
1624 bytepct = 100 * i / totsize;
Chris Allegretta14b3ca92002-01-25 21:59:02 +00001625
1626 if (totlines > 0)
1627 linepct = 100 * current->lineno / totlines;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001628
1629#ifdef DEBUG
1630 fprintf(stderr, _("do_cursorpos: linepct = %f, bytepct = %f\n"),
1631 linepct, bytepct);
1632#endif
1633
Chris Allegretta2084acc2001-11-29 03:43:08 +00001634 /* if constant is zero, display the position on the statusbar
1635 unconditionally; otherwise, only display the position when the
1636 character values have changed */
1637 if (!constant || (old_i != i || old_totsize != totsize)) {
Chris Allegretta598106e2002-01-19 01:59:37 +00001638 statusbar(_
Chris Allegrettaf27c6972002-02-12 01:57:24 +00001639 ("line %d/%d (%.0f%%), col %ld/%ld (%.0f%%), char %ld/%ld (%.0f%%)"),
Chris Allegrettaf3a07b22002-03-29 15:15:38 +00001640 current->lineno, totlines, linepct, xplustabs() + 1,
1641 xpt(current, strlen(current->data)) + 1, colpct, i, j, bytepct);
Chris Allegretta2084acc2001-11-29 03:43:08 +00001642 }
1643
1644 old_i = i;
1645 old_totsize = totsize;
1646
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001647 reset_cursor();
1648 return 1;
1649}
1650
Chris Allegretta2084acc2001-11-29 03:43:08 +00001651int do_cursorpos_void(void)
1652{
1653 return do_cursorpos(0);
1654}
1655
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001656/* Our broken, non-shortcut list compliant help function.
Chris Allegretta88520c92001-05-05 17:45:54 +00001657 But, hey, it's better than nothing, and it's dynamic! */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001658int do_help(void)
1659{
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001660#ifndef DISABLE_HELP
Chris Allegrettab3655b42001-10-22 03:15:31 +00001661 char *ptr, *end;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001662 int i, j, row = 0, page = 1, kbinput = 0, no_more = 0, kp, kp2;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001663 int no_help_flag = 0;
Chris Allegrettab3655b42001-10-22 03:15:31 +00001664 shortcut *oldshortcut;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001665
1666 blank_edit();
1667 curs_set(0);
Chris Allegrettab3655b42001-10-22 03:15:31 +00001668 wattroff(bottomwin, A_REVERSE);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001669 blank_statusbar();
1670
Chris Allegrettab3655b42001-10-22 03:15:31 +00001671 help_init();
1672 ptr = help_text;
1673
1674 oldshortcut = currshortcut;
Chris Allegrettab3655b42001-10-22 03:15:31 +00001675
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001676 currshortcut = help_list;
Chris Allegretta6fe61492001-05-21 12:56:25 +00001677
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001678 kp = keypad_on(edit, 1);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001679 kp2 = keypad_on(bottomwin, 1);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001680
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001681 if (ISSET(NO_HELP)) {
1682
Chris Allegretta88520c92001-05-05 17:45:54 +00001683 /* Well, if we're going to do this, we should at least
Chris Allegretta70444892001-01-07 23:02:02 +00001684 do it the right way */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001685 no_help_flag = 1;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001686 UNSET(NO_HELP);
Chris Allegretta70444892001-01-07 23:02:02 +00001687 window_init();
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001688 bottombars(help_list);
Chris Allegretta70444892001-01-07 23:02:02 +00001689
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001690 } else
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001691 bottombars(help_list);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001692
1693 do {
1694 ptr = help_text;
1695 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00001696#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001697#ifdef NCURSES_MOUSE_VERSION
Chris Allegretta598106e2002-01-19 01:59:37 +00001698 case KEY_MOUSE:
1699 do_mouse();
1700 break;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001701#endif
1702#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001703 case NANO_NEXTPAGE_KEY:
1704 case NANO_NEXTPAGE_FKEY:
1705 case KEY_NPAGE:
1706 if (!no_more) {
1707 blank_edit();
1708 page++;
1709 }
1710 break;
1711 case NANO_PREVPAGE_KEY:
1712 case NANO_PREVPAGE_FKEY:
1713 case KEY_PPAGE:
1714 if (page > 1) {
1715 no_more = 0;
1716 blank_edit();
1717 page--;
1718 }
1719 break;
1720 }
1721
Chris Allegretta88520c92001-05-05 17:45:54 +00001722 /* Calculate where in the text we should be, based on the page */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001723 for (i = 1; i < page; i++) {
1724 row = 0;
1725 j = 0;
Chris Allegretta44e73df2000-09-07 03:37:38 +00001726
1727 while (row < editwinrows - 2 && *ptr != '\0') {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001728 if (*ptr == '\n' || j == COLS - 5) {
1729 j = 0;
1730 row++;
1731 }
1732 ptr++;
1733 j++;
1734 }
1735 }
1736
Chris Allegretta44e73df2000-09-07 03:37:38 +00001737 if (i > 1) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001738
Chris Allegretta44e73df2000-09-07 03:37:38 +00001739 }
1740
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001741 i = 0;
1742 j = 0;
1743 while (i < editwinrows && *ptr != '\0') {
1744 end = ptr;
1745 while (*end != '\n' && *end != '\0' && j != COLS - 5) {
1746 end++;
1747 j++;
1748 }
1749 if (j == COLS - 5) {
1750
Chris Allegretta88520c92001-05-05 17:45:54 +00001751 /* Don't print half a word if we've run out of space */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001752 while (*end != ' ' && *end != '\0') {
1753 end--;
1754 j--;
1755 }
1756 }
1757 mvwaddnstr(edit, i, 0, ptr, j);
1758 j = 0;
1759 i++;
1760 if (*end == '\n')
1761 end++;
1762 ptr = end;
1763 }
1764 if (*ptr == '\0') {
1765 no_more = 1;
1766 continue;
1767 }
Chris Allegretta598106e2002-01-19 01:59:37 +00001768 } while ((kbinput = wgetch(edit)) != NANO_EXIT_KEY &&
1769 kbinput != NANO_EXIT_FKEY);
Chris Allegrettad1627cf2000-12-18 05:03:16 +00001770
Chris Allegrettab3655b42001-10-22 03:15:31 +00001771 currshortcut = oldshortcut;
Chris Allegrettab3655b42001-10-22 03:15:31 +00001772
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001773 if (no_help_flag) {
Chris Allegretta70444892001-01-07 23:02:02 +00001774 blank_bottombars();
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001775 wrefresh(bottomwin);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001776 SET(NO_HELP);
Chris Allegretta70444892001-01-07 23:02:02 +00001777 window_init();
Chris Allegretta598106e2002-01-19 01:59:37 +00001778 } else
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001779 bottombars(currshortcut);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001780
1781 curs_set(1);
1782 edit_refresh();
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001783 kp = keypad_on(edit, kp);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001784 kp2 = keypad_on(bottomwin, kp2);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001785
Chris Allegretta3bc8c722000-12-10 17:03:25 +00001786#elif defined(DISABLE_HELP)
1787 nano_disabled_msg();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001788#endif
1789
1790 return 1;
1791}
1792
1793/* Dump the current file structure to stderr */
1794void dump_buffer(filestruct * inptr)
1795{
1796#ifdef DEBUG
1797 filestruct *fileptr;
1798
1799 if (inptr == fileage)
1800 fprintf(stderr, _("Dumping file buffer to stderr...\n"));
1801 else if (inptr == cutbuffer)
1802 fprintf(stderr, _("Dumping cutbuffer to stderr...\n"));
1803 else
1804 fprintf(stderr, _("Dumping a buffer to stderr...\n"));
1805
1806 fileptr = inptr;
1807 while (fileptr != NULL) {
Chris Allegrettab3655b42001-10-22 03:15:31 +00001808 fprintf(stderr, "(%d) %s\n", fileptr->lineno, fileptr->data);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001809 fflush(stderr);
1810 fileptr = fileptr->next;
1811 }
1812#endif /* DEBUG */
1813}
1814
1815void dump_buffer_reverse(filestruct * inptr)
1816{
1817#ifdef DEBUG
1818 filestruct *fileptr;
1819
1820 fileptr = filebot;
1821 while (fileptr != NULL) {
Chris Allegrettab3655b42001-10-22 03:15:31 +00001822 fprintf(stderr, "(%d) %s\n", fileptr->lineno, fileptr->data);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001823 fflush(stderr);
1824 fileptr = fileptr->prev;
1825 }
1826#endif /* DEBUG */
1827}
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001828
Chris Allegretta88520c92001-05-05 17:45:54 +00001829/* Fix editbot, based on the assumption that edittop is correct */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001830void fix_editbot(void)
1831{
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001832 int i;
1833 editbot = edittop;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001834 for (i = 0; (i <= editwinrows - 1) && (editbot->next != NULL)
1835 && (editbot != filebot); i++, editbot = editbot->next);
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001836}
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001837
Chris Allegrettafb62f732000-12-05 11:36:41 +00001838/* highlight the current word being replaced or spell checked */
1839void do_replace_highlight(int highlight_flag, char *word)
1840{
1841 char *highlight_word = NULL;
1842 int x, y;
1843
Chris Allegretta598106e2002-01-19 01:59:37 +00001844 highlight_word =
1845 mallocstrcpy(highlight_word, &current->data[current_x]);
Chris Allegrettafb62f732000-12-05 11:36:41 +00001846 highlight_word[strlen(word)] = '\0';
1847
Chris Allegretta88520c92001-05-05 17:45:54 +00001848 /* adjust output when word extends beyond screen */
Chris Allegrettafb62f732000-12-05 11:36:41 +00001849
1850 x = xplustabs();
1851 y = get_page_end_virtual(get_page_from_virtual(x)) + 1;
1852
1853 if ((COLS - (y - x) + strlen(word)) > COLS) {
1854 highlight_word[y - x - 1] = '$';
1855 highlight_word[y - x] = '\0';
1856 }
1857
1858 /* OK display the output */
1859
1860 reset_cursor();
Chris Allegretta598106e2002-01-19 01:59:37 +00001861
Chris Allegrettafb62f732000-12-05 11:36:41 +00001862 if (highlight_flag)
1863 wattron(edit, A_REVERSE);
1864
1865 waddstr(edit, highlight_word);
1866
1867 if (highlight_flag)
1868 wattroff(edit, A_REVERSE);
1869
1870 free(highlight_word);
1871}
1872
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001873#ifdef NANO_EXTRA
Chris Allegrettadce44ab2002-03-16 01:03:41 +00001874#define CREDIT_LEN 52
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001875void do_credits(void)
1876{
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001877 int i, j = 0, k, place = 0, start_x;
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001878 char *what;
1879
1880 char *nanotext = _("The nano text editor");
1881 char *version = _("version ");
1882 char *brought = _("Brought to you by:");
1883 char *specialthx = _("Special thanks to:");
1884 char *fsf = _("The Free Software Foundation");
Chris Allegrettadce44ab2002-03-16 01:03:41 +00001885 char *ncurses = _("For ncurses:");
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001886 char *anyonelse = _("and anyone else we forgot...");
1887 char *thankyou = _("Thank you for using nano!\n");
1888
Chris Allegretta598106e2002-01-19 01:59:37 +00001889 char *credits[CREDIT_LEN] = { nanotext,
1890 version,
1891 VERSION,
1892 "",
1893 brought,
1894 "Chris Allegretta",
1895 "Jordi Mallach",
1896 "Adam Rogoyski",
1897 "Rob Siemborski",
1898 "Rocco Corsi",
Chris Allegrettaa8c22572002-02-15 19:17:02 +00001899 "David Lawrence Ramsey",
Chris Allegretta598106e2002-01-19 01:59:37 +00001900 "Ken Tyler",
1901 "Sven Guckes",
1902 "Florian König",
1903 "Pauli Virtanen",
1904 "Daniele Medri",
1905 "Clement Laforet",
1906 "Tedi Heriyanto",
1907 "Bill Soudan",
1908 "Christian Weisgerber",
1909 "Erik Andersen",
1910 "Big Gaute",
1911 "Joshua Jensen",
1912 "Ryan Krebs",
1913 "Albert Chin",
Chris Allegretta598106e2002-01-19 01:59:37 +00001914 "",
1915 specialthx,
1916 "Plattsburgh State University",
1917 "Benet Laboratories",
1918 "Amy Allegretta",
1919 "Linda Young",
1920 "Jeremy Robichaud",
1921 "Richard Kolb II",
1922 fsf,
1923 "Linus Torvalds",
1924 ncurses,
Chris Allegrettadce44ab2002-03-16 01:03:41 +00001925 "Thomas Dickey",
1926 "Pavel Curtis",
1927 "Zeyd Ben-Halim",
1928 "Eric S. Raymond",
Chris Allegretta598106e2002-01-19 01:59:37 +00001929 anyonelse,
1930 thankyou,
1931 "", "", "", "",
1932 "(c) 1999-2002 Chris Allegretta",
1933 "", "", "", "",
1934 "www.nano-editor.org"
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001935 };
1936
1937 curs_set(0);
1938 nodelay(edit, TRUE);
1939 blank_bottombars();
1940 mvwaddstr(topwin, 0, 0, hblank);
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001941 blank_edit();
1942 wrefresh(edit);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001943 wrefresh(bottomwin);
1944 wrefresh(topwin);
1945
1946 while (wgetch(edit) == ERR) {
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001947 for (k = 0; k <= 1; k++) {
1948 blank_edit();
Chris Allegretta598106e2002-01-19 01:59:37 +00001949 for (i = editwinrows / 2 - 1; i >= (editwinrows / 2 - 1 - j);
1950 i--) {
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001951 mvwaddstr(edit, i * 2 - k, 0, hblank);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001952
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001953 if (place - (editwinrows / 2 - 1 - i) < CREDIT_LEN)
1954 what = credits[place - (editwinrows / 2 - 1 - i)];
1955 else
1956 what = "";
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001957
Chris Allegretta17dcb722001-01-20 21:40:07 +00001958 start_x = COLS / 2 - strlen(what) / 2 - 1;
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001959 mvwaddstr(edit, i * 2 - k, start_x, what);
1960 }
1961 usleep(700000);
1962 wrefresh(edit);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001963 }
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001964 if (j < editwinrows / 2 - 1)
1965 j++;
1966
1967 place++;
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001968
1969 if (place >= CREDIT_LEN + editwinrows / 2)
1970 break;
1971 }
1972
1973 nodelay(edit, FALSE);
1974 curs_set(1);
1975 display_main_list();
1976 total_refresh();
Chris Allegretta598106e2002-01-19 01:59:37 +00001977}
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001978#endif
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001979
Chris Allegretta598106e2002-01-19 01:59:37 +00001980int keypad_on(WINDOW * win, int newval)
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001981{
1982
Chris Allegretta88520c92001-05-05 17:45:54 +00001983/* This is taken right from aumix. Don't sue me. */
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001984#ifdef HAVE_USEKEYPAD
Chris Allegretta598106e2002-01-19 01:59:37 +00001985 int old;
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001986
1987 old = win->_use_keypad;
Chris Allegrettae3167732001-03-18 16:59:34 +00001988 keypad(win, newval);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001989 return old;
1990#else
Chris Allegrettae3167732001-03-18 16:59:34 +00001991 keypad(win, newval);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001992 return 1;
Chris Allegretta598106e2002-01-19 01:59:37 +00001993#endif /* HAVE_USEKEYPAD */
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001994
1995}