1 /*
2 * filebuffer.cc
3 *
4 * Copyright (C) 1998, 1999 Jiann-Ching Liu
5 */
6
7
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "qe_config.h"
13 #include "keydefine.h"
14 #include "filebuffer.h"
15 #include "history.h"
16 #include "misc.h"
17 #include "colors.h"
18 #include "messages.h"
19 #include "menu.h"
20
21 #if AUTO_TERM_SIZE_DETECT
22 # include <term.h>
23 #endif
24
25
26 // const int markstacksize = 5;
27 mark filebuffer::markstack[markstacksize];
28 int filebuffer::marksp = -1;
29 mark filebuffer::current_mark;
30 filebuffer* filebuffer::current_buffer = NULL;
31 short filebuffer::enable_ctrl_k = 0;
32 short filebuffer::enable_ctrl_x = 0;
33 short filebuffer::enable_ctrl_q = 0;
34 short filebuffer::quit_confirm = 1;
35 short filebuffer::history_key = HISTORY_KEY_NONE;
36 short filebuffer::insert_mode = 0;
37 short filebuffer::blank_compress = 0;
38 short filebuffer::search_case = 0;
39 short filebuffer::big5msg_flag = 0;
40 short filebuffer::dir_sort = DIR_SORT_BY_NAME;
41 char filebuffer::current_dir[PATH_MAX] = "";
42 int filebuffer::screen_lines = 0;
43 int filebuffer::screen_columns = 0;
44 keydefine* filebuffer::kdf = NULL;
45 menu filebuffer::menubar;
46 cmdHistory filebuffer::history;
47
48 // linebuffer* filebuffer::cmdhistory = NULL;
49 // int filebuffer::history_no = 0;
50
51
52 #ifdef USE_ANSICOLOR
53 int filebuffer::ansi_color = -1;
54 #endif
55
56
filebuffer(void)57 filebuffer::filebuffer(void) : filename() {
58 init_window();
59 }
60
filebuffer(const char * fname)61 filebuffer::filebuffer(const char *fname) : filename(fname) {
62 init_window();
63 // load_file();
64 }
65
load_file(void)66 void filebuffer::load_file(void) {
67 FILE *fd;
68 unsigned int j, len, tmplen;
69 char tmpbuf[MAX_BUFFER_LEN+1];
70 char linebuf[MAX_BUFFER_LEN+1];
71
72 if (loadingOK) return;
73
74
75 if (filename.getLength() != 0) {
76
77 if (access(filename.getString(), F_OK) == 0) {
78 if (access(filename.getString(), R_OK) == 0) {
79 if ((fd = fopen(filename.getString(), "r")) != NULL) {
80 linebuffer *tmpptr, *ptr = current;
81
82 total_line = 0;
83
84 while (fgets(tmpbuf, MAX_BUFFER_LEN, fd) != NULL) {
85 if (total_line % 100 == 0) {
86 display_messages("Loading %d ...", total_line);
87 }
88 tmplen = strlen(tmpbuf);
89 for (unsigned int i = j = len = 0;
90 (i < tmplen) && (j < MAX_BUFFER_LEN); i++) {
91 switch(tmpbuf[i]) {
92 case '\r':
93 case '\n':
94 linebuf[j++] = '\0';
95 break;
96 case '\t':
97 for (int k = j % TAB_SPACE; k < TAB_SPACE;
98 k++, j++)
99 linebuf[j] = ' ';
100 break;
101 case ' ' :
102 linebuf[j++] = ' ';
103 break;
104 // case 127 :
105 // linebuf[j++] = '^';
106 // linebuf[j++] = '?';
107 // len = j;
108 // break;
109 case '\b':
110 case '\f':
111 break;
112 default :
113 linebuf[j++] = tmpbuf[i];
114 len = j;
115 break;
116 }
117 }
118 linebuf[len] = '\0';
119
120 tmpptr = new linebuffer(linebuf);
121 ptr->next = tmpptr;
122 tmpptr->previous = ptr;
123 ptr = tmpptr;
124 total_line++;
125 }
126 ptr->next = tail;
127 tail->previous = ptr;
128
129 if (ptr == current) { // empty input file
130 head->next = current;
131 current->previous = head;
132 total_line = 1;
133 } else {
134 head->next = current->next;
135 ptr = current;
136 current = current->next;
137 current->previous = head;
138 delete ptr;
139 }
140 fclose(fd);
141
142 if (access(filename.getString(), W_OK) == 0) {
143 display_messages("Loading file: %s .... ok.",
144 basename(filename.getString()));
145 } else {
146 display_messages("Reading file: %s .... ok.",
147 basename(filename.getString()));
148 }
149 } else {
150 display_messages(MSG_NEW_FILE);
151 }
152 } else {
153 display_messages(MSG_READ_ERROR);
154 }
155 } else { // new file
156 display_messages(MSG_NEW_FILE);
157 }
158
159 refresh_clientarea(0);
160 display_status();
161 }
162 loadingOK = 1;
163 }
164
165
init_window(void)166 void filebuffer::init_window(void) {
167 #ifdef USE_ANSICOLOR
168 if (ansi_color == -1) ansi_color = has_colors() ? 0 : 1;
169 #endif
170
171 if (current_dir[0] == '\0') getcwd(current_dir, PATH_MAX);
172
173 if (current_buffer == NULL) {
174 current_buffer = this;
175 next_buffer = this;
176 previous_buffer = this;
177
178 qeString::setHandler(filebuffer::out_of_memory);
179
180 init_menu();
181 } else {
182 next_buffer = current_buffer->next_buffer;
183 previous_buffer = current_buffer;
184 current_buffer->next_buffer = this;
185 next_buffer->previous_buffer = this;
186 }
187
188 head = new linebuffer("=== Top of file ===");
189 tail = new linebuffer("=== Bottom of file ===");
190 current = new linebuffer("");
191 head->previous = NULL;
192 head->next = current;
193 current->previous = head;
194 current->next = tail;
195 tail->previous = current;
196 tail->next = NULL;
197 buffer_type = NORMAL_TEXT_BUFFER;
198
199 screen_x = screen_columns;
200 screen_y = screen_lines;
201
202 read_only = 0;
203 loadingOK = 0;
204 win = NULL;
205 keep_in_menu = MENU_NOT_IN_MENU;
206
207 sprintf(outputformat, "%%-%ds", screen_x);
208
209 general_init();
210 }
211
general_init(void)212 void filebuffer::general_init(void) {
213 cursor_x = 0;
214 cursor_y = 1;
215 buffer_x = 0;
216 buffer_y = 0;
217
218 // keycommand = NULL;
219
220 topline = head;
221 total_line = 1;
222 top_line_no = -1;
223 left_col_no = 0;
224
225 dirty_flag = 0;
226 dirty_line = 0;
227 quiet_flag = 0;
228 message_dirty_flag = 0;
229
230 mode = FB_DATAAREA_MODE;
231 // input_mode = FB_REPLACE_MODE;
232 input_mode = insert_mode;
233 cmdline[(cmdline_idx = 0)] = '\0';
234 }
235
~filebuffer(void)236 filebuffer::~filebuffer(void) {
237 // FILE *fd;
238 //
239 // fd = fopen("log.txt", "a+");
240 // fprintf(fd, "quit: %s\n", filename);
241 // fclose(fd);
242
243 // if (filename != NULL) qeFree(filename);
244 filename.~qeString();
245 if (win != NULL) delwin(win);
246
247 for (linebuffer *ptr = head; ptr != NULL; ptr = current) {
248 current = ptr->next;
249 ptr->~linebuffer();
250 delete ptr; // version 0.0.23
251 }
252
253 // filename = NULL;
254 win = NULL;
255 }
256
out_of_memory(void)257 void filebuffer::out_of_memory(void) {
258 if (current_buffer != NULL) {
259 current_buffer->read_only = 1;
260 current_buffer->display_messages(MSG_OUT_OF_MEMORY);
261 }
262 }
263
init_curses(void)264 void filebuffer::init_curses(void) {
265
266 #if AUTO_TERM_SIZE_DETECT
267 if (screen_columns == 0) {
268 char entrybuf[1024];
269 char *term = getenv("TERM");
270 if (term != NULL && tgetent(entrybuf, term) != -1) { // read in entry
271 screen_columns = tgetnum("co");
272 screen_lines = tgetnum("li");
273 } else {
274 screen_columns = 80;
275 screen_lines = 24;
276 // screen_columns = COLUMNS;
277 // screen_lines = LINES;
278 }
279 }
280 #else
281 screen_columns = 80;
282 screen_lines = 24;
283 #endif
284
285 initscr(); // initialize the curses library
286 keypad(stdscr, TRUE); // enable keyboard mapping
287 nonl(); // tell curses not to do NL->CR/NL on output
288 cbreak(); // take input chars one at a time, no wait for \n
289 nocrmode(); // Control input mode: ^S, ^Q, ^C, ^Y go to kernel
290 noecho(); // don't echo input
291 color_setup();
292 raw(); // Raw input mode no processing by the kernel.
293 intrflush(stdscr, FALSE);
294 nodelay(stdscr, FALSE);
295 refresh();
296 }
297
end_curses(void)298 void filebuffer::end_curses(void) {
299 endwin();
300 }
301
302
init_keydefine(const char * fname)303 void filebuffer::init_keydefine(const char *fname) {
304 kdf = new keydefine(fname);
305 }
306
init_keydefine(void)307 void filebuffer::init_keydefine(void) {
308 kdf = new keydefine();
309 }
310
311 // char* filebuffer::qeStrdup(const char *s) {
312 // char *ptr;
313 // int len = strlen(s) + 1;
314 //
315 // if ((ptr = new char[len]) != NULL) {
316 // memcpy(ptr, s, len);
317 // }
318 // return ptr;
319 // }
320
active(void)321 filebuffer* filebuffer::active(void) {
322 int finish = 0;
323 static int quit_all = 0;
324 filebuffer *fb;
325
326 if (win == NULL) win = newwin(screen_y, screen_x, 0, 0);
327 wclear(win);
328 keypad(win, TRUE);
329 nodelay(win, FALSE);
330
331 paint();
332 load_file();
333 load_workbuffer();
334
335 switch (quit_all) {
336 case 1:
337 finish = cmd_quit_all();
338 break;
339 case 2:
340 finish = cmd_save_all_quit();
341 break;
342 default:
343 if (keep_in_menu == MENU_BACK_TO_MENU) finish = cmd_menu();
344 break;
345 }
346
347 while (finish == 0)
348 finish = (mode == FB_COMMAND_MODE) ? cmdarea() : clientarea();
349
350 if (win != NULL) delwin(win);
351 win = NULL;
352
353 quit_all = 0;
354
355 switch (finish) {
356 case RTNVAL_SHELL_ESCAPE:
357 end_curses();
358 system(getenv("SHELL"));
359 init_curses();
360 break;
361 case RTNVAL_QUIT_BUFFER:
362 unmark_all_mark();
363 if ((current_buffer = this->previous_buffer) == this) {
364 current_buffer = NULL;
365 display_messages(MSG_QUIT);
366 } else {
367 this->next_buffer->previous_buffer = current_buffer;
368 current_buffer->next_buffer = this->next_buffer;
369 }
370 this->~filebuffer();
371
372 break;
373 case RTNVAL_SAVE_ALL_AND_QUIT:
374 quit_all = 1;
375 case RTNVAL_QUIT_ALL_BUFFER:
376 quit_all++;
377 case RTNVAL_QUIT_CURRENT_BUFFER:
378 current_buffer->unmark_all_mark();
379 fb = current_buffer;
380 current_buffer = current_buffer->next_buffer;
381 if (fb == current_buffer) {
382 current_buffer = NULL;
383 } else {
384 current_buffer->previous_buffer = fb->previous_buffer;
385 fb->previous_buffer->next_buffer = current_buffer;
386 }
387
388 fb->~filebuffer();
389 break;
390 }
391
392 return current_buffer;
393 }
394
load_workbuffer(void)395 void filebuffer::load_workbuffer(void) {
396 strncpy(workbuffer, current->getString(), MAX_BUFFER_LEN);
397 workbuflen = strlen(workbuffer);
398 for (int i = strlen(workbuffer); i < MAX_BUFFER_LEN; i++)
399 workbuffer[i] = ' ';
400 workbufidx = buffer_x;
401 }
402
write_workbuffer(const int force)403 void filebuffer::write_workbuffer(const int force) {
404 if (force || dirty_line) {
405 dirty_buffer(1);
406 workbuffer[workbuflen] = '\0';
407 // current->assign(workbuffer);
408 *current = workbuffer;
409 for (int i = workbuflen; i < MAX_BUFFER_LEN; i++)
410 workbuffer[i] = ' ';
411 // workbuffer[workbuflen] = ' ';
412 }
413 dirty_line = 0;
414 }
415
dirty_buffer(const int force)416 int filebuffer::dirty_buffer(const int force) {
417 if (! dirty_flag && (force || dirty_line)) {
418 dirty_flag = 1;
419 display_filename();
420 return 1;
421 }
422 return 0;
423 }
424
cmd_kbinput(void)425 int filebuffer::cmd_kbinput(void) {
426 int key;
427
428 if (mode == FB_DATAAREA_MODE) {
429 // setattr(win, ATTRIBUTE_normal_text);
430 ca_attrset();
431 wmove(win, cursor_y, cursor_x);
432 // load_workbuffer(QE_IF_NECESSARY);
433 // if (newline_flag) {
434 // load_workbuffer();
435 // newline_flag = 0;
436 // }
437
438 if (((key = getfirstkey()) >= ' ') && (key < 256)) {
439 ca_attrset();
440 wmove(win, cursor_y, cursor_x);
441 if (read_only) {
442 display_messages(MSG_READ_ONLY_FILE);
443 } else {
444 if (workbufidx >= MAX_BUFFER_LEN-2) return 0;
445
446 if (input_mode == FB_REPLACE_MODE) {
447 mvwaddch(win, cursor_y, cursor_x, key);
448 workbuffer[workbufidx++] = key;
449 workbuflen = maximum(workbuflen, workbufidx);
450 } else {
451 mvwinsch(win, cursor_y, cursor_x, key);
452 for (int i = minimum(workbuflen, MAX_BUFFER_LEN-2);
453 i > workbufidx; i--)
454 workbuffer[i] = workbuffer[i-1];
455 workbuffer[workbufidx++] = key;
456 workbuflen=workbuflen>=workbufidx?workbuflen+1:workbufidx;
457 workbuflen = minimum(workbuflen, MAX_BUFFER_LEN-2);
458 }
459 dirty_line = 1;
460 buffer_x = workbufidx;
461 if (cursor_x < screen_x-1) {
462 cursor_x++;
463 } else {
464 left_col_no++;
465 refresh_clientarea(1);
466 }
467 display_status();
468 }
469 } else {
470 if (buffer_type == DIRECTORY_BUFFER) {
471 if (key == KEY_ENTER || key == KEY_RETURN
472 || key == KEY_LINEFEED) {
473 // load_file();
474 }
475 }
476 // if ((key = getnextkey()) != 0) return key;
477 return do_function_key(key);
478 // return getnextkey();
479 }
480 } else { /////////////// Command Line ////////////////////////
481 setattr(win, ATTRIBUTE_command_line);
482 wmove(win, screen_y-3, cmdline_idx < screen_x - 1 ? cmdline_idx :
483 screen_x -1);
484
485 int cmdlen = strlen(cmdline);
486
487 if (((key = getfirstkey()) >= ' ') && (key < 256)) {
488 setattr(win, ATTRIBUTE_command_line);
489 wmove(win, screen_y-3, cmdline_idx < screen_x - 1 ? cmdline_idx :
490 screen_x -1);
491 if (cmdline_idx < MAX_BUFFER_LEN - 2) {
492 if (input_mode == FB_REPLACE_MODE) {
493 cmdline[cmdline_idx++] = key;
494 cmdlen = maximum(cmdlen, cmdline_idx);
495 cmdline[cmdlen] = '\0';
496 if (cmdline_idx < screen_x-1) {
497 waddch(win, key);
498 } else {
499 refresh_cmdarea();
500 }
501 } else {
502 winsch(win, key);
503 for (int i = cmdlen; i > cmdline_idx; i--)
504 cmdline[i] = cmdline[i-1];
505 cmdline[cmdline_idx++] = key;
506 cmdlen = minimum(cmdlen + 1, MAX_BUFFER_LEN -2);
507 cmdline[cmdlen] = '\0';
508
509 // mvwinsch(win, cursor_y, cursor_x, key);
510 // for (int i = workbuflen; i > workbufidx; i--)
511 // workbuffer[i] = workbuffer[i-1];
512 // workbuffer[workbufidx++] = key;
513 // workbuflen=workbuflen>=workbufidx?workbuflen+1:workbufidx;
514 // workbuflen = minimum(workbuflen, MAX_BUFFER_LEN);
515 }
516 } else {
517 beep();
518 }
519 } else {
520 switch (key) {
521 // case KEY_DOWN:
522 // display_messages(MSG_CMD_HISTORY);
523 // history.push(cmdline);
524 // if (history.active(cmdline, win, screen_y, screen_x, 10, 40)) {
525 // refresh_cmdarea();
526 // cmdline_idx = 0;
527 // }
528 // history.pop();
529 // display_messages();
530 // break;
531 case KEY_RETURN:
532 case KEY_ENTER:
533 case KEY_LINEFEED:
534 if (cmdlen > 0) {
535 history.push(cmdline);
536 return cmd_execute();
537 }
538 break;
539 default:
540 // if ((key = getnextkey()) != 0) return key;
541 // return getnextkey();
542 if (((key == KEY_UP) && (history_key & HISTORY_KEY_UP )) ||
543 ((key == KEY_DOWN) && (history_key & HISTORY_KEY_DOWN))) {
544 return cmd_history();
545 } else {
546 return do_function_key(key);
547 }
548 // waddch(win, key);
549 // wprintw(win, "(%d)", key);
550 break;
551 }
552 }
553 }
554 return 0;
555 }
556
cmd_history(void)557 int filebuffer::cmd_history(void) {
558 write_workbuffer(QE_IF_NECESSARY);
559 cmd_cursor_cmd();
560
561 display_messages(MSG_CMD_HISTORY);
562 history.push(cmdline);
563
564 if (history.active(cmdline, win, screen_y, screen_x, 10, 40)) {
565 refresh_cmdarea();
566 cmdline_idx = 0;
567 }
568
569 history.pop();
570
571 display_messages();
572 return 0;
573 }
574
do_function_key(const int key)575 int filebuffer::do_function_key(const int key) {
576 return getnextkey();
577 }
578
clientarea(void)579 int filebuffer::clientarea(void) {
580 // int modified = 0;
581 // keycmdlist *keycommand;
582 int rtlval = 0;
583
584 // newline_flag = 1;
585
586 while (mode == FB_DATAAREA_MODE) {
587 if ((rtlval = cmd_kbinput()) != 0) return rtlval;
588 }
589 return rtlval;
590 }
591
display_status(void)592 void filebuffer::display_status(void) {
593 setattr(win, ATTRIBUTE_status_line);
594 mvwprintw(win, screen_y-2, screen_x-26, "%6d/%-6d %3d %7s",
595 buffer_y + 1, total_line,
596 mode == FB_DATAAREA_MODE ? buffer_x + 1 : cmdline_idx + 1,
597 (big5msg_flag == 1) ?
598 (input_mode == FB_INSERT_MODE ? "<I>���J" : "<R>���N") :
599 (input_mode == FB_INSERT_MODE ? " Insert" : "Replace"));
600
601 }
602
paint(void)603 void filebuffer::paint(void) {
604 for (int i = 0; i < screen_y-3; i++) {
605 setattr(win, ATTRIBUTE_normal_text);
606 mvprint(i, 0, "");
607 }
608 setattr(win, ATTRIBUTE_command_line);
609 mvprint(screen_y-3, 0, "");
610 setattr(win, ATTRIBUTE_status_line);
611 mvprint(screen_y-2, 0, "");
612 setattr(win, ATTRIBUTE_message_line);
613 mvprint(screen_y-1, 0, "");
614
615 display_filename();
616 display_status();
617 refresh_clientarea(0);
618 display_messages();
619 wmove(win, 0, 0);
620 setattr(win, ATTRIBUTE_normal_text);
621 touchwin(win);
622 wrefresh(win);
623 }
624
625
display_filename(void)626 void filebuffer::display_filename(void) {
627
628 if (filename.getLength() == 0 || current_buffer != this) return;
629
630 char dispbuff[MAX_BUFFER_LEN];
631 int len = filename.getLength();
632 int idx = 0;
633
634 // dispbuff[0] = '\0';
635 //
636 // if (read_only) {
637 // strcpy(dispbuff, "%% ");
638 // } else if (dirty_flag) {
639 // strcpy(dispbuff, "** ");
640 // } else {
641 // strcpy(dispbuff, "-- ");
642 // }
643 // idx = strlen(dispbuff);
644
645 if (len > screen_x - 35) {
646 dispbuff[idx] = filename[0] == '[' ? '[' : '.';
647 // sprintf(&dispbuff[idx+1], ".. %s", &filename[len + 35 - screen_x]);
648 sprintf(&dispbuff[idx+1], ".. %s",
649 filename.getString(len + 35 - screen_x));
650 } else {
651 strcpy(&dispbuff[idx], filename.getString());
652 }
653
654 setattr(win, dirty_flag ? ATTRIBUTE_modified_file_line : ATTRIBUTE_status_line);
655 mvwprintw(win, screen_y-2, 0, "%s", dispbuff);
656 }
657
658
659
refresh_bufferline(void)660 void filebuffer::refresh_bufferline(void) {
661 int mlnos = -2, mlnoe = -2;
662 unsigned int bml = MAX_BUFFER_LEN + 1;
663 unsigned int bmr = MAX_BUFFER_LEN + 1;
664 int bmfix = 0;
665
666 if (quiet_flag || current_buffer != this) return;
667
668 if (current_mark != UNKNOW_MARK && current_mark.fb == this) {
669 mlnos = minimum(current_mark.fn, current_mark.ln);
670 mlnoe = maximum(current_mark.fn, current_mark.ln);
671
672 if (current_mark == BLOCK_MARK) {
673 bml = minimum(current_mark.fc, current_mark.lc);
674 bmr = maximum(current_mark.fc, current_mark.lc);
675 }
676 }
677
678 if (buffer_y >= mlnos && buffer_y <= mlnoe) {
679 if (current_mark == BLOCK_MARK) {
680 if (bmr >= left_col_no && bml <= left_col_no + screen_x)
681 bmfix = 1;
682 setattr(win, ATTRIBUTE_normal_text);
683 } else {
684 setattr(win, ATTRIBUTE_mark_text);
685 }
686 } else {
687 setattr(win, ATTRIBUTE_normal_text);
688 }
689
690 mvprint(cursor_y, 0,
691 ((unsigned int)workbuflen > left_col_no) ? &workbuffer[left_col_no] : "");
692
693 if (bmfix) {
694 setattr(win, ATTRIBUTE_mark_text);
695 int leftmax = maximum(bml, left_col_no);
696 /*
697 mvprint(cursor_y, (bml > left_col_no ? bml - left_col_no : 0),
698 minimum(minimum(bmr+1, screen_x + left_col_no) -
699 maximum(bml, left_col_no),
700 (unsigned int) screen_x),
701 ((unsigned int) workbuflen > bml) ? &workbuffer[bml] : "");
702 */
703 mvprint(cursor_y, leftmax - left_col_no,
704 minimum(minimum(bmr+1, screen_x+left_col_no) - leftmax,
705 (unsigned int) screen_x),
706 (workbuflen > leftmax) ? &workbuffer[leftmax] : "");
707 }
708 setattr(win, ATTRIBUTE_normal_text);
709 }
710
refresh_clientarea(const int bufflag)711 void filebuffer::refresh_clientarea(const int bufflag) {
712 int i, mlnos = -2, mlnoe = -2, lno = top_line_no;
713 int blockmark_need_fix = 0;
714 unsigned int bml = MAX_BUFFER_LEN + 1;
715 unsigned int bmr = MAX_BUFFER_LEN + 1;
716 linebuffer *ptr = topline;
717
718 if (quiet_flag || current_buffer != this) return;
719
720 if (current_mark != UNKNOW_MARK && current_mark.fb == this) {
721 mlnos = minimum(current_mark.fn, current_mark.ln);
722 mlnoe = maximum(current_mark.fn, current_mark.ln);
723
724 if (current_mark == BLOCK_MARK) {
725 bml = minimum(current_mark.fc, current_mark.lc);
726 bmr = maximum(current_mark.fc, current_mark.lc);
727 }
728 }
729
730 setattr(win, ATTRIBUTE_normal_text);
731
732 for (i = 0; i < screen_y-3 && ptr != NULL; i++, ptr = ptr->next, lno++) {
733 if (lno >= mlnos && lno <= mlnoe) {
734 if (current_mark == BLOCK_MARK) {
735 if (bmr >= left_col_no && bml <= left_col_no + screen_x)
736 blockmark_need_fix = 1;
737 setattr(win, ATTRIBUTE_normal_text);
738 } else {
739 setattr(win, ATTRIBUTE_mark_text);
740 }
741 } else {
742 setattr(win, ATTRIBUTE_normal_text);
743 }
744
745 if (ptr == head || ptr == tail) {
746 mvprint(i, 0, ptr->getString());
747 } else {
748 mvprint(i, 0, (ptr->getLength() > left_col_no) ?
749 ptr->getString(left_col_no) : "");
750 // &((*ptr)[left_col_no]) : "");
751 }
752
753 if (blockmark_need_fix) {
754 blockmark_need_fix = 0;
755 setattr(win, ATTRIBUTE_mark_text);
756 unsigned int leftmax = maximum(bml, left_col_no);
757 mvprint(i, leftmax - left_col_no,
758 minimum(minimum(bmr+1, screen_x+left_col_no) - leftmax,
759 (unsigned int) screen_x),
760 (ptr->getLength() > leftmax ? ptr->getString(leftmax) : ""));
761 // (ptr->getLength() > leftmax ? &((*ptr)[leftmax]) : ""));
762 }
763 }
764 setattr(win, ATTRIBUTE_normal_text);
765
766 for (; i < screen_y-3; i++) mvprint(i, 0, "");
767
768 if (bufflag) refresh_bufferline();
769 }
770
mvprint(const int y,const int x,const char * str)771 void filebuffer::mvprint(const int y, const int x, const char *str) {
772 char buffer[MAX_BUFFER_LEN+1];
773
774 if (current_buffer != this) return;
775
776 sprintf(buffer, outputformat, str);
777 mvwaddnstr(win, y, x, buffer, screen_x);
778 }
779
mvprint(const int y,const int x,const int len,const char * str)780 void filebuffer::mvprint(const int y, const int x, const int len,
781 const char *str) {
782 char buffer[MAX_BUFFER_LEN+1];
783 char fmt[20];
784
785 if (current_buffer != this) return;
786 sprintf(fmt, "%%-%ds", len);
787 sprintf(buffer, fmt, str);
788 mvwaddnstr(win, y, x, buffer, len);
789 }
790
display_messages(const char * fmt,...)791 void filebuffer::display_messages(const char *fmt, ...) {
792 // char msg[MAX_BUFFER_LEN+1];
793 char buffer[MAX_BUFFER_LEN+1];
794 va_list ap;
795 // attr_t attr = wattr_get(win);
796
797 if (current_buffer != this) return;
798
799 message_dirty_flag = 1;
800
801 va_start(ap, fmt);
802 #ifndef HAS_VSNPRINTF
803 vsprintf(buffer, fmt, ap);
804 #else
805 vsnprintf(buffer, 80, fmt, ap);
806 #endif
807 va_end(ap);
808 // sprintf(msg, outputformat, buffer);
809 setattr(win, ATTRIBUTE_message_line);
810 mvwprintw(win, screen_y-1, 0, outputformat, "");
811 mvwaddnstr(win, screen_y-1, 0, buffer, screen_x);
812 // setattr(win, attr);
813 touchwin(win);
814 wrefresh(win);
815 }
816
display_messages(const int msgno)817 void filebuffer::display_messages(const int msgno) {
818 display_messages(big5msg_flag ? chinese_message[msgno]
819 : english_message[msgno]);
820 }
821
display_messages(void)822 void filebuffer::display_messages(void) {
823 static char *buffer =
824 " qe v" QE_VERSION
825 " (c) written by Jiann-Ching Liu. ";
826
827 if (current_buffer != this) return;
828
829 message_dirty_flag = 0;
830
831 // attr_t attr = wattr_get(win);
832
833 setattr(win, ATTRIBUTE_copyright_line);
834 mvwaddnstr(win, screen_y-1, 0, buffer, screen_x);
835 // setattr(win, attr);
836
837 touchwin(win);
838 wrefresh(win);
839 }
840
is_big5(void)841 int filebuffer::is_big5(void) {
842 return big5msg_flag == 0 ? 0 : 1;
843 }
844
845
cmd_lang_big5(void)846 int filebuffer::cmd_lang_big5(void) {
847 if (keep_in_menu == MENU_IN_MENU) keep_in_menu = MENU_KEEP_IN_MENU;
848
849 big5msg_flag = 1;
850 display_status();
851 return 0;
852 }
853
cmd_lang_english(void)854 int filebuffer::cmd_lang_english(void) {
855 if (keep_in_menu == MENU_IN_MENU) keep_in_menu = MENU_KEEP_IN_MENU;
856
857 big5msg_flag = 0;
858 display_status();
859 return 0;
860 }
861
862 #ifdef USE_ANSICOLOR
863
setattr(WINDOW * w,int color)864 void filebuffer::setattr(WINDOW *w, int color) {
865 if (ansi_color) {
866 switch(color) {
867 case ATTRIBUTE_normal_text:
868 printf("%c[37m%c[44m", 27, 27);
869 break;
870 case ATTRIBUTE_mark_text:
871 printf("%c[37m%c[41m", 27, 27);
872 break;
873 case ATTRIBUTE_command_line:
874 printf("%c[33m%c[42m", 27, 27);
875 break;
876 case ATTRIBUTE_status_line:
877 printf("%c[37m%c[40m", 27, 27);
878 break;
879 case ATTRIBUTE_message_line:
880 printf("%c[32m%c[40m", 27, 27);
881 break;
882 case ATTRIBUTE_modified_file_line:
883 printf("%c[32m%c[40m", 27, 27);
884 break;
885 case ATTRIBUTE_copyright_line:
886 printf("%c[33m%c[40m", 27, 27);
887 break;
888 }
889 } else {
890 wattrset(w, attributes[color]);
891 }
892 }
893
894 #endif
895
896
897 /***************************************************************************/
898 //
899 // resume last file buffer status
900 // Macro : [resume]
901 // Status : Still in develop
902 //
903
904
cmd_resume(void)905 int filebuffer::cmd_resume(void) {
906 FILE *fd;
907 char init_str[8000];
908 int idx;
909 char fname[MAX_BUFFER_LEN+1];
910 char arg1[MAX_BUFFER_LEN+1];
911 char arg2[MAX_BUFFER_LEN+1];
912
913 char filename[500];
914 sprintf(filename, "/root/%s", DEFAULT_USER_STATUS); //
915 if ((fd = fopen(filename, "r")) != NULL) {
916 while (fgets(init_str,MAX_BUFFER_LEN, fd) != NULL) {
917 for (idx = strlen(init_str)-1; idx >= 0; idx--) {
918 if (init_str[idx] == '\r' || init_str[idx] == '\n' ||
919 init_str[idx] == ' ' || init_str[idx] == '\t') {
920 init_str[idx] = '\0'; // make string close here
921 } else break;
922 }
923 sscanf(init_str, "%s %s %s", fname, arg1, arg2); // %s %s %s -- filename linenumber column
924 for (int finish = 0; !finish; ) {
925 if (access(fname,F_OK) == 0)
926 {
927 cmd_edit(fname); // load file in to buffer
928 cmd_goto_currline(atoi(arg1),atoi(arg2)); // goto specified line and column
929 finish = 1;
930 }
931 }
932 } // end of while
933 }
934 fclose(fd);
935 return 0;
936 }
937