1 /* 2 | ee (easy editor) 3 | 4 | An easy to use, simple screen oriented editor. 5 | 6 | written by Hugh Mahon 7 | 8 | 9 | Copyright (c) 2009, Hugh Mahon 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions 14 | are met: 15 | 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above 19 | copyright notice, this list of conditions and the following 20 | disclaimer in the documentation and/or other materials provided 21 | with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | POSSIBILITY OF SUCH DAMAGE. 35 | 36 | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 37 | 38 | This editor was purposely developed to be simple, both in 39 | interface and implementation. This editor was developed to 40 | address a specific audience: the user who is new to computers 41 | (especially UNIX). 42 | 43 | ee is not aimed at technical users; for that reason more 44 | complex features were intentionally left out. In addition, 45 | ee is intended to be compiled by people with little computer 46 | experience, which means that it needs to be small, relatively 47 | simple in implementation, and portable. 48 | 49 | This software and documentation contains 50 | proprietary information which is protected by 51 | copyright. All rights are reserved. 52 | 53 | $Header: /home/hugh/sources/old_ae/RCS/ee.c,v 1.104 2010/06/04 01:55:31 hugh Exp hugh $ 54 | 55 */ 56 57 char *ee_copyright_message = 58 "Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2009 Hugh Mahon "; 59 60 #include "ee_version.h" 61 62 char *version = "@(#) ee, version " EE_VERSION " $Revision: 1.104 $"; 63 64 #ifdef NCURSE 65 #include "new_curse.h" 66 #elif HAS_NCURSES 67 #define _XOPEN_SOURCE_EXTENDED 68 #include <ncurses.h> 69 #else 70 #include <curses.h> 71 #endif 72 73 #include <ctype.h> 74 #include <limits.h> 75 #include <signal.h> 76 #include <wchar.h> 77 #include <wctype.h> 78 #include <fcntl.h> 79 #include <sys/types.h> 80 #include <sys/stat.h> 81 #include <errno.h> 82 #include <string.h> 83 #include <pwd.h> 84 #include <locale.h> 85 86 #ifdef HAS_SYS_WAIT 87 #include <sys/wait.h> 88 #endif 89 90 #ifdef HAS_STDLIB 91 #include <stdlib.h> 92 #endif 93 94 #ifdef HAS_STDARG 95 #include <stdarg.h> 96 #endif 97 98 #ifdef HAS_UNISTD 99 #include <unistd.h> 100 #endif 101 102 #ifndef NO_CATGETS 103 #include <nl_types.h> 104 105 nl_catd catalog; 106 #else 107 #define catgetlocal(a, b) (b) 108 #endif /* NO_CATGETS */ 109 110 #ifndef SIGCHLD 111 #define SIGCHLD SIGCLD 112 #endif 113 114 #define TAB 9 115 #define max(a, b) (a > b ? a : b) 116 #define min(a, b) (a < b ? a : b) 117 118 /* 119 | defines for type of data to show in info window 120 */ 121 122 #define CONTROL_KEYS 1 123 #define COMMANDS 2 124 125 struct text { 126 unsigned char *line; /* line of characters */ 127 int line_number; /* line number */ 128 int line_length; /* actual number of characters in the line */ 129 int max_length; /* maximum number of characters the line handles */ 130 struct text *next_line; /* next line of text */ 131 struct text *prev_line; /* previous line of text */ 132 }; 133 134 struct text *first_line; /* first line of current buffer */ 135 struct text *dlt_line; /* structure for info on deleted line */ 136 struct text *curr_line; /* current line cursor is on */ 137 struct text *tmp_line; /* temporary line pointer */ 138 struct text *srch_line; /* temporary pointer for search routine */ 139 140 struct files { /* structure to store names of files to be edited*/ 141 unsigned char *name; /* name of file */ 142 struct files *next_name; 143 }; 144 145 struct files *top_of_stack = NULL; 146 147 int d_wrd_len; /* length of deleted word */ 148 int position; /* offset in bytes from begin of line */ 149 int scr_pos; /* horizontal position */ 150 int scr_vert; /* vertical position on screen */ 151 int scr_horz; /* horizontal position on screen */ 152 int absolute_lin; /* number of lines from top */ 153 int tmp_vert, tmp_horz; 154 int input_file; /* indicate to read input file */ 155 int recv_file; /* indicate reading a file */ 156 int edit; /* continue executing while true */ 157 int gold; /* 'gold' function key pressed */ 158 int fildes; /* file descriptor */ 159 int case_sen; /* case sensitive search flag */ 160 int last_line; /* last line for text display */ 161 int last_col; /* last column for text display */ 162 int horiz_offset = 0; /* offset from left edge of text */ 163 int clear_com_win; /* flag to indicate com_win needs clearing */ 164 int text_changes = FALSE; /* indicate changes have been made to text */ 165 int get_fd; /* file descriptor for reading a file */ 166 int info_window = TRUE; /* flag to indicate if help window visible */ 167 int info_type = CONTROL_KEYS; /* flag to indicate type of info to display */ 168 int expand_tabs = TRUE; /* flag for expanding tabs */ 169 int right_margin = 0; /* the right margin */ 170 int observ_margins = TRUE; /* flag for whether margins are observed */ 171 int shell_fork; 172 int temp_stdin; /* temporary storage for stdin */ 173 int temp_stdout; /* temp storage for stdout descriptor */ 174 int temp_stderr; /* temp storage for stderr descriptor */ 175 int pipe_out[2]; /* pipe file desc for output */ 176 int pipe_in[2]; /* pipe file descriptors for input */ 177 int out_pipe; /* flag that info is piped out */ 178 int in_pipe; /* flag that info is piped in */ 179 int formatted = FALSE; /* flag indicating paragraph formatted */ 180 int auto_format = FALSE; /* flag for auto_format mode */ 181 int restricted = FALSE; /* flag to indicate restricted mode */ 182 int nohighlight = FALSE; /* turns off highlighting */ 183 int eightbit = TRUE; /* eight bit character flag */ 184 int local_LINES = 0; /* copy of LINES, to detect when win resizes */ 185 int local_COLS = 0; /* copy of COLS, to detect when win resizes */ 186 int curses_initialized = FALSE; /* flag indicating if curses has been started*/ 187 int emacs_keys_mode = FALSE; /* mode for if emacs key binings are used */ 188 189 unsigned char *point; /* points to current position in line */ 190 unsigned char *srch_str; /* pointer for search string */ 191 unsigned char *u_srch_str; /* pointer to non-case sensitive search */ 192 unsigned char *srch_1; /* pointer to start of suspect string */ 193 unsigned char *srch_2; /* pointer to next character of string */ 194 unsigned char *srch_3; 195 unsigned char *in_file_name = NULL; /* name of input file */ 196 char *tmp_file; /* temporary file name */ 197 unsigned char d_char[5]; /* deleted character */ 198 unsigned char *d_word; /* deleted word */ 199 unsigned char *d_line; /* deleted line */ 200 char in_string[513]; /* buffer for reading a file */ 201 unsigned char *print_command = (unsigned char *)"lpr"; /* string to use for the print command */ 202 unsigned char *start_at_line = NULL; /* move to this line at start of session*/ 203 int in; /* input character */ 204 205 FILE *temp_fp; /* temporary file pointer */ 206 FILE *bit_bucket; /* file pointer to /dev/null */ 207 208 char *table[] = { 209 "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J", 210 "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", 211 "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_" 212 }; 213 214 WINDOW *com_win; 215 WINDOW *text_win; 216 WINDOW *help_win; 217 WINDOW *info_win; 218 219 /* 220 | UTF-8 utility functions. 221 */ 222 223 /* Return the number of bytes in the UTF-8 character starting at s. */ 224 static int 225 utf8_len(const unsigned char *s) 226 { 227 if (*s < 0x80) 228 return 1; 229 if ((*s & 0xE0) == 0xC0) 230 return 2; 231 if ((*s & 0xF0) == 0xE0) 232 return 3; 233 if ((*s & 0xF8) == 0xF0) 234 return 4; 235 return 1; /* invalid byte: treat as single byte */ 236 } 237 238 /* Return a pointer to the start of the previous UTF-8 character. */ 239 static unsigned char * 240 utf8_prev(const unsigned char *start, const unsigned char *ptr) 241 { 242 if (ptr <= start) 243 return (unsigned char *)start; 244 ptr--; 245 while (ptr > start && (*ptr & 0xC0) == 0x80) 246 ptr--; 247 return (unsigned char *)ptr; 248 } 249 250 /* Return the display width of the UTF-8 character starting at s. */ 251 static int 252 utf8_width(const unsigned char *s) 253 { 254 wchar_t wc; 255 mbstate_t mbs; 256 int w; 257 258 if (*s < 0x80) 259 return 1; 260 memset(&mbs, 0, sizeof(mbs)); 261 if (mbrtowc(&wc, (const char *)s, utf8_len(s), &mbs) == (size_t)-1) 262 return 1; 263 w = wcwidth(wc); 264 return (w >= 0) ? w : 1; 265 } 266 267 /* 268 | The following structure allows menu items to be flexibly declared. 269 | The first item is the string describing the selection, the second 270 | is the address of the procedure to call when the item is selected, 271 | and the third is the argument for the procedure. 272 | 273 | For those systems with i18n, the string should be accompanied by a 274 | catalog number. The 'int *' should be replaced with 'void *' on 275 | systems with that type. 276 | 277 | The first menu item will be the title of the menu, with NULL 278 | parameters for the procedure and argument, followed by the menu items. 279 | 280 | If the procedure value is NULL, the menu item is displayed, but no 281 | procedure is called when the item is selected. The number of the 282 | item will be returned. If the third (argument) parameter is -1, no 283 | argument is given to the procedure when it is called. 284 */ 285 286 struct menu_entries { 287 char *item_string; 288 int (*procedure)(struct menu_entries *); 289 struct menu_entries *ptr_argument; 290 int (*iprocedure)(int); 291 void (*nprocedure)(void); 292 int argument; 293 }; 294 295 unsigned char *resiz_line(int factor, struct text *rline, int rpos); 296 void insert(int character); 297 void insert_utf8(const unsigned char *mb, int len); 298 void delete(int disp); 299 void scanline(unsigned char *pos); 300 int tabshift(int temp_int); 301 int out_char(WINDOW *window, int character, int column); 302 int len_char(int character, int column); 303 void draw_line(int vertical, int horiz, unsigned char *ptr, int t_pos, int length); 304 void insert_line(int disp); 305 struct text *txtalloc(void); 306 struct files *name_alloc(void); 307 unsigned char *next_word(unsigned char *string); 308 void prev_word(void); 309 void control(void); 310 void emacs_control(void); 311 void bottom(void); 312 void top(void); 313 void nextline(void); 314 void prevline(void); 315 void left(int disp); 316 void right(int disp); 317 void find_pos(void); 318 void up(void); 319 void down(void); 320 void function_key(void); 321 void print_buffer(void); 322 void command_prompt(void); 323 void command(char *cmd_str1); 324 int scan(char *line, int offset, int column); 325 char *get_string(char *prompt, int advance); 326 int compare(char *string1, char *string2, int sensitive); 327 void goto_line(char *cmd_str); 328 void midscreen(int line, unsigned char *pnt); 329 void get_options(int numargs, char *arguments[]); 330 void check_fp(void); 331 void get_file(char *file_name); 332 void get_line(int length, unsigned char *in_string, int *append); 333 void draw_screen(void); 334 void finish(void); 335 int quit(int noverify); 336 void edit_abort(int arg); 337 void delete_text(void); 338 int write_file(char *file_name, int warn_if_exists); 339 int search(int display_message); 340 void search_prompt(void); 341 void del_char(void); 342 void undel_char(void); 343 void del_word(void); 344 void undel_word(void); 345 void del_line(void); 346 void undel_line(void); 347 void adv_word(void); 348 void move_rel(int direction, int lines); 349 void eol(void); 350 void bol(void); 351 void adv_line(void); 352 void sh_command(char *string); 353 void set_up_term(void); 354 void resize_check(void); 355 int menu_op(struct menu_entries *); 356 void paint_menu(struct menu_entries menu_list[], int max_width, int max_height, int list_size, int top_offset, WINDOW *menu_win, int off_start, int vert_size); 357 void help(void); 358 void paint_info_win(void); 359 void no_info_window(void); 360 void create_info_window(void); 361 int file_op(int arg); 362 void shell_op(void); 363 void leave_op(void); 364 void redraw(void); 365 int Blank_Line(struct text *test_line); 366 void Format(void); 367 void ee_init(void); 368 void dump_ee_conf(void); 369 void echo_string(char *string); 370 void spell_op(void); 371 void ispell_op(void); 372 int first_word_len(struct text *test_line); 373 void Auto_Format(void); 374 void modes_op(void); 375 char *is_in_string(char *string, char *substring); 376 char *resolve_name(char *name); 377 int restrict_mode(void); 378 int unique_test(char *string, char *list[]); 379 void strings_init(void); 380 381 #undef P_ 382 /* 383 | allocate space here for the strings that will be in the menu 384 */ 385 386 struct menu_entries modes_menu[] = { 387 {"", NULL, NULL, NULL, NULL, 0}, /* title */ 388 {"", NULL, NULL, NULL, NULL, -1}, /* 1. tabs to spaces */ 389 {"", NULL, NULL, NULL, NULL, -1}, /* 2. case sensitive search*/ 390 {"", NULL, NULL, NULL, NULL, -1}, /* 3. margins observed */ 391 {"", NULL, NULL, NULL, NULL, -1}, /* 4. auto-paragraph */ 392 {"", NULL, NULL, NULL, NULL, -1}, /* 5. eightbit characters*/ 393 {"", NULL, NULL, NULL, NULL, -1}, /* 6. info window */ 394 {"", NULL, NULL, NULL, NULL, -1}, /* 7. emacs key bindings*/ 395 {"", NULL, NULL, NULL, NULL, -1}, /* 8. right margin */ 396 {"", NULL, NULL, NULL, dump_ee_conf, -1}, /* 9. save editor config */ 397 {NULL, NULL, NULL, NULL, NULL, -1} /* terminator */ 398 }; 399 400 char *mode_strings[10]; 401 402 #define NUM_MODES_ITEMS 9 403 404 struct menu_entries config_dump_menu[] = { 405 {"", NULL, NULL, NULL, NULL, 0}, 406 {"", NULL, NULL, NULL, NULL, -1}, 407 {"", NULL, NULL, NULL, NULL, -1}, 408 {NULL, NULL, NULL, NULL, NULL, -1} 409 }; 410 411 struct menu_entries leave_menu[] = { 412 {"", NULL, NULL, NULL, NULL, -1}, 413 {"", NULL, NULL, NULL, finish, -1}, 414 {"", NULL, NULL, quit, NULL, TRUE}, 415 {NULL, NULL, NULL, NULL, NULL, -1} 416 }; 417 418 #define READ_FILE 1 419 #define WRITE_FILE 2 420 #define SAVE_FILE 3 421 422 struct menu_entries file_menu[] = { 423 {"", NULL, NULL, NULL, NULL, -1}, 424 {"", NULL, NULL, file_op, NULL, READ_FILE}, 425 {"", NULL, NULL, file_op, NULL, WRITE_FILE}, 426 {"", NULL, NULL, file_op, NULL, SAVE_FILE}, 427 {"", NULL, NULL, NULL, print_buffer, -1}, 428 {NULL, NULL, NULL, NULL, NULL, -1} 429 }; 430 431 struct menu_entries search_menu[] = { 432 {"", NULL, NULL, NULL, NULL, 0}, 433 {"", NULL, NULL, NULL, search_prompt, -1}, 434 {"", NULL, NULL, search, NULL, TRUE}, 435 {NULL, NULL, NULL, NULL, NULL, -1} 436 }; 437 438 struct menu_entries spell_menu[] = { 439 {"", NULL, NULL, NULL, NULL, -1}, 440 {"", NULL, NULL, NULL, spell_op, -1}, 441 {"", NULL, NULL, NULL, ispell_op, -1}, 442 {NULL, NULL, NULL, NULL, NULL, -1} 443 }; 444 445 struct menu_entries misc_menu[] = { 446 {"", NULL, NULL, NULL, NULL, -1}, 447 {"", NULL, NULL, NULL, Format, -1}, 448 {"", NULL, NULL, NULL, shell_op, -1}, 449 {"", menu_op, spell_menu, NULL, NULL, -1}, 450 {NULL, NULL, NULL, NULL, NULL, -1} 451 }; 452 453 struct menu_entries main_menu[] = { 454 {"", NULL, NULL, NULL, NULL, -1}, 455 {"", NULL, NULL, NULL, leave_op, -1}, 456 {"", NULL, NULL, NULL, help, -1}, 457 {"", menu_op, file_menu, NULL, NULL, -1}, 458 {"", NULL, NULL, NULL, redraw, -1}, 459 {"", NULL, NULL, NULL, modes_op, -1}, 460 {"", menu_op, search_menu, NULL, NULL, -1}, 461 {"", menu_op, misc_menu, NULL, NULL, -1}, 462 {NULL, NULL, NULL, NULL, NULL, -1} 463 }; 464 465 char *help_text[23]; 466 char *control_keys[5]; 467 468 char *emacs_help_text[22]; 469 char *emacs_control_keys[5]; 470 471 char *command_strings[5]; 472 char *commands[30]; 473 char *init_strings[20]; 474 475 #define MENU_WARN 1 476 477 #define max_alpha_char 36 478 479 /* 480 | Declarations for strings for localization 481 */ 482 483 char *com_win_message; /* to be shown in com_win if no info window */ 484 char *no_file_string; 485 char *ascii_code_str; 486 char *printer_msg_str; 487 char *command_str; 488 char *file_write_prompt_str; 489 char *file_read_prompt_str; 490 char *char_str; 491 char *unkn_cmd_str; 492 char *non_unique_cmd_msg; 493 char *line_num_str; 494 char *line_len_str; 495 char *current_file_str; 496 char *usage0; 497 char *usage1; 498 char *usage2; 499 char *usage3; 500 char *usage4; 501 char *file_is_dir_msg; 502 char *new_file_msg; 503 char *cant_open_msg; 504 char *open_file_msg; 505 char *file_read_fin_msg; 506 char *reading_file_msg; 507 char *read_only_msg; 508 char *file_read_lines_msg; 509 char *save_file_name_prompt; 510 char *file_not_saved_msg; 511 char *changes_made_prompt; 512 char *yes_char; 513 char *file_exists_prompt; 514 char *create_file_fail_msg; 515 char *writing_file_msg; 516 char *file_written_msg; 517 char *searching_msg; 518 char *str_not_found_msg; 519 char *search_prompt_str; 520 char *exec_err_msg; 521 char *continue_msg; 522 char *menu_cancel_msg; 523 char *menu_size_err_msg; 524 char *press_any_key_msg; 525 char *shell_prompt; 526 char *formatting_msg; 527 char *shell_echo_msg; 528 char *spell_in_prog_msg; 529 char *margin_prompt; 530 char *restricted_msg; 531 char *ON; 532 char *OFF; 533 char *HELP; 534 char *WRITE; 535 char *READ; 536 char *LINE; 537 char *FILE_str; 538 char *CHARACTER; 539 char *REDRAW; 540 char *RESEQUENCE; 541 char *AUTHOR; 542 char *VERSION; 543 char *CASE; 544 char *NOCASE; 545 char *EXPAND; 546 char *NOEXPAND; 547 char *Exit_string; 548 char *QUIT_string; 549 char *INFO; 550 char *NOINFO; 551 char *MARGINS; 552 char *NOMARGINS; 553 char *AUTOFORMAT; 554 char *NOAUTOFORMAT; 555 char *Echo; 556 char *PRINTCOMMAND; 557 char *RIGHTMARGIN; 558 char *HIGHLIGHT; 559 char *NOHIGHLIGHT; 560 char *EIGHTBIT; 561 char *NOEIGHTBIT; 562 char *EMACS_string; 563 char *NOEMACS_string; 564 char *conf_dump_err_msg; 565 char *conf_dump_success_msg; 566 char *conf_not_saved_msg; 567 char *ree_no_file_msg; 568 char *cancel_string; 569 char *menu_too_lrg_msg; 570 char *more_above_str, *more_below_str; 571 char *separator = "==============================================================================="; 572 573 #ifndef __STDC__ 574 #ifndef HAS_STDLIB 575 extern char *malloc(); 576 extern char *realloc(); 577 extern char *getenv(); 578 FILE *fopen(); /* declaration for open function */ 579 #endif /* HAS_STDLIB */ 580 #endif /* __STDC__ */ 581 582 /* beginning of main program */ 583 int 584 main(int argc, char *argv[]) 585 { 586 int counter; 587 588 for (counter = 1; counter < 24; counter++) 589 signal(counter, SIG_IGN); 590 591 /* Always read from (and write to) a terminal. */ 592 if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) { 593 fprintf(stderr, 594 "ee's standard input and output must be a terminal\n"); 595 exit(1); 596 } 597 598 signal(SIGCHLD, SIG_DFL); 599 signal(SIGSEGV, SIG_DFL); 600 signal(SIGINT, edit_abort); 601 d_word = malloc(150); 602 *d_word = '\0'; 603 d_line = NULL; 604 dlt_line = txtalloc(); 605 dlt_line->line = d_line; 606 dlt_line->line_length = 0; 607 curr_line = first_line = txtalloc(); 608 curr_line->line = point = malloc(10); 609 curr_line->line_length = 1; 610 curr_line->max_length = 10; 611 curr_line->prev_line = NULL; 612 curr_line->next_line = NULL; 613 curr_line->line_number = 1; 614 srch_str = NULL; 615 u_srch_str = NULL; 616 position = 1; 617 scr_pos =0; 618 scr_vert = 0; 619 scr_horz = 0; 620 absolute_lin = 1; 621 bit_bucket = fopen("/dev/null", "w"); 622 edit = TRUE; 623 gold = case_sen = FALSE; 624 shell_fork = TRUE; 625 strings_init(); 626 ee_init(); 627 if (argc > 0 ) 628 get_options(argc, argv); 629 set_up_term(); 630 if (right_margin == 0) 631 right_margin = COLS - 1; 632 if (top_of_stack == NULL) 633 { 634 if (restrict_mode()) 635 { 636 wmove(com_win, 0, 0); 637 werase(com_win); 638 wprintw(com_win, "%s", ree_no_file_msg); 639 wrefresh(com_win); 640 edit_abort(0); 641 } 642 wprintw(com_win, "%s", no_file_string); 643 wrefresh(com_win); 644 } 645 else 646 check_fp(); 647 648 clear_com_win = TRUE; 649 650 counter = 0; 651 652 while(edit) 653 { 654 /* 655 | display line and column information 656 */ 657 if (info_window) 658 { 659 if (!nohighlight) 660 wstandout(info_win); 661 wmove(info_win, 5, 0); 662 wprintw(info_win, "%s", separator); 663 wmove(info_win, 5, 5); 664 wprintw(info_win, "line %d col %d lines from top %d ", 665 curr_line->line_number, scr_horz, absolute_lin); 666 wstandend(info_win); 667 wrefresh(info_win); 668 } 669 670 wrefresh(text_win); 671 { 672 wint_t win; 673 int wret = wget_wch(text_win, &win); 674 /* 675 * ERR if the undersneath terminal is closed (like network failure on a ssh 676 * session) 677 * Normal exit as this is not an editor's error, but a network connection 678 * issue 679 */ 680 if (wret == ERR) 681 { 682 if (errno == EINTR) 683 continue; 684 exit(0); 685 } 686 in = (int)win; 687 688 resize_check(); 689 690 if (clear_com_win) 691 { 692 clear_com_win = FALSE; 693 wmove(com_win, 0, 0); 694 werase(com_win); 695 if (!info_window) 696 { 697 wprintw(com_win, "%s", com_win_message); 698 } 699 wrefresh(com_win); 700 } 701 702 if (wret == KEY_CODE_YES) 703 function_key(); 704 else if ((in == '\10') || (in == 127)) 705 { 706 in = 8; 707 delete(TRUE); 708 } 709 else if (in >= 0x80) 710 { 711 unsigned char mb[MB_LEN_MAX + 1]; 712 mbstate_t mbs; 713 memset(&mbs, 0, sizeof(mbs)); 714 size_t n = wcrtomb((char *)mb, (wchar_t)win, 715 &mbs); 716 if (n != (size_t)-1) 717 insert_utf8(mb, (int)n); 718 } 719 else if ((in > 31) || (in == 9)) 720 insert(in); 721 else if ((in >= 0) && (in <= 31)) 722 { 723 if (emacs_keys_mode) 724 emacs_control(); 725 else 726 control(); 727 } 728 } 729 } 730 return(0); 731 } 732 733 /* resize the line to length + factor*/ 734 unsigned char * 735 resiz_line(int factor, struct text *rline, int rpos) 736 { 737 unsigned char *rpoint; 738 int resiz_var; 739 740 rline->max_length += factor; 741 rpoint = rline->line = realloc(rline->line, rline->max_length ); 742 for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++) 743 rpoint++; 744 return(rpoint); 745 } 746 747 /* insert character into line */ 748 void 749 insert(int character) 750 { 751 int counter; 752 int value; 753 unsigned char *temp; /* temporary pointer */ 754 unsigned char *temp2; /* temporary pointer */ 755 756 if ((character == '\011') && (expand_tabs)) 757 { 758 counter = len_char('\011', scr_horz); 759 for (; counter > 0; counter--) 760 insert(' '); 761 if (auto_format) 762 Auto_Format(); 763 return; 764 } 765 text_changes = TRUE; 766 if ((curr_line->max_length - curr_line->line_length) < 5) 767 point = resiz_line(10, curr_line, position); 768 curr_line->line_length++; 769 temp = point; 770 counter = position; 771 while (counter < curr_line->line_length) /* find end of line */ 772 { 773 counter++; 774 temp++; 775 } 776 temp++; /* increase length of line by one */ 777 while (point < temp) 778 { 779 temp2=temp - 1; 780 *temp= *temp2; /* shift characters over by one */ 781 temp--; 782 } 783 *point = character; /* insert new character */ 784 wclrtoeol(text_win); 785 if (!isprint((unsigned char)character)) 786 { 787 scr_pos = scr_horz += out_char(text_win, character, scr_horz); 788 point++; 789 position++; 790 } 791 else 792 { 793 waddch(text_win, (unsigned char)character); 794 scr_pos = ++scr_horz; 795 point++; 796 position ++; 797 } 798 799 if ((observ_margins) && (right_margin < scr_pos)) 800 { 801 counter = position; 802 while (scr_pos > right_margin) 803 prev_word(); 804 if (scr_pos == 0) 805 { 806 while (position < counter) 807 right(TRUE); 808 } 809 else 810 { 811 counter -= position; 812 insert_line(TRUE); 813 for (value = 0; value < counter; value++) 814 right(TRUE); 815 } 816 } 817 818 if ((scr_horz - horiz_offset) > last_col) 819 { 820 horiz_offset += 8; 821 midscreen(scr_vert, point); 822 } 823 824 if ((auto_format) && (character == ' ') && (!formatted)) 825 Auto_Format(); 826 else if ((character != ' ') && (character != '\t')) 827 formatted = FALSE; 828 829 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 830 } 831 832 /* insert a complete multi-byte UTF-8 character into line */ 833 void 834 insert_utf8(const unsigned char *mb, int len) 835 { 836 int counter; 837 unsigned char *temp; 838 int i; 839 840 text_changes = TRUE; 841 if ((curr_line->max_length - curr_line->line_length) < (len + 5)) 842 point = resiz_line(len + 10, curr_line, position); 843 844 /* shift the tail of the line right by len bytes */ 845 curr_line->line_length += len; 846 temp = point; 847 counter = position; 848 while (counter < curr_line->line_length) 849 { 850 counter++; 851 temp++; 852 } 853 temp += len; 854 while (point + len - 1 < temp) 855 { 856 unsigned char *temp2; 857 858 temp2 = temp - len; 859 *temp = *temp2; 860 temp--; 861 } 862 863 /* copy all bytes of the UTF-8 character */ 864 memmove(point, mb, len); 865 866 /* display the character before advancing past it */ 867 wclrtoeol(text_win); 868 { 869 char buf[5]; 870 memcpy(buf, point, len); 871 buf[len] = '\0'; 872 waddstr(text_win, buf); 873 } 874 875 point += len; 876 position += len; 877 878 scanline(point); 879 scr_pos = scr_horz; 880 881 if ((observ_margins) && (right_margin < scr_pos)) 882 { 883 counter = position; 884 while (scr_pos > right_margin) 885 prev_word(); 886 if (scr_pos == 0) 887 { 888 while (position < counter) 889 right(TRUE); 890 } 891 else 892 { 893 counter -= position; 894 insert_line(TRUE); 895 for (i = 0; i < counter; i++) 896 right(TRUE); 897 } 898 } 899 900 if ((scr_horz - horiz_offset) > last_col) 901 { 902 horiz_offset += 8; 903 midscreen(scr_vert, point); 904 } 905 906 formatted = FALSE; 907 908 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 909 } 910 911 /* delete character */ 912 void 913 delete(int disp) 914 { 915 unsigned char *tp; 916 unsigned char *temp2; 917 struct text *temp_buff; 918 int temp_vert; 919 int temp_pos; 920 int del_width = 1; 921 922 if (point != curr_line->line) /* if not at beginning of line */ 923 { 924 text_changes = TRUE; 925 temp2 = tp = point; 926 unsigned char *prev = utf8_prev(curr_line->line, point); 927 del_width = point - prev; 928 tp -= del_width; 929 point -= del_width; 930 position -= del_width; 931 temp_pos = position; 932 curr_line->line_length -= del_width; 933 scanline(point); 934 scr_pos = scr_horz; 935 if (in == 8) 936 { 937 size_t width = min(del_width, 4); 938 939 memcpy(d_char, point, width); 940 d_char[width] = '\0'; 941 } 942 while (temp_pos <= curr_line->line_length) 943 { 944 temp_pos++; 945 *tp = *temp2; 946 tp++; 947 temp2++; 948 } 949 if ((scr_horz < horiz_offset) && (horiz_offset > 0)) 950 { 951 horiz_offset -= 8; 952 midscreen(scr_vert, point); 953 } 954 } 955 else if (curr_line->prev_line != NULL) 956 { 957 text_changes = TRUE; 958 left(disp); /* go to previous line */ 959 temp_buff = curr_line->next_line; 960 point = resiz_line(temp_buff->line_length, curr_line, position); 961 if (temp_buff->next_line != NULL) 962 temp_buff->next_line->prev_line = curr_line; 963 curr_line->next_line = temp_buff->next_line; 964 temp2 = temp_buff->line; 965 if (in == 8) 966 { 967 d_char[0] = '\n'; 968 d_char[1] = '\0'; 969 } 970 tp = point; 971 temp_pos = 1; 972 while (temp_pos < temp_buff->line_length) 973 { 974 curr_line->line_length++; 975 temp_pos++; 976 *tp = *temp2; 977 tp++; 978 temp2++; 979 } 980 *tp = '\0'; 981 free(temp_buff->line); 982 free(temp_buff); 983 temp_buff = curr_line; 984 temp_vert = scr_vert; 985 scr_pos = scr_horz; 986 if (scr_vert < last_line) 987 { 988 wmove(text_win, scr_vert + 1, 0); 989 wdeleteln(text_win); 990 } 991 while ((temp_buff != NULL) && (temp_vert < last_line)) 992 { 993 temp_buff = temp_buff->next_line; 994 temp_vert++; 995 } 996 if ((temp_vert == last_line) && (temp_buff != NULL)) 997 { 998 tp = temp_buff->line; 999 wmove(text_win, last_line,0); 1000 wclrtobot(text_win); 1001 draw_line(last_line, 0, tp, 1, temp_buff->line_length); 1002 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1003 } 1004 } 1005 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 1006 formatted = FALSE; 1007 } 1008 1009 /* find the proper horizontal position for the pointer */ 1010 void 1011 scanline(unsigned char *pos) 1012 { 1013 int temp; 1014 unsigned char *ptr; 1015 1016 ptr = curr_line->line; 1017 temp = 0; 1018 while (ptr < pos) 1019 { 1020 if (*ptr <= 8) 1021 temp += 2; 1022 else if (*ptr == 9) 1023 temp += tabshift(temp); 1024 else if ((*ptr >= 10) && (*ptr <= 31)) 1025 temp += 2; 1026 else if ((*ptr >= 32) && (*ptr < 127)) 1027 temp++; 1028 else if (*ptr == 127) 1029 temp += 2; 1030 else if (*ptr >= 0x80) 1031 { 1032 temp += utf8_width(ptr); 1033 ptr += utf8_len(ptr); 1034 continue; 1035 } 1036 else 1037 temp++; 1038 ptr++; 1039 } 1040 scr_horz = temp; 1041 if ((scr_horz - horiz_offset) > last_col) 1042 { 1043 horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8); 1044 midscreen(scr_vert, point); 1045 } 1046 else if (scr_horz < horiz_offset) 1047 { 1048 horiz_offset = max(0, (scr_horz - (scr_horz % 8))); 1049 midscreen(scr_vert, point); 1050 } 1051 } 1052 1053 /* give the number of spaces to shift */ 1054 int 1055 tabshift(int temp_int) 1056 { 1057 int leftover; 1058 1059 leftover = ((temp_int + 1) % 8); 1060 if (leftover == 0) 1061 return (1); 1062 else 1063 return (9 - leftover); 1064 } 1065 1066 /* output non-printing character */ 1067 int 1068 out_char(WINDOW *window, int character, int column) 1069 { 1070 int i1, i2; 1071 char *string; 1072 char string2[8]; 1073 1074 if (character == TAB) 1075 { 1076 i1 = tabshift(column); 1077 for (i2 = 0; 1078 (i2 < i1) && (((column+i2+1)-horiz_offset) < last_col); i2++) 1079 { 1080 waddch(window, ' '); 1081 } 1082 return(i1); 1083 } 1084 else if ((character >= '\0') && (character < ' ')) 1085 { 1086 string = table[(int) character]; 1087 } 1088 else if ((character < 0) || (character >= 127)) 1089 { 1090 if (character == 127) 1091 string = "^?"; 1092 else if (!eightbit) 1093 { 1094 sprintf(string2, "<%d>", (character < 0) ? (character + 256) : character); 1095 string = string2; 1096 } 1097 else 1098 { 1099 waddch(window, (unsigned char)character ); 1100 return(1); 1101 } 1102 } 1103 else 1104 { 1105 waddch(window, (unsigned char)character); 1106 return(1); 1107 } 1108 for (i2 = 0; (string[i2] != '\0') && (((column+i2+1)-horiz_offset) < last_col); i2++) 1109 waddch(window, (unsigned char)string[i2]); 1110 return(strlen(string)); 1111 } 1112 1113 /* return the length of the character */ 1114 int 1115 len_char(int character, int column) 1116 { 1117 int length; 1118 1119 if (character == '\t') 1120 length = tabshift(column); 1121 else if ((character >= 0) && (character < 32)) 1122 length = 2; 1123 else if ((character >= 32) && (character <= 126)) 1124 length = 1; 1125 else if (character == 127) 1126 length = 2; 1127 else if (((character > 126) || (character < 0)) && (!eightbit)) 1128 length = 5; 1129 else 1130 length = 1; 1131 1132 return(length); 1133 } 1134 1135 /* redraw line from current position */ 1136 void 1137 draw_line(int vertical, int horiz, unsigned char *ptr, int t_pos, int length) 1138 { 1139 int d; /* partial length of special or tab char to display */ 1140 unsigned char *temp; /* temporary pointer to position in line */ 1141 int abs_column; /* offset in screen units from begin of line */ 1142 int column; /* horizontal position on screen */ 1143 int row; /* vertical position on screen */ 1144 int posit; /* temporary position indicator within line */ 1145 1146 abs_column = horiz; 1147 column = horiz - horiz_offset; 1148 row = vertical; 1149 temp = ptr; 1150 d = 0; 1151 posit = t_pos; 1152 if (column < 0) 1153 { 1154 wmove(text_win, row, 0); 1155 wclrtoeol(text_win); 1156 } 1157 while (column < 0) 1158 { 1159 if (*temp >= 0x80) 1160 { 1161 d = utf8_width(temp); 1162 abs_column += d; 1163 column += d; 1164 posit += utf8_len(temp); 1165 temp += utf8_len(temp); 1166 } 1167 else 1168 { 1169 d = len_char(*temp, abs_column); 1170 abs_column += d; 1171 column += d; 1172 posit++; 1173 temp++; 1174 } 1175 } 1176 wmove(text_win, row, column); 1177 wclrtoeol(text_win); 1178 while ((posit < length) && (column <= last_col)) 1179 { 1180 if (*temp >= 0x80) 1181 { 1182 int clen = utf8_len(temp); 1183 int dw = utf8_width(temp); 1184 char buf[5]; 1185 memcpy(buf, temp, clen); 1186 buf[clen] = '\0'; 1187 waddstr(text_win, buf); 1188 abs_column += dw; 1189 column += dw; 1190 posit += clen; 1191 temp += clen; 1192 } 1193 else if (!isprint(*temp)) 1194 { 1195 column += len_char(*temp, abs_column); 1196 abs_column += out_char(text_win, *temp, abs_column); 1197 posit++; 1198 temp++; 1199 } 1200 else 1201 { 1202 abs_column++; 1203 column++; 1204 waddch(text_win, *temp); 1205 posit++; 1206 temp++; 1207 } 1208 } 1209 if (column < last_col) 1210 wclrtoeol(text_win); 1211 wmove(text_win, vertical, (horiz - horiz_offset)); 1212 } 1213 1214 /* insert new line */ 1215 void 1216 insert_line(int disp) 1217 { 1218 int temp_pos; 1219 int temp_pos2; 1220 unsigned char *temp; 1221 unsigned char *extra; 1222 struct text *temp_nod; 1223 1224 text_changes = TRUE; 1225 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1226 wclrtoeol(text_win); 1227 temp_nod= txtalloc(); 1228 temp_nod->line = extra= malloc(10); 1229 temp_nod->line_length = 1; 1230 temp_nod->max_length = 10; 1231 temp_nod->line_number = curr_line->line_number + 1; 1232 temp_nod->next_line = curr_line->next_line; 1233 if (temp_nod->next_line != NULL) 1234 temp_nod->next_line->prev_line = temp_nod; 1235 temp_nod->prev_line = curr_line; 1236 curr_line->next_line = temp_nod; 1237 temp_pos2 = position; 1238 temp = point; 1239 if (temp_pos2 < curr_line->line_length) 1240 { 1241 temp_pos = 1; 1242 while (temp_pos2 < curr_line->line_length) 1243 { 1244 if ((temp_nod->max_length - temp_nod->line_length)< 5) 1245 extra = resiz_line(10, temp_nod, temp_pos); 1246 temp_nod->line_length++; 1247 temp_pos++; 1248 temp_pos2++; 1249 *extra= *temp; 1250 extra++; 1251 temp++; 1252 } 1253 temp=point; 1254 *temp = '\0'; 1255 temp = resiz_line((1 - temp_nod->line_length), curr_line, position); 1256 curr_line->line_length = 1 + temp - curr_line->line; 1257 } 1258 curr_line->line_length = position; 1259 absolute_lin++; 1260 curr_line = temp_nod; 1261 *extra = '\0'; 1262 position = 1; 1263 point= curr_line->line; 1264 if (disp) 1265 { 1266 if (scr_vert < last_line) 1267 { 1268 scr_vert++; 1269 wclrtoeol(text_win); 1270 wmove(text_win, scr_vert, 0); 1271 winsertln(text_win); 1272 } 1273 else 1274 { 1275 wmove(text_win, 0,0); 1276 wdeleteln(text_win); 1277 wmove(text_win, last_line,0); 1278 wclrtobot(text_win); 1279 } 1280 scr_pos = scr_horz = 0; 1281 if (horiz_offset) 1282 { 1283 horiz_offset = 0; 1284 midscreen(scr_vert, point); 1285 } 1286 draw_line(scr_vert, scr_horz, point, position, 1287 curr_line->line_length); 1288 } 1289 } 1290 1291 /* allocate space for line structure */ 1292 struct text * 1293 txtalloc(void) 1294 { 1295 return((struct text *) malloc(sizeof( struct text))); 1296 } 1297 1298 /* allocate space for file name list node */ 1299 struct files * 1300 name_alloc(void) 1301 { 1302 return((struct files *) malloc(sizeof( struct files))); 1303 } 1304 1305 /* move to next word in string */ 1306 unsigned char * 1307 next_word(unsigned char *string) 1308 { 1309 while ((*string != '\0') && ((*string != 32) && (*string != 9))) 1310 string++; 1311 while ((*string != '\0') && ((*string == 32) || (*string == 9))) 1312 string++; 1313 return(string); 1314 } 1315 1316 /* move to start of previous word in text */ 1317 void 1318 prev_word(void) 1319 { 1320 if (position != 1) 1321 { 1322 if ((position != 1) && ((point[-1] == ' ') || (point[-1] == '\t'))) 1323 { /* if at the start of a word */ 1324 while ((position != 1) && ((*point != ' ') && (*point != '\t'))) 1325 left(TRUE); 1326 } 1327 while ((position != 1) && ((*point == ' ') || (*point == '\t'))) 1328 left(TRUE); 1329 while ((position != 1) && ((*point != ' ') && (*point != '\t'))) 1330 left(TRUE); 1331 if ((position != 1) && ((*point == ' ') || (*point == '\t'))) 1332 right(TRUE); 1333 } 1334 else 1335 left(TRUE); 1336 } 1337 1338 /* use control for commands */ 1339 void 1340 control(void) 1341 { 1342 char *string; 1343 1344 if (in == 1) /* control a */ 1345 { 1346 string = get_string(ascii_code_str, TRUE); 1347 if (*string != '\0') 1348 { 1349 in = atoi(string); 1350 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1351 insert(in); 1352 } 1353 free(string); 1354 } 1355 else if (in == 2) /* control b */ 1356 bottom(); 1357 else if (in == 3) /* control c */ 1358 { 1359 command_prompt(); 1360 } 1361 else if (in == 4) /* control d */ 1362 down(); 1363 else if (in == 5) /* control e */ 1364 search_prompt(); 1365 else if (in == 6) /* control f */ 1366 undel_char(); 1367 else if (in == 7) /* control g */ 1368 bol(); 1369 else if (in == 8) /* control h */ 1370 delete(TRUE); 1371 else if (in == 9) /* control i */ 1372 ; 1373 else if (in == 10) /* control j */ 1374 insert_line(TRUE); 1375 else if (in == 11) /* control k */ 1376 del_char(); 1377 else if (in == 12) /* control l */ 1378 left(TRUE); 1379 else if (in == 13) /* control m */ 1380 insert_line(TRUE); 1381 else if (in == 14) /* control n */ 1382 move_rel('d', max(5, (last_line - 5))); 1383 else if (in == 15) /* control o */ 1384 eol(); 1385 else if (in == 16) /* control p */ 1386 move_rel('u', max(5, (last_line - 5))); 1387 else if (in == 17) /* control q */ 1388 ; 1389 else if (in == 18) /* control r */ 1390 right(TRUE); 1391 else if (in == 19) /* control s */ 1392 ; 1393 else if (in == 20) /* control t */ 1394 top(); 1395 else if (in == 21) /* control u */ 1396 up(); 1397 else if (in == 22) /* control v */ 1398 undel_word(); 1399 else if (in == 23) /* control w */ 1400 del_word(); 1401 else if (in == 24) /* control x */ 1402 search(TRUE); 1403 else if (in == 25) /* control y */ 1404 del_line(); 1405 else if (in == 26) /* control z */ 1406 undel_line(); 1407 else if (in == 27) /* control [ (escape) */ 1408 { 1409 menu_op(main_menu); 1410 } 1411 } 1412 1413 /* 1414 | Emacs control-key bindings 1415 */ 1416 1417 void 1418 emacs_control(void) 1419 { 1420 char *string; 1421 1422 if (in == 1) /* control a */ 1423 bol(); 1424 else if (in == 2) /* control b */ 1425 left(TRUE); 1426 else if (in == 3) /* control c */ 1427 { 1428 command_prompt(); 1429 } 1430 else if (in == 4) /* control d */ 1431 del_char(); 1432 else if (in == 5) /* control e */ 1433 eol(); 1434 else if (in == 6) /* control f */ 1435 right(TRUE); 1436 else if (in == 7) /* control g */ 1437 move_rel('u', max(5, (last_line - 5))); 1438 else if (in == 8) /* control h */ 1439 delete(TRUE); 1440 else if (in == 9) /* control i */ 1441 ; 1442 else if (in == 10) /* control j */ 1443 undel_char(); 1444 else if (in == 11) /* control k */ 1445 del_line(); 1446 else if (in == 12) /* control l */ 1447 undel_line(); 1448 else if (in == 13) /* control m */ 1449 insert_line(TRUE); 1450 else if (in == 14) /* control n */ 1451 down(); 1452 else if (in == 15) /* control o */ 1453 { 1454 string = get_string(ascii_code_str, TRUE); 1455 if (*string != '\0') 1456 { 1457 in = atoi(string); 1458 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1459 insert(in); 1460 } 1461 free(string); 1462 } 1463 else if (in == 16) /* control p */ 1464 up(); 1465 else if (in == 17) /* control q */ 1466 ; 1467 else if (in == 18) /* control r */ 1468 undel_word(); 1469 else if (in == 19) /* control s */ 1470 ; 1471 else if (in == 20) /* control t */ 1472 top(); 1473 else if (in == 21) /* control u */ 1474 bottom(); 1475 else if (in == 22) /* control v */ 1476 move_rel('d', max(5, (last_line - 5))); 1477 else if (in == 23) /* control w */ 1478 del_word(); 1479 else if (in == 24) /* control x */ 1480 search(TRUE); 1481 else if (in == 25) /* control y */ 1482 search_prompt(); 1483 else if (in == 26) /* control z */ 1484 adv_word(); 1485 else if (in == 27) /* control [ (escape) */ 1486 { 1487 menu_op(main_menu); 1488 } 1489 } 1490 1491 /* go to bottom of file */ 1492 void 1493 bottom(void) 1494 { 1495 while (curr_line->next_line != NULL) 1496 { 1497 curr_line = curr_line->next_line; 1498 absolute_lin++; 1499 } 1500 point = curr_line->line; 1501 if (horiz_offset) 1502 horiz_offset = 0; 1503 position = 1; 1504 midscreen(last_line, point); 1505 scr_pos = scr_horz; 1506 } 1507 1508 /* go to top of file */ 1509 void 1510 top(void) 1511 { 1512 while (curr_line->prev_line != NULL) 1513 { 1514 curr_line = curr_line->prev_line; 1515 absolute_lin--; 1516 } 1517 point = curr_line->line; 1518 if (horiz_offset) 1519 horiz_offset = 0; 1520 position = 1; 1521 midscreen(0, point); 1522 scr_pos = scr_horz; 1523 } 1524 1525 /* move pointers to start of next line */ 1526 void 1527 nextline(void) 1528 { 1529 curr_line = curr_line->next_line; 1530 absolute_lin++; 1531 point = curr_line->line; 1532 position = 1; 1533 if (scr_vert == last_line) 1534 { 1535 wmove(text_win, 0,0); 1536 wdeleteln(text_win); 1537 wmove(text_win, last_line,0); 1538 wclrtobot(text_win); 1539 draw_line(last_line,0,point,1,curr_line->line_length); 1540 } 1541 else 1542 scr_vert++; 1543 } 1544 1545 /* move pointers to start of previous line*/ 1546 void 1547 prevline(void) 1548 { 1549 curr_line = curr_line->prev_line; 1550 absolute_lin--; 1551 point = curr_line->line; 1552 position = 1; 1553 if (scr_vert == 0) 1554 { 1555 winsertln(text_win); 1556 draw_line(0,0,point,1,curr_line->line_length); 1557 } 1558 else 1559 scr_vert--; 1560 while (position < curr_line->line_length) 1561 { 1562 position++; 1563 point++; 1564 } 1565 } 1566 1567 /* move left one character */ 1568 void 1569 left(int disp) 1570 { 1571 if (point != curr_line->line) /* if not at begin of line */ 1572 { 1573 unsigned char *prev = utf8_prev(curr_line->line, point); 1574 int char_bytes = point - prev; 1575 point = prev; 1576 position -= char_bytes; 1577 scanline(point); 1578 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1579 scr_pos = scr_horz; 1580 } 1581 else if (curr_line->prev_line != NULL) 1582 { 1583 if (!disp) 1584 { 1585 absolute_lin--; 1586 curr_line = curr_line->prev_line; 1587 point = curr_line->line + curr_line->line_length; 1588 position = curr_line->line_length; 1589 return; 1590 } 1591 position = 1; 1592 prevline(); 1593 scanline(point); 1594 scr_pos = scr_horz; 1595 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1596 } 1597 } 1598 1599 /* move right one character */ 1600 void 1601 right(int disp) 1602 { 1603 if (position < curr_line->line_length) 1604 { 1605 int char_bytes = utf8_len(point); 1606 if (position + char_bytes > curr_line->line_length) 1607 char_bytes = curr_line->line_length - position; 1608 point += char_bytes; 1609 position += char_bytes; 1610 scanline(point); 1611 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1612 scr_pos = scr_horz; 1613 } 1614 else if (curr_line->next_line != NULL) 1615 { 1616 if (!disp) 1617 { 1618 absolute_lin++; 1619 curr_line = curr_line->next_line; 1620 point = curr_line->line; 1621 position = 1; 1622 return; 1623 } 1624 nextline(); 1625 scr_pos = scr_horz = 0; 1626 if (horiz_offset) 1627 { 1628 horiz_offset = 0; 1629 midscreen(scr_vert, point); 1630 } 1631 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1632 position = 1; 1633 } 1634 } 1635 1636 /* move to the same column as on other line */ 1637 void 1638 find_pos(void) 1639 { 1640 scr_horz = 0; 1641 position = 1; 1642 while ((scr_horz < scr_pos) && (position < curr_line->line_length)) 1643 { 1644 if (*point == 9) 1645 scr_horz += tabshift(scr_horz); 1646 else if (*point < ' ') 1647 scr_horz += 2; 1648 else if (*point >= 0x80) 1649 { 1650 int clen = utf8_len(point); 1651 int dw = utf8_width(point); 1652 if (scr_horz + dw > scr_pos) 1653 break; 1654 scr_horz += dw; 1655 point += clen; 1656 position += clen; 1657 continue; 1658 } 1659 else 1660 scr_horz++; 1661 position++; 1662 point++; 1663 } 1664 if ((scr_horz - horiz_offset) > last_col) 1665 { 1666 horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8); 1667 midscreen(scr_vert, point); 1668 } 1669 else if (scr_horz < horiz_offset) 1670 { 1671 horiz_offset = max(0, (scr_horz - (scr_horz % 8))); 1672 midscreen(scr_vert, point); 1673 } 1674 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1675 } 1676 1677 /* move up one line */ 1678 void 1679 up(void) 1680 { 1681 if (curr_line->prev_line != NULL) 1682 { 1683 prevline(); 1684 point = curr_line->line; 1685 find_pos(); 1686 } 1687 } 1688 1689 /* move down one line */ 1690 void 1691 down(void) 1692 { 1693 if (curr_line->next_line != NULL) 1694 { 1695 nextline(); 1696 find_pos(); 1697 } 1698 } 1699 1700 /* process function key */ 1701 void 1702 function_key(void) 1703 { 1704 if (in == KEY_LEFT) 1705 left(TRUE); 1706 else if (in == KEY_RIGHT) 1707 right(TRUE); 1708 else if (in == KEY_HOME) 1709 bol(); 1710 else if (in == KEY_END) 1711 eol(); 1712 else if (in == KEY_UP) 1713 up(); 1714 else if (in == KEY_DOWN) 1715 down(); 1716 else if (in == KEY_NPAGE) 1717 move_rel('d', max( 5, (last_line - 5))); 1718 else if (in == KEY_PPAGE) 1719 move_rel('u', max(5, (last_line - 5))); 1720 else if (in == KEY_DL) 1721 del_line(); 1722 else if (in == KEY_DC) 1723 del_char(); 1724 else if (in == KEY_BACKSPACE) 1725 delete(TRUE); 1726 else if (in == KEY_IL) 1727 { /* insert a line before current line */ 1728 insert_line(TRUE); 1729 left(TRUE); 1730 } 1731 else if (in == KEY_F(1)) 1732 gold = !gold; 1733 else if (in == KEY_F(2)) 1734 { 1735 if (gold) 1736 { 1737 gold = FALSE; 1738 undel_line(); 1739 } 1740 else 1741 undel_char(); 1742 } 1743 else if (in == KEY_F(3)) 1744 { 1745 if (gold) 1746 { 1747 gold = FALSE; 1748 undel_word(); 1749 } 1750 else 1751 del_word(); 1752 } 1753 else if (in == KEY_F(4)) 1754 { 1755 if (gold) 1756 { 1757 gold = FALSE; 1758 paint_info_win(); 1759 midscreen(scr_vert, point); 1760 } 1761 else 1762 adv_word(); 1763 } 1764 else if (in == KEY_F(5)) 1765 { 1766 if (gold) 1767 { 1768 gold = FALSE; 1769 search_prompt(); 1770 } 1771 else 1772 search(TRUE); 1773 } 1774 else if (in == KEY_F(6)) 1775 { 1776 if (gold) 1777 { 1778 gold = FALSE; 1779 bottom(); 1780 } 1781 else 1782 top(); 1783 } 1784 else if (in == KEY_F(7)) 1785 { 1786 if (gold) 1787 { 1788 gold = FALSE; 1789 eol(); 1790 } 1791 else 1792 bol(); 1793 } 1794 else if (in == KEY_F(8)) 1795 { 1796 if (gold) 1797 { 1798 gold = FALSE; 1799 command_prompt(); 1800 } 1801 else 1802 adv_line(); 1803 } 1804 } 1805 1806 void 1807 print_buffer(void) 1808 { 1809 char buffer[256]; 1810 1811 sprintf(buffer, ">!%s", print_command); 1812 wmove(com_win, 0, 0); 1813 wclrtoeol(com_win); 1814 wprintw(com_win, printer_msg_str, print_command); 1815 wrefresh(com_win); 1816 command(buffer); 1817 } 1818 1819 void 1820 command_prompt(void) 1821 { 1822 char *cmd_str; 1823 int result; 1824 1825 info_type = COMMANDS; 1826 paint_info_win(); 1827 cmd_str = get_string(command_str, TRUE); 1828 if ((result = unique_test(cmd_str, commands)) != 1) 1829 { 1830 werase(com_win); 1831 wmove(com_win, 0, 0); 1832 if (result == 0) 1833 wprintw(com_win, unkn_cmd_str, cmd_str); 1834 else 1835 wprintw(com_win, "%s", non_unique_cmd_msg); 1836 1837 wrefresh(com_win); 1838 1839 info_type = CONTROL_KEYS; 1840 paint_info_win(); 1841 1842 if (cmd_str != NULL) 1843 free(cmd_str); 1844 return; 1845 } 1846 command(cmd_str); 1847 wrefresh(com_win); 1848 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1849 info_type = CONTROL_KEYS; 1850 paint_info_win(); 1851 if (cmd_str != NULL) 1852 free(cmd_str); 1853 } 1854 1855 /* process commands from keyboard */ 1856 void 1857 command(char *cmd_str1) 1858 { 1859 char *cmd_str2 = NULL; 1860 char *cmd_str = cmd_str1; 1861 1862 clear_com_win = TRUE; 1863 if (compare(cmd_str, HELP, FALSE)) 1864 help(); 1865 else if (compare(cmd_str, WRITE, FALSE)) 1866 { 1867 if (restrict_mode()) 1868 { 1869 return; 1870 } 1871 cmd_str = next_word(cmd_str); 1872 if (*cmd_str == '\0') 1873 { 1874 cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE); 1875 } 1876 tmp_file = resolve_name(cmd_str); 1877 write_file(tmp_file, 1); 1878 if (tmp_file != cmd_str) 1879 free(tmp_file); 1880 } 1881 else if (compare(cmd_str, READ, FALSE)) 1882 { 1883 if (restrict_mode()) 1884 { 1885 return; 1886 } 1887 cmd_str = next_word(cmd_str); 1888 if (*cmd_str == '\0') 1889 { 1890 cmd_str = cmd_str2 = get_string(file_read_prompt_str, TRUE); 1891 } 1892 tmp_file = cmd_str; 1893 recv_file = TRUE; 1894 tmp_file = resolve_name(cmd_str); 1895 check_fp(); 1896 if (tmp_file != cmd_str) 1897 free(tmp_file); 1898 } 1899 else if (compare(cmd_str, LINE, FALSE)) 1900 { 1901 wmove(com_win, 0, 0); 1902 wclrtoeol(com_win); 1903 wprintw(com_win, line_num_str, curr_line->line_number); 1904 wprintw(com_win, line_len_str, curr_line->line_length); 1905 } 1906 else if (compare(cmd_str, FILE_str, FALSE)) 1907 { 1908 wmove(com_win, 0, 0); 1909 wclrtoeol(com_win); 1910 if (in_file_name == NULL) 1911 wprintw(com_win, "%s", no_file_string); 1912 else 1913 wprintw(com_win, current_file_str, in_file_name); 1914 } 1915 else if ((*cmd_str >= '0') && (*cmd_str <= '9')) 1916 goto_line(cmd_str); 1917 else if (compare(cmd_str, CHARACTER, FALSE)) 1918 { 1919 wmove(com_win, 0, 0); 1920 wclrtoeol(com_win); 1921 wprintw(com_win, char_str, *point); 1922 } 1923 else if (compare(cmd_str, REDRAW, FALSE)) 1924 redraw(); 1925 else if (compare(cmd_str, RESEQUENCE, FALSE)) 1926 { 1927 tmp_line = first_line->next_line; 1928 while (tmp_line != NULL) 1929 { 1930 tmp_line->line_number = tmp_line->prev_line->line_number + 1; 1931 tmp_line = tmp_line->next_line; 1932 } 1933 } 1934 else if (compare(cmd_str, AUTHOR, FALSE)) 1935 { 1936 wmove(com_win, 0, 0); 1937 wclrtoeol(com_win); 1938 wprintw(com_win, "written by Hugh Mahon"); 1939 } 1940 else if (compare(cmd_str, VERSION, FALSE)) 1941 { 1942 wmove(com_win, 0, 0); 1943 wclrtoeol(com_win); 1944 wprintw(com_win, "%s", version); 1945 } 1946 else if (compare(cmd_str, CASE, FALSE)) 1947 case_sen = TRUE; 1948 else if (compare(cmd_str, NOCASE, FALSE)) 1949 case_sen = FALSE; 1950 else if (compare(cmd_str, EXPAND, FALSE)) 1951 expand_tabs = TRUE; 1952 else if (compare(cmd_str, NOEXPAND, FALSE)) 1953 expand_tabs = FALSE; 1954 else if (compare(cmd_str, Exit_string, FALSE)) 1955 finish(); 1956 else if (compare(cmd_str, QUIT_string, FALSE)) 1957 quit(0); 1958 else if (*cmd_str == '!') 1959 { 1960 cmd_str++; 1961 if ((*cmd_str == ' ') || (*cmd_str == 9)) 1962 cmd_str = next_word(cmd_str); 1963 sh_command(cmd_str); 1964 } 1965 else if ((*cmd_str == '<') && (!in_pipe)) 1966 { 1967 in_pipe = TRUE; 1968 shell_fork = FALSE; 1969 cmd_str++; 1970 if ((*cmd_str == ' ') || (*cmd_str == '\t')) 1971 cmd_str = next_word(cmd_str); 1972 command(cmd_str); 1973 in_pipe = FALSE; 1974 shell_fork = TRUE; 1975 } 1976 else if ((*cmd_str == '>') && (!out_pipe)) 1977 { 1978 out_pipe = TRUE; 1979 cmd_str++; 1980 if ((*cmd_str == ' ') || (*cmd_str == '\t')) 1981 cmd_str = next_word(cmd_str); 1982 command(cmd_str); 1983 out_pipe = FALSE; 1984 } 1985 else 1986 { 1987 wmove(com_win, 0, 0); 1988 wclrtoeol(com_win); 1989 wprintw(com_win, unkn_cmd_str, cmd_str); 1990 } 1991 if (cmd_str2 != NULL) 1992 free(cmd_str2); 1993 } 1994 1995 /* determine horizontal position for get_string */ 1996 int 1997 scan(char *line, int offset, int column) 1998 { 1999 char *stemp; 2000 int i; 2001 int j; 2002 2003 stemp = line; 2004 i = 0; 2005 j = column; 2006 while (i < offset) 2007 { 2008 if (*(unsigned char *)stemp >= 0x80) 2009 { 2010 int clen = utf8_len((const unsigned char *)stemp); 2011 j += utf8_width((const unsigned char *)stemp); 2012 stemp += clen; 2013 i += clen; 2014 } 2015 else 2016 { 2017 j += len_char(*stemp, j); 2018 stemp++; 2019 i++; 2020 } 2021 } 2022 return(j); 2023 } 2024 2025 /* read string from input on command line */ 2026 char * 2027 get_string(char *prompt, int advance) 2028 { 2029 char *string; 2030 char *tmp_string; 2031 char *nam_str; 2032 char *g_point; 2033 int tmp_int; 2034 int g_horz, g_position, g_pos; 2035 int esc_flag; 2036 2037 g_point = tmp_string = malloc(512); 2038 wmove(com_win,0,0); 2039 wclrtoeol(com_win); 2040 waddstr(com_win, prompt); 2041 wrefresh(com_win); 2042 nam_str = tmp_string; 2043 clear_com_win = TRUE; 2044 g_horz = g_position = scan(prompt, strlen(prompt), 0); 2045 g_pos = 0; 2046 do 2047 { 2048 wint_t win; 2049 int wret; 2050 2051 esc_flag = FALSE; 2052 wret = wget_wch(com_win, &win); 2053 if (wret == ERR) 2054 exit(0); 2055 in = (int)win; 2056 if (wret == KEY_CODE_YES && win == KEY_BACKSPACE) 2057 in = 8; 2058 if (((in == 8) || (in == 127)) && (g_pos > 0)) 2059 { 2060 unsigned char *prev = utf8_prev( 2061 (const unsigned char *)g_point, 2062 (const unsigned char *)nam_str); 2063 int char_bytes = (unsigned char *)nam_str - prev; 2064 tmp_int = g_horz; 2065 g_pos -= char_bytes; 2066 nam_str -= char_bytes; 2067 g_horz = scan(g_point, g_pos, g_position); 2068 tmp_int = tmp_int - g_horz; 2069 for (; 0 < tmp_int; tmp_int--) 2070 { 2071 if ((g_horz+tmp_int) < (last_col - 1)) 2072 { 2073 waddch(com_win, '\010'); 2074 waddch(com_win, ' '); 2075 waddch(com_win, '\010'); 2076 } 2077 } 2078 } 2079 else if (wret == KEY_CODE_YES) 2080 { 2081 /* ignore other function keys in string input */ 2082 } 2083 else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r')) 2084 { 2085 if (in == '\026') /* control-v */ 2086 { 2087 esc_flag = TRUE; 2088 wret = wget_wch(com_win, &win); 2089 if (wret == ERR) 2090 exit(0); 2091 in = (int)win; 2092 } 2093 if (in >= 0x80) 2094 { 2095 char mb[MB_LEN_MAX + 1]; 2096 mbstate_t mbs; 2097 memset(&mbs, 0, sizeof(mbs)); 2098 size_t n = wcrtomb(mb, (wchar_t)win, &mbs); 2099 if (n != (size_t)-1) 2100 { 2101 size_t i; 2102 for (i = 0; i < n; i++) 2103 { 2104 *nam_str = mb[i]; 2105 nam_str++; 2106 g_pos++; 2107 } 2108 if (g_horz < (last_col - 1)) 2109 { 2110 char buf[5]; 2111 memcpy(buf, mb, n); 2112 buf[n] = '\0'; 2113 waddstr(com_win, buf); 2114 } 2115 g_horz += utf8_width( 2116 (const unsigned char *) 2117 (nam_str - n)); 2118 } 2119 } 2120 else 2121 { 2122 *nam_str = in; 2123 g_pos++; 2124 if (!isprint((unsigned char)in) && 2125 (g_horz < (last_col - 1))) 2126 g_horz += out_char(com_win, in, 2127 g_horz); 2128 else 2129 { 2130 g_horz++; 2131 if (g_horz < (last_col - 1)) 2132 waddch(com_win, 2133 (unsigned char)in); 2134 } 2135 nam_str++; 2136 } 2137 } 2138 wrefresh(com_win); 2139 if (esc_flag) 2140 in = '\0'; 2141 } while ((in != '\n') && (in != '\r')); 2142 *nam_str = '\0'; 2143 nam_str = tmp_string; 2144 if (((*nam_str == ' ') || (*nam_str == 9)) && (advance)) 2145 nam_str = next_word(nam_str); 2146 string = malloc(strlen(nam_str) + 1); 2147 strcpy(string, nam_str); 2148 free(tmp_string); 2149 wrefresh(com_win); 2150 return(string); 2151 } 2152 2153 /* compare two strings */ 2154 int 2155 compare(char *string1, char *string2, int sensitive) 2156 { 2157 char *strng1; 2158 char *strng2; 2159 int equal; 2160 2161 strng1 = string1; 2162 strng2 = string2; 2163 if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == '\0') || (*strng2 == '\0')) 2164 return(FALSE); 2165 equal = TRUE; 2166 while (equal) 2167 { 2168 if (sensitive) 2169 { 2170 if (*strng1 != *strng2) 2171 equal = FALSE; 2172 } 2173 else 2174 { 2175 if (toupper((unsigned char)*strng1) != toupper((unsigned char)*strng2)) 2176 equal = FALSE; 2177 } 2178 strng1++; 2179 strng2++; 2180 if ((*strng1 == '\0') || (*strng2 == '\0') || (*strng1 == ' ') || (*strng2 == ' ')) 2181 break; 2182 } 2183 return(equal); 2184 } 2185 2186 void 2187 goto_line(char *cmd_str) 2188 { 2189 int number; 2190 int i; 2191 char *ptr; 2192 char direction = '\0'; 2193 struct text *t_line; 2194 2195 ptr = cmd_str; 2196 i= 0; 2197 while ((*ptr >='0') && (*ptr <= '9')) 2198 { 2199 i= i * 10 + (*ptr - '0'); 2200 ptr++; 2201 } 2202 number = i; 2203 i = 0; 2204 t_line = curr_line; 2205 while ((t_line->line_number > number) && (t_line->prev_line != NULL)) 2206 { 2207 i++; 2208 t_line = t_line->prev_line; 2209 direction = 'u'; 2210 } 2211 while ((t_line->line_number < number) && (t_line->next_line != NULL)) 2212 { 2213 i++; 2214 direction = 'd'; 2215 t_line = t_line->next_line; 2216 } 2217 if ((i < 30) && (i > 0)) 2218 { 2219 move_rel(direction, i); 2220 } 2221 else 2222 { 2223 if (direction != 'd') 2224 { 2225 absolute_lin += i; 2226 } 2227 else 2228 { 2229 absolute_lin -= i; 2230 } 2231 curr_line = t_line; 2232 point = curr_line->line; 2233 position = 1; 2234 midscreen((last_line / 2), point); 2235 scr_pos = scr_horz; 2236 } 2237 wmove(com_win, 0, 0); 2238 wclrtoeol(com_win); 2239 wprintw(com_win, line_num_str, curr_line->line_number); 2240 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2241 } 2242 2243 /* put current line in middle of screen */ 2244 void 2245 midscreen(int line, unsigned char *pnt) 2246 { 2247 struct text *mid_line; 2248 int i; 2249 2250 line = min(line, last_line); 2251 mid_line = curr_line; 2252 for (i = 0; ((i < line) && (curr_line->prev_line != NULL)); i++) 2253 curr_line = curr_line->prev_line; 2254 scr_vert = scr_horz = 0; 2255 wmove(text_win, 0, 0); 2256 draw_screen(); 2257 scr_vert = i; 2258 curr_line = mid_line; 2259 scanline(pnt); 2260 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2261 } 2262 2263 /* get arguments from command line */ 2264 void 2265 get_options(int numargs, char *arguments[]) 2266 { 2267 char *buff; 2268 int count; 2269 struct files *temp_names = NULL; 2270 char *name; 2271 char *ptr; 2272 int no_more_opts = FALSE; 2273 2274 /* 2275 | see if editor was invoked as 'ree' (restricted mode) 2276 */ 2277 2278 if (!(name = strrchr(arguments[0], '/'))) 2279 name = arguments[0]; 2280 else 2281 name++; 2282 if (!strcmp(name, "ree")) 2283 restricted = TRUE; 2284 2285 top_of_stack = NULL; 2286 input_file = FALSE; 2287 recv_file = FALSE; 2288 count = 1; 2289 while ((count < numargs)&& (!no_more_opts)) 2290 { 2291 buff = arguments[count]; 2292 if (!strcmp("-i", buff)) 2293 { 2294 info_window = FALSE; 2295 } 2296 else if (!strcmp("-e", buff)) 2297 { 2298 expand_tabs = FALSE; 2299 } 2300 else if (!strcmp("-h", buff)) 2301 { 2302 nohighlight = TRUE; 2303 } 2304 else if (!strcmp("-?", buff)) 2305 { 2306 fprintf(stderr, usage0, arguments[0]); 2307 fputs(usage1, stderr); 2308 fputs(usage2, stderr); 2309 fputs(usage3, stderr); 2310 fputs(usage4, stderr); 2311 exit(1); 2312 } 2313 else if ((*buff == '+') && (start_at_line == NULL)) 2314 { 2315 buff++; 2316 start_at_line = buff; 2317 } 2318 else if (!(strcmp("--", buff))) 2319 no_more_opts = TRUE; 2320 else 2321 { 2322 count--; 2323 no_more_opts = TRUE; 2324 } 2325 count++; 2326 } 2327 while (count < numargs) 2328 { 2329 buff = arguments[count]; 2330 if (top_of_stack == NULL) 2331 { 2332 temp_names = top_of_stack = name_alloc(); 2333 } 2334 else 2335 { 2336 temp_names->next_name = name_alloc(); 2337 temp_names = temp_names->next_name; 2338 } 2339 ptr = temp_names->name = malloc(strlen(buff) + 1); 2340 while (*buff != '\0') 2341 { 2342 *ptr = *buff; 2343 buff++; 2344 ptr++; 2345 } 2346 *ptr = '\0'; 2347 temp_names->next_name = NULL; 2348 input_file = TRUE; 2349 recv_file = TRUE; 2350 count++; 2351 } 2352 } 2353 2354 /* open or close files according to flags */ 2355 void 2356 check_fp(void) 2357 { 2358 int line_num; 2359 int temp; 2360 struct stat buf; 2361 2362 clear_com_win = TRUE; 2363 tmp_vert = scr_vert; 2364 tmp_horz = scr_horz; 2365 tmp_line = curr_line; 2366 if (input_file) 2367 { 2368 in_file_name = tmp_file = top_of_stack->name; 2369 top_of_stack = top_of_stack->next_name; 2370 } 2371 temp = stat(tmp_file, &buf); 2372 buf.st_mode &= ~07777; 2373 if ((temp != -1) && (buf.st_mode != 0100000) && (buf.st_mode != 0)) 2374 { 2375 wprintw(com_win, file_is_dir_msg, tmp_file); 2376 wrefresh(com_win); 2377 if (input_file) 2378 { 2379 quit(0); 2380 return; 2381 } 2382 else 2383 return; 2384 } 2385 if ((get_fd = open(tmp_file, O_RDONLY)) == -1) 2386 { 2387 wmove(com_win, 0, 0); 2388 wclrtoeol(com_win); 2389 if (input_file) 2390 wprintw(com_win, new_file_msg, tmp_file); 2391 else 2392 wprintw(com_win, cant_open_msg, tmp_file); 2393 wrefresh(com_win); 2394 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2395 wrefresh(text_win); 2396 recv_file = FALSE; 2397 input_file = FALSE; 2398 return; 2399 } 2400 else 2401 get_file(tmp_file); 2402 2403 recv_file = FALSE; 2404 line_num = curr_line->line_number; 2405 scr_vert = tmp_vert; 2406 scr_horz = tmp_horz; 2407 if (input_file) 2408 curr_line= first_line; 2409 else 2410 curr_line = tmp_line; 2411 point = curr_line->line; 2412 draw_screen(); 2413 if (input_file) 2414 { 2415 input_file = FALSE; 2416 if (start_at_line != NULL) 2417 { 2418 line_num = atoi(start_at_line) - 1; 2419 move_rel('d', line_num); 2420 line_num = 0; 2421 start_at_line = NULL; 2422 } 2423 } 2424 else 2425 { 2426 wmove(com_win, 0, 0); 2427 wclrtoeol(com_win); 2428 text_changes = TRUE; 2429 if ((tmp_file != NULL) && (*tmp_file != '\0')) 2430 wprintw(com_win, file_read_fin_msg, tmp_file); 2431 } 2432 wrefresh(com_win); 2433 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2434 wrefresh(text_win); 2435 } 2436 2437 /* read specified file into current buffer */ 2438 void 2439 get_file(char *file_name) 2440 { 2441 int can_read; /* file has at least one character */ 2442 int length; /* length of line read by read */ 2443 int append; /* should text be appended to current line */ 2444 struct text *temp_line; 2445 char ro_flag = FALSE; 2446 2447 if (recv_file) /* if reading a file */ 2448 { 2449 wmove(com_win, 0, 0); 2450 wclrtoeol(com_win); 2451 wprintw(com_win, reading_file_msg, file_name); 2452 if (access(file_name, 2)) /* check permission to write */ 2453 { 2454 if ((errno == ENOTDIR) || (errno == EACCES) || (errno == EROFS) || (errno == ETXTBSY) || (errno == EFAULT)) 2455 { 2456 wprintw(com_win, "%s", read_only_msg); 2457 ro_flag = TRUE; 2458 } 2459 } 2460 wrefresh(com_win); 2461 } 2462 if (curr_line->line_length > 1) /* if current line is not blank */ 2463 { 2464 insert_line(FALSE); 2465 left(FALSE); 2466 append = FALSE; 2467 } 2468 else 2469 append = TRUE; 2470 can_read = FALSE; /* test if file has any characters */ 2471 while (((length = read(get_fd, in_string, 512)) != 0) && (length != -1)) 2472 { 2473 can_read = TRUE; /* if set file has at least 1 character */ 2474 get_line(length, in_string, &append); 2475 } 2476 if ((can_read) && (curr_line->line_length == 1)) 2477 { 2478 temp_line = curr_line->prev_line; 2479 temp_line->next_line = curr_line->next_line; 2480 if (temp_line->next_line != NULL) 2481 temp_line->next_line->prev_line = temp_line; 2482 if (curr_line->line != NULL) 2483 free(curr_line->line); 2484 free(curr_line); 2485 curr_line = temp_line; 2486 } 2487 if (input_file) /* if this is the file to be edited display number of lines */ 2488 { 2489 wmove(com_win, 0, 0); 2490 wclrtoeol(com_win); 2491 wprintw(com_win, file_read_lines_msg, in_file_name, curr_line->line_number); 2492 if (ro_flag) 2493 wprintw(com_win, "%s", read_only_msg); 2494 wrefresh(com_win); 2495 } 2496 else if (can_read) /* not input_file and file is non-zero size */ 2497 text_changes = TRUE; 2498 2499 if (recv_file) /* if reading a file */ 2500 { 2501 in = EOF; 2502 } 2503 } 2504 2505 /* read string and split into lines */ 2506 void 2507 get_line(int length, unsigned char *in_string, int *append) 2508 { 2509 unsigned char *str1; 2510 unsigned char *str2; 2511 int num; /* offset from start of string */ 2512 int char_count; /* length of new line (or added portion */ 2513 int temp_counter; /* temporary counter value */ 2514 struct text *tline; /* temporary pointer to new line */ 2515 int first_time; /* if TRUE, the first time through the loop */ 2516 2517 str2 = in_string; 2518 num = 0; 2519 first_time = TRUE; 2520 while (num < length) 2521 { 2522 if (!first_time) 2523 { 2524 if (num < length) 2525 { 2526 str2++; 2527 num++; 2528 } 2529 } 2530 else 2531 first_time = FALSE; 2532 str1 = str2; 2533 char_count = 1; 2534 /* find end of line */ 2535 while ((*str2 != '\n') && (num < length)) 2536 { 2537 str2++; 2538 num++; 2539 char_count++; 2540 } 2541 if (!(*append)) /* if not append to current line, insert new one */ 2542 { 2543 tline = txtalloc(); /* allocate data structure for next line */ 2544 tline->line_number = curr_line->line_number + 1; 2545 tline->next_line = curr_line->next_line; 2546 tline->prev_line = curr_line; 2547 curr_line->next_line = tline; 2548 if (tline->next_line != NULL) 2549 tline->next_line->prev_line = tline; 2550 curr_line = tline; 2551 curr_line->line = point = (unsigned char *) malloc(char_count); 2552 curr_line->line_length = char_count; 2553 curr_line->max_length = char_count; 2554 } 2555 else 2556 { 2557 point = resiz_line(char_count, curr_line, curr_line->line_length); 2558 curr_line->line_length += (char_count - 1); 2559 } 2560 for (temp_counter = 1; temp_counter < char_count; temp_counter++) 2561 { 2562 *point = *str1; 2563 point++; 2564 str1++; 2565 } 2566 *point = '\0'; 2567 *append = FALSE; 2568 if ((num == length) && (*str2 != '\n')) 2569 *append = TRUE; 2570 } 2571 } 2572 2573 void 2574 draw_screen() /* redraw the screen from current postion */ 2575 { 2576 struct text *temp_line; 2577 unsigned char *line_out; 2578 int temp_vert; 2579 2580 temp_line = curr_line; 2581 temp_vert = scr_vert; 2582 wclrtobot(text_win); 2583 while ((temp_line != NULL) && (temp_vert <= last_line)) 2584 { 2585 line_out = temp_line->line; 2586 draw_line(temp_vert, 0, line_out, 1, temp_line->line_length); 2587 temp_vert++; 2588 temp_line = temp_line->next_line; 2589 } 2590 wmove(text_win, temp_vert, 0); 2591 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2592 } 2593 2594 /* prepare to exit edit session */ 2595 void 2596 finish(void) 2597 { 2598 char *file_name = in_file_name; 2599 2600 /* 2601 | changes made here should be reflected in the 'save' 2602 | portion of file_op() 2603 */ 2604 2605 if ((file_name == NULL) || (*file_name == '\0')) 2606 file_name = get_string(save_file_name_prompt, TRUE); 2607 2608 if ((file_name == NULL) || (*file_name == '\0')) 2609 { 2610 wmove(com_win, 0, 0); 2611 wprintw(com_win, "%s", file_not_saved_msg); 2612 wclrtoeol(com_win); 2613 wrefresh(com_win); 2614 clear_com_win = TRUE; 2615 return; 2616 } 2617 2618 tmp_file = resolve_name(file_name); 2619 if (tmp_file != file_name) 2620 { 2621 free(file_name); 2622 file_name = tmp_file; 2623 } 2624 2625 if (write_file(file_name, 1)) 2626 { 2627 text_changes = FALSE; 2628 quit(0); 2629 } 2630 } 2631 2632 /* exit editor */ 2633 int 2634 quit(int noverify) 2635 { 2636 char *ans; 2637 2638 touchwin(text_win); 2639 wrefresh(text_win); 2640 if ((text_changes) && (!noverify)) 2641 { 2642 ans = get_string(changes_made_prompt, TRUE); 2643 if (toupper((unsigned char)*ans) == toupper((unsigned char)*yes_char)) 2644 text_changes = FALSE; 2645 else 2646 return(0); 2647 free(ans); 2648 } 2649 if (top_of_stack == NULL) 2650 { 2651 if (info_window) 2652 wrefresh(info_win); 2653 wrefresh(com_win); 2654 resetty(); 2655 endwin(); 2656 putchar('\n'); 2657 exit(0); 2658 } 2659 else 2660 { 2661 delete_text(); 2662 recv_file = TRUE; 2663 input_file = TRUE; 2664 check_fp(); 2665 } 2666 return(0); 2667 } 2668 2669 void 2670 edit_abort(int arg) 2671 { 2672 wrefresh(com_win); 2673 resetty(); 2674 endwin(); 2675 putchar('\n'); 2676 exit(1); 2677 } 2678 2679 void 2680 delete_text(void) 2681 { 2682 while (curr_line->next_line != NULL) 2683 curr_line = curr_line->next_line; 2684 while (curr_line != first_line) 2685 { 2686 free(curr_line->line); 2687 curr_line = curr_line->prev_line; 2688 absolute_lin--; 2689 free(curr_line->next_line); 2690 } 2691 curr_line->next_line = NULL; 2692 *curr_line->line = '\0'; 2693 curr_line->line_length = 1; 2694 curr_line->line_number = 1; 2695 point = curr_line->line; 2696 scr_pos = scr_vert = scr_horz = 0; 2697 position = 1; 2698 } 2699 2700 int 2701 write_file(char *file_name, int warn_if_exists) 2702 { 2703 char cr; 2704 char *tmp_point; 2705 struct text *out_line; 2706 int lines, charac; 2707 int temp_pos; 2708 int write_flag = TRUE; 2709 2710 charac = lines = 0; 2711 if (warn_if_exists && 2712 ((in_file_name == NULL) || strcmp(in_file_name, file_name))) 2713 { 2714 if ((temp_fp = fopen(file_name, "r"))) 2715 { 2716 tmp_point = get_string(file_exists_prompt, TRUE); 2717 if (toupper((unsigned char)*tmp_point) == toupper((unsigned char)*yes_char)) 2718 write_flag = TRUE; 2719 else 2720 write_flag = FALSE; 2721 fclose(temp_fp); 2722 free(tmp_point); 2723 } 2724 } 2725 2726 clear_com_win = TRUE; 2727 2728 if (write_flag) 2729 { 2730 if ((temp_fp = fopen(file_name, "w")) == NULL) 2731 { 2732 clear_com_win = TRUE; 2733 wmove(com_win,0,0); 2734 wclrtoeol(com_win); 2735 wprintw(com_win, create_file_fail_msg, file_name); 2736 wrefresh(com_win); 2737 return(FALSE); 2738 } 2739 else 2740 { 2741 wmove(com_win,0,0); 2742 wclrtoeol(com_win); 2743 wprintw(com_win, writing_file_msg, file_name); 2744 wrefresh(com_win); 2745 cr = '\n'; 2746 out_line = first_line; 2747 while (out_line != NULL) 2748 { 2749 temp_pos = 1; 2750 tmp_point= out_line->line; 2751 while (temp_pos < out_line->line_length) 2752 { 2753 putc(*tmp_point, temp_fp); 2754 tmp_point++; 2755 temp_pos++; 2756 } 2757 charac += out_line->line_length; 2758 out_line = out_line->next_line; 2759 putc(cr, temp_fp); 2760 lines++; 2761 } 2762 fclose(temp_fp); 2763 wmove(com_win,0,0); 2764 wclrtoeol(com_win); 2765 wprintw(com_win, file_written_msg, file_name, lines, charac); 2766 wrefresh(com_win); 2767 return(TRUE); 2768 } 2769 } 2770 else 2771 return(FALSE); 2772 } 2773 2774 /* search for string in srch_str */ 2775 int 2776 search(int display_message) 2777 { 2778 int lines_moved; 2779 int iter; 2780 int found; 2781 2782 if ((srch_str == NULL) || (*srch_str == '\0')) 2783 return(FALSE); 2784 if (display_message) 2785 { 2786 wmove(com_win, 0, 0); 2787 wclrtoeol(com_win); 2788 wprintw(com_win, "%s", searching_msg); 2789 wrefresh(com_win); 2790 clear_com_win = TRUE; 2791 } 2792 lines_moved = 0; 2793 found = FALSE; 2794 srch_line = curr_line; 2795 srch_1 = point; 2796 if (position < curr_line->line_length) 2797 srch_1++; 2798 iter = position + 1; 2799 while ((!found) && (srch_line != NULL)) 2800 { 2801 while ((iter < srch_line->line_length) && (!found)) 2802 { 2803 srch_2 = srch_1; 2804 if (case_sen) /* if case sensitive */ 2805 { 2806 srch_3 = srch_str; 2807 while ((*srch_2 == *srch_3) && (*srch_3 != '\0')) 2808 { 2809 found = TRUE; 2810 srch_2++; 2811 srch_3++; 2812 } /* end while */ 2813 } 2814 else /* if not case sensitive */ 2815 { 2816 srch_3 = u_srch_str; 2817 while (*srch_3 != '\0') 2818 { 2819 wchar_t wc_text, wc_srch; 2820 mbstate_t mbs; 2821 int len_text, len_srch; 2822 memset(&mbs, 0, sizeof(mbs)); 2823 len_text = (int)mbrtowc(&wc_text, 2824 (char *)srch_2, 2825 MB_CUR_MAX, &mbs); 2826 if (len_text <= 0) len_text = 1; 2827 memset(&mbs, 0, sizeof(mbs)); 2828 len_srch = (int)mbrtowc(&wc_srch, 2829 (char *)srch_3, 2830 MB_CUR_MAX, &mbs); 2831 if (len_srch <= 0) len_srch = 1; 2832 if (towupper(wc_text) != towupper(wc_srch)) 2833 break; 2834 found = TRUE; 2835 srch_2 += len_text; 2836 srch_3 += len_srch; 2837 } 2838 } /* end else */ 2839 if (!((*srch_3 == '\0') && (found))) 2840 { 2841 found = FALSE; 2842 if (iter < srch_line->line_length) 2843 srch_1++; 2844 iter++; 2845 } 2846 } 2847 if (!found) 2848 { 2849 srch_line = srch_line->next_line; 2850 if (srch_line != NULL) 2851 srch_1 = srch_line->line; 2852 iter = 1; 2853 lines_moved++; 2854 } 2855 } 2856 if (found) 2857 { 2858 if (display_message) 2859 { 2860 wmove(com_win, 0, 0); 2861 wclrtoeol(com_win); 2862 wrefresh(com_win); 2863 } 2864 if (lines_moved == 0) 2865 { 2866 while (position < iter) 2867 right(TRUE); 2868 } 2869 else 2870 { 2871 if (lines_moved < 30) 2872 { 2873 move_rel('d', lines_moved); 2874 while (position < iter) 2875 right(TRUE); 2876 } 2877 else 2878 { 2879 absolute_lin += lines_moved; 2880 curr_line = srch_line; 2881 point = srch_1; 2882 position = iter; 2883 scanline(point); 2884 scr_pos = scr_horz; 2885 midscreen((last_line / 2), point); 2886 } 2887 } 2888 } 2889 else 2890 { 2891 if (display_message) 2892 { 2893 wmove(com_win, 0, 0); 2894 wclrtoeol(com_win); 2895 wprintw(com_win, str_not_found_msg, srch_str); 2896 wrefresh(com_win); 2897 } 2898 wmove(text_win, scr_vert,(scr_horz - horiz_offset)); 2899 } 2900 return(found); 2901 } 2902 2903 /* prompt and read search string (srch_str) */ 2904 void 2905 search_prompt(void) 2906 { 2907 if (srch_str != NULL) 2908 free(srch_str); 2909 if ((u_srch_str != NULL) && (*u_srch_str != '\0')) 2910 free(u_srch_str); 2911 srch_str = get_string(search_prompt_str, FALSE); 2912 gold = FALSE; 2913 srch_3 = srch_str; 2914 srch_1 = u_srch_str = malloc(strlen((char *)srch_str) * 4 + 1); 2915 while (*srch_3 != '\0') 2916 { 2917 if (*srch_3 >= 0x80) 2918 { 2919 wchar_t wc; 2920 mbstate_t mbs; 2921 int clen; 2922 memset(&mbs, 0, sizeof(mbs)); 2923 clen = (int)mbrtowc(&wc, (char *)srch_3, 2924 utf8_len(srch_3), &mbs); 2925 if (clen > 0) 2926 { 2927 wc = towupper(wc); 2928 memset(&mbs, 0, sizeof(mbs)); 2929 size_t n = wcrtomb((char *)srch_1, 2930 wc, &mbs); 2931 if (n != (size_t)-1) 2932 srch_1 += n; 2933 srch_3 += clen; 2934 } 2935 else 2936 { 2937 *srch_1++ = *srch_3++; 2938 } 2939 } 2940 else 2941 { 2942 *srch_1 = toupper(*srch_3); 2943 srch_1++; 2944 srch_3++; 2945 } 2946 } 2947 *srch_1 = '\0'; 2948 search(TRUE); 2949 } 2950 2951 /* delete current character */ 2952 void 2953 del_char(void) 2954 { 2955 in = 8; /* backspace */ 2956 if (position < curr_line->line_length) /* if not end of line */ 2957 { 2958 int clen = utf8_len(point); 2959 if (position + clen > curr_line->line_length) 2960 clen = curr_line->line_length - position; 2961 point += clen; 2962 position += clen; 2963 scanline(point); 2964 delete(TRUE); 2965 } 2966 else 2967 { 2968 right(TRUE); 2969 delete(TRUE); 2970 } 2971 } 2972 2973 /* undelete last deleted character */ 2974 void 2975 undel_char(void) 2976 { 2977 if (d_char[0] == '\n') /* insert line if last del_char deleted eol */ 2978 insert_line(TRUE); 2979 else if ((unsigned char)d_char[0] >= 0x80) 2980 insert_utf8(d_char, strlen((char *)d_char)); 2981 else 2982 { 2983 in = d_char[0]; 2984 insert(in); 2985 } 2986 } 2987 2988 /* delete word in front of cursor */ 2989 void 2990 del_word(void) 2991 { 2992 int tposit; 2993 int difference; 2994 unsigned char *d_word2; 2995 unsigned char *d_word3; 2996 unsigned char tmp_char[5]; 2997 2998 if (d_word != NULL) 2999 free(d_word); 3000 d_word = malloc(curr_line->line_length); 3001 memcpy(tmp_char, d_char, sizeof(tmp_char)); 3002 d_word3 = point; 3003 d_word2 = d_word; 3004 tposit = position; 3005 while ((tposit < curr_line->line_length) && 3006 ((*d_word3 != ' ') && (*d_word3 != '\t'))) 3007 { 3008 tposit++; 3009 *d_word2 = *d_word3; 3010 d_word2++; 3011 d_word3++; 3012 } 3013 while ((tposit < curr_line->line_length) && 3014 ((*d_word3 == ' ') || (*d_word3 == '\t'))) 3015 { 3016 tposit++; 3017 *d_word2 = *d_word3; 3018 d_word2++; 3019 d_word3++; 3020 } 3021 *d_word2 = '\0'; 3022 d_wrd_len = difference = d_word2 - d_word; 3023 d_word2 = point; 3024 while (tposit < curr_line->line_length) 3025 { 3026 tposit++; 3027 *d_word2 = *d_word3; 3028 d_word2++; 3029 d_word3++; 3030 } 3031 curr_line->line_length -= difference; 3032 *d_word2 = '\0'; 3033 draw_line(scr_vert, scr_horz,point,position,curr_line->line_length); 3034 memcpy(d_char, tmp_char, sizeof(d_char)); 3035 text_changes = TRUE; 3036 formatted = FALSE; 3037 } 3038 3039 /* undelete last deleted word */ 3040 void 3041 undel_word(void) 3042 { 3043 int temp; 3044 int tposit; 3045 unsigned char *tmp_old_ptr; 3046 unsigned char *tmp_space; 3047 unsigned char *tmp_ptr; 3048 unsigned char *d_word_ptr; 3049 3050 /* 3051 | resize line to handle undeleted word 3052 */ 3053 if ((curr_line->max_length - (curr_line->line_length + d_wrd_len)) < 5) 3054 point = resiz_line(d_wrd_len, curr_line, position); 3055 tmp_ptr = tmp_space = malloc(curr_line->line_length + d_wrd_len); 3056 d_word_ptr = d_word; 3057 temp = 1; 3058 /* 3059 | copy d_word contents into temp space 3060 */ 3061 while (temp <= d_wrd_len) 3062 { 3063 temp++; 3064 *tmp_ptr = *d_word_ptr; 3065 tmp_ptr++; 3066 d_word_ptr++; 3067 } 3068 tmp_old_ptr = point; 3069 tposit = position; 3070 /* 3071 | copy contents of line from curent position to eol into 3072 | temp space 3073 */ 3074 while (tposit < curr_line->line_length) 3075 { 3076 temp++; 3077 tposit++; 3078 *tmp_ptr = *tmp_old_ptr; 3079 tmp_ptr++; 3080 tmp_old_ptr++; 3081 } 3082 curr_line->line_length += d_wrd_len; 3083 tmp_old_ptr = point; 3084 *tmp_ptr = '\0'; 3085 tmp_ptr = tmp_space; 3086 tposit = 1; 3087 /* 3088 | now copy contents from temp space back to original line 3089 */ 3090 while (tposit < temp) 3091 { 3092 tposit++; 3093 *tmp_old_ptr = *tmp_ptr; 3094 tmp_ptr++; 3095 tmp_old_ptr++; 3096 } 3097 *tmp_old_ptr = '\0'; 3098 free(tmp_space); 3099 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 3100 } 3101 3102 /* delete from cursor to end of line */ 3103 void 3104 del_line(void) 3105 { 3106 unsigned char *dl1; 3107 unsigned char *dl2; 3108 int tposit; 3109 3110 if (d_line != NULL) 3111 free(d_line); 3112 d_line = malloc(curr_line->line_length); 3113 dl1 = d_line; 3114 dl2 = point; 3115 tposit = position; 3116 while (tposit < curr_line->line_length) 3117 { 3118 *dl1 = *dl2; 3119 dl1++; 3120 dl2++; 3121 tposit++; 3122 } 3123 dlt_line->line_length = 1 + tposit - position; 3124 *dl1 = '\0'; 3125 *point = '\0'; 3126 curr_line->line_length = position; 3127 wclrtoeol(text_win); 3128 if (curr_line->next_line != NULL) 3129 { 3130 right(FALSE); 3131 delete(FALSE); 3132 } 3133 text_changes = TRUE; 3134 } 3135 3136 /* undelete last deleted line */ 3137 void 3138 undel_line(void) 3139 { 3140 unsigned char *ud1; 3141 unsigned char *ud2; 3142 int tposit; 3143 3144 if (dlt_line->line_length == 0) 3145 return; 3146 3147 insert_line(TRUE); 3148 left(TRUE); 3149 point = resiz_line(dlt_line->line_length, curr_line, position); 3150 curr_line->line_length += dlt_line->line_length - 1; 3151 ud1 = point; 3152 ud2 = d_line; 3153 tposit = 1; 3154 while (tposit < dlt_line->line_length) 3155 { 3156 tposit++; 3157 *ud1 = *ud2; 3158 ud1++; 3159 ud2++; 3160 } 3161 *ud1 = '\0'; 3162 draw_line(scr_vert, scr_horz,point,position,curr_line->line_length); 3163 } 3164 3165 /* advance to next word */ 3166 void 3167 adv_word(void) 3168 { 3169 while ((position < curr_line->line_length) && ((*point != 32) && (*point != 9))) 3170 right(TRUE); 3171 while ((position < curr_line->line_length) && ((*point == 32) || (*point == 9))) 3172 right(TRUE); 3173 } 3174 3175 /* move relative to current line */ 3176 void 3177 move_rel(int direction, int lines) 3178 { 3179 int i; 3180 char *tmp; 3181 3182 if (direction == 'u') 3183 { 3184 scr_pos = 0; 3185 while (position > 1) 3186 left(TRUE); 3187 for (i = 0; i < lines; i++) 3188 { 3189 up(); 3190 } 3191 if ((last_line > 5) && ( scr_vert < 4)) 3192 { 3193 tmp = point; 3194 tmp_line = curr_line; 3195 for (i= 0;(i<5)&&(curr_line->prev_line != NULL); i++) 3196 { 3197 up(); 3198 } 3199 scr_vert = scr_vert + i; 3200 curr_line = tmp_line; 3201 absolute_lin += i; 3202 point = tmp; 3203 scanline(point); 3204 } 3205 } 3206 else 3207 { 3208 if ((position != 1) && (curr_line->next_line != NULL)) 3209 { 3210 nextline(); 3211 scr_pos = scr_horz = 0; 3212 if (horiz_offset) 3213 { 3214 horiz_offset = 0; 3215 midscreen(scr_vert, point); 3216 } 3217 } 3218 else 3219 adv_line(); 3220 for (i = 1; i < lines; i++) 3221 { 3222 down(); 3223 } 3224 if ((last_line > 10) && (scr_vert > (last_line - 5))) 3225 { 3226 tmp = point; 3227 tmp_line = curr_line; 3228 for (i=0; (i<5) && (curr_line->next_line != NULL); i++) 3229 { 3230 down(); 3231 } 3232 absolute_lin -= i; 3233 scr_vert = scr_vert - i; 3234 curr_line = tmp_line; 3235 point = tmp; 3236 scanline(point); 3237 } 3238 } 3239 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 3240 } 3241 3242 /* go to end of line */ 3243 void 3244 eol(void) 3245 { 3246 if (position < curr_line->line_length) 3247 { 3248 while (position < curr_line->line_length) 3249 right(TRUE); 3250 } 3251 else if (curr_line->next_line != NULL) 3252 { 3253 right(TRUE); 3254 while (position < curr_line->line_length) 3255 right(TRUE); 3256 } 3257 } 3258 3259 /* move to beginning of line */ 3260 void 3261 bol(void) 3262 { 3263 if (point != curr_line->line) 3264 { 3265 while (point != curr_line->line) 3266 left(TRUE); 3267 } 3268 else if (curr_line->prev_line != NULL) 3269 { 3270 scr_pos = 0; 3271 up(); 3272 } 3273 } 3274 3275 /* advance to beginning of next line */ 3276 void 3277 adv_line(void) 3278 { 3279 if ((point != curr_line->line) || (scr_pos > 0)) 3280 { 3281 while (position < curr_line->line_length) 3282 right(TRUE); 3283 right(TRUE); 3284 } 3285 else if (curr_line->next_line != NULL) 3286 { 3287 scr_pos = 0; 3288 down(); 3289 } 3290 } 3291 3292 void 3293 from_top(void) 3294 { 3295 struct text *tmpline = first_line; 3296 int x = 1; 3297 3298 while ((tmpline != NULL) && (tmpline != curr_line)) 3299 { 3300 x++; 3301 tmpline = tmpline->next_line; 3302 } 3303 absolute_lin = x; 3304 } 3305 3306 /* execute shell command */ 3307 void 3308 sh_command(char *string) 3309 { 3310 char *temp_point; 3311 char *last_slash; 3312 char *path; /* directory path to executable */ 3313 int parent; /* zero if child, child's pid if parent */ 3314 int value; 3315 int return_val; 3316 struct text *line_holder; 3317 3318 if (restrict_mode()) 3319 { 3320 return; 3321 } 3322 3323 if (!(path = getenv("SHELL"))) 3324 path = "/bin/sh"; 3325 last_slash = temp_point = path; 3326 while (*temp_point != '\0') 3327 { 3328 if (*temp_point == '/') 3329 last_slash = ++temp_point; 3330 else 3331 temp_point++; 3332 } 3333 3334 /* 3335 | if in_pipe is true, then output of the shell operation will be 3336 | read by the editor, and curses doesn't need to be turned off 3337 */ 3338 3339 if (!in_pipe) 3340 { 3341 keypad(com_win, FALSE); 3342 keypad(text_win, FALSE); 3343 echo(); 3344 nl(); 3345 noraw(); 3346 resetty(); 3347 3348 #ifndef NCURSE 3349 endwin(); 3350 #endif 3351 } 3352 3353 if (in_pipe) 3354 { 3355 pipe(pipe_in); /* create a pipe */ 3356 parent = fork(); 3357 if (!parent) /* if the child */ 3358 { 3359 /* 3360 | child process which will fork and exec shell command (if shell output is 3361 | to be read by editor) 3362 */ 3363 in_pipe = FALSE; 3364 /* 3365 | redirect stdout to pipe 3366 */ 3367 temp_stdout = dup(1); 3368 close(1); 3369 dup(pipe_in[1]); 3370 /* 3371 | redirect stderr to pipe 3372 */ 3373 temp_stderr = dup(2); 3374 close(2); 3375 dup(pipe_in[1]); 3376 close(pipe_in[1]); 3377 /* 3378 | child will now continue down 'if (!in_pipe)' 3379 | path below 3380 */ 3381 } 3382 else /* if the parent */ 3383 { 3384 /* 3385 | prepare editor to read from the pipe 3386 */ 3387 signal(SIGCHLD, SIG_IGN); 3388 line_holder = curr_line; 3389 tmp_vert = scr_vert; 3390 close(pipe_in[1]); 3391 get_fd = pipe_in[0]; 3392 get_file(""); 3393 close(pipe_in[0]); 3394 scr_vert = tmp_vert; 3395 scr_horz = scr_pos = 0; 3396 position = 1; 3397 curr_line = line_holder; 3398 from_top(); 3399 point = curr_line->line; 3400 out_pipe = FALSE; 3401 signal(SIGCHLD, SIG_DFL); 3402 /* 3403 | since flag "in_pipe" is still TRUE, the path which waits for the child 3404 | process to die will be avoided. 3405 | (the pipe is closed, no more output can be expected) 3406 */ 3407 } 3408 } 3409 if (!in_pipe) 3410 { 3411 signal(SIGINT, SIG_IGN); 3412 if (out_pipe) 3413 { 3414 pipe(pipe_out); 3415 } 3416 /* 3417 | fork process which will exec command 3418 */ 3419 parent = fork(); 3420 if (!parent) /* if the child */ 3421 { 3422 if (shell_fork) 3423 putchar('\n'); 3424 if (out_pipe) 3425 { 3426 /* 3427 | prepare the child process (soon to exec a shell command) to read from the 3428 | pipe (which will be output from the editor's buffer) 3429 */ 3430 close(0); 3431 dup(pipe_out[0]); 3432 close(pipe_out[0]); 3433 close(pipe_out[1]); 3434 } 3435 for (value = 1; value < 24; value++) 3436 signal(value, SIG_DFL); 3437 execl(path, last_slash, "-c", string, NULL); 3438 fprintf(stderr, exec_err_msg, path); 3439 exit(-1); 3440 } 3441 else /* if the parent */ 3442 { 3443 if (out_pipe) 3444 { 3445 /* 3446 | output the contents of the buffer to the pipe (to be read by the 3447 | process forked and exec'd above as stdin) 3448 */ 3449 close(pipe_out[0]); 3450 line_holder = first_line; 3451 while (line_holder != NULL) 3452 { 3453 write(pipe_out[1], line_holder->line, (line_holder->line_length-1)); 3454 write(pipe_out[1], "\n", 1); 3455 line_holder = line_holder->next_line; 3456 } 3457 close(pipe_out[1]); 3458 out_pipe = FALSE; 3459 } 3460 do 3461 { 3462 return_val = wait((int *) 0); 3463 } 3464 while ((return_val != parent) && (return_val != -1)); 3465 /* 3466 | if this process is actually the child of the editor, exit. Here's how it 3467 | works: 3468 | The editor forks a process. If output must be sent to the command to be 3469 | exec'd another process is forked, and that process (the child's child) 3470 | will exec the command. In this case, "shell_fork" will be FALSE. If no 3471 | output is to be performed to the shell command, "shell_fork" will be TRUE. 3472 | If this is the editor process, shell_fork will be true, otherwise this is 3473 | the child of the edit process. 3474 */ 3475 if (!shell_fork) 3476 exit(0); 3477 } 3478 signal(SIGINT, edit_abort); 3479 } 3480 if (shell_fork) 3481 { 3482 fputs(continue_msg, stdout); 3483 fflush(stdout); 3484 while ((in = getchar()) != '\n') 3485 ; 3486 } 3487 3488 if (!in_pipe) 3489 { 3490 fixterm(); 3491 noecho(); 3492 nonl(); 3493 raw(); 3494 keypad(text_win, TRUE); 3495 keypad(com_win, TRUE); 3496 if (info_window) 3497 clearok(info_win, TRUE); 3498 } 3499 3500 redraw(); 3501 } 3502 3503 /* set up the terminal for operating with ae */ 3504 void 3505 set_up_term(void) 3506 { 3507 if (!curses_initialized) 3508 { 3509 initscr(); 3510 savetty(); 3511 noecho(); 3512 raw(); 3513 nonl(); 3514 curses_initialized = TRUE; 3515 } 3516 3517 if (((LINES > 15) && (COLS >= 80)) && info_window) 3518 last_line = LINES - 8; 3519 else 3520 { 3521 info_window = FALSE; 3522 last_line = LINES - 2; 3523 } 3524 3525 idlok(stdscr, TRUE); 3526 com_win = newwin(1, COLS, (LINES - 1), 0); 3527 keypad(com_win, TRUE); 3528 idlok(com_win, TRUE); 3529 wrefresh(com_win); 3530 if (!info_window) 3531 text_win = newwin((LINES - 1), COLS, 0, 0); 3532 else 3533 text_win = newwin((LINES - 7), COLS, 6, 0); 3534 keypad(text_win, TRUE); 3535 idlok(text_win, TRUE); 3536 wrefresh(text_win); 3537 help_win = newwin((LINES - 1), COLS, 0, 0); 3538 keypad(help_win, TRUE); 3539 idlok(help_win, TRUE); 3540 if (info_window) 3541 { 3542 info_type = CONTROL_KEYS; 3543 info_win = newwin(6, COLS, 0, 0); 3544 werase(info_win); 3545 paint_info_win(); 3546 } 3547 3548 last_col = COLS - 1; 3549 local_LINES = LINES; 3550 local_COLS = COLS; 3551 3552 } 3553 3554 void 3555 resize_check(void) 3556 { 3557 if ((LINES == local_LINES) && (COLS == local_COLS)) 3558 return; 3559 3560 if (info_window) 3561 delwin(info_win); 3562 delwin(text_win); 3563 delwin(com_win); 3564 delwin(help_win); 3565 set_up_term(); 3566 redraw(); 3567 wrefresh(text_win); 3568 } 3569 3570 static char item_alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789 "; 3571 3572 int 3573 menu_op(struct menu_entries menu_list[]) 3574 { 3575 WINDOW *temp_win; 3576 int max_width, max_height; 3577 int x_off, y_off; 3578 int counter; 3579 int length; 3580 int input; 3581 int temp; 3582 int list_size; 3583 int top_offset; /* offset from top where menu items start */ 3584 int vert_size; /* vertical size for menu list item display */ 3585 int off_start = 1; /* offset from start of menu items to start display */ 3586 3587 3588 /* 3589 | determine number and width of menu items 3590 */ 3591 3592 list_size = 1; 3593 while (menu_list[list_size + 1].item_string != NULL) 3594 list_size++; 3595 max_width = 0; 3596 for (counter = 0; counter <= list_size; counter++) 3597 { 3598 if ((length = strlen(menu_list[counter].item_string)) > max_width) 3599 max_width = length; 3600 } 3601 max_width += 3; 3602 max_width = max(max_width, strlen(menu_cancel_msg)); 3603 max_width = max(max_width, max(strlen(more_above_str), strlen(more_below_str))); 3604 max_width += 6; 3605 3606 /* 3607 | make sure that window is large enough to handle menu 3608 | if not, print error message and return to calling function 3609 */ 3610 3611 if (max_width > COLS) 3612 { 3613 wmove(com_win, 0, 0); 3614 werase(com_win); 3615 wprintw(com_win, "%s", menu_too_lrg_msg); 3616 wrefresh(com_win); 3617 clear_com_win = TRUE; 3618 return(0); 3619 } 3620 3621 top_offset = 0; 3622 3623 if (list_size > LINES) 3624 { 3625 max_height = LINES; 3626 if (max_height > 11) 3627 vert_size = max_height - 8; 3628 else 3629 vert_size = max_height; 3630 } 3631 else 3632 { 3633 vert_size = list_size; 3634 max_height = list_size; 3635 } 3636 3637 if (LINES >= (vert_size + 8)) 3638 { 3639 if (menu_list[0].argument != MENU_WARN) 3640 max_height = vert_size + 8; 3641 else 3642 max_height = vert_size + 7; 3643 top_offset = 4; 3644 } 3645 x_off = (COLS - max_width) / 2; 3646 y_off = (LINES - max_height - 1) / 2; 3647 temp_win = newwin(max_height, max_width, y_off, x_off); 3648 keypad(temp_win, TRUE); 3649 3650 paint_menu(menu_list, max_width, max_height, list_size, top_offset, temp_win, off_start, vert_size); 3651 3652 counter = 1; 3653 do 3654 { 3655 if (off_start > 2) 3656 wmove(temp_win, (1 + counter + top_offset - off_start), 3); 3657 else 3658 wmove(temp_win, (counter + top_offset - off_start), 3); 3659 3660 wrefresh(temp_win); 3661 { 3662 wint_t win; 3663 if (wget_wch(temp_win, &win) == ERR) 3664 exit(0); 3665 in = input = (int)win; 3666 } 3667 3668 if (isascii(input) && isalnum(input)) 3669 { 3670 if (isalpha(input)) 3671 { 3672 temp = 1 + tolower(input) - 'a'; 3673 } 3674 else if (isdigit(input)) 3675 { 3676 temp = (2 + 'z' - 'a') + (input - '0'); 3677 } 3678 3679 if (temp <= list_size) 3680 { 3681 input = '\n'; 3682 counter = temp; 3683 } 3684 } 3685 else 3686 { 3687 switch (input) 3688 { 3689 case ' ': /* space */ 3690 case '\004': /* ^d, down */ 3691 case KEY_RIGHT: 3692 case KEY_DOWN: 3693 counter++; 3694 if (counter > list_size) 3695 counter = 1; 3696 break; 3697 case '\010': /* ^h, backspace*/ 3698 case '\025': /* ^u, up */ 3699 case 127: /* ^?, delete */ 3700 case KEY_BACKSPACE: 3701 case KEY_LEFT: 3702 case KEY_UP: 3703 counter--; 3704 if (counter == 0) 3705 counter = list_size; 3706 break; 3707 case '\033': /* escape key */ 3708 if (menu_list[0].argument != MENU_WARN) 3709 counter = 0; 3710 break; 3711 case '\014': /* ^l */ 3712 case '\022': /* ^r, redraw */ 3713 paint_menu(menu_list, max_width, max_height, 3714 list_size, top_offset, temp_win, 3715 off_start, vert_size); 3716 break; 3717 default: 3718 break; 3719 } 3720 } 3721 3722 if (((list_size - off_start) >= (vert_size - 1)) && 3723 (counter > (off_start + vert_size - 3)) && 3724 (off_start > 1)) 3725 { 3726 if (counter == list_size) 3727 off_start = (list_size - vert_size) + 2; 3728 else 3729 off_start++; 3730 3731 paint_menu(menu_list, max_width, max_height, 3732 list_size, top_offset, temp_win, off_start, 3733 vert_size); 3734 } 3735 else if ((list_size != vert_size) && 3736 (counter > (off_start + vert_size - 2))) 3737 { 3738 if (counter == list_size) 3739 off_start = 2 + (list_size - vert_size); 3740 else if (off_start == 1) 3741 off_start = 3; 3742 else 3743 off_start++; 3744 3745 paint_menu(menu_list, max_width, max_height, 3746 list_size, top_offset, temp_win, off_start, 3747 vert_size); 3748 } 3749 else if (counter < off_start) 3750 { 3751 if (counter <= 2) 3752 off_start = 1; 3753 else 3754 off_start = counter; 3755 3756 paint_menu(menu_list, max_width, max_height, 3757 list_size, top_offset, temp_win, off_start, 3758 vert_size); 3759 } 3760 } 3761 while ((input != '\r') && (input != '\n') && (counter != 0)); 3762 3763 werase(temp_win); 3764 wrefresh(temp_win); 3765 delwin(temp_win); 3766 3767 if ((menu_list[counter].procedure != NULL) || 3768 (menu_list[counter].iprocedure != NULL) || 3769 (menu_list[counter].nprocedure != NULL)) 3770 { 3771 if (menu_list[counter].argument != -1) 3772 (*menu_list[counter].iprocedure)(menu_list[counter].argument); 3773 else if (menu_list[counter].ptr_argument != NULL) 3774 (*menu_list[counter].procedure)(menu_list[counter].ptr_argument); 3775 else 3776 (*menu_list[counter].nprocedure)(); 3777 } 3778 3779 if (info_window) 3780 paint_info_win(); 3781 redraw(); 3782 3783 return(counter); 3784 } 3785 3786 void 3787 paint_menu(struct menu_entries menu_list[], int max_width, int max_height, 3788 int list_size, int top_offset, WINDOW *menu_win, int off_start, 3789 int vert_size) 3790 { 3791 int counter, temp_int; 3792 3793 werase(menu_win); 3794 3795 /* 3796 | output top and bottom portions of menu box only if window 3797 | large enough 3798 */ 3799 3800 if (max_height > vert_size) 3801 { 3802 wmove(menu_win, 1, 1); 3803 if (!nohighlight) 3804 wstandout(menu_win); 3805 waddch(menu_win, '+'); 3806 for (counter = 0; counter < (max_width - 4); counter++) 3807 waddch(menu_win, '-'); 3808 waddch(menu_win, '+'); 3809 3810 wmove(menu_win, (max_height - 2), 1); 3811 waddch(menu_win, '+'); 3812 for (counter = 0; counter < (max_width - 4); counter++) 3813 waddch(menu_win, '-'); 3814 waddch(menu_win, '+'); 3815 wstandend(menu_win); 3816 wmove(menu_win, 2, 3); 3817 waddstr(menu_win, menu_list[0].item_string); 3818 wmove(menu_win, (max_height - 3), 3); 3819 if (menu_list[0].argument != MENU_WARN) 3820 waddstr(menu_win, menu_cancel_msg); 3821 } 3822 if (!nohighlight) 3823 wstandout(menu_win); 3824 3825 for (counter = 0; counter < (vert_size + top_offset); counter++) 3826 { 3827 if (top_offset == 4) 3828 { 3829 temp_int = counter + 2; 3830 } 3831 else 3832 temp_int = counter; 3833 3834 wmove(menu_win, temp_int, 1); 3835 waddch(menu_win, '|'); 3836 wmove(menu_win, temp_int, (max_width - 2)); 3837 waddch(menu_win, '|'); 3838 } 3839 wstandend(menu_win); 3840 3841 if (list_size > vert_size) 3842 { 3843 if (off_start >= 3) 3844 { 3845 temp_int = 1; 3846 wmove(menu_win, top_offset, 3); 3847 waddstr(menu_win, more_above_str); 3848 } 3849 else 3850 temp_int = 0; 3851 3852 for (counter = off_start; 3853 ((temp_int + counter - off_start) < (vert_size - 1)); 3854 counter++) 3855 { 3856 wmove(menu_win, (top_offset + temp_int + 3857 (counter - off_start)), 3); 3858 if (list_size > 1) 3859 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3860 waddstr(menu_win, menu_list[counter].item_string); 3861 } 3862 3863 wmove(menu_win, (top_offset + (vert_size - 1)), 3); 3864 3865 if (counter == list_size) 3866 { 3867 if (list_size > 1) 3868 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3869 wprintw(menu_win, "%s", menu_list[counter].item_string); 3870 } 3871 else 3872 wprintw(menu_win, "%s", more_below_str); 3873 } 3874 else 3875 { 3876 for (counter = 1; counter <= list_size; counter++) 3877 { 3878 wmove(menu_win, (top_offset + counter - 1), 3); 3879 if (list_size > 1) 3880 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3881 waddstr(menu_win, menu_list[counter].item_string); 3882 } 3883 } 3884 } 3885 3886 void 3887 help(void) 3888 { 3889 int counter; 3890 3891 werase(help_win); 3892 clearok(help_win, TRUE); 3893 for (counter = 0; counter < 22; counter++) 3894 { 3895 wmove(help_win, counter, 0); 3896 waddstr(help_win, (emacs_keys_mode) ? 3897 emacs_help_text[counter] : help_text[counter]); 3898 } 3899 wrefresh(help_win); 3900 werase(com_win); 3901 wmove(com_win, 0, 0); 3902 wprintw(com_win, "%s", press_any_key_msg); 3903 wrefresh(com_win); 3904 { 3905 wint_t win; 3906 if (wget_wch(com_win, &win) == ERR) 3907 exit(0); 3908 counter = (int)win; 3909 } 3910 werase(com_win); 3911 wmove(com_win, 0, 0); 3912 werase(help_win); 3913 wrefresh(help_win); 3914 wrefresh(com_win); 3915 redraw(); 3916 } 3917 3918 void 3919 paint_info_win(void) 3920 { 3921 int counter; 3922 3923 if (!info_window) 3924 return; 3925 3926 werase(info_win); 3927 for (counter = 0; counter < 5; counter++) 3928 { 3929 wmove(info_win, counter, 0); 3930 wclrtoeol(info_win); 3931 if (info_type == CONTROL_KEYS) 3932 waddstr(info_win, (emacs_keys_mode) ? 3933 emacs_control_keys[counter] : control_keys[counter]); 3934 else if (info_type == COMMANDS) 3935 waddstr(info_win, command_strings[counter]); 3936 } 3937 wmove(info_win, 5, 0); 3938 if (!nohighlight) 3939 wstandout(info_win); 3940 waddstr(info_win, separator); 3941 wstandend(info_win); 3942 wrefresh(info_win); 3943 } 3944 3945 void 3946 no_info_window(void) 3947 { 3948 if (!info_window) 3949 return; 3950 delwin(info_win); 3951 delwin(text_win); 3952 info_window = FALSE; 3953 last_line = LINES - 2; 3954 text_win = newwin((LINES - 1), COLS, 0, 0); 3955 keypad(text_win, TRUE); 3956 idlok(text_win, TRUE); 3957 clearok(text_win, TRUE); 3958 midscreen(scr_vert, point); 3959 wrefresh(text_win); 3960 clear_com_win = TRUE; 3961 } 3962 3963 void 3964 create_info_window(void) 3965 { 3966 if (info_window) 3967 return; 3968 last_line = LINES - 8; 3969 delwin(text_win); 3970 text_win = newwin((LINES - 7), COLS, 6, 0); 3971 keypad(text_win, TRUE); 3972 idlok(text_win, TRUE); 3973 werase(text_win); 3974 info_window = TRUE; 3975 info_win = newwin(6, COLS, 0, 0); 3976 werase(info_win); 3977 info_type = CONTROL_KEYS; 3978 midscreen(min(scr_vert, last_line), point); 3979 clearok(info_win, TRUE); 3980 paint_info_win(); 3981 wrefresh(text_win); 3982 clear_com_win = TRUE; 3983 } 3984 3985 int 3986 file_op(int arg) 3987 { 3988 char *string; 3989 int flag; 3990 3991 if (restrict_mode()) 3992 { 3993 return(0); 3994 } 3995 3996 if (arg == READ_FILE) 3997 { 3998 string = get_string(file_read_prompt_str, TRUE); 3999 recv_file = TRUE; 4000 tmp_file = resolve_name(string); 4001 check_fp(); 4002 if (tmp_file != string) 4003 free(tmp_file); 4004 free(string); 4005 } 4006 else if (arg == WRITE_FILE) 4007 { 4008 string = get_string(file_write_prompt_str, TRUE); 4009 tmp_file = resolve_name(string); 4010 write_file(tmp_file, 1); 4011 if (tmp_file != string) 4012 free(tmp_file); 4013 free(string); 4014 } 4015 else if (arg == SAVE_FILE) 4016 { 4017 /* 4018 | changes made here should be reflected in finish() 4019 */ 4020 4021 if (in_file_name) 4022 flag = TRUE; 4023 else 4024 flag = FALSE; 4025 4026 string = in_file_name; 4027 if ((string == NULL) || (*string == '\0')) 4028 string = get_string(save_file_name_prompt, TRUE); 4029 if ((string == NULL) || (*string == '\0')) 4030 { 4031 wmove(com_win, 0, 0); 4032 wprintw(com_win, "%s", file_not_saved_msg); 4033 wclrtoeol(com_win); 4034 wrefresh(com_win); 4035 clear_com_win = TRUE; 4036 return(0); 4037 } 4038 if (!flag) 4039 { 4040 tmp_file = resolve_name(string); 4041 if (tmp_file != string) 4042 { 4043 free(string); 4044 string = tmp_file; 4045 } 4046 } 4047 if (write_file(string, 1)) 4048 { 4049 in_file_name = string; 4050 text_changes = FALSE; 4051 } 4052 else if (!flag) 4053 free(string); 4054 } 4055 return(0); 4056 } 4057 4058 void 4059 shell_op(void) 4060 { 4061 char *string; 4062 4063 if (((string = get_string(shell_prompt, TRUE)) != NULL) && 4064 (*string != '\0')) 4065 { 4066 sh_command(string); 4067 free(string); 4068 } 4069 } 4070 4071 void 4072 leave_op(void) 4073 { 4074 if (text_changes) 4075 { 4076 menu_op(leave_menu); 4077 } 4078 else 4079 quit(TRUE); 4080 } 4081 4082 void 4083 redraw(void) 4084 { 4085 if (info_window) 4086 { 4087 clearok(info_win, TRUE); 4088 paint_info_win(); 4089 } 4090 else 4091 clearok(text_win, TRUE); 4092 midscreen(scr_vert, point); 4093 } 4094 4095 /* 4096 | The following routines will "format" a paragraph (as defined by a 4097 | block of text with blank lines before and after the block). 4098 */ 4099 4100 /* test if line has any non-space characters */ 4101 int 4102 Blank_Line(struct text *test_line) 4103 { 4104 unsigned char *line; 4105 int length; 4106 4107 if (test_line == NULL) 4108 return(TRUE); 4109 4110 length = 1; 4111 line = test_line->line; 4112 4113 /* 4114 | To handle troff/nroff documents, consider a line with a 4115 | period ('.') in the first column to be blank. To handle mail 4116 | messages with included text, consider a line with a '>' blank. 4117 */ 4118 4119 if ((*line == '.') || (*line == '>')) 4120 return(TRUE); 4121 4122 while (((*line == ' ') || (*line == '\t')) && (length < test_line->line_length)) 4123 { 4124 length++; 4125 line++; 4126 } 4127 if (length != test_line->line_length) 4128 return(FALSE); 4129 else 4130 return(TRUE); 4131 } 4132 4133 /* format the paragraph according to set margins */ 4134 void 4135 Format(void) 4136 { 4137 int string_count; 4138 int offset; 4139 int temp_case; 4140 int status; 4141 int tmp_af; 4142 int counter; 4143 unsigned char *line; 4144 unsigned char *tmp_srchstr; 4145 unsigned char *temp1, *temp2; 4146 unsigned char *temp_dword; 4147 unsigned char temp_d_char[5]; 4148 4149 memcpy(temp_d_char, d_char, sizeof(temp_d_char)); 4150 4151 /* 4152 | if observ_margins is not set, or the current line is blank, 4153 | do not format the current paragraph 4154 */ 4155 4156 if ((!observ_margins) || (Blank_Line(curr_line))) 4157 return; 4158 4159 /* 4160 | save the currently set flags, and clear them 4161 */ 4162 4163 wmove(com_win, 0, 0); 4164 wclrtoeol(com_win); 4165 wprintw(com_win, "%s", formatting_msg); 4166 wrefresh(com_win); 4167 4168 /* 4169 | get current position in paragraph, so after formatting, the cursor 4170 | will be in the same relative position 4171 */ 4172 4173 tmp_af = auto_format; 4174 auto_format = FALSE; 4175 offset = position; 4176 if (position != 1) 4177 prev_word(); 4178 temp_dword = d_word; 4179 d_word = NULL; 4180 temp_case = case_sen; 4181 case_sen = TRUE; 4182 tmp_srchstr = srch_str; 4183 temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); 4184 if ((*point == ' ') || (*point == '\t')) 4185 adv_word(); 4186 offset -= position; 4187 counter = position; 4188 line = temp1 = point; 4189 while ((*temp1 != '\0') && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) 4190 { 4191 *temp2 = *temp1; 4192 temp2++; 4193 temp1++; 4194 counter++; 4195 } 4196 *temp2 = '\0'; 4197 if (position != 1) 4198 bol(); 4199 while (!Blank_Line(curr_line->prev_line)) 4200 bol(); 4201 string_count = 0; 4202 status = TRUE; 4203 while ((line != point) && (status)) 4204 { 4205 status = search(FALSE); 4206 string_count++; 4207 } 4208 4209 wmove(com_win, 0, 0); 4210 wclrtoeol(com_win); 4211 wprintw(com_win, "%s", formatting_msg); 4212 wrefresh(com_win); 4213 4214 /* 4215 | now get back to the start of the paragraph to start formatting 4216 */ 4217 4218 if (position != 1) 4219 bol(); 4220 while (!Blank_Line(curr_line->prev_line)) 4221 bol(); 4222 4223 observ_margins = FALSE; 4224 4225 /* 4226 | Start going through lines, putting spaces at end of lines if they do 4227 | not already exist. Append lines together to get one long line, and 4228 | eliminate spacing at begin of lines. 4229 */ 4230 4231 while (!Blank_Line(curr_line->next_line)) 4232 { 4233 eol(); 4234 left(TRUE); 4235 if (*point != ' ') 4236 { 4237 right(TRUE); 4238 insert(' '); 4239 } 4240 else 4241 right(TRUE); 4242 del_char(); 4243 if ((*point == ' ') || (*point == '\t')) 4244 del_word(); 4245 } 4246 4247 /* 4248 | Now there is one long line. Eliminate extra spaces within the line 4249 | after the first word (so as not to blow away any indenting the user 4250 | may have put in). 4251 */ 4252 4253 bol(); 4254 adv_word(); 4255 while (position < curr_line->line_length) 4256 { 4257 if ((*point == ' ') && (*(point + 1) == ' ')) 4258 del_char(); 4259 else 4260 right(TRUE); 4261 } 4262 4263 /* 4264 | Now make sure there are two spaces after a '.'. 4265 */ 4266 4267 bol(); 4268 while (position < curr_line->line_length) 4269 { 4270 if ((*point == '.') && (*(point + 1) == ' ')) 4271 { 4272 right(TRUE); 4273 insert(' '); 4274 insert(' '); 4275 while (*point == ' ') 4276 del_char(); 4277 } 4278 right(TRUE); 4279 } 4280 4281 observ_margins = TRUE; 4282 bol(); 4283 4284 wmove(com_win, 0, 0); 4285 wclrtoeol(com_win); 4286 wprintw(com_win, "%s", formatting_msg); 4287 wrefresh(com_win); 4288 4289 /* 4290 | create lines between margins 4291 */ 4292 4293 while (position < curr_line->line_length) 4294 { 4295 while ((scr_pos < right_margin) && (position < curr_line->line_length)) 4296 right(TRUE); 4297 if (position < curr_line->line_length) 4298 { 4299 prev_word(); 4300 if (position == 1) 4301 adv_word(); 4302 insert_line(TRUE); 4303 } 4304 } 4305 4306 /* 4307 | go back to begin of paragraph, put cursor back to original position 4308 */ 4309 4310 bol(); 4311 while (!Blank_Line(curr_line->prev_line)) 4312 bol(); 4313 4314 /* 4315 | find word cursor was in 4316 */ 4317 4318 while ((status) && (string_count > 0)) 4319 { 4320 search(FALSE); 4321 string_count--; 4322 } 4323 4324 /* 4325 | offset the cursor to where it was before from the start of the word 4326 */ 4327 4328 while (offset > 0) 4329 { 4330 offset--; 4331 right(TRUE); 4332 } 4333 4334 /* 4335 | reset flags and strings to what they were before formatting 4336 */ 4337 4338 if (d_word != NULL) 4339 free(d_word); 4340 d_word = temp_dword; 4341 case_sen = temp_case; 4342 free(srch_str); 4343 srch_str = tmp_srchstr; 4344 memcpy(d_char, temp_d_char, sizeof(d_char)); 4345 auto_format = tmp_af; 4346 4347 midscreen(scr_vert, point); 4348 werase(com_win); 4349 wrefresh(com_win); 4350 } 4351 4352 unsigned char *init_name[3] = { 4353 "/usr/share/misc/init.ee", 4354 NULL, 4355 ".init.ee" 4356 }; 4357 4358 /* check for init file and read it if it exists */ 4359 void 4360 ee_init(void) 4361 { 4362 FILE *init_file; 4363 unsigned char *string; 4364 unsigned char *str1; 4365 unsigned char *str2; 4366 char *home; 4367 int counter; 4368 int temp_int; 4369 4370 string = getenv("HOME"); 4371 if (string == NULL) 4372 string = "/tmp"; 4373 str1 = home = malloc(strlen(string)+10); 4374 strcpy(home, string); 4375 strcat(home, "/.init.ee"); 4376 init_name[1] = home; 4377 string = malloc(512); 4378 4379 for (counter = 0; counter < 3; counter++) 4380 { 4381 if (!(access(init_name[counter], 4))) 4382 { 4383 init_file = fopen(init_name[counter], "r"); 4384 while ((str2 = fgets(string, 512, init_file)) != NULL) 4385 { 4386 str1 = str2 = string; 4387 while (*str2 != '\n') 4388 str2++; 4389 *str2 = '\0'; 4390 4391 if (unique_test(string, init_strings) != 1) 4392 continue; 4393 4394 if (compare(str1, CASE, FALSE)) 4395 case_sen = TRUE; 4396 else if (compare(str1, NOCASE, FALSE)) 4397 case_sen = FALSE; 4398 else if (compare(str1, EXPAND, FALSE)) 4399 expand_tabs = TRUE; 4400 else if (compare(str1, NOEXPAND, FALSE)) 4401 expand_tabs = FALSE; 4402 else if (compare(str1, INFO, FALSE)) 4403 info_window = TRUE; 4404 else if (compare(str1, NOINFO, FALSE)) 4405 info_window = FALSE; 4406 else if (compare(str1, MARGINS, FALSE)) 4407 observ_margins = TRUE; 4408 else if (compare(str1, NOMARGINS, FALSE)) 4409 observ_margins = FALSE; 4410 else if (compare(str1, AUTOFORMAT, FALSE)) 4411 { 4412 auto_format = TRUE; 4413 observ_margins = TRUE; 4414 } 4415 else if (compare(str1, NOAUTOFORMAT, FALSE)) 4416 auto_format = FALSE; 4417 else if (compare(str1, Echo, FALSE)) 4418 { 4419 str1 = next_word(str1); 4420 if (*str1 != '\0') 4421 echo_string(str1); 4422 } 4423 else if (compare(str1, PRINTCOMMAND, FALSE)) 4424 { 4425 str1 = next_word(str1); 4426 print_command = malloc(strlen(str1)+1); 4427 strcpy(print_command, str1); 4428 } 4429 else if (compare(str1, RIGHTMARGIN, FALSE)) 4430 { 4431 str1 = next_word(str1); 4432 if ((*str1 >= '0') && (*str1 <= '9')) 4433 { 4434 temp_int = atoi(str1); 4435 if (temp_int > 0) 4436 right_margin = temp_int; 4437 } 4438 } 4439 else if (compare(str1, HIGHLIGHT, FALSE)) 4440 nohighlight = FALSE; 4441 else if (compare(str1, NOHIGHLIGHT, FALSE)) 4442 nohighlight = TRUE; 4443 else if (compare(str1, EIGHTBIT, FALSE)) 4444 eightbit = TRUE; 4445 else if (compare(str1, NOEIGHTBIT, FALSE)) 4446 { 4447 eightbit = FALSE; 4448 } 4449 else if (compare(str1, EMACS_string, FALSE)) 4450 emacs_keys_mode = TRUE; 4451 else if (compare(str1, NOEMACS_string, FALSE)) 4452 emacs_keys_mode = FALSE; 4453 } 4454 fclose(init_file); 4455 } 4456 } 4457 free(string); 4458 free(home); 4459 4460 } 4461 4462 /* 4463 | Save current configuration to .init.ee file in the current directory. 4464 */ 4465 4466 void 4467 dump_ee_conf(void) 4468 { 4469 FILE *init_file; 4470 FILE *old_init_file = NULL; 4471 char *file_name = ".init.ee"; 4472 char *home_dir = "~/.init.ee"; 4473 char buffer[512]; 4474 struct stat buf; 4475 char *string; 4476 int length; 4477 int option = 0; 4478 4479 if (restrict_mode()) 4480 { 4481 return; 4482 } 4483 4484 option = menu_op(config_dump_menu); 4485 4486 werase(com_win); 4487 wmove(com_win, 0, 0); 4488 4489 if (option == 0) 4490 { 4491 wprintw(com_win, "%s", conf_not_saved_msg); 4492 wrefresh(com_win); 4493 return; 4494 } 4495 else if (option == 2) 4496 file_name = resolve_name(home_dir); 4497 4498 /* 4499 | If a .init.ee file exists, move it to .init.ee.old. 4500 */ 4501 4502 if (stat(file_name, &buf) != -1) 4503 { 4504 sprintf(buffer, "%s.old", file_name); 4505 unlink(buffer); 4506 link(file_name, buffer); 4507 unlink(file_name); 4508 old_init_file = fopen(buffer, "r"); 4509 } 4510 4511 init_file = fopen(file_name, "w"); 4512 if (init_file == NULL) 4513 { 4514 wprintw(com_win, "%s", conf_dump_err_msg); 4515 wrefresh(com_win); 4516 return; 4517 } 4518 4519 if (old_init_file != NULL) 4520 { 4521 /* 4522 | Copy non-configuration info into new .init.ee file. 4523 */ 4524 while ((string = fgets(buffer, 512, old_init_file)) != NULL) 4525 { 4526 length = strlen(string); 4527 string[length - 1] = '\0'; 4528 4529 if (unique_test(string, init_strings) == 1) 4530 { 4531 if (compare(string, Echo, FALSE)) 4532 { 4533 fprintf(init_file, "%s\n", string); 4534 } 4535 } 4536 else 4537 fprintf(init_file, "%s\n", string); 4538 } 4539 4540 fclose(old_init_file); 4541 } 4542 4543 fprintf(init_file, "%s\n", case_sen ? CASE : NOCASE); 4544 fprintf(init_file, "%s\n", expand_tabs ? EXPAND : NOEXPAND); 4545 fprintf(init_file, "%s\n", info_window ? INFO : NOINFO ); 4546 fprintf(init_file, "%s\n", observ_margins ? MARGINS : NOMARGINS ); 4547 fprintf(init_file, "%s\n", auto_format ? AUTOFORMAT : NOAUTOFORMAT ); 4548 fprintf(init_file, "%s %s\n", PRINTCOMMAND, print_command); 4549 fprintf(init_file, "%s %d\n", RIGHTMARGIN, right_margin); 4550 fprintf(init_file, "%s\n", nohighlight ? NOHIGHLIGHT : HIGHLIGHT ); 4551 fprintf(init_file, "%s\n", eightbit ? EIGHTBIT : NOEIGHTBIT ); 4552 fprintf(init_file, "%s\n", emacs_keys_mode ? EMACS_string : NOEMACS_string ); 4553 4554 fclose(init_file); 4555 4556 wprintw(com_win, conf_dump_success_msg, file_name); 4557 wrefresh(com_win); 4558 4559 if ((option == 2) && (file_name != home_dir)) 4560 { 4561 free(file_name); 4562 } 4563 } 4564 4565 /* echo the given string */ 4566 void 4567 echo_string(char *string) 4568 { 4569 char *temp; 4570 int Counter; 4571 4572 temp = string; 4573 while (*temp != '\0') 4574 { 4575 if (*temp == '\\') 4576 { 4577 temp++; 4578 if (*temp == 'n') 4579 putchar('\n'); 4580 else if (*temp == 't') 4581 putchar('\t'); 4582 else if (*temp == 'b') 4583 putchar('\b'); 4584 else if (*temp == 'r') 4585 putchar('\r'); 4586 else if (*temp == 'f') 4587 putchar('\f'); 4588 else if ((*temp == 'e') || (*temp == 'E')) 4589 putchar('\033'); /* escape */ 4590 else if (*temp == '\\') 4591 putchar('\\'); 4592 else if (*temp == '\'') 4593 putchar('\''); 4594 else if ((*temp >= '0') && (*temp <= '9')) 4595 { 4596 Counter = 0; 4597 while ((*temp >= '0') && (*temp <= '9')) 4598 { 4599 Counter = (8 * Counter) + (*temp - '0'); 4600 temp++; 4601 } 4602 putchar(Counter); 4603 temp--; 4604 } 4605 temp++; 4606 } 4607 else 4608 { 4609 putchar(*temp); 4610 temp++; 4611 } 4612 } 4613 4614 fflush(stdout); 4615 } 4616 4617 /* check spelling of words in the editor */ 4618 void 4619 spell_op(void) 4620 { 4621 if (restrict_mode()) 4622 { 4623 return; 4624 } 4625 top(); /* go to top of file */ 4626 insert_line(FALSE); /* create two blank lines */ 4627 insert_line(FALSE); 4628 top(); 4629 command(shell_echo_msg); 4630 adv_line(); 4631 wmove(com_win, 0, 0); 4632 wprintw(com_win, "%s", spell_in_prog_msg); 4633 wrefresh(com_win); 4634 command("<>!spell"); /* send contents of buffer to command 'spell' 4635 and read the results back into the editor */ 4636 } 4637 4638 void 4639 ispell_op(void) 4640 { 4641 char template[128], *name; 4642 char string[256]; 4643 int fd; 4644 4645 if (restrict_mode()) 4646 { 4647 return; 4648 } 4649 (void)sprintf(template, "/tmp/ee.XXXXXXXX"); 4650 fd = mkstemp(template); 4651 name = template; 4652 if (fd < 0) { 4653 wmove(com_win, 0, 0); 4654 wprintw(com_win, create_file_fail_msg, name); 4655 wrefresh(com_win); 4656 return; 4657 } 4658 close(fd); 4659 if (write_file(name, 0)) 4660 { 4661 sprintf(string, "ispell %s", name); 4662 sh_command(string); 4663 delete_text(); 4664 tmp_file = name; 4665 recv_file = TRUE; 4666 check_fp(); 4667 unlink(name); 4668 } 4669 } 4670 4671 int 4672 first_word_len(struct text *test_line) 4673 { 4674 int counter; 4675 unsigned char *pnt; 4676 4677 if (test_line == NULL) 4678 return(0); 4679 4680 pnt = test_line->line; 4681 if ((pnt == NULL) || (*pnt == '\0') || 4682 (*pnt == '.') || (*pnt == '>')) 4683 return(0); 4684 4685 if ((*pnt == ' ') || (*pnt == '\t')) 4686 { 4687 pnt = next_word(pnt); 4688 } 4689 4690 if (*pnt == '\0') 4691 return(0); 4692 4693 counter = 0; 4694 while ((*pnt != '\0') && ((*pnt != ' ') && (*pnt != '\t'))) 4695 { 4696 pnt++; 4697 counter++; 4698 } 4699 while ((*pnt != '\0') && ((*pnt == ' ') || (*pnt == '\t'))) 4700 { 4701 pnt++; 4702 counter++; 4703 } 4704 return(counter); 4705 } 4706 4707 /* format the paragraph according to set margins */ 4708 void 4709 Auto_Format(void) 4710 { 4711 int string_count; 4712 int offset; 4713 int temp_case; 4714 int word_len; 4715 int temp_dwl; 4716 int tmp_d_line_length; 4717 int leave_loop = FALSE; 4718 int status; 4719 int counter; 4720 char not_blank; 4721 unsigned char *line; 4722 unsigned char *tmp_srchstr; 4723 unsigned char *temp1, *temp2; 4724 unsigned char *temp_dword; 4725 unsigned char temp_d_char[5]; 4726 unsigned char *tmp_d_line; 4727 4728 memcpy(temp_d_char, d_char, sizeof(temp_d_char)); 4729 4730 /* 4731 | if observ_margins is not set, or the current line is blank, 4732 | do not format the current paragraph 4733 */ 4734 4735 if ((!observ_margins) || (Blank_Line(curr_line))) 4736 return; 4737 4738 /* 4739 | get current position in paragraph, so after formatting, the cursor 4740 | will be in the same relative position 4741 */ 4742 4743 tmp_d_line = d_line; 4744 tmp_d_line_length = dlt_line->line_length; 4745 d_line = NULL; 4746 auto_format = FALSE; 4747 offset = position; 4748 if ((position != 1) && ((*point == ' ') || (*point == '\t') || (position == curr_line->line_length) || (*point == '\0'))) 4749 prev_word(); 4750 temp_dword = d_word; 4751 temp_dwl = d_wrd_len; 4752 d_wrd_len = 0; 4753 d_word = NULL; 4754 temp_case = case_sen; 4755 case_sen = TRUE; 4756 tmp_srchstr = srch_str; 4757 temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); 4758 if ((*point == ' ') || (*point == '\t')) 4759 adv_word(); 4760 offset -= position; 4761 counter = position; 4762 line = temp1 = point; 4763 while ((*temp1 != '\0') && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) 4764 { 4765 *temp2 = *temp1; 4766 temp2++; 4767 temp1++; 4768 counter++; 4769 } 4770 *temp2 = '\0'; 4771 if (position != 1) 4772 bol(); 4773 while (!Blank_Line(curr_line->prev_line)) 4774 bol(); 4775 string_count = 0; 4776 status = TRUE; 4777 while ((line != point) && (status)) 4778 { 4779 status = search(FALSE); 4780 string_count++; 4781 } 4782 4783 /* 4784 | now get back to the start of the paragraph to start checking 4785 */ 4786 4787 if (position != 1) 4788 bol(); 4789 while (!Blank_Line(curr_line->prev_line)) 4790 bol(); 4791 4792 /* 4793 | Start going through lines, putting spaces at end of lines if they do 4794 | not already exist. Check line length, and move words to the next line 4795 | if they cross the margin. Then get words from the next line if they 4796 | will fit in before the margin. 4797 */ 4798 4799 counter = 0; 4800 4801 while (!leave_loop) 4802 { 4803 if (position != curr_line->line_length) 4804 eol(); 4805 left(TRUE); 4806 if (*point != ' ') 4807 { 4808 right(TRUE); 4809 insert(' '); 4810 } 4811 else 4812 right(TRUE); 4813 4814 not_blank = FALSE; 4815 4816 /* 4817 | fill line if first word on next line will fit 4818 | in the line without crossing the margin 4819 */ 4820 4821 while ((curr_line->next_line != NULL) && 4822 ((word_len = first_word_len(curr_line->next_line)) > 0) 4823 && ((scr_pos + word_len) < right_margin)) 4824 { 4825 adv_line(); 4826 if ((*point == ' ') || (*point == '\t')) 4827 adv_word(); 4828 del_word(); 4829 if (position != 1) 4830 bol(); 4831 4832 /* 4833 | We know this line was not blank before, so 4834 | make sure that it doesn't have one of the 4835 | leading characters that indicate the line 4836 | should not be modified. 4837 | 4838 | We also know that this character should not 4839 | be left as the first character of this line. 4840 */ 4841 4842 if ((Blank_Line(curr_line)) && 4843 (curr_line->line[0] != '.') && 4844 (curr_line->line[0] != '>')) 4845 { 4846 del_line(); 4847 not_blank = FALSE; 4848 } 4849 else 4850 not_blank = TRUE; 4851 4852 /* 4853 | go to end of previous line 4854 */ 4855 left(TRUE); 4856 undel_word(); 4857 eol(); 4858 /* 4859 | make sure there's a space at the end of the line 4860 */ 4861 left(TRUE); 4862 if (*point != ' ') 4863 { 4864 right(TRUE); 4865 insert(' '); 4866 } 4867 else 4868 right(TRUE); 4869 } 4870 4871 /* 4872 | make sure line does not cross right margin 4873 */ 4874 4875 while (right_margin <= scr_pos) 4876 { 4877 prev_word(); 4878 if (position != 1) 4879 { 4880 del_word(); 4881 if (Blank_Line(curr_line->next_line)) 4882 insert_line(TRUE); 4883 else 4884 adv_line(); 4885 if ((*point == ' ') || (*point == '\t')) 4886 adv_word(); 4887 undel_word(); 4888 not_blank = TRUE; 4889 if (position != 1) 4890 bol(); 4891 left(TRUE); 4892 } 4893 } 4894 4895 if ((!Blank_Line(curr_line->next_line)) || (not_blank)) 4896 { 4897 adv_line(); 4898 counter++; 4899 } 4900 else 4901 leave_loop = TRUE; 4902 } 4903 4904 /* 4905 | go back to begin of paragraph, put cursor back to original position 4906 */ 4907 4908 if (position != 1) 4909 bol(); 4910 while ((counter-- > 0) || (!Blank_Line(curr_line->prev_line))) 4911 bol(); 4912 4913 /* 4914 | find word cursor was in 4915 */ 4916 4917 status = TRUE; 4918 while ((status) && (string_count > 0)) 4919 { 4920 status = search(FALSE); 4921 string_count--; 4922 } 4923 4924 /* 4925 | offset the cursor to where it was before from the start of the word 4926 */ 4927 4928 while (offset > 0) 4929 { 4930 offset--; 4931 right(TRUE); 4932 } 4933 4934 if ((string_count > 0) && (offset < 0)) 4935 { 4936 while (offset < 0) 4937 { 4938 offset++; 4939 left(TRUE); 4940 } 4941 } 4942 4943 /* 4944 | reset flags and strings to what they were before formatting 4945 */ 4946 4947 if (d_word != NULL) 4948 free(d_word); 4949 d_word = temp_dword; 4950 d_wrd_len = temp_dwl; 4951 case_sen = temp_case; 4952 free(srch_str); 4953 srch_str = tmp_srchstr; 4954 memcpy(d_char, temp_d_char, sizeof(d_char)); 4955 auto_format = TRUE; 4956 dlt_line->line_length = tmp_d_line_length; 4957 d_line = tmp_d_line; 4958 4959 formatted = TRUE; 4960 midscreen(scr_vert, point); 4961 } 4962 4963 void 4964 modes_op(void) 4965 { 4966 int ret_value; 4967 int counter; 4968 char *string; 4969 4970 do 4971 { 4972 sprintf(modes_menu[1].item_string, "%s %s", mode_strings[1], 4973 (expand_tabs ? ON : OFF)); 4974 sprintf(modes_menu[2].item_string, "%s %s", mode_strings[2], 4975 (case_sen ? ON : OFF)); 4976 sprintf(modes_menu[3].item_string, "%s %s", mode_strings[3], 4977 (observ_margins ? ON : OFF)); 4978 sprintf(modes_menu[4].item_string, "%s %s", mode_strings[4], 4979 (auto_format ? ON : OFF)); 4980 sprintf(modes_menu[5].item_string, "%s %s", mode_strings[5], 4981 (eightbit ? ON : OFF)); 4982 sprintf(modes_menu[6].item_string, "%s %s", mode_strings[6], 4983 (info_window ? ON : OFF)); 4984 sprintf(modes_menu[7].item_string, "%s %s", mode_strings[7], 4985 (emacs_keys_mode ? ON : OFF)); 4986 sprintf(modes_menu[8].item_string, "%s %d", mode_strings[8], 4987 right_margin); 4988 4989 ret_value = menu_op(modes_menu); 4990 4991 switch (ret_value) 4992 { 4993 case 1: 4994 expand_tabs = !expand_tabs; 4995 break; 4996 case 2: 4997 case_sen = !case_sen; 4998 break; 4999 case 3: 5000 observ_margins = !observ_margins; 5001 break; 5002 case 4: 5003 auto_format = !auto_format; 5004 if (auto_format) 5005 observ_margins = TRUE; 5006 break; 5007 case 5: 5008 eightbit = !eightbit; 5009 redraw(); 5010 wnoutrefresh(text_win); 5011 break; 5012 case 6: 5013 if (info_window) 5014 no_info_window(); 5015 else 5016 create_info_window(); 5017 break; 5018 case 7: 5019 emacs_keys_mode = !emacs_keys_mode; 5020 if (info_window) 5021 paint_info_win(); 5022 break; 5023 case 8: 5024 string = get_string(margin_prompt, TRUE); 5025 if (string != NULL) 5026 { 5027 counter = atoi(string); 5028 if (counter > 0) 5029 right_margin = counter; 5030 free(string); 5031 } 5032 break; 5033 default: 5034 break; 5035 } 5036 } 5037 while (ret_value != 0); 5038 } 5039 5040 /* a strchr() look-alike for systems without strchr() */ 5041 char * 5042 is_in_string(char *string, char *substring) 5043 { 5044 char *full, *sub; 5045 5046 for (sub = substring; (sub != NULL) && (*sub != '\0'); sub++) 5047 { 5048 for (full = string; (full != NULL) && (*full != '\0'); 5049 full++) 5050 { 5051 if (*sub == *full) 5052 return(full); 5053 } 5054 } 5055 return(NULL); 5056 } 5057 5058 /* 5059 | handle names of the form "~/file", "~user/file", 5060 | "$HOME/foo", "~/$FOO", etc. 5061 */ 5062 5063 char * 5064 resolve_name(char *name) 5065 { 5066 char long_buffer[1024]; 5067 char short_buffer[128]; 5068 char *buffer; 5069 char *slash; 5070 char *tmp; 5071 char *start_of_var; 5072 int offset; 5073 int index; 5074 int counter; 5075 struct passwd *user; 5076 5077 if (name[0] == '~') 5078 { 5079 if (name[1] == '/') 5080 { 5081 index = getuid(); 5082 user = (struct passwd *) getpwuid(index); 5083 slash = name + 1; 5084 } 5085 else 5086 { 5087 slash = strchr(name, '/'); 5088 if (slash == NULL) 5089 return(name); 5090 *slash = '\0'; 5091 user = (struct passwd *) getpwnam((name + 1)); 5092 *slash = '/'; 5093 } 5094 if (user == NULL) 5095 { 5096 return(name); 5097 } 5098 buffer = malloc(strlen(user->pw_dir) + strlen(slash) + 1); 5099 strcpy(buffer, user->pw_dir); 5100 strcat(buffer, slash); 5101 } 5102 else 5103 buffer = name; 5104 5105 if (is_in_string(buffer, "$")) 5106 { 5107 tmp = buffer; 5108 index = 0; 5109 5110 while ((*tmp != '\0') && (index < 1024)) 5111 { 5112 5113 while ((*tmp != '\0') && (*tmp != '$') && 5114 (index < 1024)) 5115 { 5116 long_buffer[index] = *tmp; 5117 tmp++; 5118 index++; 5119 } 5120 5121 if ((*tmp == '$') && (index < 1024)) 5122 { 5123 counter = 0; 5124 start_of_var = tmp; 5125 tmp++; 5126 if (*tmp == '{') /* } */ /* bracketed variable name */ 5127 { 5128 tmp++; /* { */ 5129 while ((*tmp != '\0') && 5130 (*tmp != '}') && 5131 (counter < 128)) 5132 { 5133 short_buffer[counter] = *tmp; 5134 counter++; 5135 tmp++; 5136 } /* { */ 5137 if (*tmp == '}') 5138 tmp++; 5139 } 5140 else 5141 { 5142 while ((*tmp != '\0') && 5143 (*tmp != '/') && 5144 (*tmp != '$') && 5145 (counter < 128)) 5146 { 5147 short_buffer[counter] = *tmp; 5148 counter++; 5149 tmp++; 5150 } 5151 } 5152 short_buffer[counter] = '\0'; 5153 if ((slash = getenv(short_buffer)) != NULL) 5154 { 5155 offset = strlen(slash); 5156 if ((offset + index) < 1024) 5157 strcpy(&long_buffer[index], slash); 5158 index += offset; 5159 } 5160 else 5161 { 5162 while ((start_of_var != tmp) && (index < 1024)) 5163 { 5164 long_buffer[index] = *start_of_var; 5165 start_of_var++; 5166 index++; 5167 } 5168 } 5169 } 5170 } 5171 5172 if (index == 1024) 5173 return(buffer); 5174 else 5175 long_buffer[index] = '\0'; 5176 5177 if (name != buffer) 5178 free(buffer); 5179 buffer = malloc(index + 1); 5180 strcpy(buffer, long_buffer); 5181 } 5182 5183 return(buffer); 5184 } 5185 5186 int 5187 restrict_mode(void) 5188 { 5189 if (!restricted) 5190 return(FALSE); 5191 5192 wmove(com_win, 0, 0); 5193 wprintw(com_win, "%s", restricted_msg); 5194 wclrtoeol(com_win); 5195 wrefresh(com_win); 5196 clear_com_win = TRUE; 5197 return(TRUE); 5198 } 5199 5200 /* 5201 | The following routine tests the input string against the list of 5202 | strings, to determine if the string is a unique match with one of the 5203 | valid values. 5204 */ 5205 5206 int 5207 unique_test(char *string, char *list[]) 5208 { 5209 int counter; 5210 int num_match; 5211 int result; 5212 5213 num_match = 0; 5214 counter = 0; 5215 while (list[counter] != NULL) 5216 { 5217 result = compare(string, list[counter], FALSE); 5218 if (result) 5219 num_match++; 5220 counter++; 5221 } 5222 return(num_match); 5223 } 5224 5225 #ifndef NO_CATGETS 5226 /* 5227 | Get the catalog entry, and if it got it from the catalog, 5228 | make a copy, since the buffer will be overwritten by the 5229 | next call to catgets(). 5230 */ 5231 5232 char * 5233 catgetlocal(int number, char *string) 5234 { 5235 char *temp1; 5236 char *temp2; 5237 5238 temp1 = catgets(catalog, 1, number, string); 5239 if (temp1 != string) 5240 { 5241 temp2 = malloc(strlen(temp1) + 1); 5242 strcpy(temp2, temp1); 5243 temp1 = temp2; 5244 } 5245 return(temp1); 5246 } 5247 #endif /* NO_CATGETS */ 5248 5249 /* 5250 | The following is to allow for using message catalogs which allow 5251 | the software to be 'localized', that is, to use different languages 5252 | all with the same binary. For more information, see your system 5253 | documentation, or the X/Open Internationalization Guide. 5254 */ 5255 5256 void 5257 strings_init(void) 5258 { 5259 int counter; 5260 5261 setlocale(LC_ALL, ""); 5262 #ifndef NO_CATGETS 5263 catalog = catopen("ee", NL_CAT_LOCALE); 5264 #endif /* NO_CATGETS */ 5265 5266 modes_menu[0].item_string = catgetlocal( 1, "modes menu"); 5267 mode_strings[1] = catgetlocal( 2, "tabs to spaces "); 5268 mode_strings[2] = catgetlocal( 3, "case sensitive search"); 5269 mode_strings[3] = catgetlocal( 4, "margins observed "); 5270 mode_strings[4] = catgetlocal( 5, "auto-paragraph format"); 5271 mode_strings[5] = catgetlocal( 6, "eightbit characters "); 5272 mode_strings[6] = catgetlocal( 7, "info window "); 5273 mode_strings[8] = catgetlocal( 8, "right margin "); 5274 leave_menu[0].item_string = catgetlocal( 9, "leave menu"); 5275 leave_menu[1].item_string = catgetlocal( 10, "save changes"); 5276 leave_menu[2].item_string = catgetlocal( 11, "no save"); 5277 file_menu[0].item_string = catgetlocal( 12, "file menu"); 5278 file_menu[1].item_string = catgetlocal( 13, "read a file"); 5279 file_menu[2].item_string = catgetlocal( 14, "write a file"); 5280 file_menu[3].item_string = catgetlocal( 15, "save file"); 5281 file_menu[4].item_string = catgetlocal( 16, "print editor contents"); 5282 search_menu[0].item_string = catgetlocal( 17, "search menu"); 5283 search_menu[1].item_string = catgetlocal( 18, "search for ..."); 5284 search_menu[2].item_string = catgetlocal( 19, "search"); 5285 spell_menu[0].item_string = catgetlocal( 20, "spell menu"); 5286 spell_menu[1].item_string = catgetlocal( 21, "use 'spell'"); 5287 spell_menu[2].item_string = catgetlocal( 22, "use 'ispell'"); 5288 misc_menu[0].item_string = catgetlocal( 23, "miscellaneous menu"); 5289 misc_menu[1].item_string = catgetlocal( 24, "format paragraph"); 5290 misc_menu[2].item_string = catgetlocal( 25, "shell command"); 5291 misc_menu[3].item_string = catgetlocal( 26, "check spelling"); 5292 main_menu[0].item_string = catgetlocal( 27, "main menu"); 5293 main_menu[1].item_string = catgetlocal( 28, "leave editor"); 5294 main_menu[2].item_string = catgetlocal( 29, "help"); 5295 main_menu[3].item_string = catgetlocal( 30, "file operations"); 5296 main_menu[4].item_string = catgetlocal( 31, "redraw screen"); 5297 main_menu[5].item_string = catgetlocal( 32, "settings"); 5298 main_menu[6].item_string = catgetlocal( 33, "search"); 5299 main_menu[7].item_string = catgetlocal( 34, "miscellaneous"); 5300 help_text[0] = catgetlocal( 35, "Control keys: "); 5301 help_text[1] = catgetlocal( 36, "^a ascii code ^i tab ^r right "); 5302 help_text[2] = catgetlocal( 37, "^b bottom of text ^j newline ^t top of text "); 5303 help_text[3] = catgetlocal( 38, "^c command ^k delete char ^u up "); 5304 help_text[4] = catgetlocal( 39, "^d down ^l left ^v undelete word "); 5305 help_text[5] = catgetlocal( 40, "^e search prompt ^m newline ^w delete word "); 5306 help_text[6] = catgetlocal( 41, "^f undelete char ^n next page ^x search "); 5307 help_text[7] = catgetlocal( 42, "^g begin of line ^o end of line ^y delete line "); 5308 help_text[8] = catgetlocal( 43, "^h backspace ^p prev page ^z undelete line "); 5309 help_text[9] = catgetlocal( 44, "^[ (escape) menu ESC-Enter: exit ee "); 5310 help_text[10] = catgetlocal( 45, " "); 5311 help_text[11] = catgetlocal( 46, "Commands: "); 5312 help_text[12] = catgetlocal( 47, "help : get this info file : print file name "); 5313 help_text[13] = catgetlocal( 48, "read : read a file char : ascii code of char "); 5314 help_text[14] = catgetlocal( 49, "write : write a file case : case sensitive search "); 5315 help_text[15] = catgetlocal( 50, "exit : leave and save nocase : case insensitive search "); 5316 help_text[16] = catgetlocal( 51, "quit : leave, no save !cmd : execute \"cmd\" in shell "); 5317 help_text[17] = catgetlocal( 52, "line : display line # 0-9 : go to line \"#\" "); 5318 help_text[18] = catgetlocal( 53, "expand : expand tabs noexpand: do not expand tabs "); 5319 help_text[19] = catgetlocal( 54, " "); 5320 help_text[20] = catgetlocal( 55, " ee [+#] [-i] [-e] [-h] [file(s)] "); 5321 help_text[21] = catgetlocal( 56, "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight"); 5322 control_keys[0] = catgetlocal( 57, "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page "); 5323 control_keys[1] = catgetlocal( 58, "^a ascii code ^x search ^z undelete line ^d down ^n next page "); 5324 control_keys[2] = catgetlocal( 59, "^b bottom of text ^g begin of line ^w delete word ^l left "); 5325 control_keys[3] = catgetlocal( 60, "^t top of text ^o end of line ^v undelete word ^r right "); 5326 control_keys[4] = catgetlocal( 61, "^c command ^k delete char ^f undelete char ESC-Enter: exit ee "); 5327 command_strings[0] = catgetlocal( 62, "help : get help info |file : print file name |line : print line # "); 5328 command_strings[1] = catgetlocal( 63, "read : read a file |char : ascii code of char |0-9 : go to line \"#\""); 5329 command_strings[2] = catgetlocal( 64, "write: write a file |case : case sensitive search |exit : leave and save "); 5330 command_strings[3] = catgetlocal( 65, "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save"); 5331 command_strings[4] = catgetlocal( 66, "expand: expand tabs |noexpand: do not expand tabs "); 5332 com_win_message = catgetlocal( 67, " press Escape (^[) for menu"); 5333 no_file_string = catgetlocal( 68, "no file"); 5334 ascii_code_str = catgetlocal( 69, "ascii code: "); 5335 printer_msg_str = catgetlocal( 70, "sending contents of buffer to \"%s\" "); 5336 command_str = catgetlocal( 71, "command: "); 5337 file_write_prompt_str = catgetlocal( 72, "name of file to write: "); 5338 file_read_prompt_str = catgetlocal( 73, "name of file to read: "); 5339 char_str = catgetlocal( 74, "character = %d"); 5340 unkn_cmd_str = catgetlocal( 75, "unknown command \"%s\""); 5341 non_unique_cmd_msg = catgetlocal( 76, "entered command is not unique"); 5342 line_num_str = catgetlocal( 77, "line %d "); 5343 line_len_str = catgetlocal( 78, "length = %d"); 5344 current_file_str = catgetlocal( 79, "current file is \"%s\" "); 5345 usage0 = catgetlocal( 80, "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n"); 5346 usage1 = catgetlocal( 81, " -i turn off info window\n"); 5347 usage2 = catgetlocal( 82, " -e do not convert tabs to spaces\n"); 5348 usage3 = catgetlocal( 83, " -h do not use highlighting\n"); 5349 file_is_dir_msg = catgetlocal( 84, "file \"%s\" is a directory"); 5350 new_file_msg = catgetlocal( 85, "new file \"%s\""); 5351 cant_open_msg = catgetlocal( 86, "can't open \"%s\""); 5352 open_file_msg = catgetlocal( 87, "file \"%s\", %d lines"); 5353 file_read_fin_msg = catgetlocal( 88, "finished reading file \"%s\""); 5354 reading_file_msg = catgetlocal( 89, "reading file \"%s\""); 5355 read_only_msg = catgetlocal( 90, ", read only"); 5356 file_read_lines_msg = catgetlocal( 91, "file \"%s\", %d lines"); 5357 save_file_name_prompt = catgetlocal( 92, "enter name of file: "); 5358 file_not_saved_msg = catgetlocal( 93, "no filename entered: file not saved"); 5359 changes_made_prompt = catgetlocal( 94, "changes have been made, are you sure? (y/n [n]) "); 5360 yes_char = catgetlocal( 95, "y"); 5361 file_exists_prompt = catgetlocal( 96, "file already exists, overwrite? (y/n) [n] "); 5362 create_file_fail_msg = catgetlocal( 97, "unable to create file \"%s\""); 5363 writing_file_msg = catgetlocal( 98, "writing file \"%s\""); 5364 file_written_msg = catgetlocal( 99, "\"%s\" %d lines, %d characters"); 5365 searching_msg = catgetlocal( 100, " ...searching"); 5366 str_not_found_msg = catgetlocal( 101, "string \"%s\" not found"); 5367 search_prompt_str = catgetlocal( 102, "search for: "); 5368 exec_err_msg = catgetlocal( 103, "could not exec %s\n"); 5369 continue_msg = catgetlocal( 104, "press return to continue "); 5370 menu_cancel_msg = catgetlocal( 105, "press Esc to cancel"); 5371 menu_size_err_msg = catgetlocal( 106, "menu too large for window"); 5372 press_any_key_msg = catgetlocal( 107, "press any key to continue "); 5373 shell_prompt = catgetlocal( 108, "shell command: "); 5374 formatting_msg = catgetlocal( 109, "...formatting paragraph..."); 5375 shell_echo_msg = catgetlocal( 110, "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-"); 5376 spell_in_prog_msg = catgetlocal( 111, "sending contents of edit buffer to 'spell'"); 5377 margin_prompt = catgetlocal( 112, "right margin is: "); 5378 restricted_msg = catgetlocal( 113, "restricted mode: unable to perform requested operation"); 5379 ON = catgetlocal( 114, "ON"); 5380 OFF = catgetlocal( 115, "OFF"); 5381 HELP = catgetlocal( 116, "HELP"); 5382 WRITE = catgetlocal( 117, "WRITE"); 5383 READ = catgetlocal( 118, "READ"); 5384 LINE = catgetlocal( 119, "LINE"); 5385 FILE_str = catgetlocal( 120, "FILE"); 5386 CHARACTER = catgetlocal( 121, "CHARACTER"); 5387 REDRAW = catgetlocal( 122, "REDRAW"); 5388 RESEQUENCE = catgetlocal( 123, "RESEQUENCE"); 5389 AUTHOR = catgetlocal( 124, "AUTHOR"); 5390 VERSION = catgetlocal( 125, "VERSION"); 5391 CASE = catgetlocal( 126, "CASE"); 5392 NOCASE = catgetlocal( 127, "NOCASE"); 5393 EXPAND = catgetlocal( 128, "EXPAND"); 5394 NOEXPAND = catgetlocal( 129, "NOEXPAND"); 5395 Exit_string = catgetlocal( 130, "EXIT"); 5396 QUIT_string = catgetlocal( 131, "QUIT"); 5397 INFO = catgetlocal( 132, "INFO"); 5398 NOINFO = catgetlocal( 133, "NOINFO"); 5399 MARGINS = catgetlocal( 134, "MARGINS"); 5400 NOMARGINS = catgetlocal( 135, "NOMARGINS"); 5401 AUTOFORMAT = catgetlocal( 136, "AUTOFORMAT"); 5402 NOAUTOFORMAT = catgetlocal( 137, "NOAUTOFORMAT"); 5403 Echo = catgetlocal( 138, "ECHO"); 5404 PRINTCOMMAND = catgetlocal( 139, "PRINTCOMMAND"); 5405 RIGHTMARGIN = catgetlocal( 140, "RIGHTMARGIN"); 5406 HIGHLIGHT = catgetlocal( 141, "HIGHLIGHT"); 5407 NOHIGHLIGHT = catgetlocal( 142, "NOHIGHLIGHT"); 5408 EIGHTBIT = catgetlocal( 143, "EIGHTBIT"); 5409 NOEIGHTBIT = catgetlocal( 144, "NOEIGHTBIT"); 5410 /* 5411 | additions 5412 */ 5413 mode_strings[7] = catgetlocal( 145, "emacs key bindings "); 5414 emacs_help_text[0] = help_text[0]; 5415 emacs_help_text[1] = catgetlocal( 146, "^a beginning of line ^i tab ^r restore word "); 5416 emacs_help_text[2] = catgetlocal( 147, "^b back 1 char ^j undel char ^t top of text "); 5417 emacs_help_text[3] = catgetlocal( 148, "^c command ^k delete line ^u bottom of text "); 5418 emacs_help_text[4] = catgetlocal( 149, "^d delete char ^l undelete line ^v next page "); 5419 emacs_help_text[5] = catgetlocal( 150, "^e end of line ^m newline ^w delete word "); 5420 emacs_help_text[6] = catgetlocal( 151, "^f forward 1 char ^n next line ^x search "); 5421 emacs_help_text[7] = catgetlocal( 152, "^g go back 1 page ^o ascii char insert ^y search prompt "); 5422 emacs_help_text[8] = catgetlocal( 153, "^h backspace ^p prev line ^z next word "); 5423 emacs_help_text[9] = help_text[9]; 5424 emacs_help_text[10] = help_text[10]; 5425 emacs_help_text[11] = help_text[11]; 5426 emacs_help_text[12] = help_text[12]; 5427 emacs_help_text[13] = help_text[13]; 5428 emacs_help_text[14] = help_text[14]; 5429 emacs_help_text[15] = help_text[15]; 5430 emacs_help_text[16] = help_text[16]; 5431 emacs_help_text[17] = help_text[17]; 5432 emacs_help_text[18] = help_text[18]; 5433 emacs_help_text[19] = help_text[19]; 5434 emacs_help_text[20] = help_text[20]; 5435 emacs_help_text[21] = help_text[21]; 5436 emacs_control_keys[0] = catgetlocal( 154, "^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page"); 5437 emacs_control_keys[1] = catgetlocal( 155, "^o ascii code ^x search ^l undelete line ^n next li ^v next page"); 5438 emacs_control_keys[2] = catgetlocal( 156, "^u end of file ^a begin of line ^w delete word ^b back 1 char ^z next word"); 5439 emacs_control_keys[3] = catgetlocal( 157, "^t top of text ^e end of line ^r restore word ^f forward char "); 5440 emacs_control_keys[4] = catgetlocal( 158, "^c command ^d delete char ^j undelete char ESC-Enter: exit"); 5441 EMACS_string = catgetlocal( 159, "EMACS"); 5442 NOEMACS_string = catgetlocal( 160, "NOEMACS"); 5443 usage4 = catgetlocal( 161, " +# put cursor at line #\n"); 5444 conf_dump_err_msg = catgetlocal( 162, "unable to open .init.ee for writing, no configuration saved!"); 5445 conf_dump_success_msg = catgetlocal( 163, "ee configuration saved in file %s"); 5446 modes_menu[9].item_string = catgetlocal( 164, "save editor configuration"); 5447 config_dump_menu[0].item_string = catgetlocal( 165, "save ee configuration"); 5448 config_dump_menu[1].item_string = catgetlocal( 166, "save in current directory"); 5449 config_dump_menu[2].item_string = catgetlocal( 167, "save in home directory"); 5450 conf_not_saved_msg = catgetlocal( 168, "ee configuration not saved"); 5451 ree_no_file_msg = catgetlocal( 169, "must specify a file when invoking ree"); 5452 menu_too_lrg_msg = catgetlocal( 180, "menu too large for window"); 5453 more_above_str = catgetlocal( 181, "^^more^^"); 5454 more_below_str = catgetlocal( 182, "VVmoreVV"); 5455 5456 commands[0] = HELP; 5457 commands[1] = WRITE; 5458 commands[2] = READ; 5459 commands[3] = LINE; 5460 commands[4] = FILE_str; 5461 commands[5] = REDRAW; 5462 commands[6] = RESEQUENCE; 5463 commands[7] = AUTHOR; 5464 commands[8] = VERSION; 5465 commands[9] = CASE; 5466 commands[10] = NOCASE; 5467 commands[11] = EXPAND; 5468 commands[12] = NOEXPAND; 5469 commands[13] = Exit_string; 5470 commands[14] = QUIT_string; 5471 commands[15] = "<"; 5472 commands[16] = ">"; 5473 commands[17] = "!"; 5474 commands[18] = "0"; 5475 commands[19] = "1"; 5476 commands[20] = "2"; 5477 commands[21] = "3"; 5478 commands[22] = "4"; 5479 commands[23] = "5"; 5480 commands[24] = "6"; 5481 commands[25] = "7"; 5482 commands[26] = "8"; 5483 commands[27] = "9"; 5484 commands[28] = CHARACTER; 5485 commands[29] = NULL; 5486 init_strings[0] = CASE; 5487 init_strings[1] = NOCASE; 5488 init_strings[2] = EXPAND; 5489 init_strings[3] = NOEXPAND; 5490 init_strings[4] = INFO; 5491 init_strings[5] = NOINFO; 5492 init_strings[6] = MARGINS; 5493 init_strings[7] = NOMARGINS; 5494 init_strings[8] = AUTOFORMAT; 5495 init_strings[9] = NOAUTOFORMAT; 5496 init_strings[10] = Echo; 5497 init_strings[11] = PRINTCOMMAND; 5498 init_strings[12] = RIGHTMARGIN; 5499 init_strings[13] = HIGHLIGHT; 5500 init_strings[14] = NOHIGHLIGHT; 5501 init_strings[15] = EIGHTBIT; 5502 init_strings[16] = NOEIGHTBIT; 5503 init_strings[17] = EMACS_string; 5504 init_strings[18] = NOEMACS_string; 5505 init_strings[19] = NULL; 5506 5507 /* 5508 | allocate space for strings here for settings menu 5509 */ 5510 5511 for (counter = 1; counter < NUM_MODES_ITEMS; counter++) 5512 { 5513 modes_menu[counter].item_string = malloc(80); 5514 } 5515 5516 #ifndef NO_CATGETS 5517 catclose(catalog); 5518 #endif /* NO_CATGETS */ 5519 } 5520 5521