blob: 88ec03f85d35fe91938dbfee3a0cc8d0dcfc8ed0 [file] [log] [blame]
Chris Allegretta11b00112000-08-06 21:13:45 +00001/* $Id$ */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00002/**************************************************************************
3 * winio.c *
4 * *
5 * Copyright (C) 1999 Chris Allegretta *
6 * 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 *
8 * the Free Software Foundation; either version 1, or (at your option) *
9 * 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 ;
87 else if (fileptr->data[i] < 32)
88 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() */
137int strlenpt(char *buf)
138{
139 int i, tabs = 0;
140
141 if (buf == NULL)
142 return 0;
143
144 for (i = 0; buf[i] != 0; i++) {
145 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
161
Chris Allegretta88520c92001-05-05 17:45:54 +0000162/* resets current_y, based on the position of current, and puts the cursor at
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000163 (current_y, current_x) */
164void reset_cursor(void)
165{
166 filestruct *ptr = edittop;
167 int x;
168
169 current_y = 0;
170
171 while (ptr != current && ptr != editbot && ptr->next != NULL) {
172 ptr = ptr->next;
173 current_y++;
174 }
175
176 x = xplustabs();
177 if (x <= COLS - 2)
Robert Siemborskid8510b22000-06-06 23:04:06 +0000178 wmove(edit, current_y, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000179 else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000180 wmove(edit, current_y, x -
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000181 get_page_start_virtual(get_page_from_virtual(x)));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000182
183}
184
185void blank_bottombars(void)
186{
187 int i = no_help()? 3 : 1;
188
189 for (; i <= 2; i++)
190 mvwaddstr(bottomwin, i, 0, hblank);
191
192}
193
194void blank_edit(void)
195{
196 int i;
197 for (i = 0; i <= editwinrows - 1; i++)
198 mvwaddstr(edit, i, 0, hblank);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000199}
200
201
202void blank_statusbar(void)
203{
204 mvwaddstr(bottomwin, 0, 0, hblank);
205}
206
207void blank_statusbar_refresh(void)
208{
209 blank_statusbar();
210 wrefresh(bottomwin);
211}
212
213void check_statblank(void)
214{
215
216 if (statblank > 1)
217 statblank--;
218 else if (statblank == 1 && !ISSET(CONSTUPDATE)) {
219 statblank--;
220 blank_statusbar_refresh();
221 }
222}
223
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000224/* Repaint the statusbar when getting a character in nanogetstr */
225void nanoget_repaint(char *buf, char *inputbuf, int x)
226{
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000227 int len = strlen(buf);
228 int wid = COLS - len;
229
Chris Allegretta8ce24132001-04-30 11:28:46 +0000230#ifdef ENABLE_COLOR
231 color_on(bottomwin, COLOR_STATUSBAR);
232#endif
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000233 blank_statusbar();
Chris Allegretta8ce24132001-04-30 11:28:46 +0000234
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000235 if (x <= COLS - 1) {
236 /* Black magic */
237 buf[len - 1] = ' ';
Chris Allegretta31925e42000-11-02 04:40:39 +0000238
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000239 mvwaddstr(bottomwin, 0, 0, buf);
240 waddnstr(bottomwin, inputbuf, wid);
241 wmove(bottomwin, 0, (x % COLS));
242 }
243 else {
244 /* Black magic */
245 buf[len - 1] = '$';
Chris Allegretta31925e42000-11-02 04:40:39 +0000246
Chris Allegretta0d1e8d62000-11-02 15:30:24 +0000247 mvwaddstr(bottomwin, 0, 0, buf);
248 waddnstr(bottomwin, &inputbuf[wid * ((x - len) / (wid))], wid);
249 wmove(bottomwin, 0, ((x - len) % wid) + len);
250 }
Chris Allegretta8ce24132001-04-30 11:28:46 +0000251
252#ifdef ENABLE_COLOR
253 color_off(bottomwin, COLOR_STATUSBAR);
254#endif
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000255}
256
Chris Allegretta88520c92001-05-05 17:45:54 +0000257/* Get the input from the kb; this should only be called from statusq */
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000258int nanogetstr(int allowtabs, char *buf, char *def, shortcut s[], int slen,
259 int start_x)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000260{
261 int kbinput = 0, j = 0, x = 0, xend;
Chris Allegrettabe77c612000-11-24 14:00:16 +0000262 int x_left = 0, inputlen, tabbed = 0;
Chris Allegretta31925e42000-11-02 04:40:39 +0000263 char *inputbuf;
Rocco Corsi06aca1c2001-01-11 05:30:31 +0000264#ifndef DISABLE_TABCOMP
Chris Allegrettabe77c612000-11-24 14:00:16 +0000265 int shift = 0;
266#endif
Chris Allegretta31925e42000-11-02 04:40:39 +0000267
268 inputbuf = nmalloc(strlen(def) + 1);
269 inputbuf[0] = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000270
271 x_left = strlen(buf);
272 x = strlen(def) + x_left;
273
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000274 currshortcut = s;
275 currslen = slen;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000276 /* Get the input! */
Chris Allegretta31925e42000-11-02 04:40:39 +0000277 if (strlen(def) > 0)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000278 strcpy(inputbuf, def);
Chris Allegretta31925e42000-11-02 04:40:39 +0000279
280 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000281
Chris Allegretta022b96f2000-11-14 17:47:58 +0000282 /* Make sure any editor screen updates are displayed before getting input */
283 wrefresh(edit);
284
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000285 while ((kbinput = wgetch(bottomwin)) != 13) {
286 for (j = 0; j <= slen - 1; j++) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000287#ifdef DEBUG
288 fprintf(stderr, _("Aha! \'%c\' (%d)\n"), kbinput, kbinput);
289#endif
290
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000291 if (kbinput == s[j].val) {
Chris Allegretta5bf51d32000-11-16 06:01:10 +0000292
293 /* We shouldn't discard the answer it gave, just because
294 we hit a keystroke, GEEZ! */
295 answer = mallocstrcpy(answer, inputbuf);
Chris Allegretta92d2bab2000-11-02 14:53:46 +0000296 free(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000297 return s[j].val;
298 }
299 }
300 xend = strlen(buf) + strlen(inputbuf);
301
Chris Allegretta04d848e2000-11-05 17:54:41 +0000302 if (kbinput != '\t')
303 tabbed = 0;
304
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000305 switch (kbinput) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000306
307 /* Stuff we want to equate with <enter>, ASCII 13 */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000308 case 343:
Chris Allegrettaf9b6c9b2000-10-18 19:35:59 +0000309 ungetch(13); /* Enter on iris-ansi $TERM, sometimes */
310 break;
Chris Allegretta75155df2000-11-28 23:04:24 +0000311 /* Stuff we want to ignore */
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000312#ifdef PDCURSES
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000313 case 541:
314 case 542:
Chris Allegretta72623582000-11-29 23:43:28 +0000315 case 543: /* Right ctrl again */
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000316 case 544:
Chris Allegretta72623582000-11-29 23:43:28 +0000317 case 545: /* Right alt again */
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000318 break;
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000319#endif
Chris Allegretta84de5522001-04-12 14:51:48 +0000320#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000321#ifdef NCURSES_MOUSE_VERSION
322 case KEY_MOUSE:
323 do_mouse();
324 break;
325#endif
326#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000327 case KEY_HOME:
328 x = x_left;
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000329 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000330 break;
331 case KEY_END:
332 x = x_left + strlen(inputbuf);
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000333 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000334 break;
335 case KEY_RIGHT:
Chris Allegretta35dac582001-03-21 15:07:20 +0000336 case NANO_FORWARD_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000337
338 if (x < xend)
339 x++;
340 wmove(bottomwin, 0, x);
341 break;
342 case NANO_CONTROL_D:
343 if (strlen(inputbuf) > 0 && (x - x_left) != strlen(inputbuf)) {
344 memmove(inputbuf + (x - x_left),
345 inputbuf + (x - x_left) + 1,
346 strlen(inputbuf) - (x - x_left) - 1);
347 inputbuf[strlen(inputbuf) - 1] = 0;
348 }
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000349 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000350 break;
351 case NANO_CONTROL_K:
352 case NANO_CONTROL_U:
353 *inputbuf = 0;
354 x = x_left;
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000355 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000356 break;
357 case KEY_BACKSPACE:
358 case KEY_DC:
359 case 127:
360 case NANO_CONTROL_H:
361 if (strlen(inputbuf) > 0) {
362 if (x == (x_left + strlen(inputbuf)))
363 inputbuf[strlen(inputbuf) - 1] = 0;
364 else if (x - x_left) {
365 memmove(inputbuf + (x - x_left) - 1,
366 inputbuf + (x - x_left),
367 strlen(inputbuf) - (x - x_left));
368 inputbuf[strlen(inputbuf) - 1] = 0;
369 }
370 }
Chris Allegretta04d848e2000-11-05 17:54:41 +0000371 if (x > strlen(buf))
372 x--;
Chris Allegretta31925e42000-11-02 04:40:39 +0000373 nanoget_repaint(buf, inputbuf, x);
Chris Allegretta04d848e2000-11-05 17:54:41 +0000374 break;
Rocco Corsi06aca1c2001-01-11 05:30:31 +0000375#ifndef DISABLE_TABCOMP
Chris Allegretta04d848e2000-11-05 17:54:41 +0000376 case NANO_CONTROL_I:
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000377 if (allowtabs) {
Chris Allegretta442f2c52000-11-14 17:46:06 +0000378 shift = 0;
379 inputbuf = input_tab(inputbuf, (x - x_left),
Chris Allegrettab5b89ae2000-11-14 18:25:26 +0000380 &tabbed, &shift);
Chris Allegretta442f2c52000-11-14 17:46:06 +0000381 x += shift;
Chris Allegrettae434b452001-01-27 19:25:00 +0000382 if (x - x_left > strlen(inputbuf))
383 x = strlen(inputbuf) + x_left;
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000384 nanoget_repaint(buf, inputbuf, x);
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000385 }
Chris Allegretta04d848e2000-11-05 17:54:41 +0000386 break;
Chris Allegrettabe77c612000-11-24 14:00:16 +0000387#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000388 case KEY_LEFT:
Chris Allegretta35dac582001-03-21 15:07:20 +0000389 case NANO_BACK_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000390 if (x > strlen(buf))
391 x--;
392 wmove(bottomwin, 0, x);
393 break;
394 case KEY_UP:
395 case KEY_DOWN:
396 break;
397
398 case 27:
399 switch (kbinput = wgetch(edit)) {
400 case 79:
401 switch (kbinput = wgetch(edit)) {
402 case 70:
403 x = x_left + strlen(inputbuf);
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000404 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000405 break;
406 case 72:
407 x = x_left;
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000408 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000409 break;
410 }
411 break;
412 case 91:
413 switch (kbinput = wgetch(edit)) {
414 case 'C':
415 if (x < xend)
416 x++;
417 wmove(bottomwin, 0, x);
418 break;
419 case 'D':
420 if (x > strlen(buf))
421 x--;
422 wmove(bottomwin, 0, x);
423 break;
424 case 49:
425 x = x_left;
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000426 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000427 goto skip_126;
428 case 51:
429 if (strlen(inputbuf) > 0
430 && (x - x_left) != strlen(inputbuf)) {
431 memmove(inputbuf + (x - x_left),
432 inputbuf + (x - x_left) + 1,
433 strlen(inputbuf) - (x - x_left) - 1);
434 inputbuf[strlen(inputbuf) - 1] = 0;
435 }
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000436 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000437 goto skip_126;
438 case 52:
439 x = x_left + strlen(inputbuf);
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000440 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000441 goto skip_126;
442 skip_126:
443 nodelay(edit, TRUE);
444 kbinput = wgetch(edit);
445 if (kbinput == 126 || kbinput == ERR)
446 kbinput = -1;
447 nodelay(edit, FALSE);
448 break;
449 }
450 }
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000451 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000452 break;
453
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000454 default:
455 if (kbinput < 32)
456 break;
Chris Allegretta31925e42000-11-02 04:40:39 +0000457
458 inputlen = strlen(inputbuf);
459 inputbuf = nrealloc(inputbuf, inputlen + 2);
460
461 memmove(&inputbuf[x - x_left + 1],
462 &inputbuf[x - x_left],
463 inputlen - (x - x_left) + 1);
464 inputbuf[x - x_left] = kbinput;
465
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000466 x++;
467
Chris Allegrettaa0e957b2000-10-24 22:25:36 +0000468 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000469#ifdef DEBUG
470 fprintf(stderr, _("input \'%c\' (%d)\n"), kbinput, kbinput);
471#endif
472 }
473 wrefresh(bottomwin);
474 }
475
Chris Allegretta31925e42000-11-02 04:40:39 +0000476 answer = mallocstrcpy(answer, inputbuf);
Chris Allegretta92d2bab2000-11-02 14:53:46 +0000477 free(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000478
Chris Allegretta105da332000-10-31 05:10:10 +0000479 /* Now that the text is editable instead of bracketed, we have to
480 check for answer == def, instead of answer == "" */
Chris Allegrettabf9a8cc2000-11-17 01:37:39 +0000481 if (((ISSET(PICO_MODE)) && !strcmp(answer, "")) ||
482 ((!ISSET(PICO_MODE)) && !strcmp(answer, def)))
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000483 return -2;
484 else
485 return 0;
486}
487
488void horizbar(WINDOW * win, int y)
489{
490 wattron(win, A_REVERSE);
491 mvwaddstr(win, 0, 0, hblank);
492 wattroff(win, A_REVERSE);
493}
494
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000495void titlebar(char *path)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000496{
497 int namelen, space;
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000498 char *what = path;
499
500 if (path == NULL)
501 what = filename;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000502
Chris Allegretta8ce24132001-04-30 11:28:46 +0000503#ifdef ENABLE_COLOR
504 color_on(topwin, COLOR_TITLEBAR);
505 mvwaddstr(topwin, 0, 0, hblank);
506#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000507 horizbar(topwin, 0);
508 wattron(topwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000509#endif
510
511
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000512 mvwaddstr(topwin, 0, 3, VERMSG);
513
514 space = COLS - strlen(VERMSG) - strlen(VERSION) - 21;
515
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000516 namelen = strlen(what);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000517
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000518 if (!strcmp(what, ""))
Chris Allegretta17dcb722001-01-20 21:40:07 +0000519 mvwaddstr(topwin, 0, COLS / 2 - 6, _("New Buffer"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000520 else {
521 if (namelen > space) {
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000522 if (path == NULL)
523 waddstr(topwin, _(" File: ..."));
524 else
525 waddstr(topwin, _(" DIR: ..."));
526 waddstr(topwin, &what[namelen - space]);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000527 } else {
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000528 if (path == NULL)
Chris Allegretta17dcb722001-01-20 21:40:07 +0000529 mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1), "File: ");
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000530 else
Chris Allegretta17dcb722001-01-20 21:40:07 +0000531 mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1), " DIR: ");
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000532 waddstr(topwin, what);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000533 }
534 }
535 if (ISSET(MODIFIED))
536 mvwaddstr(topwin, 0, COLS - 10, _("Modified"));
Chris Allegretta8ce24132001-04-30 11:28:46 +0000537
538
539#ifdef ENABLE_COLOR
540 color_off(topwin, COLOR_TITLEBAR);
541#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000542 wattroff(topwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000543#endif
544
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000545 wrefresh(topwin);
546 reset_cursor();
547}
548
549void onekey(char *keystroke, char *desc)
550{
551 char description[80];
552
Chris Allegrettae7034c62000-09-15 03:31:09 +0000553 snprintf(description, 12, " %-10s", desc);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000554 wattron(bottomwin, A_REVERSE);
555 waddstr(bottomwin, keystroke);
556 wattroff(bottomwin, A_REVERSE);
557 waddstr(bottomwin, description);
558}
559
560void clear_bottomwin(void)
561{
562 if (ISSET(NO_HELP))
563 return;
564
565 mvwaddstr(bottomwin, 1, 0, hblank);
566 mvwaddstr(bottomwin, 2, 0, hblank);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000567}
568
569void bottombars(shortcut s[], int slen)
570{
571 int i, j, k;
572 char keystr[10];
573
574 if (ISSET(NO_HELP))
575 return;
576
Chris Allegretta8ce24132001-04-30 11:28:46 +0000577#ifdef ENABLE_COLOR
578 color_on(bottomwin, COLOR_BOTTOMBARS);
579#endif
580
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000581 /* Determine how many extra spaces are needed to fill the bottom of the screen */
582 k = COLS / 6 - 13;
583
584 clear_bottomwin();
585 wmove(bottomwin, 1, 0);
586 for (i = 0; i <= slen - 1; i += 2) {
Robert Siemborski6af14312000-07-01 21:34:26 +0000587 snprintf(keystr, 10, "^%c", s[i].val + 64);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000588 onekey(keystr, s[i].desc);
589
590 for (j = 0; j < k; j++)
591 waddch(bottomwin, ' ');
592 }
593
594 wmove(bottomwin, 2, 0);
595 for (i = 1; i <= slen - 1; i += 2) {
Robert Siemborski6af14312000-07-01 21:34:26 +0000596 snprintf(keystr, 10, "^%c", s[i].val + 64);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000597 onekey(keystr, s[i].desc);
598
599 for (j = 0; j < k; j++)
600 waddch(bottomwin, ' ');
601 }
602
Chris Allegretta8ce24132001-04-30 11:28:46 +0000603#ifdef ENABLE_COLOR
604 color_off(bottomwin, COLOR_BOTTOMBARS);
605#endif
606
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000607 wrefresh(bottomwin);
608
609}
610
611/* If modified is not already set, set it and update titlebar */
612void set_modified(void)
613{
614 if (!ISSET(MODIFIED)) {
615 SET(MODIFIED);
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000616 titlebar(NULL);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000617 wrefresh(topwin);
618 }
619}
620
Robert Siemborski9d584552000-07-08 00:41:29 +0000621/* And so start the display update routines */
622/* Given a column, this returns the "page" it is on */
623/* "page" in the case of the display columns, means which set of 80 */
Chris Allegretta88520c92001-05-05 17:45:54 +0000624/* characters is viewable (e.g.: page 1 shows from 1 to COLS) */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000625inline int get_page_from_virtual(int virtual)
626{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000627 int page = 2;
628
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000629 if (virtual <= COLS - 2)
630 return 1;
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000631 virtual -= (COLS - 2);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000632
633 while (virtual > COLS - 2 - 7) {
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000634 virtual -= (COLS - 2 - 7);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000635 page++;
636 }
637
638 return page;
639}
640
Robert Siemborski9d584552000-07-08 00:41:29 +0000641/* The inverse of the above function */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000642inline int get_page_start_virtual(int page)
643{
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000644 int virtual;
645 virtual = --page * (COLS - 7);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000646 if (page)
647 virtual -= 2 * page - 1;
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000648 return virtual;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000649}
650
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000651inline int get_page_end_virtual(int page)
652{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000653 return get_page_start_virtual(page) + COLS - 1;
654}
655
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000656#ifndef NANO_SMALL
Robert Siemborski9d584552000-07-08 00:41:29 +0000657/* This takes care of the case where there is a mark that covers only */
658/* the current line. */
659
Chris Allegretta88520c92001-05-05 17:45:54 +0000660/* It expects a line with no tab characters (i.e.: the type that edit_add */
Robert Siemborski9d584552000-07-08 00:41:29 +0000661/* deals with */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000662void add_marked_sameline(int begin, int end, filestruct * fileptr, int y,
663 int virt_cur_x, int this_page)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000664{
Robert Siemborski9d584552000-07-08 00:41:29 +0000665 /*
666 * The general idea is to break the line up into 3 sections: before
667 * the mark, the mark, and after the mark. We then paint each in
Chris Allegretta88520c92001-05-05 17:45:54 +0000668 * turn (for those that are currently visible, of course)
Robert Siemborski9d584552000-07-08 00:41:29 +0000669 *
670 * 3 start points: 0 -> begin, begin->end, end->strlen(data)
671 * in data : pre sel post
672 */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000673 int this_page_start = get_page_start_virtual(this_page),
Robert Siemborski53875912000-06-16 04:25:30 +0000674 this_page_end = get_page_end_virtual(this_page);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000675
Robert Siemborskid8510b22000-06-06 23:04:06 +0000676 /* likewise, 3 data lengths */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000677 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 +0000678
679 /* now fix the start locations & lengths according to the cursor's
Chris Allegretta88520c92001-05-05 17:45:54 +0000680 * position (i.e.: our page) */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000681 if (pre_data_len < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000682 pre_data_len = 0;
683 else
684 pre_data_len -= this_page_start;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000685
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000686 if (begin < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000687 begin = this_page_start;
688
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000689 if (end < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000690 end = this_page_start;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000691
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000692 if (begin > this_page_end)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000693 begin = this_page_end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000694
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000695 if (end > this_page_end)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000696 end = this_page_end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000697
Robert Siemborski9d584552000-07-08 00:41:29 +0000698 /* Now calculate the lengths */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000699 sel_data_len = end - begin;
700 post_data_len = this_page_end - end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000701
Robert Siemborski9d584552000-07-08 00:41:29 +0000702 /* Paint this line! */
Robert Siemborski53875912000-06-16 04:25:30 +0000703 mvwaddnstr(edit, y, 0, &fileptr->data[this_page_start], pre_data_len);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000704
705#ifdef ENABLE_COLOR
706 color_on(edit, COLOR_MARKER);
707#else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000708 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000709#endif /* ENABLE_COLOR */
710
Robert Siemborskia9addc72000-06-17 06:06:35 +0000711 mvwaddnstr(edit, y, begin - this_page_start,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000712 &fileptr->data[begin], sel_data_len);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000713
714#ifdef ENABLE_COLOR
715 color_off(edit, COLOR_MARKER);
716#else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000717 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000718#endif /* ENABLE_COLOR */
719
Robert Siemborskia9addc72000-06-17 06:06:35 +0000720 mvwaddnstr(edit, y, end - this_page_start,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000721 &fileptr->data[end], post_data_len);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000722}
723#endif
724
Robert Siemborski9d584552000-07-08 00:41:29 +0000725/* edit_add takes care of the job of actually painting a line into the
726 * edit window.
727 *
728 * Called only from update_line. Expects a converted-to-not-have-tabs
Robert Siemborski53875912000-06-16 04:25:30 +0000729 * line */
730void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000731 int virt_mark_beginx, int this_page)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000732{
733#ifndef NANO_SMALL
Chris Allegretta88520c92001-05-05 17:45:54 +0000734 /* There are quite a few cases that could take place; we'll deal
Robert Siemborski9d584552000-07-08 00:41:29 +0000735 * with them each in turn */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000736 if (ISSET(MARK_ISSET)
Robert Siemborski9d584552000-07-08 00:41:29 +0000737 && !((fileptr->lineno > mark_beginbuf->lineno
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000738 && fileptr->lineno > current->lineno)
739 || (fileptr->lineno < mark_beginbuf->lineno
740 && fileptr->lineno < current->lineno))) {
Chris Allegretta88520c92001-05-05 17:45:54 +0000741 /* If we get here we are on a line that is at least
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000742 * partially selected. The lineno checks above determined
743 * that */
744 if (fileptr != mark_beginbuf && fileptr != current) {
745 /* We are on a completely marked line, paint it all
746 * inverse */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000747#ifdef ENABLE_COLOR
748 color_on(edit, COLOR_MARKER);
749#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000750 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000751#endif /* ENABLE_COLOR */
752
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000753 mvwaddnstr(edit, yval, 0, fileptr->data, COLS);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000754
755#ifdef ENABLE_COLOR
756 color_off(edit, COLOR_MARKER);
757#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000758 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000759#endif /* ENABLE_COLOR */
760
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000761 } else if (fileptr == mark_beginbuf && fileptr == current) {
762 /* Special case, we're still on the same line we started
763 * marking -- so we call our helper function */
764 if (virt_cur_x < virt_mark_beginx) {
765 /* To the right of us is marked */
766 add_marked_sameline(virt_cur_x, virt_mark_beginx,
767 fileptr, yval, virt_cur_x, this_page);
768 } else {
769 /* To the left of us is marked */
770 add_marked_sameline(virt_mark_beginx, virt_cur_x,
771 fileptr, yval, virt_cur_x, this_page);
772 }
773 } else if (fileptr == mark_beginbuf) {
774 /*
Chris Allegretta88520c92001-05-05 17:45:54 +0000775 * We're updating the line that was first marked,
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000776 * but we're not currently on it. So we want to
Robert Siemborskia0238ed2001-03-31 21:46:43 +0000777 * figure out which half to invert based on our
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000778 * relative line numbers.
779 *
Chris Allegretta88520c92001-05-05 17:45:54 +0000780 * I.e. if we're above the "beginbuf" line, we want to
781 * mark the left side. Otherwise, we're below, so we
782 * mark the right.
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000783 */
784 int target;
785
Chris Allegretta8ce24132001-04-30 11:28:46 +0000786 if (mark_beginbuf->lineno > current->lineno) {
787#ifdef ENABLE_COLOR
788 color_on(edit, COLOR_MARKER);
789#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000790 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000791#endif /* ENABLE_COLOR */
792 }
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000793
794 target =
795 (virt_mark_beginx <
796 COLS - 1) ? virt_mark_beginx : COLS - 1;
797
798 mvwaddnstr(edit, yval, 0, fileptr->data, target);
799
Chris Allegretta8ce24132001-04-30 11:28:46 +0000800 if (mark_beginbuf->lineno < current->lineno) {
801
802#ifdef ENABLE_COLOR
803 color_on(edit, COLOR_MARKER);
804#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000805 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000806#endif /* ENABLE_COLOR */
807
808 } else {
809
810#ifdef ENABLE_COLOR
811 color_off(edit, COLOR_MARKER);
812#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000813 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000814#endif /* ENABLE_COLOR */
815
816 }
Robert Siemborskid8510b22000-06-06 23:04:06 +0000817
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000818 target = (COLS - 1) - virt_mark_beginx;
819 if (target < 0)
820 target = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000821
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000822 mvwaddnstr(edit, yval, virt_mark_beginx,
823 &fileptr->data[virt_mark_beginx], target);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000824
Chris Allegretta8ce24132001-04-30 11:28:46 +0000825 if (mark_beginbuf->lineno < current->lineno) {
826
827#ifdef ENABLE_COLOR
828 color_off(edit, COLOR_MARKER);
829#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000830 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000831#endif /* ENABLE_COLOR */
832
833 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000834
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000835 } else if (fileptr == current) {
Chris Allegretta88520c92001-05-05 17:45:54 +0000836 /* We're on the cursor's line, but it's not the first
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000837 * one we marked. Similar to the previous logic. */
838 int this_page_start = get_page_start_virtual(this_page),
839 this_page_end = get_page_end_virtual(this_page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000840
Chris Allegretta8ce24132001-04-30 11:28:46 +0000841 if (mark_beginbuf->lineno < current->lineno) {
842
843#ifdef ENABLE_COLOR
844 color_on(edit, COLOR_MARKER);
845#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000846 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000847#endif /* ENABLE_COLOR */
848
849 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000850
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000851 if (virt_cur_x > COLS - 2) {
852 mvwaddnstr(edit, yval, 0,
853 &fileptr->data[this_page_start],
854 virt_cur_x - this_page_start);
855 } else {
856 mvwaddnstr(edit, yval, 0, fileptr->data, virt_cur_x);
857 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000858
Chris Allegretta8ce24132001-04-30 11:28:46 +0000859 if (mark_beginbuf->lineno > current->lineno) {
860
861#ifdef ENABLE_COLOR
862 color_on(edit, COLOR_MARKER);
863#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000864 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000865#endif /* ENABLE_COLOR */
866
867 } else {
868
869#ifdef ENABLE_COLOR
870 color_off(edit, COLOR_MARKER);
871#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000872 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000873#endif /* ENABLE_COLOR */
874
875 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000876
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000877 if (virt_cur_x > COLS - 2)
878 mvwaddnstr(edit, yval, virt_cur_x - this_page_start,
879 &fileptr->data[virt_cur_x],
880 this_page_end - virt_cur_x);
881 else
882 mvwaddnstr(edit, yval, virt_cur_x,
883 &fileptr->data[virt_cur_x], COLS - virt_cur_x);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000884
Chris Allegretta8ce24132001-04-30 11:28:46 +0000885 if (mark_beginbuf->lineno > current->lineno) {
886
887#ifdef ENABLE_COLOR
888 color_off(edit, COLOR_MARKER);
889#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000890 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000891#endif /* ENABLE_COLOR */
892
893 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000894 }
895
896 } else
897#endif
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000898 /* Just paint the string (no mark on this line) */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000899 mvwaddnstr(edit, yval, 0, &fileptr->data[start],
Chris Allegretta908805a2000-12-04 04:42:56 +0000900 get_page_end_virtual(this_page) - start + 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000901}
902
903/*
Robert Siemborski9d584552000-07-08 00:41:29 +0000904 * Just update one line in the edit buffer. Basically a wrapper for
905 * edit_add
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000906 *
Chris Allegretta88520c92001-05-05 17:45:54 +0000907 * index gives us a place in the string to update starting from.
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000908 * Likely args are current_x or 0.
909 */
910void update_line(filestruct * fileptr, int index)
911{
912 filestruct *filetmp;
Robert Siemborski53875912000-06-16 04:25:30 +0000913 int line = 0, col = 0;
914 int virt_cur_x = current_x, virt_mark_beginx = mark_beginx;
915 char *realdata, *tmp;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000916 int i, pos, len, page;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000917
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000918 if (!fileptr)
919 return;
Robert Siemborski53154a72000-06-18 00:11:03 +0000920
Robert Siemborski53875912000-06-16 04:25:30 +0000921 /* First, blank out the line (at a minimum) */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000922 for (filetmp = edittop; filetmp != fileptr && filetmp != editbot;
923 filetmp = filetmp->next)
924 line++;
925
926 mvwaddstr(edit, line, 0, hblank);
927
Chris Allegretta88520c92001-05-05 17:45:54 +0000928 /* Next, convert all the tabs to spaces, so everything else is easy */
Robert Siemborski53875912000-06-16 04:25:30 +0000929 index = xpt(fileptr, index);
930
931 realdata = fileptr->data;
932 len = strlen(realdata);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000933 fileptr->data = nmalloc(xpt(fileptr, len) + 1);
Robert Siemborski53875912000-06-16 04:25:30 +0000934
935 pos = 0;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000936 for (i = 0; i < len; i++) {
937 if (realdata[i] == '\t') {
Robert Siemborski53875912000-06-16 04:25:30 +0000938 do {
939 fileptr->data[pos++] = ' ';
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000940 if (i < current_x)
941 virt_cur_x++;
942 if (i < mark_beginx)
943 virt_mark_beginx++;
Chris Allegretta6d690a32000-08-03 22:51:21 +0000944 } while (pos % tabsize);
Robert Siemborski53875912000-06-16 04:25:30 +0000945 /* must decrement once to account for tab-is-one-character */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000946 if (i < current_x)
947 virt_cur_x--;
948 if (i < mark_beginx)
949 virt_mark_beginx--;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000950 } else if (realdata[i] >= 1 && realdata[i] <= 26) {
951 /* Treat control characters as ^letter */
Chris Allegretta6306a112000-09-02 07:55:41 +0000952 fileptr->data[pos++] = '^';
953 fileptr->data[pos++] = realdata[i] + 64;
Robert Siemborski53875912000-06-16 04:25:30 +0000954 } else {
955 fileptr->data[pos++] = realdata[i];
956 }
957 }
958
959 fileptr->data[pos] = '\0';
960
961 /* Now, Paint the line */
962 if (current == fileptr && index > COLS - 2) {
Robert Siemborskia9addc72000-06-17 06:06:35 +0000963 /* This handles when the current line is beyond COLS */
Chris Allegretta88520c92001-05-05 17:45:54 +0000964 /* It requires figuring out what page we're on */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000965 page = get_page_from_virtual(index);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000966 col = get_page_start_virtual(page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000967
Robert Siemborskia9addc72000-06-17 06:06:35 +0000968 edit_add(filetmp, line, col, virt_cur_x, virt_mark_beginx, page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000969 mvwaddch(edit, line, 0, '$');
970
Chris Allegrettafb62f732000-12-05 11:36:41 +0000971 if (strlenpt(fileptr->data) > get_page_end_virtual(page) + 1)
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000972 mvwaddch(edit, line, COLS - 1, '$');
Robert Siemborskid8510b22000-06-06 23:04:06 +0000973 } else {
Robert Siemborskia9addc72000-06-17 06:06:35 +0000974 /* It's not the current line means that it's at x=0 and page=1 */
975 /* If it is the current line, then we're in the same boat */
976 edit_add(filetmp, line, 0, virt_cur_x, virt_mark_beginx, 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000977
Robert Siemborski53875912000-06-16 04:25:30 +0000978 if (strlenpt(&filetmp->data[col]) > COLS)
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000979 mvwaddch(edit, line, COLS - 1, '$');
Robert Siemborskid8510b22000-06-06 23:04:06 +0000980 }
Robert Siemborski53875912000-06-16 04:25:30 +0000981
982 /* Clean up our mess */
983 tmp = fileptr->data;
984 fileptr->data = realdata;
985 free(tmp);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000986}
987
988void center_cursor(void)
989{
990 current_y = editwinrows / 2;
991 wmove(edit, current_y, current_x);
992}
993
994/* Refresh the screen without changing the position of lines */
995void edit_refresh(void)
996{
Chris Allegrettaed022162000-08-03 16:54:11 +0000997 static int noloop = 0;
Chris Allegretta95b0b522000-07-28 02:58:06 +0000998 int lines = 0, i = 0, currentcheck = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000999 filestruct *temp, *hold = current;
1000
1001 if (current == NULL)
1002 return;
1003
1004 temp = edittop;
1005
1006 while (lines <= editwinrows - 1 && lines <= totlines && temp != NULL) {
1007 hold = temp;
1008 update_line(temp, current_x);
Chris Allegretta95b0b522000-07-28 02:58:06 +00001009 if (temp == current)
1010 currentcheck = 1;
1011
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001012 temp = temp->next;
1013 lines++;
1014 }
Chris Allegrettaed022162000-08-03 16:54:11 +00001015 /* If noloop == 1, then we already did an edit_update without finishing
1016 this function. So we don't run edit_update again */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001017 if (!currentcheck && !noloop) { /* Then current has run off the screen... */
Chris Allegrettada721be2000-07-31 01:26:42 +00001018 edit_update(current, CENTER);
Chris Allegrettaed022162000-08-03 16:54:11 +00001019 noloop = 1;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001020 } else if (noloop)
Chris Allegrettaed022162000-08-03 16:54:11 +00001021 noloop = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001022
1023 if (lines <= editwinrows - 1)
1024 while (lines <= editwinrows - 1) {
1025 mvwaddstr(edit, lines, i, hblank);
1026 lines++;
1027 }
1028 if (temp == NULL)
1029 editbot = hold;
1030 else
1031 editbot = temp;
1032}
1033
1034/*
Chris Allegretta88520c92001-05-05 17:45:54 +00001035 * Same as above, but touch the window first, so everything is redrawn.
Chris Allegrettaf1d33d32000-08-19 03:53:39 +00001036 */
1037void edit_refresh_clearok(void)
1038{
1039 clearok(edit, TRUE);
1040 edit_refresh();
1041 clearok(edit, FALSE);
1042}
1043
1044/*
Chris Allegretta88520c92001-05-05 17:45:54 +00001045 * Nice generic routine to update the edit buffer, given a pointer to the
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001046 * file struct =)
1047 */
Chris Allegretta234a34d2000-07-29 04:33:38 +00001048void edit_update(filestruct * fileptr, int topmidbot)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001049{
Robert Siemborski29e9a762000-07-05 03:16:04 +00001050 int i = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001051 filestruct *temp;
1052
1053 if (fileptr == NULL)
1054 return;
1055
1056 temp = fileptr;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001057 if (topmidbot == 2);
Chris Allegretta234a34d2000-07-29 04:33:38 +00001058 else if (topmidbot == 0)
1059 for (i = 0; i <= editwinrows - 1 && temp->prev != NULL; i++)
1060 temp = temp->prev;
1061 else
1062 for (i = 0; i <= editwinrows / 2 && temp->prev != NULL; i++)
1063 temp = temp->prev;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001064
Robert Siemborski29e9a762000-07-05 03:16:04 +00001065 edittop = temp;
1066 fix_editbot();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001067
1068 edit_refresh();
1069}
1070
Chris Allegretta88520c92001-05-05 17:45:54 +00001071/* This function updates current, based on where current_y is; reset_cursor
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001072 does the opposite */
1073void update_cursor(void)
1074{
1075 int i = 0;
1076
1077#ifdef DEBUG
1078 fprintf(stderr, _("Moved to (%d, %d) in edit buffer\n"), current_y,
1079 current_x);
1080#endif
1081
1082 current = edittop;
1083 while (i <= current_y - 1 && current->next != NULL) {
1084 current = current->next;
1085 i++;
1086 }
1087
1088#ifdef DEBUG
1089 fprintf(stderr, _("current->data = \"%s\"\n"), current->data);
1090#endif
1091
1092}
1093
1094/*
1095 * Ask a question on the statusbar. Answer will be stored in answer
1096 * global. Returns -1 on aborted enter, -2 on a blank string, and 0
Chris Allegretta88520c92001-05-05 17:45:54 +00001097 * otherwise, the valid shortcut key caught. Def is any editable text we
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001098 * want to put up by default.
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001099 *
1100 * New arg tabs tells whether or not to allow tab completion.
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001101 */
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001102int statusq(int tabs, shortcut s[], int slen, char *def, char *msg, ...)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001103{
1104 va_list ap;
1105 char foo[133];
1106 int ret;
1107
1108 bottombars(s, slen);
1109
1110 va_start(ap, msg);
1111 vsnprintf(foo, 132, msg, ap);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001112 va_end(ap);
Chris Allegrettaa4d21622000-07-08 23:57:03 +00001113 strncat(foo, ": ", 132);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001114
Chris Allegretta8ce24132001-04-30 11:28:46 +00001115#ifdef ENABLE_COLOR
1116 color_on(bottomwin, COLOR_STATUSBAR);
1117#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001118 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001119#endif
1120
1121
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001122 ret = nanogetstr(tabs, foo, def, s, slen, (strlen(foo) + 3));
Chris Allegretta8ce24132001-04-30 11:28:46 +00001123
1124#ifdef ENABLE_COLOR
1125 color_off(bottomwin, COLOR_STATUSBAR);
1126#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001127 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001128#endif
1129
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001130
1131 switch (ret) {
1132
1133 case NANO_FIRSTLINE_KEY:
1134 do_first_line();
1135 break;
1136 case NANO_LASTLINE_KEY:
1137 do_last_line();
1138 break;
1139 case NANO_CANCEL_KEY:
1140 return -1;
1141 default:
Chris Allegretta5b1faac2000-11-16 19:55:30 +00001142 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001143 }
1144
1145#ifdef DEBUG
1146 fprintf(stderr, _("I got \"%s\"\n"), answer);
1147#endif
1148
1149 return ret;
1150}
1151
1152/*
1153 * Ask a simple yes/no question on the statusbar. Returns 1 for Y, 0 for
1154 * N, 2 for All (if all is non-zero when passed in) and -1 for abort (^C)
1155 */
1156int do_yesno(int all, int leavecursor, char *msg, ...)
1157{
1158 va_list ap;
1159 char foo[133];
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001160 int kbinput, ok = -1, i;
1161 char *yesstr; /* String of yes characters accepted */
1162 char *nostr; /* Same for no */
1163 char *allstr; /* And all, surprise! */
1164 char shortstr[5]; /* Temp string for above */
Chris Allegretta84de5522001-04-12 14:51:48 +00001165#ifndef DISABLE_MOUSE
Chris Allegretta235ab192001-04-12 13:24:40 +00001166#ifdef NCURSES_MOUSE_VERSION
1167 MEVENT mevent;
1168#endif
1169#endif
1170
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001171
1172 /* Yes, no and all are strings of any length. Each string consists of
1173 all characters accepted as a valid character for that value.
1174 The first value will be the one displayed in the shortcuts. */
1175 yesstr = _("Yy");
1176 nostr = _("Nn");
1177 allstr = _("Aa");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001178
1179 /* Write the bottom of the screen */
1180 clear_bottomwin();
Chris Allegretta8ce24132001-04-30 11:28:46 +00001181
1182#ifdef ENABLE_COLOR
1183 color_on(bottomwin, COLOR_BOTTOMBARS);
1184#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001185
Jordi Mallach0b0fc492000-06-23 01:00:13 +00001186 /* Remove gettext call for keybindings until we clear the thing up */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001187 if (!ISSET(NO_HELP)) {
1188 wmove(bottomwin, 1, 0);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001189
1190 snprintf(shortstr, 3, " %c", yesstr[0]);
1191 onekey(shortstr, _("Yes"));
1192
1193 if (all) {
1194 snprintf(shortstr, 3, " %c", allstr[0]);
1195 onekey(shortstr, _("All"));
1196 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001197 wmove(bottomwin, 2, 0);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001198
1199 snprintf(shortstr, 3, " %c", nostr[0]);
1200 onekey(shortstr, _("No"));
1201
Jordi Mallach0b0fc492000-06-23 01:00:13 +00001202 onekey("^C", _("Cancel"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001203 }
1204 va_start(ap, msg);
1205 vsnprintf(foo, 132, msg, ap);
1206 va_end(ap);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001207
1208#ifdef ENABLE_COLOR
1209 color_off(bottomwin, COLOR_BOTTOMBARS);
1210 color_on(bottomwin, COLOR_STATUSBAR);
1211#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001212 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001213#endif /* ENABLE_COLOR */
1214
1215 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001216 mvwaddstr(bottomwin, 0, 0, foo);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001217
1218#ifdef ENABLE_COLOR
1219 color_off(bottomwin, COLOR_STATUSBAR);
1220#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001221 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001222#endif
1223
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001224 wrefresh(bottomwin);
1225
1226 if (leavecursor == 1)
1227 reset_cursor();
1228
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001229 while (ok == -1) {
1230 kbinput = wgetch(edit);
1231
1232 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00001233#ifndef DISABLE_MOUSE
Chris Allegretta235ab192001-04-12 13:24:40 +00001234#ifdef NCURSES_MOUSE_VERSION
1235 case KEY_MOUSE:
1236
1237 /* Look ma! We get to duplicate lots of code from do_mouse!! */
1238 if (getmouse(&mevent) == ERR)
1239 break;
1240 if (!wenclose(bottomwin, mevent.y, mevent.x) || ISSET(NO_HELP))
1241 break;
1242 mevent.y -= editwinrows + 3;
1243 if (mevent.y < 0)
1244 break;
1245 else {
1246
1247 /* Rather than a bunch of if statements, set up a matrix
1248 of possible return keystrokes based on the x and y values */
1249 if (all) {
1250 char yesnosquare[2][2] = {
1251 {yesstr[0], allstr[0]},
1252 {nostr[0], NANO_CONTROL_C }};
1253
1254 ungetch(yesnosquare[mevent.y][mevent.x/(COLS/6)]);
1255 } else {
1256 char yesnosquare[2][2] = {
1257 {yesstr[0], '\0'},
1258 {nostr[0], NANO_CONTROL_C }};
1259
1260 ungetch(yesnosquare[mevent.y][mevent.x/(COLS/6)]);
1261 }
1262 }
1263 break;
1264#endif
1265#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001266 case NANO_CONTROL_C:
1267 ok = -2;
1268 break;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001269 default:
1270
Chris Allegretta88520c92001-05-05 17:45:54 +00001271 /* Look for the kbinput in the yes, no and (optimally) all str */
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001272 for (i = 0; yesstr[i] != 0 && yesstr[i] != kbinput; i++)
1273 ;
1274 if (yesstr[i] != 0) {
Chris Allegrettaea620fe2001-02-18 05:39:41 +00001275 ok = 1;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001276 break;
1277 }
1278
1279 for (i = 0; nostr[i] != 0 && nostr[i] != kbinput; i++)
1280 ;
1281 if (nostr[i] != 0) {
1282 ok = 0;
1283 break;
1284 }
1285
1286 if (all) {
1287 for (i = 0; allstr[i] != 0 && allstr[i] != kbinput; i++)
1288 ;
1289 if (allstr[i] != 0) {
1290 ok = 2;
1291 break;
1292 }
1293 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001294 }
1295 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001296
1297 /* Then blank the screen */
1298 blank_statusbar_refresh();
1299
1300 if (ok == -2)
1301 return -1;
1302 else
1303 return ok;
1304}
1305
1306void statusbar(char *msg, ...)
1307{
1308 va_list ap;
1309 char foo[133];
1310 int start_x = 0;
1311
1312 va_start(ap, msg);
1313 vsnprintf(foo, 132, msg, ap);
1314 va_end(ap);
1315
Chris Allegretta17dcb722001-01-20 21:40:07 +00001316 start_x = COLS / 2 - strlen(foo) / 2 - 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001317
1318 /* Blank out line */
1319 blank_statusbar();
1320
1321 wmove(bottomwin, 0, start_x);
1322
Chris Allegretta8ce24132001-04-30 11:28:46 +00001323#ifdef ENABLE_COLOR
1324 color_on(bottomwin, COLOR_STATUSBAR);
1325#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001326 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001327#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001328
1329 waddstr(bottomwin, "[ ");
1330 waddstr(bottomwin, foo);
1331 waddstr(bottomwin, " ]");
Chris Allegretta8ce24132001-04-30 11:28:46 +00001332
1333#ifdef ENABLE_COLOR
1334 color_off(bottomwin, COLOR_STATUSBAR);
1335#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001336 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001337#endif
1338
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001339 wrefresh(bottomwin);
1340
1341 if (ISSET(CONSTUPDATE))
1342 statblank = 1;
1343 else
1344 statblank = 25;
1345}
1346
1347void display_main_list(void)
1348{
1349 bottombars(main_list, MAIN_VISIBLE);
1350}
1351
1352int total_refresh(void)
1353{
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001354 clearok(edit, TRUE);
1355 clearok(topwin, TRUE);
1356 clearok(bottomwin, TRUE);
1357 wnoutrefresh(edit);
1358 wnoutrefresh(topwin);
1359 wnoutrefresh(bottomwin);
1360 doupdate();
1361 clearok(edit, FALSE);
1362 clearok(topwin, FALSE);
1363 clearok(bottomwin, FALSE);
Chris Allegrettaf1d33d32000-08-19 03:53:39 +00001364 edit_refresh();
Chris Allegrettaf4b96012001-01-03 07:11:47 +00001365 titlebar(NULL);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001366 return 1;
1367}
1368
1369void previous_line(void)
1370{
1371 if (current_y > 0)
1372 current_y--;
1373}
1374
1375int do_cursorpos(void)
1376{
1377 filestruct *fileptr;
Chris Allegretta66795ec2000-12-27 04:47:28 +00001378 float linepct = 0.0, bytepct = 0.0;
1379 int i = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001380
1381 if (current == NULL || fileage == NULL)
1382 return 0;
1383
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001384 for (fileptr = fileage; fileptr != current && fileptr != NULL;
1385 fileptr = fileptr->next)
Chris Allegretta66795ec2000-12-27 04:47:28 +00001386 i += strlen(fileptr->data) + 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001387
1388 if (fileptr == NULL)
1389 return -1;
1390
Chris Allegretta66795ec2000-12-27 04:47:28 +00001391 i += current_x;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001392
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001393 if (totlines > 0)
1394 linepct = 100 * current->lineno / totlines;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001395
1396 if (totsize > 0)
1397 bytepct = 100 * i / totsize;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001398
1399#ifdef DEBUG
1400 fprintf(stderr, _("do_cursorpos: linepct = %f, bytepct = %f\n"),
1401 linepct, bytepct);
1402#endif
1403
1404 statusbar(_("line %d of %d (%.0f%%), character %d of %d (%.0f%%)"),
1405 current->lineno, totlines, linepct, i, totsize, bytepct);
1406 reset_cursor();
1407 return 1;
1408}
1409
1410/* Our broken, non-shortcut list compliant help function.
Chris Allegretta88520c92001-05-05 17:45:54 +00001411 But, hey, it's better than nothing, and it's dynamic! */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001412int do_help(void)
1413{
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001414#ifndef DISABLE_HELP
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001415 char *ptr = help_text, *end;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001416 int i, j, row = 0, page = 1, kbinput = 0, no_more = 0, kp, kp2;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001417 int no_help_flag = 0;
1418
1419 blank_edit();
1420 curs_set(0);
1421 blank_statusbar();
1422
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001423 currshortcut = help_list;
1424 currslen = HELP_LIST_LEN;
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001425 kp = keypad_on(edit, 1);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001426 kp2 = keypad_on(bottomwin, 1);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001427
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001428 if (ISSET(NO_HELP)) {
1429
Chris Allegretta88520c92001-05-05 17:45:54 +00001430 /* Well, if we're going to do this, we should at least
Chris Allegretta70444892001-01-07 23:02:02 +00001431 do it the right way */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001432 no_help_flag = 1;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001433 UNSET(NO_HELP);
Chris Allegretta70444892001-01-07 23:02:02 +00001434 window_init();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001435 bottombars(help_list, HELP_LIST_LEN);
Chris Allegretta70444892001-01-07 23:02:02 +00001436
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001437 } else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001438 bottombars(help_list, HELP_LIST_LEN);
1439
1440 do {
1441 ptr = help_text;
1442 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00001443#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001444#ifdef NCURSES_MOUSE_VERSION
1445 case KEY_MOUSE:
1446 do_mouse();
1447 break;
1448#endif
1449#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001450 case NANO_NEXTPAGE_KEY:
1451 case NANO_NEXTPAGE_FKEY:
1452 case KEY_NPAGE:
1453 if (!no_more) {
1454 blank_edit();
1455 page++;
1456 }
1457 break;
1458 case NANO_PREVPAGE_KEY:
1459 case NANO_PREVPAGE_FKEY:
1460 case KEY_PPAGE:
1461 if (page > 1) {
1462 no_more = 0;
1463 blank_edit();
1464 page--;
1465 }
1466 break;
1467 }
1468
Chris Allegretta88520c92001-05-05 17:45:54 +00001469 /* Calculate where in the text we should be, based on the page */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001470 for (i = 1; i < page; i++) {
1471 row = 0;
1472 j = 0;
Chris Allegretta44e73df2000-09-07 03:37:38 +00001473
1474 while (row < editwinrows - 2 && *ptr != '\0') {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001475 if (*ptr == '\n' || j == COLS - 5) {
1476 j = 0;
1477 row++;
1478 }
1479 ptr++;
1480 j++;
1481 }
1482 }
1483
Chris Allegretta44e73df2000-09-07 03:37:38 +00001484 if (i > 1) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001485
Chris Allegretta44e73df2000-09-07 03:37:38 +00001486 }
1487
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001488 i = 0;
1489 j = 0;
1490 while (i < editwinrows && *ptr != '\0') {
1491 end = ptr;
1492 while (*end != '\n' && *end != '\0' && j != COLS - 5) {
1493 end++;
1494 j++;
1495 }
1496 if (j == COLS - 5) {
1497
Chris Allegretta88520c92001-05-05 17:45:54 +00001498 /* Don't print half a word if we've run out of space */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001499 while (*end != ' ' && *end != '\0') {
1500 end--;
1501 j--;
1502 }
1503 }
1504 mvwaddnstr(edit, i, 0, ptr, j);
1505 j = 0;
1506 i++;
1507 if (*end == '\n')
1508 end++;
1509 ptr = end;
1510 }
1511 if (*ptr == '\0') {
1512 no_more = 1;
1513 continue;
1514 }
Chris Allegrettad1627cf2000-12-18 05:03:16 +00001515 } while ((kbinput = wgetch(edit)) != NANO_EXIT_KEY &&
1516 kbinput != NANO_EXIT_FKEY);
1517
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001518 if (no_help_flag) {
Chris Allegretta70444892001-01-07 23:02:02 +00001519 blank_bottombars();
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001520 wrefresh(bottomwin);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001521 SET(NO_HELP);
Chris Allegretta70444892001-01-07 23:02:02 +00001522 window_init();
1523 }
1524 display_main_list();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001525
1526 curs_set(1);
1527 edit_refresh();
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001528 kp = keypad_on(edit, kp);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001529 kp2 = keypad_on(bottomwin, kp2);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001530
Chris Allegretta3bc8c722000-12-10 17:03:25 +00001531#elif defined(DISABLE_HELP)
1532 nano_disabled_msg();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001533#endif
1534
1535 return 1;
1536}
1537
1538/* Dump the current file structure to stderr */
1539void dump_buffer(filestruct * inptr)
1540{
1541#ifdef DEBUG
1542 filestruct *fileptr;
1543
1544 if (inptr == fileage)
1545 fprintf(stderr, _("Dumping file buffer to stderr...\n"));
1546 else if (inptr == cutbuffer)
1547 fprintf(stderr, _("Dumping cutbuffer to stderr...\n"));
1548 else
1549 fprintf(stderr, _("Dumping a buffer to stderr...\n"));
1550
1551 fileptr = inptr;
1552 while (fileptr != NULL) {
1553 fprintf(stderr, "(%ld) %s\n", fileptr->lineno, fileptr->data);
1554 fflush(stderr);
1555 fileptr = fileptr->next;
1556 }
1557#endif /* DEBUG */
1558}
1559
1560void dump_buffer_reverse(filestruct * inptr)
1561{
1562#ifdef DEBUG
1563 filestruct *fileptr;
1564
1565 fileptr = filebot;
1566 while (fileptr != NULL) {
1567 fprintf(stderr, "(%ld) %s\n", fileptr->lineno, fileptr->data);
1568 fflush(stderr);
1569 fileptr = fileptr->prev;
1570 }
1571#endif /* DEBUG */
1572}
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001573
Chris Allegretta88520c92001-05-05 17:45:54 +00001574/* Fix editbot, based on the assumption that edittop is correct */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001575void fix_editbot(void)
1576{
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001577 int i;
1578 editbot = edittop;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001579 for (i = 0; (i <= editwinrows - 1) && (editbot->next != NULL)
1580 && (editbot != filebot); i++, editbot = editbot->next);
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001581}
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001582
Chris Allegrettafb62f732000-12-05 11:36:41 +00001583/* highlight the current word being replaced or spell checked */
1584void do_replace_highlight(int highlight_flag, char *word)
1585{
1586 char *highlight_word = NULL;
1587 int x, y;
1588
1589 highlight_word = mallocstrcpy(highlight_word, &current->data[current_x]);
1590 highlight_word[strlen(word)] = '\0';
1591
Chris Allegretta88520c92001-05-05 17:45:54 +00001592 /* adjust output when word extends beyond screen */
Chris Allegrettafb62f732000-12-05 11:36:41 +00001593
1594 x = xplustabs();
1595 y = get_page_end_virtual(get_page_from_virtual(x)) + 1;
1596
1597 if ((COLS - (y - x) + strlen(word)) > COLS) {
1598 highlight_word[y - x - 1] = '$';
1599 highlight_word[y - x] = '\0';
1600 }
1601
1602 /* OK display the output */
1603
1604 reset_cursor();
1605
1606 if (highlight_flag)
1607 wattron(edit, A_REVERSE);
1608
1609 waddstr(edit, highlight_word);
1610
1611 if (highlight_flag)
1612 wattroff(edit, A_REVERSE);
1613
1614 free(highlight_word);
1615}
1616
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001617#ifdef NANO_EXTRA
Chris Allegretta2bfbda02001-03-23 03:50:44 +00001618#define CREDIT_LEN 47
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001619void do_credits(void)
1620{
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001621 int i, j = 0, k, place = 0, start_x;
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001622 char *what;
1623
1624 char *nanotext = _("The nano text editor");
1625 char *version = _("version ");
1626 char *brought = _("Brought to you by:");
1627 char *specialthx = _("Special thanks to:");
1628 char *fsf = _("The Free Software Foundation");
1629 char *ncurses = _("Pavel Curtis, Zeyd Ben-Halim and Eric S. Raymond for ncurses");
1630 char *anyonelse = _("and anyone else we forgot...");
1631 char *thankyou = _("Thank you for using nano!\n");
1632
1633 char *credits[CREDIT_LEN] = {nanotext,
1634 version,
1635 VERSION,
1636 "",
1637 brought,
1638 "Chris Allegretta",
1639 "Jordi Mallach",
1640 "Adam Rogoyski",
1641 "Rob Siemborski",
1642 "Rocco Corsi",
1643 "Ken Tyler",
1644 "Sven Guckes",
1645 "Florian König",
1646 "Pauli Virtanen",
1647 "Daniele Medri",
1648 "Clement Laforet",
1649 "Tedi Heriyanto",
Chris Allegrettaa131c7c2000-11-25 19:59:41 +00001650 "Bill Soudan",
Chris Allegretta7cd9f742000-11-25 20:17:28 +00001651 "Christian Weisgerber",
Chris Allegretta827b15f2001-01-03 02:09:04 +00001652 "Erik Andersen",
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001653 "Big Gaute",
1654 "Joshua Jensen",
Chris Allegretta0d471de2001-03-15 14:40:42 +00001655 "Ryan Krebs",
Chris Allegretta7ab3e8f2001-03-22 23:12:22 +00001656 "Albert Chin",
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001657 "",
1658 specialthx,
1659 "Plattsburgh State University",
1660 "Benet Laboratories",
1661 "Amy Allegretta",
1662 "Linda Young",
1663 "Jeremy Robichaud",
1664 "Richard Kolb II",
1665 fsf,
1666 "Linus Torvalds",
1667 ncurses,
1668 anyonelse,
1669 thankyou,
1670 "", "", "", "",
1671 "(c) 2000 Chris Allegretta",
1672 "", "", "", "",
1673 "www.nano-editor.org"
1674 };
1675
1676 curs_set(0);
1677 nodelay(edit, TRUE);
1678 blank_bottombars();
1679 mvwaddstr(topwin, 0, 0, hblank);
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001680 blank_edit();
1681 wrefresh(edit);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001682 wrefresh(bottomwin);
1683 wrefresh(topwin);
1684
1685 while (wgetch(edit) == ERR) {
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001686 for (k = 0; k <= 1; k++) {
1687 blank_edit();
1688 for (i = editwinrows / 2 - 1; i >= (editwinrows / 2 - 1 - j); i--) {
1689 mvwaddstr(edit, i * 2 - k, 0, hblank);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001690
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001691 if (place - (editwinrows / 2 - 1 - i) < CREDIT_LEN)
1692 what = credits[place - (editwinrows / 2 - 1 - i)];
1693 else
1694 what = "";
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001695
Chris Allegretta17dcb722001-01-20 21:40:07 +00001696 start_x = COLS / 2 - strlen(what) / 2 - 1;
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001697 mvwaddstr(edit, i * 2 - k, start_x, what);
1698 }
1699 usleep(700000);
1700 wrefresh(edit);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001701 }
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001702 if (j < editwinrows / 2 - 1)
1703 j++;
1704
1705 place++;
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001706
1707 if (place >= CREDIT_LEN + editwinrows / 2)
1708 break;
1709 }
1710
1711 nodelay(edit, FALSE);
1712 curs_set(1);
1713 display_main_list();
1714 total_refresh();
1715 }
1716#endif
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001717
Chris Allegrettae3167732001-03-18 16:59:34 +00001718int keypad_on(WINDOW * win, int newval)
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001719{
1720
Chris Allegretta88520c92001-05-05 17:45:54 +00001721/* This is taken right from aumix. Don't sue me. */
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001722#ifdef HAVE_USEKEYPAD
1723 int old;
1724
1725 old = win->_use_keypad;
Chris Allegrettae3167732001-03-18 16:59:34 +00001726 keypad(win, newval);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001727 return old;
1728#else
Chris Allegrettae3167732001-03-18 16:59:34 +00001729 keypad(win, newval);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001730 return 1;
1731#endif /* HAVE_USEKEYPAD */
1732
1733}
1734
1735
1736