blob: 043a72d39b0aaf3da3c5d2096408c1dab5c0af2e [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
Chris Allegretta88b09152001-05-17 11:35:43 +0000268 inputbuf = charalloc(strlen(def) + 1);
Chris Allegretta31925e42000-11-02 04:40:39 +0000269 inputbuf[0] = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000270
271 x_left = strlen(buf);
272 x = strlen(def) + x_left;
273
Chris Allegretta6fe61492001-05-21 12:56:25 +0000274#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000275 currshortcut = s;
276 currslen = slen;
Chris Allegretta6fe61492001-05-21 12:56:25 +0000277#endif
278
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000279 /* Get the input! */
Chris Allegretta31925e42000-11-02 04:40:39 +0000280 if (strlen(def) > 0)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000281 strcpy(inputbuf, def);
Chris Allegretta31925e42000-11-02 04:40:39 +0000282
283 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000284
Chris Allegretta022b96f2000-11-14 17:47:58 +0000285 /* Make sure any editor screen updates are displayed before getting input */
286 wrefresh(edit);
287
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000288 while ((kbinput = wgetch(bottomwin)) != 13) {
289 for (j = 0; j <= slen - 1; j++) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000290#ifdef DEBUG
291 fprintf(stderr, _("Aha! \'%c\' (%d)\n"), kbinput, kbinput);
292#endif
293
Chris Allegretta658399a2001-06-14 02:54:22 +0000294 if (kbinput == s[j].val && kbinput < 32) {
Chris Allegretta5bf51d32000-11-16 06:01:10 +0000295
296 /* We shouldn't discard the answer it gave, just because
297 we hit a keystroke, GEEZ! */
298 answer = mallocstrcpy(answer, inputbuf);
Chris Allegretta92d2bab2000-11-02 14:53:46 +0000299 free(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000300 return s[j].val;
301 }
302 }
303 xend = strlen(buf) + strlen(inputbuf);
304
Chris Allegretta04d848e2000-11-05 17:54:41 +0000305 if (kbinput != '\t')
306 tabbed = 0;
307
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000308 switch (kbinput) {
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000309
310 /* Stuff we want to equate with <enter>, ASCII 13 */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000311 case 343:
Chris Allegrettaf9b6c9b2000-10-18 19:35:59 +0000312 ungetch(13); /* Enter on iris-ansi $TERM, sometimes */
313 break;
Chris Allegretta75155df2000-11-28 23:04:24 +0000314 /* Stuff we want to ignore */
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000315#ifdef PDCURSES
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000316 case 541:
317 case 542:
Chris Allegretta72623582000-11-29 23:43:28 +0000318 case 543: /* Right ctrl again */
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000319 case 544:
Chris Allegretta72623582000-11-29 23:43:28 +0000320 case 545: /* Right alt again */
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000321 break;
Chris Allegretta5b1faac2000-11-16 19:55:30 +0000322#endif
Chris Allegretta84de5522001-04-12 14:51:48 +0000323#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +0000324#ifdef NCURSES_MOUSE_VERSION
325 case KEY_MOUSE:
326 do_mouse();
327 break;
328#endif
329#endif
Chris Allegretta658399a2001-06-14 02:54:22 +0000330 case NANO_HOME_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000331 case KEY_HOME:
332 x = x_left;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000333 break;
Chris Allegretta658399a2001-06-14 02:54:22 +0000334 case NANO_END_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000335 case KEY_END:
336 x = x_left + strlen(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000337 break;
338 case KEY_RIGHT:
Chris Allegretta35dac582001-03-21 15:07:20 +0000339 case NANO_FORWARD_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000340
341 if (x < xend)
342 x++;
343 wmove(bottomwin, 0, x);
344 break;
345 case NANO_CONTROL_D:
346 if (strlen(inputbuf) > 0 && (x - x_left) != strlen(inputbuf)) {
347 memmove(inputbuf + (x - x_left),
348 inputbuf + (x - x_left) + 1,
349 strlen(inputbuf) - (x - x_left) - 1);
350 inputbuf[strlen(inputbuf) - 1] = 0;
351 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000352 break;
353 case NANO_CONTROL_K:
354 case NANO_CONTROL_U:
355 *inputbuf = 0;
356 x = x_left;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000357 break;
358 case KEY_BACKSPACE:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000359 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 Allegretta04d848e2000-11-05 17:54:41 +0000373 break;
Rocco Corsi06aca1c2001-01-11 05:30:31 +0000374#ifndef DISABLE_TABCOMP
Chris Allegretta04d848e2000-11-05 17:54:41 +0000375 case NANO_CONTROL_I:
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000376 if (allowtabs) {
Chris Allegretta442f2c52000-11-14 17:46:06 +0000377 shift = 0;
378 inputbuf = input_tab(inputbuf, (x - x_left),
Chris Allegrettab5b89ae2000-11-14 18:25:26 +0000379 &tabbed, &shift);
Chris Allegretta442f2c52000-11-14 17:46:06 +0000380 x += shift;
Chris Allegrettae434b452001-01-27 19:25:00 +0000381 if (x - x_left > strlen(inputbuf))
382 x = strlen(inputbuf) + x_left;
Chris Allegretta7da4e9f2000-11-06 02:57:22 +0000383 }
Chris Allegretta04d848e2000-11-05 17:54:41 +0000384 break;
Chris Allegrettabe77c612000-11-24 14:00:16 +0000385#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000386 case KEY_LEFT:
Chris Allegretta35dac582001-03-21 15:07:20 +0000387 case NANO_BACK_KEY:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000388 if (x > strlen(buf))
389 x--;
390 wmove(bottomwin, 0, x);
391 break;
392 case KEY_UP:
393 case KEY_DOWN:
394 break;
395
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000396 case KEY_DC:
397 goto do_deletekey;
398
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000399 case 27:
400 switch (kbinput = wgetch(edit)) {
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000401 case 'O':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000402 switch (kbinput = wgetch(edit)) {
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000403 case 'F':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000404 x = x_left + strlen(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000405 break;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000406 case 'H':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000407 x = x_left;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000408 break;
409 }
410 break;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000411 case '[':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000412 switch (kbinput = wgetch(edit)) {
413 case 'C':
414 if (x < xend)
415 x++;
416 wmove(bottomwin, 0, x);
417 break;
418 case 'D':
419 if (x > strlen(buf))
420 x--;
421 wmove(bottomwin, 0, x);
422 break;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000423 case '1':
424 case '7':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000425 x = x_left;
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000426 goto skip_tilde;
427 case '3':
428 do_deletekey:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000429 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 Allegrettace78c1e2001-09-23 01:18:03 +0000436 goto skip_tilde;
437 case '4':
438 case '8':
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000439 x = x_left + strlen(inputbuf);
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000440 goto skip_tilde;
441 skip_tilde:
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000442 nodelay(edit, TRUE);
443 kbinput = wgetch(edit);
Chris Allegrettace78c1e2001-09-23 01:18:03 +0000444 if (kbinput == '~' || kbinput == ERR)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000445 kbinput = -1;
446 nodelay(edit, FALSE);
447 break;
448 }
Chris Allegretta658399a2001-06-14 02:54:22 +0000449 default:
450
451 for (j = 0; j <= slen - 1; j++) {
452#ifdef DEBUG
453 fprintf(stderr, _("Aha! \'%c\' (%d)\n"), kbinput, kbinput);
454#endif
455 if (kbinput == s[j].val || kbinput == s[j].val - 32) {
456
457 /* We hit an Alt key. Do like above. We don't
458 just ungetch the letter and let it get caught
459 above cause that screws the keypad... */
460 answer = mallocstrcpy(answer, inputbuf);
461 free(inputbuf);
462 return s[j].val;
463 }
464 }
465
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000466 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000467 break;
468
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000469 default:
Chris Allegretta658399a2001-06-14 02:54:22 +0000470
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000471 if (kbinput < 32)
472 break;
Chris Allegretta31925e42000-11-02 04:40:39 +0000473
474 inputlen = strlen(inputbuf);
475 inputbuf = nrealloc(inputbuf, inputlen + 2);
476
477 memmove(&inputbuf[x - x_left + 1],
478 &inputbuf[x - x_left],
479 inputlen - (x - x_left) + 1);
480 inputbuf[x - x_left] = kbinput;
481
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000482 x++;
483
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000484#ifdef DEBUG
485 fprintf(stderr, _("input \'%c\' (%d)\n"), kbinput, kbinput);
486#endif
487 }
Chris Allegretta386e0512001-10-02 02:57:26 +0000488 nanoget_repaint(buf, inputbuf, x);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000489 wrefresh(bottomwin);
490 }
491
Chris Allegretta31925e42000-11-02 04:40:39 +0000492 answer = mallocstrcpy(answer, inputbuf);
Chris Allegretta92d2bab2000-11-02 14:53:46 +0000493 free(inputbuf);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000494
Chris Allegrettac1049ac2001-08-17 00:03:46 +0000495 /* In pico mode, just check for a blank answer here */
496 if (((ISSET(PICO_MODE)) && !strcmp(answer, "")))
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000497 return -2;
498 else
499 return 0;
500}
501
502void horizbar(WINDOW * win, int y)
503{
504 wattron(win, A_REVERSE);
505 mvwaddstr(win, 0, 0, hblank);
506 wattroff(win, A_REVERSE);
507}
508
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000509void titlebar(char *path)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000510{
511 int namelen, space;
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000512 char *what = path;
513
514 if (path == NULL)
515 what = filename;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000516
Chris Allegretta8ce24132001-04-30 11:28:46 +0000517#ifdef ENABLE_COLOR
518 color_on(topwin, COLOR_TITLEBAR);
519 mvwaddstr(topwin, 0, 0, hblank);
520#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000521 horizbar(topwin, 0);
522 wattron(topwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000523#endif
524
525
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000526 mvwaddstr(topwin, 0, 3, VERMSG);
527
528 space = COLS - strlen(VERMSG) - strlen(VERSION) - 21;
529
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000530 namelen = strlen(what);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000531
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000532 if (!strcmp(what, ""))
Chris Allegretta17dcb722001-01-20 21:40:07 +0000533 mvwaddstr(topwin, 0, COLS / 2 - 6, _("New Buffer"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000534 else {
535 if (namelen > space) {
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000536 if (path == NULL)
537 waddstr(topwin, _(" File: ..."));
538 else
539 waddstr(topwin, _(" DIR: ..."));
540 waddstr(topwin, &what[namelen - space]);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000541 } else {
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000542 if (path == NULL)
Chris Allegretta17dcb722001-01-20 21:40:07 +0000543 mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1), "File: ");
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000544 else
Chris Allegretta17dcb722001-01-20 21:40:07 +0000545 mvwaddstr(topwin, 0, COLS / 2 - (namelen / 2 + 1), " DIR: ");
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000546 waddstr(topwin, what);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000547 }
548 }
549 if (ISSET(MODIFIED))
550 mvwaddstr(topwin, 0, COLS - 10, _("Modified"));
Chris Allegretta8ce24132001-04-30 11:28:46 +0000551
552
553#ifdef ENABLE_COLOR
554 color_off(topwin, COLOR_TITLEBAR);
555#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000556 wattroff(topwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000557#endif
558
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000559 wrefresh(topwin);
560 reset_cursor();
561}
562
563void onekey(char *keystroke, char *desc)
564{
565 char description[80];
566
Chris Allegretta658399a2001-06-14 02:54:22 +0000567 snprintf(description, 12 - (strlen(keystroke) - 2), " %-10s", desc);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000568 wattron(bottomwin, A_REVERSE);
569 waddstr(bottomwin, keystroke);
570 wattroff(bottomwin, A_REVERSE);
571 waddstr(bottomwin, description);
572}
573
574void clear_bottomwin(void)
575{
576 if (ISSET(NO_HELP))
577 return;
578
579 mvwaddstr(bottomwin, 1, 0, hblank);
580 mvwaddstr(bottomwin, 2, 0, hblank);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000581}
582
583void bottombars(shortcut s[], int slen)
584{
585 int i, j, k;
586 char keystr[10];
587
588 if (ISSET(NO_HELP))
589 return;
590
Chris Allegretta8ce24132001-04-30 11:28:46 +0000591#ifdef ENABLE_COLOR
592 color_on(bottomwin, COLOR_BOTTOMBARS);
593#endif
594
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000595 /* Determine how many extra spaces are needed to fill the bottom of the screen */
Chris Allegretta96eef732001-08-25 16:41:37 +0000596 if (slen < 2)
597 k = COLS / 6 - 13;
598 else
Chris Allegretta7dd18692001-08-26 23:16:44 +0000599 k = COLS / ((slen + (slen %2)) / 2) - 13;
Chris Allegretta96eef732001-08-25 16:41:37 +0000600
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000601
602 clear_bottomwin();
603 wmove(bottomwin, 1, 0);
Chris Allegretta658399a2001-06-14 02:54:22 +0000604
Chris Allegretta5f36c372001-07-16 00:48:53 +0000605 for (i = 0; i <= slen - 1; i += 2) {
Chris Allegretta658399a2001-06-14 02:54:22 +0000606
607 if (s[i].val < 97)
608 snprintf(keystr, 10, "^%c", s[i].val + 64);
609 else
610 snprintf(keystr, 10, "M-%c", s[i].val - 32);
611
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000612 onekey(keystr, s[i].desc);
613
614 for (j = 0; j < k; j++)
615 waddch(bottomwin, ' ');
616 }
617
618 wmove(bottomwin, 2, 0);
619 for (i = 1; i <= slen - 1; i += 2) {
Chris Allegretta658399a2001-06-14 02:54:22 +0000620
621 if (s[i].val < 97)
622 snprintf(keystr, 10, "^%c", s[i].val + 64);
623 else
624 snprintf(keystr, 10, "M-%c", s[i].val - 32);
625
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000626 onekey(keystr, s[i].desc);
627
628 for (j = 0; j < k; j++)
629 waddch(bottomwin, ' ');
630 }
631
Chris Allegretta8ce24132001-04-30 11:28:46 +0000632#ifdef ENABLE_COLOR
633 color_off(bottomwin, COLOR_BOTTOMBARS);
634#endif
635
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000636 wrefresh(bottomwin);
637
638}
639
640/* If modified is not already set, set it and update titlebar */
641void set_modified(void)
642{
643 if (!ISSET(MODIFIED)) {
644 SET(MODIFIED);
Chris Allegrettaf4b96012001-01-03 07:11:47 +0000645 titlebar(NULL);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000646 wrefresh(topwin);
647 }
648}
649
Robert Siemborski9d584552000-07-08 00:41:29 +0000650/* And so start the display update routines */
651/* Given a column, this returns the "page" it is on */
652/* "page" in the case of the display columns, means which set of 80 */
Chris Allegretta88520c92001-05-05 17:45:54 +0000653/* characters is viewable (e.g.: page 1 shows from 1 to COLS) */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000654inline int get_page_from_virtual(int virtual)
655{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000656 int page = 2;
657
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000658 if (virtual <= COLS - 2)
659 return 1;
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000660 virtual -= (COLS - 2);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000661
662 while (virtual > COLS - 2 - 7) {
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000663 virtual -= (COLS - 2 - 7);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000664 page++;
665 }
666
667 return page;
668}
669
Robert Siemborski9d584552000-07-08 00:41:29 +0000670/* The inverse of the above function */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000671inline int get_page_start_virtual(int page)
672{
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000673 int virtual;
674 virtual = --page * (COLS - 7);
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000675 if (page)
676 virtual -= 2 * page - 1;
Robert Siemborskie8c6fd02000-06-07 04:40:09 +0000677 return virtual;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000678}
679
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000680inline int get_page_end_virtual(int page)
681{
Robert Siemborskid8510b22000-06-06 23:04:06 +0000682 return get_page_start_virtual(page) + COLS - 1;
683}
684
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000685#ifndef NANO_SMALL
Robert Siemborski9d584552000-07-08 00:41:29 +0000686/* This takes care of the case where there is a mark that covers only */
687/* the current line. */
688
Chris Allegretta88520c92001-05-05 17:45:54 +0000689/* It expects a line with no tab characters (i.e.: the type that edit_add */
Robert Siemborski9d584552000-07-08 00:41:29 +0000690/* deals with */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000691void add_marked_sameline(int begin, int end, filestruct * fileptr, int y,
692 int virt_cur_x, int this_page)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000693{
Robert Siemborski9d584552000-07-08 00:41:29 +0000694 /*
695 * The general idea is to break the line up into 3 sections: before
696 * the mark, the mark, and after the mark. We then paint each in
Chris Allegretta88520c92001-05-05 17:45:54 +0000697 * turn (for those that are currently visible, of course)
Robert Siemborski9d584552000-07-08 00:41:29 +0000698 *
699 * 3 start points: 0 -> begin, begin->end, end->strlen(data)
700 * in data : pre sel post
701 */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000702 int this_page_start = get_page_start_virtual(this_page),
Robert Siemborski53875912000-06-16 04:25:30 +0000703 this_page_end = get_page_end_virtual(this_page);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000704
Robert Siemborskid8510b22000-06-06 23:04:06 +0000705 /* likewise, 3 data lengths */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000706 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 +0000707
708 /* now fix the start locations & lengths according to the cursor's
Chris Allegretta88520c92001-05-05 17:45:54 +0000709 * position (i.e.: our page) */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000710 if (pre_data_len < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000711 pre_data_len = 0;
712 else
713 pre_data_len -= this_page_start;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000714
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000715 if (begin < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000716 begin = this_page_start;
717
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000718 if (end < this_page_start)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000719 end = this_page_start;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000720
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000721 if (begin > this_page_end)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000722 begin = this_page_end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000723
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000724 if (end > this_page_end)
Robert Siemborskia9addc72000-06-17 06:06:35 +0000725 end = this_page_end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000726
Robert Siemborski9d584552000-07-08 00:41:29 +0000727 /* Now calculate the lengths */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000728 sel_data_len = end - begin;
729 post_data_len = this_page_end - end;
Robert Siemborskid8510b22000-06-06 23:04:06 +0000730
Robert Siemborski9d584552000-07-08 00:41:29 +0000731 /* Paint this line! */
Robert Siemborski53875912000-06-16 04:25:30 +0000732 mvwaddnstr(edit, y, 0, &fileptr->data[this_page_start], pre_data_len);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000733
734#ifdef ENABLE_COLOR
735 color_on(edit, COLOR_MARKER);
736#else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000737 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000738#endif /* ENABLE_COLOR */
739
Robert Siemborskia9addc72000-06-17 06:06:35 +0000740 mvwaddnstr(edit, y, begin - this_page_start,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000741 &fileptr->data[begin], sel_data_len);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000742
743#ifdef ENABLE_COLOR
744 color_off(edit, COLOR_MARKER);
745#else
Robert Siemborskid8510b22000-06-06 23:04:06 +0000746 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000747#endif /* ENABLE_COLOR */
748
Robert Siemborskia9addc72000-06-17 06:06:35 +0000749 mvwaddnstr(edit, y, end - this_page_start,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000750 &fileptr->data[end], post_data_len);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000751}
752#endif
753
Robert Siemborski9d584552000-07-08 00:41:29 +0000754/* edit_add takes care of the job of actually painting a line into the
755 * edit window.
756 *
757 * Called only from update_line. Expects a converted-to-not-have-tabs
Robert Siemborski53875912000-06-16 04:25:30 +0000758 * line */
759void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000760 int virt_mark_beginx, int this_page)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000761{
762#ifndef NANO_SMALL
Chris Allegretta88520c92001-05-05 17:45:54 +0000763 /* There are quite a few cases that could take place; we'll deal
Robert Siemborski9d584552000-07-08 00:41:29 +0000764 * with them each in turn */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000765 if (ISSET(MARK_ISSET)
Robert Siemborski9d584552000-07-08 00:41:29 +0000766 && !((fileptr->lineno > mark_beginbuf->lineno
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000767 && fileptr->lineno > current->lineno)
768 || (fileptr->lineno < mark_beginbuf->lineno
769 && fileptr->lineno < current->lineno))) {
Chris Allegretta88520c92001-05-05 17:45:54 +0000770 /* If we get here we are on a line that is at least
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000771 * partially selected. The lineno checks above determined
772 * that */
773 if (fileptr != mark_beginbuf && fileptr != current) {
774 /* We are on a completely marked line, paint it all
775 * inverse */
Chris Allegretta8ce24132001-04-30 11:28:46 +0000776#ifdef ENABLE_COLOR
777 color_on(edit, COLOR_MARKER);
778#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000779 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000780#endif /* ENABLE_COLOR */
781
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000782 mvwaddnstr(edit, yval, 0, fileptr->data, COLS);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000783
784#ifdef ENABLE_COLOR
785 color_off(edit, COLOR_MARKER);
786#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000787 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000788#endif /* ENABLE_COLOR */
789
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000790 } else if (fileptr == mark_beginbuf && fileptr == current) {
791 /* Special case, we're still on the same line we started
792 * marking -- so we call our helper function */
793 if (virt_cur_x < virt_mark_beginx) {
794 /* To the right of us is marked */
795 add_marked_sameline(virt_cur_x, virt_mark_beginx,
796 fileptr, yval, virt_cur_x, this_page);
797 } else {
798 /* To the left of us is marked */
799 add_marked_sameline(virt_mark_beginx, virt_cur_x,
800 fileptr, yval, virt_cur_x, this_page);
801 }
802 } else if (fileptr == mark_beginbuf) {
803 /*
Chris Allegretta88520c92001-05-05 17:45:54 +0000804 * We're updating the line that was first marked,
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000805 * but we're not currently on it. So we want to
Robert Siemborskia0238ed2001-03-31 21:46:43 +0000806 * figure out which half to invert based on our
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000807 * relative line numbers.
808 *
Chris Allegretta88520c92001-05-05 17:45:54 +0000809 * I.e. if we're above the "beginbuf" line, we want to
810 * mark the left side. Otherwise, we're below, so we
811 * mark the right.
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000812 */
813 int target;
814
Chris Allegretta8ce24132001-04-30 11:28:46 +0000815 if (mark_beginbuf->lineno > current->lineno) {
816#ifdef ENABLE_COLOR
817 color_on(edit, COLOR_MARKER);
818#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000819 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000820#endif /* ENABLE_COLOR */
821 }
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000822
823 target =
824 (virt_mark_beginx <
825 COLS - 1) ? virt_mark_beginx : COLS - 1;
826
827 mvwaddnstr(edit, yval, 0, fileptr->data, target);
828
Chris Allegretta8ce24132001-04-30 11:28:46 +0000829 if (mark_beginbuf->lineno < current->lineno) {
830
831#ifdef ENABLE_COLOR
832 color_on(edit, COLOR_MARKER);
833#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000834 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000835#endif /* ENABLE_COLOR */
836
837 } else {
838
839#ifdef ENABLE_COLOR
840 color_off(edit, COLOR_MARKER);
841#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000842 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000843#endif /* ENABLE_COLOR */
844
845 }
Robert Siemborskid8510b22000-06-06 23:04:06 +0000846
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000847 target = (COLS - 1) - virt_mark_beginx;
848 if (target < 0)
849 target = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000850
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000851 mvwaddnstr(edit, yval, virt_mark_beginx,
852 &fileptr->data[virt_mark_beginx], target);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000853
Chris Allegretta8ce24132001-04-30 11:28:46 +0000854 if (mark_beginbuf->lineno < current->lineno) {
855
856#ifdef ENABLE_COLOR
857 color_off(edit, COLOR_MARKER);
858#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000859 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000860#endif /* ENABLE_COLOR */
861
862 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000863
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000864 } else if (fileptr == current) {
Chris Allegretta88520c92001-05-05 17:45:54 +0000865 /* We're on the cursor's line, but it's not the first
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000866 * one we marked. Similar to the previous logic. */
867 int this_page_start = get_page_start_virtual(this_page),
868 this_page_end = get_page_end_virtual(this_page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000869
Chris Allegretta8ce24132001-04-30 11:28:46 +0000870 if (mark_beginbuf->lineno < current->lineno) {
871
872#ifdef ENABLE_COLOR
873 color_on(edit, COLOR_MARKER);
874#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000875 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000876#endif /* ENABLE_COLOR */
877
878 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000879
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000880 if (virt_cur_x > COLS - 2) {
881 mvwaddnstr(edit, yval, 0,
882 &fileptr->data[this_page_start],
883 virt_cur_x - this_page_start);
884 } else {
885 mvwaddnstr(edit, yval, 0, fileptr->data, virt_cur_x);
886 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000887
Chris Allegretta8ce24132001-04-30 11:28:46 +0000888 if (mark_beginbuf->lineno > current->lineno) {
889
890#ifdef ENABLE_COLOR
891 color_on(edit, COLOR_MARKER);
892#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000893 wattron(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000894#endif /* ENABLE_COLOR */
895
896 } else {
897
898#ifdef ENABLE_COLOR
899 color_off(edit, COLOR_MARKER);
900#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000901 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000902#endif /* ENABLE_COLOR */
903
904 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000905
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000906 if (virt_cur_x > COLS - 2)
907 mvwaddnstr(edit, yval, virt_cur_x - this_page_start,
908 &fileptr->data[virt_cur_x],
909 this_page_end - virt_cur_x);
910 else
911 mvwaddnstr(edit, yval, virt_cur_x,
912 &fileptr->data[virt_cur_x], COLS - virt_cur_x);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000913
Chris Allegretta8ce24132001-04-30 11:28:46 +0000914 if (mark_beginbuf->lineno > current->lineno) {
915
916#ifdef ENABLE_COLOR
917 color_off(edit, COLOR_MARKER);
918#else
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000919 wattroff(edit, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +0000920#endif /* ENABLE_COLOR */
921
922 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000923 }
924
925 } else
926#endif
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000927 /* Just paint the string (no mark on this line) */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000928 mvwaddnstr(edit, yval, 0, &fileptr->data[start],
Chris Allegretta908805a2000-12-04 04:42:56 +0000929 get_page_end_virtual(this_page) - start + 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000930}
931
932/*
Robert Siemborski9d584552000-07-08 00:41:29 +0000933 * Just update one line in the edit buffer. Basically a wrapper for
934 * edit_add
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000935 *
Chris Allegretta88520c92001-05-05 17:45:54 +0000936 * index gives us a place in the string to update starting from.
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000937 * Likely args are current_x or 0.
938 */
939void update_line(filestruct * fileptr, int index)
940{
941 filestruct *filetmp;
Robert Siemborski53875912000-06-16 04:25:30 +0000942 int line = 0, col = 0;
943 int virt_cur_x = current_x, virt_mark_beginx = mark_beginx;
944 char *realdata, *tmp;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000945 int i, pos, len, page;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000946
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000947 if (!fileptr)
948 return;
Robert Siemborski53154a72000-06-18 00:11:03 +0000949
Robert Siemborski53875912000-06-16 04:25:30 +0000950 /* First, blank out the line (at a minimum) */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000951 for (filetmp = edittop; filetmp != fileptr && filetmp != editbot;
952 filetmp = filetmp->next)
953 line++;
954
955 mvwaddstr(edit, line, 0, hblank);
956
Chris Allegretta88520c92001-05-05 17:45:54 +0000957 /* Next, convert all the tabs to spaces, so everything else is easy */
Robert Siemborski53875912000-06-16 04:25:30 +0000958 index = xpt(fileptr, index);
959
960 realdata = fileptr->data;
961 len = strlen(realdata);
Chris Allegretta88b09152001-05-17 11:35:43 +0000962 fileptr->data = charalloc(xpt(fileptr, len) + 1);
Robert Siemborski53875912000-06-16 04:25:30 +0000963
964 pos = 0;
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000965 for (i = 0; i < len; i++) {
966 if (realdata[i] == '\t') {
Robert Siemborski53875912000-06-16 04:25:30 +0000967 do {
968 fileptr->data[pos++] = ' ';
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000969 if (i < current_x)
970 virt_cur_x++;
971 if (i < mark_beginx)
972 virt_mark_beginx++;
Chris Allegretta6d690a32000-08-03 22:51:21 +0000973 } while (pos % tabsize);
Robert Siemborski53875912000-06-16 04:25:30 +0000974 /* must decrement once to account for tab-is-one-character */
Chris Allegretta4da1fc62000-06-21 03:00:43 +0000975 if (i < current_x)
976 virt_cur_x--;
977 if (i < mark_beginx)
978 virt_mark_beginx--;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +0000979 } else if (realdata[i] >= 1 && realdata[i] <= 26) {
980 /* Treat control characters as ^letter */
Chris Allegretta6306a112000-09-02 07:55:41 +0000981 fileptr->data[pos++] = '^';
982 fileptr->data[pos++] = realdata[i] + 64;
Robert Siemborski53875912000-06-16 04:25:30 +0000983 } else {
984 fileptr->data[pos++] = realdata[i];
985 }
986 }
987
988 fileptr->data[pos] = '\0';
989
990 /* Now, Paint the line */
991 if (current == fileptr && index > COLS - 2) {
Robert Siemborskia9addc72000-06-17 06:06:35 +0000992 /* This handles when the current line is beyond COLS */
Chris Allegretta88520c92001-05-05 17:45:54 +0000993 /* It requires figuring out what page we're on */
Robert Siemborskia9addc72000-06-17 06:06:35 +0000994 page = get_page_from_virtual(index);
Robert Siemborskid8510b22000-06-06 23:04:06 +0000995 col = get_page_start_virtual(page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000996
Robert Siemborskia9addc72000-06-17 06:06:35 +0000997 edit_add(filetmp, line, col, virt_cur_x, virt_mark_beginx, page);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +0000998 mvwaddch(edit, line, 0, '$');
999
Chris Allegrettafb62f732000-12-05 11:36:41 +00001000 if (strlenpt(fileptr->data) > get_page_end_virtual(page) + 1)
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001001 mvwaddch(edit, line, COLS - 1, '$');
Robert Siemborskid8510b22000-06-06 23:04:06 +00001002 } else {
Robert Siemborskia9addc72000-06-17 06:06:35 +00001003 /* It's not the current line means that it's at x=0 and page=1 */
1004 /* If it is the current line, then we're in the same boat */
1005 edit_add(filetmp, line, 0, virt_cur_x, virt_mark_beginx, 1);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001006
Robert Siemborski53875912000-06-16 04:25:30 +00001007 if (strlenpt(&filetmp->data[col]) > COLS)
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001008 mvwaddch(edit, line, COLS - 1, '$');
Robert Siemborskid8510b22000-06-06 23:04:06 +00001009 }
Robert Siemborski53875912000-06-16 04:25:30 +00001010
1011 /* Clean up our mess */
1012 tmp = fileptr->data;
1013 fileptr->data = realdata;
1014 free(tmp);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001015}
1016
1017void center_cursor(void)
1018{
1019 current_y = editwinrows / 2;
1020 wmove(edit, current_y, current_x);
1021}
1022
1023/* Refresh the screen without changing the position of lines */
1024void edit_refresh(void)
1025{
Chris Allegrettaed022162000-08-03 16:54:11 +00001026 static int noloop = 0;
Chris Allegretta95b0b522000-07-28 02:58:06 +00001027 int lines = 0, i = 0, currentcheck = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001028 filestruct *temp, *hold = current;
1029
1030 if (current == NULL)
1031 return;
1032
1033 temp = edittop;
1034
1035 while (lines <= editwinrows - 1 && lines <= totlines && temp != NULL) {
1036 hold = temp;
1037 update_line(temp, current_x);
Chris Allegretta95b0b522000-07-28 02:58:06 +00001038 if (temp == current)
1039 currentcheck = 1;
1040
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001041 temp = temp->next;
1042 lines++;
1043 }
Chris Allegrettaed022162000-08-03 16:54:11 +00001044 /* If noloop == 1, then we already did an edit_update without finishing
1045 this function. So we don't run edit_update again */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001046 if (!currentcheck && !noloop) { /* Then current has run off the screen... */
Chris Allegrettada721be2000-07-31 01:26:42 +00001047 edit_update(current, CENTER);
Chris Allegrettaed022162000-08-03 16:54:11 +00001048 noloop = 1;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001049 } else if (noloop)
Chris Allegrettaed022162000-08-03 16:54:11 +00001050 noloop = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001051
1052 if (lines <= editwinrows - 1)
1053 while (lines <= editwinrows - 1) {
1054 mvwaddstr(edit, lines, i, hblank);
1055 lines++;
1056 }
1057 if (temp == NULL)
1058 editbot = hold;
1059 else
1060 editbot = temp;
1061}
1062
1063/*
Chris Allegretta88520c92001-05-05 17:45:54 +00001064 * Same as above, but touch the window first, so everything is redrawn.
Chris Allegrettaf1d33d32000-08-19 03:53:39 +00001065 */
1066void edit_refresh_clearok(void)
1067{
1068 clearok(edit, TRUE);
1069 edit_refresh();
1070 clearok(edit, FALSE);
1071}
1072
1073/*
Chris Allegretta88520c92001-05-05 17:45:54 +00001074 * Nice generic routine to update the edit buffer, given a pointer to the
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001075 * file struct =)
1076 */
Chris Allegretta2d7893d2001-07-11 02:08:33 +00001077void edit_update(filestruct * fileptr, int topmidbotnone)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001078{
Robert Siemborski29e9a762000-07-05 03:16:04 +00001079 int i = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001080 filestruct *temp;
1081
1082 if (fileptr == NULL)
1083 return;
1084
1085 temp = fileptr;
Chris Allegretta2d7893d2001-07-11 02:08:33 +00001086 if (topmidbotnone == TOP);
1087 else if (topmidbotnone == NONE)
1088 for (i = 0; i <= current_y - 1 && temp->prev != NULL; i++)
1089 temp = temp->prev;
1090 else if (topmidbotnone == BOTTOM)
Chris Allegretta234a34d2000-07-29 04:33:38 +00001091 for (i = 0; i <= editwinrows - 1 && temp->prev != NULL; i++)
1092 temp = temp->prev;
1093 else
1094 for (i = 0; i <= editwinrows / 2 && temp->prev != NULL; i++)
1095 temp = temp->prev;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001096
Robert Siemborski29e9a762000-07-05 03:16:04 +00001097 edittop = temp;
1098 fix_editbot();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001099
1100 edit_refresh();
1101}
1102
Chris Allegretta88520c92001-05-05 17:45:54 +00001103/* This function updates current, based on where current_y is; reset_cursor
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001104 does the opposite */
1105void update_cursor(void)
1106{
1107 int i = 0;
1108
1109#ifdef DEBUG
1110 fprintf(stderr, _("Moved to (%d, %d) in edit buffer\n"), current_y,
1111 current_x);
1112#endif
1113
1114 current = edittop;
1115 while (i <= current_y - 1 && current->next != NULL) {
1116 current = current->next;
1117 i++;
1118 }
1119
1120#ifdef DEBUG
1121 fprintf(stderr, _("current->data = \"%s\"\n"), current->data);
1122#endif
1123
1124}
1125
1126/*
1127 * Ask a question on the statusbar. Answer will be stored in answer
1128 * global. Returns -1 on aborted enter, -2 on a blank string, and 0
Chris Allegretta88520c92001-05-05 17:45:54 +00001129 * otherwise, the valid shortcut key caught. Def is any editable text we
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001130 * want to put up by default.
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001131 *
1132 * New arg tabs tells whether or not to allow tab completion.
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001133 */
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001134int statusq(int tabs, shortcut s[], int slen, char *def, char *msg, ...)
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001135{
1136 va_list ap;
1137 char foo[133];
1138 int ret;
1139
1140 bottombars(s, slen);
1141
1142 va_start(ap, msg);
1143 vsnprintf(foo, 132, msg, ap);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001144 va_end(ap);
Chris Allegrettaa4d21622000-07-08 23:57:03 +00001145 strncat(foo, ": ", 132);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001146
Chris Allegretta8ce24132001-04-30 11:28:46 +00001147#ifdef ENABLE_COLOR
1148 color_on(bottomwin, COLOR_STATUSBAR);
1149#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001150 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001151#endif
1152
1153
Chris Allegretta7da4e9f2000-11-06 02:57:22 +00001154 ret = nanogetstr(tabs, foo, def, s, slen, (strlen(foo) + 3));
Chris Allegretta8ce24132001-04-30 11:28:46 +00001155
1156#ifdef ENABLE_COLOR
1157 color_off(bottomwin, COLOR_STATUSBAR);
1158#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001159 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001160#endif
1161
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001162
1163 switch (ret) {
1164
1165 case NANO_FIRSTLINE_KEY:
1166 do_first_line();
1167 break;
1168 case NANO_LASTLINE_KEY:
1169 do_last_line();
1170 break;
1171 case NANO_CANCEL_KEY:
1172 return -1;
1173 default:
Chris Allegretta5b1faac2000-11-16 19:55:30 +00001174 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001175 }
1176
1177#ifdef DEBUG
1178 fprintf(stderr, _("I got \"%s\"\n"), answer);
1179#endif
1180
1181 return ret;
1182}
1183
1184/*
1185 * Ask a simple yes/no question on the statusbar. Returns 1 for Y, 0 for
1186 * N, 2 for All (if all is non-zero when passed in) and -1 for abort (^C)
1187 */
1188int do_yesno(int all, int leavecursor, char *msg, ...)
1189{
1190 va_list ap;
1191 char foo[133];
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001192 int kbinput, ok = -1, i;
1193 char *yesstr; /* String of yes characters accepted */
1194 char *nostr; /* Same for no */
1195 char *allstr; /* And all, surprise! */
1196 char shortstr[5]; /* Temp string for above */
Chris Allegretta84de5522001-04-12 14:51:48 +00001197#ifndef DISABLE_MOUSE
Chris Allegretta235ab192001-04-12 13:24:40 +00001198#ifdef NCURSES_MOUSE_VERSION
1199 MEVENT mevent;
1200#endif
1201#endif
1202
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001203
1204 /* Yes, no and all are strings of any length. Each string consists of
1205 all characters accepted as a valid character for that value.
1206 The first value will be the one displayed in the shortcuts. */
1207 yesstr = _("Yy");
1208 nostr = _("Nn");
1209 allstr = _("Aa");
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001210
1211 /* Write the bottom of the screen */
1212 clear_bottomwin();
Chris Allegretta8ce24132001-04-30 11:28:46 +00001213
1214#ifdef ENABLE_COLOR
1215 color_on(bottomwin, COLOR_BOTTOMBARS);
1216#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001217
Jordi Mallach0b0fc492000-06-23 01:00:13 +00001218 /* Remove gettext call for keybindings until we clear the thing up */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001219 if (!ISSET(NO_HELP)) {
1220 wmove(bottomwin, 1, 0);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001221
1222 snprintf(shortstr, 3, " %c", yesstr[0]);
1223 onekey(shortstr, _("Yes"));
1224
1225 if (all) {
1226 snprintf(shortstr, 3, " %c", allstr[0]);
1227 onekey(shortstr, _("All"));
1228 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001229 wmove(bottomwin, 2, 0);
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001230
1231 snprintf(shortstr, 3, " %c", nostr[0]);
1232 onekey(shortstr, _("No"));
1233
Jordi Mallach0b0fc492000-06-23 01:00:13 +00001234 onekey("^C", _("Cancel"));
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001235 }
1236 va_start(ap, msg);
1237 vsnprintf(foo, 132, msg, ap);
1238 va_end(ap);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001239
1240#ifdef ENABLE_COLOR
1241 color_off(bottomwin, COLOR_BOTTOMBARS);
1242 color_on(bottomwin, COLOR_STATUSBAR);
1243#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001244 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001245#endif /* ENABLE_COLOR */
1246
1247 blank_statusbar();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001248 mvwaddstr(bottomwin, 0, 0, foo);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001249
1250#ifdef ENABLE_COLOR
1251 color_off(bottomwin, COLOR_STATUSBAR);
1252#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001253 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001254#endif
1255
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001256 wrefresh(bottomwin);
1257
1258 if (leavecursor == 1)
1259 reset_cursor();
1260
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001261 while (ok == -1) {
1262 kbinput = wgetch(edit);
1263
1264 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00001265#ifndef DISABLE_MOUSE
Chris Allegretta235ab192001-04-12 13:24:40 +00001266#ifdef NCURSES_MOUSE_VERSION
1267 case KEY_MOUSE:
1268
1269 /* Look ma! We get to duplicate lots of code from do_mouse!! */
1270 if (getmouse(&mevent) == ERR)
1271 break;
1272 if (!wenclose(bottomwin, mevent.y, mevent.x) || ISSET(NO_HELP))
1273 break;
1274 mevent.y -= editwinrows + 3;
1275 if (mevent.y < 0)
1276 break;
1277 else {
1278
1279 /* Rather than a bunch of if statements, set up a matrix
1280 of possible return keystrokes based on the x and y values */
1281 if (all) {
1282 char yesnosquare[2][2] = {
1283 {yesstr[0], allstr[0]},
1284 {nostr[0], NANO_CONTROL_C }};
1285
1286 ungetch(yesnosquare[mevent.y][mevent.x/(COLS/6)]);
1287 } else {
1288 char yesnosquare[2][2] = {
1289 {yesstr[0], '\0'},
1290 {nostr[0], NANO_CONTROL_C }};
1291
1292 ungetch(yesnosquare[mevent.y][mevent.x/(COLS/6)]);
1293 }
1294 }
1295 break;
1296#endif
1297#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001298 case NANO_CONTROL_C:
1299 ok = -2;
1300 break;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001301 default:
1302
Chris Allegretta88520c92001-05-05 17:45:54 +00001303 /* Look for the kbinput in the yes, no and (optimally) all str */
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001304 for (i = 0; yesstr[i] != 0 && yesstr[i] != kbinput; i++)
1305 ;
1306 if (yesstr[i] != 0) {
Chris Allegrettaea620fe2001-02-18 05:39:41 +00001307 ok = 1;
Chris Allegretta4ce8e3b2001-02-16 01:49:31 +00001308 break;
1309 }
1310
1311 for (i = 0; nostr[i] != 0 && nostr[i] != kbinput; i++)
1312 ;
1313 if (nostr[i] != 0) {
1314 ok = 0;
1315 break;
1316 }
1317
1318 if (all) {
1319 for (i = 0; allstr[i] != 0 && allstr[i] != kbinput; i++)
1320 ;
1321 if (allstr[i] != 0) {
1322 ok = 2;
1323 break;
1324 }
1325 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001326 }
1327 }
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001328
1329 /* Then blank the screen */
1330 blank_statusbar_refresh();
1331
1332 if (ok == -2)
1333 return -1;
1334 else
1335 return ok;
1336}
1337
1338void statusbar(char *msg, ...)
1339{
1340 va_list ap;
1341 char foo[133];
1342 int start_x = 0;
1343
1344 va_start(ap, msg);
1345 vsnprintf(foo, 132, msg, ap);
1346 va_end(ap);
1347
Chris Allegretta17dcb722001-01-20 21:40:07 +00001348 start_x = COLS / 2 - strlen(foo) / 2 - 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001349
1350 /* Blank out line */
1351 blank_statusbar();
1352
1353 wmove(bottomwin, 0, start_x);
1354
Chris Allegretta8ce24132001-04-30 11:28:46 +00001355#ifdef ENABLE_COLOR
1356 color_on(bottomwin, COLOR_STATUSBAR);
1357#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001358 wattron(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001359#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001360
1361 waddstr(bottomwin, "[ ");
1362 waddstr(bottomwin, foo);
1363 waddstr(bottomwin, " ]");
Chris Allegretta8ce24132001-04-30 11:28:46 +00001364
1365#ifdef ENABLE_COLOR
1366 color_off(bottomwin, COLOR_STATUSBAR);
1367#else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001368 wattroff(bottomwin, A_REVERSE);
Chris Allegretta8ce24132001-04-30 11:28:46 +00001369#endif
1370
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001371 wrefresh(bottomwin);
1372
1373 if (ISSET(CONSTUPDATE))
1374 statblank = 1;
1375 else
1376 statblank = 25;
1377}
1378
1379void display_main_list(void)
1380{
1381 bottombars(main_list, MAIN_VISIBLE);
1382}
1383
1384int total_refresh(void)
1385{
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001386 clearok(edit, TRUE);
1387 clearok(topwin, TRUE);
1388 clearok(bottomwin, TRUE);
1389 wnoutrefresh(edit);
1390 wnoutrefresh(topwin);
1391 wnoutrefresh(bottomwin);
1392 doupdate();
1393 clearok(edit, FALSE);
1394 clearok(topwin, FALSE);
1395 clearok(bottomwin, FALSE);
Chris Allegrettaf1d33d32000-08-19 03:53:39 +00001396 edit_refresh();
Chris Allegrettaf4b96012001-01-03 07:11:47 +00001397 titlebar(NULL);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001398 return 1;
1399}
1400
1401void previous_line(void)
1402{
1403 if (current_y > 0)
1404 current_y--;
1405}
1406
1407int do_cursorpos(void)
1408{
1409 filestruct *fileptr;
Chris Allegretta66795ec2000-12-27 04:47:28 +00001410 float linepct = 0.0, bytepct = 0.0;
1411 int i = 0;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001412
1413 if (current == NULL || fileage == NULL)
1414 return 0;
1415
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001416 for (fileptr = fileage; fileptr != current && fileptr != NULL;
1417 fileptr = fileptr->next)
Chris Allegretta66795ec2000-12-27 04:47:28 +00001418 i += strlen(fileptr->data) + 1;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001419
1420 if (fileptr == NULL)
1421 return -1;
1422
Chris Allegretta66795ec2000-12-27 04:47:28 +00001423 i += current_x;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001424
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001425 if (totlines > 0)
1426 linepct = 100 * current->lineno / totlines;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001427
1428 if (totsize > 0)
1429 bytepct = 100 * i / totsize;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001430
1431#ifdef DEBUG
1432 fprintf(stderr, _("do_cursorpos: linepct = %f, bytepct = %f\n"),
1433 linepct, bytepct);
1434#endif
1435
1436 statusbar(_("line %d of %d (%.0f%%), character %d of %d (%.0f%%)"),
1437 current->lineno, totlines, linepct, i, totsize, bytepct);
1438 reset_cursor();
1439 return 1;
1440}
1441
1442/* Our broken, non-shortcut list compliant help function.
Chris Allegretta88520c92001-05-05 17:45:54 +00001443 But, hey, it's better than nothing, and it's dynamic! */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001444int do_help(void)
1445{
Rocco Corsiaf5c3022001-01-12 07:51:05 +00001446#ifndef DISABLE_HELP
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001447 char *ptr = help_text, *end;
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001448 int i, j, row = 0, page = 1, kbinput = 0, no_more = 0, kp, kp2;
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001449 int no_help_flag = 0;
1450
1451 blank_edit();
1452 curs_set(0);
1453 blank_statusbar();
1454
Chris Allegretta6fe61492001-05-21 12:56:25 +00001455#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001456 currshortcut = help_list;
1457 currslen = HELP_LIST_LEN;
Chris Allegretta6fe61492001-05-21 12:56:25 +00001458#endif
1459
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001460 kp = keypad_on(edit, 1);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001461 kp2 = keypad_on(bottomwin, 1);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001462
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001463 if (ISSET(NO_HELP)) {
1464
Chris Allegretta88520c92001-05-05 17:45:54 +00001465 /* Well, if we're going to do this, we should at least
Chris Allegretta70444892001-01-07 23:02:02 +00001466 do it the right way */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001467 no_help_flag = 1;
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001468 UNSET(NO_HELP);
Chris Allegretta70444892001-01-07 23:02:02 +00001469 window_init();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001470 bottombars(help_list, HELP_LIST_LEN);
Chris Allegretta70444892001-01-07 23:02:02 +00001471
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001472 } else
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001473 bottombars(help_list, HELP_LIST_LEN);
1474
1475 do {
1476 ptr = help_text;
1477 switch (kbinput) {
Chris Allegretta84de5522001-04-12 14:51:48 +00001478#ifndef DISABLE_MOUSE
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001479#ifdef NCURSES_MOUSE_VERSION
1480 case KEY_MOUSE:
1481 do_mouse();
1482 break;
1483#endif
1484#endif
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001485 case NANO_NEXTPAGE_KEY:
1486 case NANO_NEXTPAGE_FKEY:
1487 case KEY_NPAGE:
1488 if (!no_more) {
1489 blank_edit();
1490 page++;
1491 }
1492 break;
1493 case NANO_PREVPAGE_KEY:
1494 case NANO_PREVPAGE_FKEY:
1495 case KEY_PPAGE:
1496 if (page > 1) {
1497 no_more = 0;
1498 blank_edit();
1499 page--;
1500 }
1501 break;
1502 }
1503
Chris Allegretta88520c92001-05-05 17:45:54 +00001504 /* Calculate where in the text we should be, based on the page */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001505 for (i = 1; i < page; i++) {
1506 row = 0;
1507 j = 0;
Chris Allegretta44e73df2000-09-07 03:37:38 +00001508
1509 while (row < editwinrows - 2 && *ptr != '\0') {
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001510 if (*ptr == '\n' || j == COLS - 5) {
1511 j = 0;
1512 row++;
1513 }
1514 ptr++;
1515 j++;
1516 }
1517 }
1518
Chris Allegretta44e73df2000-09-07 03:37:38 +00001519 if (i > 1) {
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001520
Chris Allegretta44e73df2000-09-07 03:37:38 +00001521 }
1522
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001523 i = 0;
1524 j = 0;
1525 while (i < editwinrows && *ptr != '\0') {
1526 end = ptr;
1527 while (*end != '\n' && *end != '\0' && j != COLS - 5) {
1528 end++;
1529 j++;
1530 }
1531 if (j == COLS - 5) {
1532
Chris Allegretta88520c92001-05-05 17:45:54 +00001533 /* Don't print half a word if we've run out of space */
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001534 while (*end != ' ' && *end != '\0') {
1535 end--;
1536 j--;
1537 }
1538 }
1539 mvwaddnstr(edit, i, 0, ptr, j);
1540 j = 0;
1541 i++;
1542 if (*end == '\n')
1543 end++;
1544 ptr = end;
1545 }
1546 if (*ptr == '\0') {
1547 no_more = 1;
1548 continue;
1549 }
Chris Allegrettad1627cf2000-12-18 05:03:16 +00001550 } while ((kbinput = wgetch(edit)) != NANO_EXIT_KEY &&
1551 kbinput != NANO_EXIT_FKEY);
1552
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001553 if (no_help_flag) {
Chris Allegretta70444892001-01-07 23:02:02 +00001554 blank_bottombars();
Chris Allegretta4da1fc62000-06-21 03:00:43 +00001555 wrefresh(bottomwin);
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001556 SET(NO_HELP);
Chris Allegretta70444892001-01-07 23:02:02 +00001557 window_init();
1558 }
1559 display_main_list();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001560
1561 curs_set(1);
1562 edit_refresh();
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001563 kp = keypad_on(edit, kp);
Chris Allegretta6b58acd2001-04-12 03:01:53 +00001564 kp2 = keypad_on(bottomwin, kp2);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001565
Chris Allegretta3bc8c722000-12-10 17:03:25 +00001566#elif defined(DISABLE_HELP)
1567 nano_disabled_msg();
Chris Allegrettaa2ea1932000-06-06 05:53:49 +00001568#endif
1569
1570 return 1;
1571}
1572
1573/* Dump the current file structure to stderr */
1574void dump_buffer(filestruct * inptr)
1575{
1576#ifdef DEBUG
1577 filestruct *fileptr;
1578
1579 if (inptr == fileage)
1580 fprintf(stderr, _("Dumping file buffer to stderr...\n"));
1581 else if (inptr == cutbuffer)
1582 fprintf(stderr, _("Dumping cutbuffer to stderr...\n"));
1583 else
1584 fprintf(stderr, _("Dumping a buffer to stderr...\n"));
1585
1586 fileptr = inptr;
1587 while (fileptr != NULL) {
1588 fprintf(stderr, "(%ld) %s\n", fileptr->lineno, fileptr->data);
1589 fflush(stderr);
1590 fileptr = fileptr->next;
1591 }
1592#endif /* DEBUG */
1593}
1594
1595void dump_buffer_reverse(filestruct * inptr)
1596{
1597#ifdef DEBUG
1598 filestruct *fileptr;
1599
1600 fileptr = filebot;
1601 while (fileptr != NULL) {
1602 fprintf(stderr, "(%ld) %s\n", fileptr->lineno, fileptr->data);
1603 fflush(stderr);
1604 fileptr = fileptr->prev;
1605 }
1606#endif /* DEBUG */
1607}
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001608
Chris Allegretta88520c92001-05-05 17:45:54 +00001609/* Fix editbot, based on the assumption that edittop is correct */
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001610void fix_editbot(void)
1611{
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001612 int i;
1613 editbot = edittop;
Chris Allegrettabd9e7c32000-10-26 01:44:42 +00001614 for (i = 0; (i <= editwinrows - 1) && (editbot->next != NULL)
1615 && (editbot != filebot); i++, editbot = editbot->next);
Robert Siemborskidd53ec22000-07-04 02:35:19 +00001616}
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001617
Chris Allegrettafb62f732000-12-05 11:36:41 +00001618/* highlight the current word being replaced or spell checked */
1619void do_replace_highlight(int highlight_flag, char *word)
1620{
1621 char *highlight_word = NULL;
1622 int x, y;
1623
1624 highlight_word = mallocstrcpy(highlight_word, &current->data[current_x]);
1625 highlight_word[strlen(word)] = '\0';
1626
Chris Allegretta88520c92001-05-05 17:45:54 +00001627 /* adjust output when word extends beyond screen */
Chris Allegrettafb62f732000-12-05 11:36:41 +00001628
1629 x = xplustabs();
1630 y = get_page_end_virtual(get_page_from_virtual(x)) + 1;
1631
1632 if ((COLS - (y - x) + strlen(word)) > COLS) {
1633 highlight_word[y - x - 1] = '$';
1634 highlight_word[y - x] = '\0';
1635 }
1636
1637 /* OK display the output */
1638
1639 reset_cursor();
1640
1641 if (highlight_flag)
1642 wattron(edit, A_REVERSE);
1643
1644 waddstr(edit, highlight_word);
1645
1646 if (highlight_flag)
1647 wattroff(edit, A_REVERSE);
1648
1649 free(highlight_word);
1650}
1651
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001652#ifdef NANO_EXTRA
Chris Allegretta9b3c7e82001-08-25 16:00:53 +00001653#define CREDIT_LEN 48
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001654void do_credits(void)
1655{
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001656 int i, j = 0, k, place = 0, start_x;
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001657 char *what;
1658
1659 char *nanotext = _("The nano text editor");
1660 char *version = _("version ");
1661 char *brought = _("Brought to you by:");
1662 char *specialthx = _("Special thanks to:");
1663 char *fsf = _("The Free Software Foundation");
1664 char *ncurses = _("Pavel Curtis, Zeyd Ben-Halim and Eric S. Raymond for ncurses");
1665 char *anyonelse = _("and anyone else we forgot...");
1666 char *thankyou = _("Thank you for using nano!\n");
1667
1668 char *credits[CREDIT_LEN] = {nanotext,
1669 version,
1670 VERSION,
1671 "",
1672 brought,
1673 "Chris Allegretta",
1674 "Jordi Mallach",
1675 "Adam Rogoyski",
1676 "Rob Siemborski",
1677 "Rocco Corsi",
1678 "Ken Tyler",
1679 "Sven Guckes",
1680 "Florian König",
1681 "Pauli Virtanen",
1682 "Daniele Medri",
1683 "Clement Laforet",
1684 "Tedi Heriyanto",
Chris Allegrettaa131c7c2000-11-25 19:59:41 +00001685 "Bill Soudan",
Chris Allegretta7cd9f742000-11-25 20:17:28 +00001686 "Christian Weisgerber",
Chris Allegretta827b15f2001-01-03 02:09:04 +00001687 "Erik Andersen",
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001688 "Big Gaute",
1689 "Joshua Jensen",
Chris Allegretta0d471de2001-03-15 14:40:42 +00001690 "Ryan Krebs",
Chris Allegretta7ab3e8f2001-03-22 23:12:22 +00001691 "Albert Chin",
Chris Allegretta9b3c7e82001-08-25 16:00:53 +00001692 "David Lawrence Ramsey",
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001693 "",
1694 specialthx,
1695 "Plattsburgh State University",
1696 "Benet Laboratories",
1697 "Amy Allegretta",
1698 "Linda Young",
1699 "Jeremy Robichaud",
1700 "Richard Kolb II",
1701 fsf,
1702 "Linus Torvalds",
1703 ncurses,
1704 anyonelse,
1705 thankyou,
1706 "", "", "", "",
1707 "(c) 2000 Chris Allegretta",
1708 "", "", "", "",
1709 "www.nano-editor.org"
1710 };
1711
1712 curs_set(0);
1713 nodelay(edit, TRUE);
1714 blank_bottombars();
1715 mvwaddstr(topwin, 0, 0, hblank);
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001716 blank_edit();
1717 wrefresh(edit);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001718 wrefresh(bottomwin);
1719 wrefresh(topwin);
1720
1721 while (wgetch(edit) == ERR) {
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001722 for (k = 0; k <= 1; k++) {
1723 blank_edit();
1724 for (i = editwinrows / 2 - 1; i >= (editwinrows / 2 - 1 - j); i--) {
1725 mvwaddstr(edit, i * 2 - k, 0, hblank);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001726
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001727 if (place - (editwinrows / 2 - 1 - i) < CREDIT_LEN)
1728 what = credits[place - (editwinrows / 2 - 1 - i)];
1729 else
1730 what = "";
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001731
Chris Allegretta17dcb722001-01-20 21:40:07 +00001732 start_x = COLS / 2 - strlen(what) / 2 - 1;
Chris Allegretta8b4ca4a2000-11-25 18:21:37 +00001733 mvwaddstr(edit, i * 2 - k, start_x, what);
1734 }
1735 usleep(700000);
1736 wrefresh(edit);
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001737 }
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001738 if (j < editwinrows / 2 - 1)
1739 j++;
1740
1741 place++;
Chris Allegretta8a0de3b2000-11-24 20:45:14 +00001742
1743 if (place >= CREDIT_LEN + editwinrows / 2)
1744 break;
1745 }
1746
1747 nodelay(edit, FALSE);
1748 curs_set(1);
1749 display_main_list();
1750 total_refresh();
1751 }
1752#endif
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001753
Chris Allegrettae3167732001-03-18 16:59:34 +00001754int keypad_on(WINDOW * win, int newval)
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001755{
1756
Chris Allegretta88520c92001-05-05 17:45:54 +00001757/* This is taken right from aumix. Don't sue me. */
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001758#ifdef HAVE_USEKEYPAD
1759 int old;
1760
1761 old = win->_use_keypad;
Chris Allegrettae3167732001-03-18 16:59:34 +00001762 keypad(win, newval);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001763 return old;
1764#else
Chris Allegrettae3167732001-03-18 16:59:34 +00001765 keypad(win, newval);
Chris Allegrettac08f50d2001-01-06 18:12:43 +00001766 return 1;
1767#endif /* HAVE_USEKEYPAD */
1768
1769}
1770
1771
1772