4 | An easy to use, simple screen oriented editor.
6 | written by Hugh Mahon
8 | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
9 | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
10 | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
11 | IMPLIED WARRANTIES OF MERCHANTABILITY AND
12 | FITNESS FOR A PARTICULAR PURPOSE. Neither
13 | Hewlett-Packard nor Hugh Mahon shall be liable
14 | for errors contained herein, nor for
15 | incidental or consequential damages in
16 | connection with the furnishing, performance or
17 | use of this material. Neither Hewlett-Packard
18 | nor Hugh Mahon assumes any responsibility for
19 | the use or reliability of this software or
20 | documentation. This software and
21 | documentation is totally UNSUPPORTED. There
22 | is no support contract available. Hewlett-
23 | Packard has done NO Quality Assurance on ANY
24 | of the program or documentation. You may find
25 | the quality of the materials inferior to
26 | supported materials.
28 | This software is not a product of Hewlett-Packard, Co., or any
29 | other company. No support is implied or offered with this software.
30 | You've got the source, and you're on your own.
32 | This software may be distributed under the terms of Larry Wall's
33 | Artistic license, a copy of which is included in this distribution.
35 | This notice must be included with this software and any derivatives.
37 | This editor was purposely developed to be simple, both in
38 | interface and implementation. This editor was developed to
39 | address a specific audience: the user who is new to computers
42 | ee is not aimed at technical users; for that reason more
43 | complex features were intentionally left out. In addition,
44 | ee is intended to be compiled by people with little computer
45 | experience, which means that it needs to be small, relatively
46 | simple in implementation, and portable.
48 | This software and documentation contains
49 | proprietary information which is protected by
50 | copyright. All rights are reserved.
52 * $FreeBSD: src/usr.bin/ee/ee.c,v 1.16.2.6 2002/05/11 16:33:06 mp Exp $
53 * $DragonFly: src/usr.bin/ee/ee.c,v 1.5 2008/10/16 01:52:32 swildner Exp $
56 char *ee_copyright_message
=
57 "Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Hugh Mahon ";
59 char *ee_long_notice
[] = {
60 "This software and documentation contains",
61 "proprietary information which is protected by",
62 "copyright. All rights are reserved."
65 char *version
= "@(#) ee, version 1.4.1";
68 #include "new_curse.h"
84 #include <sys/types.h>
102 #include <nl_types.h>
106 #define catgetlocal(a, b) (b)
107 #endif /* NO_CATGETS */
110 #define SIGCHLD SIGCLD
114 #define max(a, b) (a > b ? a : b)
115 #define min(a, b) (a < b ? a : b)
118 | defines for type of data to show in info window
121 #define CONTROL_KEYS 1
125 unsigned char *line
; /* line of characters */
126 int line_number
; /* line number */
127 int line_length
; /* actual number of characters in the line */
128 int max_length
; /* maximum number of characters the line handles */
129 struct text
*next_line
; /* next line of text */
130 struct text
*prev_line
; /* previous line of text */
133 struct text
*first_line
; /* first line of current buffer */
134 struct text
*dlt_line
; /* structure for info on deleted line */
135 struct text
*curr_line
; /* current line cursor is on */
136 struct text
*tmp_line
; /* temporary line pointer */
137 struct text
*srch_line
; /* temporary pointer for search routine */
139 struct files
{ /* structure to store names of files to be edited*/
140 unsigned char *name
; /* name of file */
141 struct files
*next_name
;
144 struct files
*top_of_stack
= NULL
;
146 int d_wrd_len
; /* length of deleted word */
147 int position
; /* offset in bytes from begin of line */
148 int scr_pos
; /* horizontal position */
149 int scr_vert
; /* vertical position on screen */
150 int scr_horz
; /* horizontal position on screen */
151 int tmp_vert
, tmp_horz
;
152 int input_file
; /* indicate to read input file */
153 int recv_file
; /* indicate reading a file */
154 int edit
; /* continue executing while true */
155 int gold
; /* 'gold' function key pressed */
156 int fildes
; /* file descriptor */
157 int case_sen
; /* case sensitive search flag */
158 int last_line
; /* last line for text display */
159 int last_col
; /* last column for text display */
160 int horiz_offset
= 0; /* offset from left edge of text */
161 int clear_com_win
; /* flag to indicate com_win needs clearing */
162 int text_changes
= FALSE
; /* indicate changes have been made to text */
163 int get_fd
; /* file descriptor for reading a file */
164 int info_window
= TRUE
; /* flag to indicate if help window visible */
165 int info_type
= CONTROL_KEYS
; /* flag to indicate type of info to display */
166 int expand_tabs
= TRUE
; /* flag for expanding tabs */
167 int right_margin
= 0; /* the right margin */
168 int observ_margins
= TRUE
; /* flag for whether margins are observed */
170 int temp_stdin
; /* temporary storage for stdin */
171 int temp_stdout
; /* temp storage for stdout descriptor */
172 int temp_stderr
; /* temp storage for stderr descriptor */
173 int pipe_out
[2]; /* pipe file desc for output */
174 int pipe_in
[2]; /* pipe file descriptors for input */
175 int out_pipe
; /* flag that info is piped out */
176 int in_pipe
; /* flag that info is piped in */
177 int formatted
= FALSE
; /* flag indicating paragraph formatted */
178 int auto_format
= FALSE
; /* flag for auto_format mode */
179 int restricted
= FALSE
; /* flag to indicate restricted mode */
180 int nohighlight
= FALSE
; /* turns off highlighting */
181 int eightbit
= TRUE
; /* eight bit character flag */
182 int local_LINES
= 0; /* copy of LINES, to detect when win resizes */
183 int local_COLS
= 0; /* copy of COLS, to detect when win resizes */
184 int curses_initialized
= FALSE
; /* flag indicating if curses has been started*/
185 int emacs_keys_mode
= FALSE
; /* mode for if emacs key binings are used */
186 int ee_chinese
= FALSE
; /* allows handling of multi-byte characters */
187 /* by checking for high bit in a byte the */
188 /* code recognizes a two-byte character */
191 unsigned char *point
; /* points to current position in line */
192 unsigned char *srch_str
; /* pointer for search string */
193 unsigned char *u_srch_str
; /* pointer to non-case sensitive search */
194 unsigned char *srch_1
; /* pointer to start of suspect string */
195 unsigned char *srch_2
; /* pointer to next character of string */
196 unsigned char *srch_3
;
197 unsigned char *in_file_name
= NULL
; /* name of input file */
198 char *tmp_file
; /* temporary file name */
199 unsigned char *d_char
; /* deleted character */
200 unsigned char *d_word
; /* deleted word */
201 unsigned char *d_line
; /* deleted line */
202 char in_string
[513]; /* buffer for reading a file */
203 unsigned char *print_command
= "lpr"; /* string to use for the print command */
204 unsigned char *start_at_line
= NULL
; /* move to this line at start of session*/
205 const char count_text_default
[] = "===============================================================================";
206 int count_text_len
= sizeof(count_text_default
); /* length of the line above */
207 char count_text
[sizeof(count_text_default
)]; /* buffer for current position display */
208 int in
; /* input character */
210 FILE *temp_fp
; /* temporary file pointer */
211 FILE *bit_bucket
; /* file pointer to /dev/null */
214 "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J",
215 "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U",
216 "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_"
226 | The following structure allows menu items to be flexibly declared.
227 | The first item is the string describing the selection, the second
228 | is the address of the procedure to call when the item is selected,
229 | and the third is the argument for the procedure.
231 | For those systems with i18n, the string should be accompanied by a
232 | catalog number. The 'int *' should be replaced with 'void *' on
233 | systems with that type.
235 | The first menu item will be the title of the menu, with NULL
236 | parameters for the procedure and argument, followed by the menu items.
238 | If the procedure value is NULL, the menu item is displayed, but no
239 | procedure is called when the item is selected. The number of the
240 | item will be returned. If the third (argument) parameter is -1, no
241 | argument is given to the procedure when it is called.
244 struct menu_entries
{
246 int (*procedure
)(struct menu_entries
*);
247 struct menu_entries
*ptr_argument
;
248 int (*iprocedure
)(int);
249 void (*nprocedure
)(void);
253 int main(int argc
, char *argv
[]);
254 unsigned char *resiz_line(int factor
, struct text
*rline
, int rpos
);
255 void insert(int character
);
256 void delete(int disp
);
257 void scanline(unsigned char *pos
);
258 int tabshift(int temp_int
);
259 int out_char(WINDOW
*window
, int character
, int column
);
260 int len_char(int character
, int column
);
261 void draw_line(int vertical
, int horiz
, unsigned char *ptr
, int t_pos
, int length
);
262 void insert_line(int disp
);
263 struct text
*txtalloc(void);
264 struct files
*name_alloc(void);
265 unsigned char *next_word(unsigned char *string
);
266 void prev_word(void);
268 void emacs_control(void);
274 void right(int disp
);
278 void function_key(void);
279 void print_buffer(void);
280 void command_prompt(void);
281 void command(char *cmd_str1
);
282 int scan(char *line
, int offset
, int column
);
283 char *get_string(char *prompt
, int advance
);
284 int compare(char *string1
, char *string2
, int sensitive
);
285 void goto_line(char *cmd_str
);
286 void midscreen(int line
, unsigned char *pnt
);
287 void get_options(int numargs
, char *arguments
[]);
289 void get_file(char *file_name
);
290 void get_line(int length
, unsigned char *in_string
, int *append
);
291 void draw_screen(void);
293 int quit(int noverify
);
294 void edit_abort(int arg
);
295 void delete_text(void);
296 int write_file(char *file_name
, int warn_if_exists
);
297 int search(int display_message
);
298 void search_prompt(void);
300 void undel_char(void);
302 void undel_word(void);
304 void undel_line(void);
306 void move_rel(char *direction
, int lines
);
310 void sh_command(char *string
);
311 void set_up_term(void);
312 void resize_check(void);
313 int menu_op(struct menu_entries
*);
314 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
);
316 void paint_info_win(void);
317 void no_info_window(void);
318 void create_info_window(void);
319 int file_op(int arg
);
323 int Blank_Line(struct text
*test_line
);
326 void dump_ee_conf(void);
327 void echo_string(char *string
);
329 void ispell_op(void);
330 int first_word_len(struct text
*test_line
);
331 void Auto_Format(void);
333 char *is_in_string(char *string
, char *substring
);
334 char *resolve_name(char *name
);
335 int restrict_mode(void);
336 int unique_test(char *string
, char *list
[]);
337 void renumber_lines(struct text
*firstline
, int startnumber
);
338 void strings_init(void);
341 | allocate space here for the strings that will be in the menu
344 struct menu_entries modes_menu
[] = {
345 {"", NULL
, NULL
, NULL
, NULL
, 0}, /* title */
346 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 1. tabs to spaces */
347 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 2. case sensitive search*/
348 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 3. margins observed */
349 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 4. auto-paragraph */
350 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 5. eightbit characters*/
351 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 6. info window */
352 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 7. emacs key bindings*/
353 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 8. right margin */
354 {"", NULL
, NULL
, NULL
, NULL
, -1}, /* 9. chinese text */
355 {"", NULL
, NULL
, NULL
, dump_ee_conf
, -1}, /* 10. save editor config */
356 {NULL
, NULL
, NULL
, NULL
, NULL
, -1} /* terminator */
359 char *mode_strings
[11];
361 #define NUM_MODES_ITEMS 10
363 struct menu_entries config_dump_menu
[] = {
364 {"", NULL
, NULL
, NULL
, NULL
, 0},
365 {"", NULL
, NULL
, NULL
, NULL
, -1},
366 {"", NULL
, NULL
, NULL
, NULL
, -1},
367 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
370 struct menu_entries leave_menu
[] = {
371 {"", NULL
, NULL
, NULL
, NULL
, -1},
372 {"", NULL
, NULL
, NULL
, finish
, -1},
373 {"", NULL
, NULL
, quit
, NULL
, TRUE
},
374 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
381 struct menu_entries file_menu
[] = {
382 {"", NULL
, NULL
, NULL
, NULL
, -1},
383 {"", NULL
, NULL
, file_op
, NULL
, READ_FILE
},
384 {"", NULL
, NULL
, file_op
, NULL
, WRITE_FILE
},
385 {"", NULL
, NULL
, file_op
, NULL
, SAVE_FILE
},
386 {"", NULL
, NULL
, NULL
, print_buffer
, -1},
387 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
390 struct menu_entries search_menu
[] = {
391 {"", NULL
, NULL
, NULL
, NULL
, 0},
392 {"", NULL
, NULL
, NULL
, search_prompt
, -1},
393 {"", NULL
, NULL
, search
, NULL
, TRUE
},
394 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
397 struct menu_entries spell_menu
[] = {
398 {"", NULL
, NULL
, NULL
, NULL
, -1},
399 {"", NULL
, NULL
, NULL
, spell_op
, -1},
400 {"", NULL
, NULL
, NULL
, ispell_op
, -1},
401 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
404 struct menu_entries misc_menu
[] = {
405 {"", NULL
, NULL
, NULL
, NULL
, -1},
406 {"", NULL
, NULL
, NULL
, Format
, -1},
407 {"", NULL
, NULL
, NULL
, shell_op
, -1},
408 {"", menu_op
, spell_menu
, NULL
, NULL
, -1},
409 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
412 struct menu_entries main_menu
[] = {
413 {"", NULL
, NULL
, NULL
, NULL
, -1},
414 {"", NULL
, NULL
, NULL
, leave_op
, -1},
415 {"", NULL
, NULL
, NULL
, help
, -1},
416 {"", menu_op
, file_menu
, NULL
, NULL
, -1},
417 {"", NULL
, NULL
, NULL
, redraw
, -1},
418 {"", NULL
, NULL
, NULL
, modes_op
, -1},
419 {"", menu_op
, search_menu
, NULL
, NULL
, -1},
420 {"", menu_op
, misc_menu
, NULL
, NULL
, -1},
421 {NULL
, NULL
, NULL
, NULL
, NULL
, -1}
425 char *control_keys
[5];
427 char *emacs_help_text
[22];
428 char *emacs_control_keys
[5];
430 char *command_strings
[5];
432 char *init_strings
[22];
436 #define max_alpha_char 36
439 | Declarations for strings for localization
442 char *com_win_message
; /* to be shown in com_win if no info window */
443 char *no_file_string
;
444 char *ascii_code_str
;
445 char *printer_msg_str
;
447 char *file_write_prompt_str
;
448 char *file_read_prompt_str
;
451 char *non_unique_cmd_msg
;
454 char *current_file_str
;
460 char *file_is_dir_msg
;
464 char *file_read_fin_msg
;
465 char *reading_file_msg
;
467 char *file_read_lines_msg
;
468 char *save_file_name_prompt
;
469 char *file_not_saved_msg
;
470 char *changes_made_prompt
;
472 char *file_exists_prompt
;
473 char *create_file_fail_msg
;
474 char *writing_file_msg
;
475 char *file_written_msg
;
477 char *str_not_found_msg
;
478 char *search_prompt_str
;
481 char *menu_cancel_msg
;
482 char *menu_size_err_msg
;
483 char *press_any_key_msg
;
485 char *formatting_msg
;
486 char *shell_echo_msg
;
487 char *spell_in_prog_msg
;
489 char *restricted_msg
;
522 char *NOEMACS_string
;
523 char *conf_dump_err_msg
;
524 char *conf_dump_success_msg
;
525 char *conf_not_saved_msg
;
526 char *ree_no_file_msg
;
528 char *menu_too_lrg_msg
;
529 char *more_above_str
, *more_below_str
;
531 char *chinese_cmd
, *nochinese_cmd
;
535 extern char *malloc();
536 extern char *realloc();
537 extern char *getenv();
538 FILE *fopen(); /* declaration for open function */
539 #endif /* HAS_STDLIB */
540 #endif /* __STDC__ */
543 main(int argc
, char **argv
) /* beginning of main program */
547 for (counter
= 1; counter
< 24; counter
++)
548 signal(counter
, SIG_IGN
);
550 signal(SIGCHLD
, SIG_DFL
);
551 signal(SIGSEGV
, SIG_DFL
);
552 signal(SIGINT
, edit_abort
);
553 signal(SIGHUP
, edit_abort
);
555 d_char
= malloc(3); /* provide a buffer for multi-byte chars */
556 d_word
= malloc(150);
559 dlt_line
= txtalloc();
560 dlt_line
->line
= d_line
;
561 dlt_line
->line_length
= 0;
562 curr_line
= first_line
= txtalloc();
563 curr_line
->line
= point
= malloc(10);
564 curr_line
->line_length
= 1;
565 curr_line
->max_length
= 10;
566 curr_line
->prev_line
= NULL
;
567 curr_line
->next_line
= NULL
;
568 curr_line
->line_number
= 1;
575 bit_bucket
= fopen(_PATH_DEVNULL
, "w");
577 gold
= case_sen
= FALSE
;
582 get_options(argc
, argv
);
584 if (right_margin
== 0)
585 right_margin
= COLS
- 1;
586 if (top_of_stack
== NULL
)
590 wmove(com_win
, 0, 0);
592 wprintw(com_win
, ree_no_file_msg
);
596 wprintw(com_win
, no_file_string
);
602 clear_com_win
= TRUE
;
608 snprintf(count_text
, count_text_len
, "L: %d C: %d %s", \
609 curr_line
->line_number
, scr_horz
+ 1, count_text_default
);
610 wmove(count_win
, 0, 0);
612 wstandout(count_win
);
613 wprintw(count_win
, count_text
);
614 wstandend(count_win
);
615 wnoutrefresh(count_win
);
618 wnoutrefresh(text_win
);
620 in
= wgetch(text_win
);
628 clear_com_win
= FALSE
;
629 wmove(com_win
, 0, 0);
633 wprintw(com_win
, "%s", com_win_message
);
640 else if ((in
== '\10') || (in
== 127))
642 in
= 8; /* make sure key is set to backspace */
645 else if ((in
> 31) || (in
== 9))
647 else if ((in
>= 0) && (in
<= 31))
658 /* factor: resize factor */
659 /* rline: position in line */
661 resiz_line(int factor
, struct text
*rline
, int rpos
)
662 /* resize the line to length + factor*/
664 unsigned char *rpoint
;
667 rline
->max_length
+= factor
;
668 rpoint
= rline
->line
= realloc(rline
->line
, rline
->max_length
);
669 for (resiz_var
= 1 ; (resiz_var
< rpos
) ; resiz_var
++)
675 insert(int character
) /* insert character into line */
679 unsigned char *temp
; /* temporary pointer */
680 unsigned char *temp2
; /* temporary pointer */
682 if ((character
== '\011') && (expand_tabs
))
684 counter
= len_char('\011', scr_horz
);
685 for (; counter
> 0; counter
--)
692 if ((curr_line
->max_length
- curr_line
->line_length
) < 5)
693 point
= resiz_line(10, curr_line
, position
);
694 curr_line
->line_length
++;
697 while (counter
< curr_line
->line_length
) /* find end of line */
702 temp
++; /* increase length of line by one */
706 *temp
= *temp2
; /* shift characters over by one */
709 *point
= character
; /* insert new character */
711 if (((character
>= 0) && (character
< ' ')) || (character
>= 127)) /* check for TAB character*/
713 scr_pos
= scr_horz
+= out_char(text_win
, character
, scr_horz
);
719 waddch(text_win
, character
);
720 scr_pos
= ++scr_horz
;
725 if ((observ_margins
) && (right_margin
< scr_pos
))
728 while (scr_pos
> right_margin
)
732 while (position
< counter
)
739 for (value
= 0; value
< counter
; value
++)
744 if ((scr_horz
- horiz_offset
) > last_col
)
747 midscreen(scr_vert
, point
);
750 if ((auto_format
) && (character
== ' ') && (!formatted
))
752 else if ((character
!= ' ') && (character
!= '\t'))
755 draw_line(scr_vert
, scr_horz
, point
, position
, curr_line
->line_length
);
759 delete(int disp
) /* delete character */
762 unsigned char *temp2
;
763 struct text
*temp_buff
;
768 if (point
!= curr_line
->line
) /* if not at beginning of line */
772 if ((ee_chinese
) && (position
>= 2) && (*(point
- 2) > 127))
778 position
-= del_width
;
780 curr_line
->line_length
-= del_width
;
781 if ((*tp
< ' ') || (*tp
>= 127)) /* check for TAB */
784 scr_horz
-= del_width
;
789 *d_char
= *point
; /* save deleted character */
793 d_char
[1] = *(point
+ 1);
795 d_char
[del_width
] = 0;
797 while (temp_pos
<= curr_line
->line_length
)
804 if (scr_horz
< horiz_offset
)
807 midscreen(scr_vert
, point
);
810 else if (curr_line
->prev_line
!= NULL
)
813 left(disp
); /* go to previous line */
814 temp_buff
= curr_line
->next_line
;
815 point
= resiz_line(temp_buff
->line_length
, curr_line
, position
);
816 if (temp_buff
->next_line
!= NULL
)
817 temp_buff
->next_line
->prev_line
= curr_line
;
818 curr_line
->next_line
= temp_buff
->next_line
;
819 renumber_lines(curr_line
->next_line
, curr_line
->line_number
+ 1);
820 temp2
= temp_buff
->line
;
828 while (temp_pos
< temp_buff
->line_length
)
830 curr_line
->line_length
++;
837 free(temp_buff
->line
);
839 temp_buff
= curr_line
;
840 temp_vert
= scr_vert
;
842 if (scr_vert
< last_line
)
844 wmove(text_win
, scr_vert
+ 1, 0);
847 while ((temp_buff
!= NULL
) && (temp_vert
< last_line
))
849 temp_buff
= temp_buff
->next_line
;
852 if ((temp_vert
== last_line
) && (temp_buff
!= NULL
))
854 tp
= temp_buff
->line
;
855 wmove(text_win
, last_line
,0);
857 draw_line(last_line
, 0, tp
, 1, temp_buff
->line_length
);
858 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
861 draw_line(scr_vert
, scr_horz
, point
, position
, curr_line
->line_length
);
866 scanline(unsigned char *pos
) /* find the proper horizontal position for the pointer */
871 ptr
= curr_line
->line
;
878 temp
+= tabshift(temp
);
879 else if ((*ptr
>= 10) && (*ptr
<= 31))
881 else if ((*ptr
>= 32) && (*ptr
< 127))
883 else if (*ptr
== 127)
892 if ((scr_horz
- horiz_offset
) > last_col
)
894 horiz_offset
= (scr_horz
- (scr_horz
% 8)) - (COLS
- 8);
895 midscreen(scr_vert
, point
);
897 else if (scr_horz
< horiz_offset
)
899 horiz_offset
= max(0, (scr_horz
- (scr_horz
% 8)));
900 midscreen(scr_vert
, point
);
905 tabshift(int temp_int
) /* give the number of spaces to shift */
909 leftover
= ((temp_int
+ 1) % 8);
913 return (9 - leftover
);
917 out_char(WINDOW
*window
, int character
, int column
)
918 /* output non-printing character */
921 unsigned char *string
;
924 if (character
== TAB
)
926 i1
= tabshift(column
);
928 (i2
< i1
) && (((column
+i2
+1)-horiz_offset
) < last_col
); i2
++)
934 else if ((character
>= '\0') && (character
< ' '))
936 string
= table
[(int) character
];
938 else if ((character
< 0) || (character
>= 127))
940 if (character
== 127)
944 sprintf(string2
, "<%d>", (character
< 0) ? (character
+ 256) : character
);
949 waddch(window
, (unsigned char)character
);
955 waddch(window
, (unsigned char)character
);
958 for (i2
= 0; (string
[i2
] != 0) && (((column
+i2
+1)-horiz_offset
) < last_col
); i2
++)
959 waddch(window
, string
[i2
]);
960 return(strlen(string
));
963 /* column: the column must be known to provide spacing for tabs */
965 len_char(int character
, int column
) /* return the length of the character */
969 if (character
== '\t')
970 length
= tabshift(column
);
971 else if ((character
>= 0) && (character
< 32))
973 else if ((character
>= 32) && (character
<= 126))
975 else if (character
== 127)
977 else if (((character
> 126) || (character
< 0)) && (!eightbit
))
986 vertical: current vertical position on screen
987 horiz: current horizontal position on screen
989 t_pos: current position (offset in bytes) from bol
990 length: length (in bytes) of line
993 draw_line(int vertical
, int horiz
, unsigned char *ptr
, int t_pos
, int length
)
994 /* redraw line from current position */
996 int d
; /* partial length of special or tab char to display */
997 unsigned char *temp
; /* temporary pointer to position in line */
998 int abs_column
; /* offset in screen units from begin of line */
999 int column
; /* horizontal position on screen */
1000 int row
; /* vertical position on screen */
1001 int posit
; /* temporary position indicator within line */
1004 column
= horiz
- horiz_offset
;
1011 wmove(text_win
, row
, 0);
1012 wclrtoeol(text_win
);
1016 d
= len_char(*temp
, abs_column
);
1022 wmove(text_win
, row
, column
);
1023 wclrtoeol(text_win
);
1024 while ((posit
< length
) && (column
<= last_col
))
1026 if ((*temp
< 32) || (*temp
>= 127))
1028 column
+= len_char(*temp
, abs_column
);
1029 abs_column
+= out_char(text_win
, *temp
, abs_column
);
1035 waddch(text_win
, *temp
);
1040 if (column
< last_col
)
1041 wclrtoeol(text_win
);
1042 wmove(text_win
, vertical
, (horiz
- horiz_offset
));
1046 insert_line(int disp
) /* insert new line */
1050 unsigned char *temp
;
1051 unsigned char *extra
;
1052 struct text
*temp_nod
;
1054 text_changes
= TRUE
;
1055 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1056 wclrtoeol(text_win
);
1057 temp_nod
= txtalloc();
1058 temp_nod
->line
= extra
= malloc(10);
1059 temp_nod
->line_length
= 1;
1060 temp_nod
->max_length
= 10;
1061 temp_nod
->next_line
= curr_line
->next_line
;
1062 renumber_lines(temp_nod
, curr_line
->line_number
+ 1);
1063 if (temp_nod
->next_line
!= NULL
)
1064 temp_nod
->next_line
->prev_line
= temp_nod
;
1065 temp_nod
->prev_line
= curr_line
;
1066 curr_line
->next_line
= temp_nod
;
1067 temp_pos2
= position
;
1069 if (temp_pos2
< curr_line
->line_length
)
1072 while (temp_pos2
< curr_line
->line_length
)
1074 if ((temp_nod
->max_length
- temp_nod
->line_length
)< 5)
1075 extra
= resiz_line(10, temp_nod
, temp_pos
);
1076 temp_nod
->line_length
++;
1085 temp
= resiz_line((1 - temp_nod
->line_length
), curr_line
, position
);
1086 curr_line
->line_length
= 1 + temp
- curr_line
->line
;
1088 curr_line
->line_length
= position
;
1089 curr_line
= temp_nod
;
1092 point
= curr_line
->line
;
1095 if (scr_vert
< last_line
)
1098 wclrtoeol(text_win
);
1099 wmove(text_win
, scr_vert
, 0);
1100 winsertln(text_win
);
1104 wmove(text_win
, 0,0);
1105 wdeleteln(text_win
);
1106 wmove(text_win
, last_line
,0);
1107 wclrtobot(text_win
);
1109 scr_pos
= scr_horz
= 0;
1113 midscreen(scr_vert
, point
);
1115 draw_line(scr_vert
, scr_horz
, point
, position
,
1116 curr_line
->line_length
);
1120 struct text
*txtalloc(void) /* allocate space for line structure */
1122 return((struct text
*) malloc(sizeof( struct text
)));
1125 struct files
*name_alloc(void) /* allocate space for file name list node */
1127 return((struct files
*) malloc(sizeof( struct files
)));
1130 unsigned char *next_word(unsigned char *string
)
1131 /* move to next word in string */
1133 while ((*string
!= 0) && ((*string
!= 32) && (*string
!= 9)))
1135 while ((*string
!= 0) && ((*string
== 32) || (*string
== 9)))
1141 prev_word(void) /* move to start of previous word in text */
1145 if ((position
!= 1) && ((point
[-1] == ' ') || (point
[-1] == '\t')))
1146 { /* if at the start of a word */
1147 while ((position
!= 1) && ((*point
!= ' ') && (*point
!= '\t')))
1150 while ((position
!= 1) && ((*point
== ' ') || (*point
== '\t')))
1152 while ((position
!= 1) && ((*point
!= ' ') && (*point
!= '\t')))
1154 if ((position
!= 1) && ((*point
== ' ') || (*point
== '\t')))
1162 control(void) /* use control for commands */
1166 if (in
== 1) /* control a */
1168 string
= get_string(ascii_code_str
, TRUE
);
1172 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1177 else if (in
== 2) /* control b */
1179 else if (in
== 3) /* control c */
1183 else if (in
== 4) /* control d */
1185 else if (in
== 5) /* control e */
1187 else if (in
== 6) /* control f */
1189 else if (in
== 7) /* control g */
1191 else if (in
== 8) /* control h */
1193 else if (in
== 9) /* control i */
1195 else if (in
== 10) /* control j */
1197 else if (in
== 11) /* control k */
1199 else if (in
== 12) /* control l */
1201 else if (in
== 13) /* control m */
1203 else if (in
== 14) /* control n */
1204 move_rel("d", max(5, (last_line
- 5)));
1205 else if (in
== 15) /* control o */
1207 else if (in
== 16) /* control p */
1208 move_rel("u", max(5, (last_line
- 5)));
1209 else if (in
== 17) /* control q */
1211 else if (in
== 18) /* control r */
1213 else if (in
== 19) /* control s */
1215 else if (in
== 20) /* control t */
1217 else if (in
== 21) /* control u */
1219 else if (in
== 22) /* control v */
1221 else if (in
== 23) /* control w */
1223 else if (in
== 24) /* control x */
1225 else if (in
== 25) /* control y */
1227 else if (in
== 26) /* control z */
1229 else if (in
== 27) /* control [ (escape) */
1236 | Emacs control-key bindings
1244 if (in
== 1) /* control a */
1246 else if (in
== 2) /* control b */
1248 else if (in
== 3) /* control c */
1252 else if (in
== 4) /* control d */
1254 else if (in
== 5) /* control e */
1256 else if (in
== 6) /* control f */
1258 else if (in
== 7) /* control g */
1259 move_rel("u", max(5, (last_line
- 5)));
1260 else if (in
== 8) /* control h */
1262 else if (in
== 9) /* control i */
1264 else if (in
== 10) /* control j */
1266 else if (in
== 11) /* control k */
1268 else if (in
== 12) /* control l */
1270 else if (in
== 13) /* control m */
1272 else if (in
== 14) /* control n */
1274 else if (in
== 15) /* control o */
1276 string
= get_string(ascii_code_str
, TRUE
);
1280 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1285 else if (in
== 16) /* control p */
1287 else if (in
== 17) /* control q */
1289 else if (in
== 18) /* control r */
1291 else if (in
== 19) /* control s */
1293 else if (in
== 20) /* control t */
1295 else if (in
== 21) /* control u */
1297 else if (in
== 22) /* control v */
1298 move_rel("d", max(5, (last_line
- 5)));
1299 else if (in
== 23) /* control w */
1301 else if (in
== 24) /* control x */
1303 else if (in
== 25) /* control y */
1305 else if (in
== 26) /* control z */
1307 else if (in
== 27) /* control [ (escape) */
1314 bottom(void) /* go to bottom of file */
1316 while (curr_line
->next_line
!= NULL
)
1317 curr_line
= curr_line
->next_line
;
1318 point
= curr_line
->line
;
1322 midscreen(last_line
, point
);
1327 top(void) /* go to top of file */
1329 while (curr_line
->prev_line
!= NULL
)
1330 curr_line
= curr_line
->prev_line
;
1331 point
= curr_line
->line
;
1335 midscreen(0, point
);
1340 nextline(void) /* move pointers to start of next line */
1342 curr_line
= curr_line
->next_line
;
1343 point
= curr_line
->line
;
1345 if (scr_vert
== last_line
)
1347 wmove(text_win
, 0,0);
1348 wdeleteln(text_win
);
1349 wmove(text_win
, last_line
,0);
1350 wclrtobot(text_win
);
1351 draw_line(last_line
,0,point
,1,curr_line
->line_length
);
1358 prevline(void) /* move pointers to start of previous line*/
1360 curr_line
= curr_line
->prev_line
;
1361 point
= curr_line
->line
;
1365 winsertln(text_win
);
1366 draw_line(0,0,point
,1,curr_line
->line_length
);
1370 while (position
< curr_line
->line_length
)
1378 left(int disp
) /* move left one character */
1380 if (point
!= curr_line
->line
) /* if not at begin of line */
1382 if ((ee_chinese
) && (position
>= 2) && (*(point
- 2) > 127))
1390 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1393 else if (curr_line
->prev_line
!= NULL
)
1397 curr_line
= curr_line
->prev_line
;
1398 point
= curr_line
->line
+ curr_line
->line_length
;
1399 position
= curr_line
->line_length
;
1406 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1411 right(int disp
) /* move right one character */
1413 if (position
< curr_line
->line_length
)
1415 if ((ee_chinese
) && (*point
> 127) &&
1416 ((curr_line
->line_length
- position
) >= 2))
1424 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1427 else if (curr_line
->next_line
!= NULL
)
1431 curr_line
= curr_line
->next_line
;
1432 point
= curr_line
->line
;
1437 scr_pos
= scr_horz
= 0;
1441 midscreen(scr_vert
, point
);
1443 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1449 find_pos(void) /* move to the same column as on other line */
1453 while ((scr_horz
< scr_pos
) && (position
< curr_line
->line_length
))
1456 scr_horz
+= tabshift(scr_horz
);
1457 else if (*point
< ' ')
1459 else if ((ee_chinese
) && (*point
> 127) &&
1460 ((curr_line
->line_length
- position
) >= 2))
1471 if ((scr_horz
- horiz_offset
) > last_col
)
1473 horiz_offset
= (scr_horz
- (scr_horz
% 8)) - (COLS
- 8);
1474 midscreen(scr_vert
, point
);
1476 else if (scr_horz
< horiz_offset
)
1478 horiz_offset
= max(0, (scr_horz
- (scr_horz
% 8)));
1479 midscreen(scr_vert
, point
);
1481 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1485 up(void) /* move up one line */
1487 if (curr_line
->prev_line
!= NULL
)
1490 point
= curr_line
->line
;
1496 down(void) /* move down one line */
1498 if (curr_line
->next_line
!= NULL
)
1506 function_key(void) /* process function key */
1510 else if (in
== KEY_RIGHT
)
1512 else if (in
== KEY_HOME
)
1514 else if (in
== KEY_END
)
1516 else if ( in
== KEY_UP
)
1518 else if (in
== KEY_DOWN
)
1520 else if (in
== KEY_NPAGE
)
1521 move_rel("d", max( 5, (last_line
- 5)));
1522 else if (in
== KEY_PPAGE
)
1523 move_rel("u", max(5, (last_line
- 5)));
1524 else if (in
== KEY_DL
)
1526 else if (in
== KEY_DC
)
1528 else if (in
== KEY_BACKSPACE
)
1530 else if (in
== KEY_IL
)
1531 { /* insert a line before current line */
1535 else if (in
== KEY_F(1))
1537 else if (in
== KEY_F(2))
1547 else if (in
== KEY_F(3))
1557 else if (in
== KEY_F(4))
1563 midscreen(scr_vert
, point
);
1568 else if (in
== KEY_F(5))
1578 else if (in
== KEY_F(6))
1588 else if (in
== KEY_F(7))
1598 else if (in
== KEY_F(8))
1615 sprintf(buffer
, ">!%s", print_command
);
1616 wmove(com_win
, 0, 0);
1618 wprintw(com_win
, printer_msg_str
, print_command
);
1624 command_prompt(void)
1629 info_type
= COMMANDS
;
1631 cmd_str
= get_string(command_str
, TRUE
);
1632 if ((result
= unique_test(cmd_str
, commands
)) != 1)
1635 wmove(com_win
, 0, 0);
1637 wprintw(com_win
, unkn_cmd_str
, cmd_str
);
1639 wprintw(com_win
, non_unique_cmd_msg
);
1643 info_type
= CONTROL_KEYS
;
1646 if (cmd_str
!= NULL
)
1652 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
1653 info_type
= CONTROL_KEYS
;
1655 if (cmd_str
!= NULL
)
1660 command(char *cmd_str1
) /* process commands from keyboard */
1662 char *cmd_str2
= NULL
;
1663 char *cmd_str
= cmd_str1
;
1665 clear_com_win
= TRUE
;
1666 if (compare(cmd_str
, HELP
, FALSE
))
1668 else if (compare(cmd_str
, WRITE
, FALSE
))
1670 if (restrict_mode())
1674 cmd_str
= next_word(cmd_str
);
1677 cmd_str
= cmd_str2
= get_string(file_write_prompt_str
, TRUE
);
1679 tmp_file
= resolve_name(cmd_str
);
1680 write_file(tmp_file
, 1);
1681 if (tmp_file
!= cmd_str
)
1684 else if (compare(cmd_str
, READ
, FALSE
))
1686 if (restrict_mode())
1690 cmd_str
= next_word(cmd_str
);
1693 cmd_str
= cmd_str2
= get_string(file_read_prompt_str
, TRUE
);
1697 tmp_file
= resolve_name(cmd_str
);
1699 if (tmp_file
!= cmd_str
)
1702 else if (compare(cmd_str
, LINE
, FALSE
))
1704 wmove(com_win
, 0, 0);
1706 wprintw(com_win
, line_num_str
, curr_line
->line_number
);
1707 wprintw(com_win
, line_len_str
, curr_line
->line_length
);
1709 else if (compare(cmd_str
, FILE_str
, FALSE
))
1711 wmove(com_win
, 0, 0);
1713 if (in_file_name
== NULL
)
1714 wprintw(com_win
, no_file_string
);
1716 wprintw(com_win
, current_file_str
, in_file_name
);
1718 else if ((*cmd_str
>= '0') && (*cmd_str
<= '9'))
1720 else if (compare(cmd_str
, CHARACTER
, FALSE
))
1722 wmove(com_win
, 0, 0);
1724 wprintw(com_win
, char_str
, *point
);
1726 else if (compare(cmd_str
, REDRAW
, FALSE
))
1728 else if (compare(cmd_str
, RESEQUENCE
, FALSE
))
1730 tmp_line
= first_line
->next_line
;
1731 while (tmp_line
!= NULL
)
1733 tmp_line
->line_number
= tmp_line
->prev_line
->line_number
+ 1;
1734 tmp_line
= tmp_line
->next_line
;
1737 else if (compare(cmd_str
, AUTHOR
, FALSE
))
1739 wmove(com_win
, 0, 0);
1741 wprintw(com_win
, "written by Hugh Mahon");
1743 else if (compare(cmd_str
, VERSION
, FALSE
))
1745 wmove(com_win
, 0, 0);
1747 wprintw(com_win
, "%s", version
);
1749 else if (compare(cmd_str
, CASE
, FALSE
))
1751 else if (compare(cmd_str
, NOCASE
, FALSE
))
1753 else if (compare(cmd_str
, EXPAND
, FALSE
))
1755 else if (compare(cmd_str
, NOEXPAND
, FALSE
))
1756 expand_tabs
= FALSE
;
1757 else if (compare(cmd_str
, Exit_string
, FALSE
))
1759 else if (compare(cmd_str
, chinese_cmd
, FALSE
))
1763 nc_setattrib(A_NC_BIG5
);
1766 else if (compare(cmd_str
, nochinese_cmd
, FALSE
))
1770 nc_clearattrib(A_NC_BIG5
);
1773 else if (compare(cmd_str
, QUIT_string
, FALSE
))
1775 else if (*cmd_str
== '!')
1778 if ((*cmd_str
== ' ') || (*cmd_str
== 9))
1779 cmd_str
= next_word(cmd_str
);
1780 sh_command(cmd_str
);
1782 else if ((*cmd_str
== '<') && (!in_pipe
))
1787 if ((*cmd_str
== ' ') || (*cmd_str
== '\t'))
1788 cmd_str
= next_word(cmd_str
);
1793 else if ((*cmd_str
== '>') && (!out_pipe
))
1797 if ((*cmd_str
== ' ') || (*cmd_str
== '\t'))
1798 cmd_str
= next_word(cmd_str
);
1804 wmove(com_win
, 0, 0);
1806 wprintw(com_win
, unkn_cmd_str
, cmd_str
);
1808 if (cmd_str2
!= NULL
)
1813 scan(char *line
, int offset
, int column
)
1814 /* determine horizontal position for get_string */
1826 j
+= len_char(*stemp
, j
);
1833 prompt: string containing user prompt message
1834 advance: if true, skip leading spaces and tabs
1837 get_string(char *prompt
, int advance
)
1838 /* read string from input on command line */
1845 int g_horz
, g_position
, g_pos
;
1848 g_point
= tmp_string
= malloc(512);
1851 waddstr(com_win
, prompt
);
1853 nam_str
= tmp_string
;
1854 clear_com_win
= TRUE
;
1855 g_horz
= g_position
= scan(prompt
, strlen(prompt
), 0);
1860 in
= wgetch(com_win
);
1863 if (((in
== 8) || (in
== 127) || (in
== KEY_BACKSPACE
)) && (g_pos
> 0))
1867 g_horz
= scan(g_point
, g_pos
, g_position
);
1868 tmp_int
= tmp_int
- g_horz
;
1869 for (; 0 < tmp_int
; tmp_int
--)
1871 if ((g_horz
+tmp_int
) < (last_col
- 1))
1873 waddch(com_win
, '\010');
1874 waddch(com_win
, ' ');
1875 waddch(com_win
, '\010');
1880 else if ((in
!= 8) && (in
!= 127) && (in
!= '\n') && (in
!= '\r') && (in
< 256))
1882 if (in
== '\026') /* control-v, accept next character verbatim */
1883 { /* allows entry of ^m, ^j, and ^h */
1885 in
= wgetch(com_win
);
1891 if (((in
< ' ') || (in
> 126)) && (g_horz
< (last_col
- 1)))
1892 g_horz
+= out_char(com_win
, in
, g_horz
);
1896 if (g_horz
< (last_col
- 1))
1897 waddch(com_win
, in
);
1904 } while ((in
!= '\n') && (in
!= '\r'));
1906 nam_str
= tmp_string
;
1907 if (((*nam_str
== ' ') || (*nam_str
== 9)) && (advance
))
1908 nam_str
= next_word(nam_str
);
1909 string
= malloc(strlen(nam_str
) + 1);
1910 strcpy(string
, nam_str
);
1917 compare(char *string1
, char *string2
, int sensitive
) /* compare two strings */
1927 if ((strng1
== NULL
) || (strng2
== NULL
) || (*strng1
== 0) || (*strng2
== 0))
1934 if (*strng1
!= *strng2
)
1939 if (toupper(*strng1
) != toupper(*strng2
))
1944 if ((*strng1
== 0) || (*strng2
== 0) || (*strng1
== ' ') || (*strng2
== ' '))
1952 goto_line(char *cmd_str
)
1957 char *direction
= NULL
;
1958 struct text
*t_line
;
1962 while ((*ptr
>='0') && (*ptr
<= '9'))
1964 i
= i
* 10 + (*ptr
- '0');
1970 while ((t_line
->line_number
> number
) && (t_line
->prev_line
!= NULL
))
1973 t_line
= t_line
->prev_line
;
1976 while ((t_line
->line_number
< number
) && (t_line
->next_line
!= NULL
))
1980 t_line
= t_line
->next_line
;
1982 if ((i
< 30) && (i
> 0))
1984 move_rel(direction
, i
);
1989 point
= curr_line
->line
;
1991 midscreen((last_line
/ 2), point
);
1994 wmove(com_win
, 0, 0);
1996 wprintw(com_win
, line_num_str
, curr_line
->line_number
);
1997 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
2001 midscreen(int line
, unsigned char *pnt
)
2002 /* put current line in middle of screen */
2004 struct text
*mid_line
;
2007 line
= min(line
, last_line
);
2008 mid_line
= curr_line
;
2009 for (i
= 0; ((i
< line
) && (curr_line
->prev_line
!= NULL
)); i
++)
2010 curr_line
= curr_line
->prev_line
;
2011 scr_vert
= scr_horz
= 0;
2012 wmove(text_win
, 0, 0);
2015 curr_line
= mid_line
;
2017 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
2021 get_options(int numargs
, char **arguments
)
2022 /* get arguments from command line */
2026 struct files
*temp_names
= NULL
;
2031 | see if editor was invoked as 'ree' (restricted mode)
2034 if (!(name
= strrchr(arguments
[0], '/')))
2035 name
= arguments
[0];
2038 if (!strcmp(name
, "ree"))
2041 top_of_stack
= NULL
;
2045 while (count
< numargs
)
2047 buff
= arguments
[count
];
2048 if (!strcmp("-i", buff
))
2050 info_window
= FALSE
;
2052 else if (!strcmp("-e", buff
))
2054 expand_tabs
= FALSE
;
2056 else if (!strcmp("-h", buff
))
2060 else if (!strcmp("-?", buff
))
2062 fprintf(stderr
, usage0
, arguments
[0]);
2063 fprintf(stderr
, usage1
);
2064 fprintf(stderr
, usage2
);
2065 fprintf(stderr
, usage3
);
2066 fprintf(stderr
, usage4
);
2069 else if (*buff
== '+')
2072 start_at_line
= buff
;
2077 if (top_of_stack
== NULL
)
2079 temp_names
= top_of_stack
= name_alloc();
2083 temp_names
->next_name
= name_alloc();
2084 temp_names
= temp_names
->next_name
;
2086 ptr
= temp_names
->name
= malloc(strlen(buff
) + 1);
2094 temp_names
->next_name
= NULL
;
2103 check_fp(void) /* open or close files according to flags */
2109 clear_com_win
= TRUE
;
2110 tmp_vert
= scr_vert
;
2111 tmp_horz
= scr_horz
;
2112 tmp_line
= curr_line
;
2115 in_file_name
= tmp_file
= top_of_stack
->name
;
2116 top_of_stack
= top_of_stack
->next_name
;
2118 temp
= stat(tmp_file
, &buf
);
2119 buf
.st_mode
&= ~07777;
2120 if ((temp
!= -1) && (buf
.st_mode
!= 0100000) && (buf
.st_mode
!= 0))
2122 wprintw(com_win
, file_is_dir_msg
, tmp_file
);
2132 if ((get_fd
= open(tmp_file
, O_RDONLY
)) == -1)
2134 wmove(com_win
, 0, 0);
2137 wprintw(com_win
, new_file_msg
, tmp_file
);
2139 wprintw(com_win
, cant_open_msg
, tmp_file
);
2141 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
2151 line_num
= curr_line
->line_number
;
2152 scr_vert
= tmp_vert
;
2153 scr_horz
= tmp_horz
;
2155 curr_line
= first_line
;
2157 curr_line
= tmp_line
;
2158 point
= curr_line
->line
;
2163 if (start_at_line
!= NULL
)
2165 line_num
= atoi(start_at_line
) - 1;
2166 move_rel("d", line_num
);
2168 start_at_line
= NULL
;
2173 wmove(com_win
, 0, 0);
2175 text_changes
= TRUE
;
2176 if ((tmp_file
!= NULL
) && (*tmp_file
!= 0))
2177 wprintw(com_win
, file_read_fin_msg
, tmp_file
);
2180 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
2185 get_file(char *file_name
) /* read specified file into current buffer */
2187 int can_read
; /* file has at least one character */
2188 int length
; /* length of line read by read */
2189 int append
; /* should text be appended to current line */
2190 struct text
*temp_line
;
2191 char ro_flag
= FALSE
;
2193 if (recv_file
) /* if reading a file */
2195 wmove(com_win
, 0, 0);
2197 wprintw(com_win
, reading_file_msg
, file_name
);
2198 if (access(file_name
, 2)) /* check permission to write */
2200 if ((errno
== ENOTDIR
) || (errno
== EACCES
) || (errno
== EROFS
) || (errno
== ETXTBSY
) || (errno
== EFAULT
))
2202 wprintw(com_win
, read_only_msg
);
2208 if (curr_line
->line_length
> 1) /* if current line is not blank */
2216 can_read
= FALSE
; /* test if file has any characters */
2217 while (((length
= read(get_fd
, in_string
, 512)) != 0) && (length
!= -1))
2219 can_read
= TRUE
; /* if set file has at least 1 character */
2220 get_line(length
, in_string
, &append
);
2222 if ((can_read
) && (curr_line
->line_length
== 1))
2224 temp_line
= curr_line
->prev_line
;
2225 temp_line
->next_line
= curr_line
->next_line
;
2226 if (temp_line
->next_line
!= NULL
)
2227 temp_line
->next_line
->prev_line
= temp_line
;
2228 if (curr_line
->line
!= NULL
)
2229 free(curr_line
->line
);
2231 curr_line
= temp_line
;
2233 if (input_file
) /* if this is the file to be edited display number of lines */
2235 wmove(com_win
, 0, 0);
2237 wprintw(com_win
, file_read_lines_msg
, in_file_name
, curr_line
->line_number
);
2239 wprintw(com_win
, read_only_msg
);
2242 else if (can_read
) /* not input_file and file is non-zero size */
2243 text_changes
= TRUE
;
2245 if (recv_file
) /* if reading a file */
2252 length: length of string read by read
2253 in_string: string read by read
2254 append: TRUE if must append more text to end of current line
2257 get_line(int length
, unsigned char *in_string
, int *append
)
2258 /* read string and split into lines */
2260 unsigned char *str1
;
2261 unsigned char *str2
;
2262 int num
; /* offset from start of string */
2263 int char_count
; /* length of new line (or added portion */
2264 int temp_counter
; /* temporary counter value */
2265 struct text
*tline
; /* temporary pointer to new line */
2266 int first_time
; /* if TRUE, the first time through the loop */
2271 while (num
< length
)
2285 /* find end of line */
2286 while ((*str2
!= '\n') && (num
< length
))
2292 if (!(*append
)) /* if not append to current line, insert new one */
2294 tline
= txtalloc(); /* allocate data structure for next line */
2295 tline
->next_line
= curr_line
->next_line
;
2296 renumber_lines(tline
, curr_line
->line_number
+ 1);
2297 tline
->prev_line
= curr_line
;
2298 curr_line
->next_line
= tline
;
2299 if (tline
->next_line
!= NULL
)
2300 tline
->next_line
->prev_line
= tline
;
2302 curr_line
->line
= point
= (unsigned char *) malloc(char_count
);
2303 curr_line
->line_length
= char_count
;
2304 curr_line
->max_length
= char_count
;
2308 point
= resiz_line(char_count
, curr_line
, curr_line
->line_length
);
2309 curr_line
->line_length
+= (char_count
- 1);
2311 for (temp_counter
= 1; temp_counter
< char_count
; temp_counter
++)
2319 if ((num
== length
) && (*str2
!= '\n'))
2325 draw_screen(void) /* redraw the screen from current postion */
2327 struct text
*temp_line
;
2328 unsigned char *line_out
;
2331 temp_line
= curr_line
;
2332 temp_vert
= scr_vert
;
2333 wclrtobot(text_win
);
2334 while ((temp_line
!= NULL
) && (temp_vert
<= last_line
))
2336 line_out
= temp_line
->line
;
2337 draw_line(temp_vert
, 0, line_out
, 1, temp_line
->line_length
);
2339 temp_line
= temp_line
->next_line
;
2341 wmove(text_win
, temp_vert
, 0);
2342 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
2346 finish(void) /* prepare to exit edit session */
2348 char *file_name
= in_file_name
;
2351 | changes made here should be reflected in the 'save'
2352 | portion of file_op()
2355 if ((file_name
== NULL
) || (*file_name
== 0))
2356 file_name
= get_string(save_file_name_prompt
, TRUE
);
2358 if ((file_name
== NULL
) || (*file_name
== 0))
2360 wmove(com_win
, 0, 0);
2361 wprintw(com_win
, file_not_saved_msg
);
2364 clear_com_win
= TRUE
;
2368 tmp_file
= resolve_name(file_name
);
2369 if (tmp_file
!= file_name
)
2372 file_name
= tmp_file
;
2375 if (write_file(file_name
, 1))
2377 text_changes
= FALSE
;
2383 quit(int noverify
) /* exit editor */
2389 if ((text_changes
) && (!noverify
))
2391 ans
= get_string(changes_made_prompt
, TRUE
);
2392 if (toupper(*ans
) == toupper(*yes_char
))
2393 text_changes
= FALSE
;
2398 if (top_of_stack
== NULL
)
2414 text_changes
= FALSE
;
2432 while (curr_line
->next_line
!= NULL
)
2433 curr_line
= curr_line
->next_line
;
2434 while (curr_line
!= first_line
)
2436 free(curr_line
->line
);
2437 curr_line
= curr_line
->prev_line
;
2438 free(curr_line
->next_line
);
2440 curr_line
->next_line
= NULL
;
2441 *curr_line
->line
= 0;
2442 curr_line
->line_length
= 1;
2443 curr_line
->line_number
= 1;
2444 point
= curr_line
->line
;
2445 scr_pos
= scr_vert
= scr_horz
= 0;
2450 write_file(char *file_name
, int warn_if_exists
)
2454 struct text
*out_line
;
2457 int write_flag
= TRUE
;
2460 if (warn_if_exists
&&
2461 ((in_file_name
== NULL
) || strcmp(in_file_name
, file_name
)))
2463 if ((temp_fp
= fopen(file_name
, "r")))
2465 tmp_point
= get_string(file_exists_prompt
, TRUE
);
2466 if (toupper(*tmp_point
) == toupper(*yes_char
))
2475 clear_com_win
= TRUE
;
2479 if ((temp_fp
= fopen(file_name
, "w")) == NULL
)
2481 clear_com_win
= TRUE
;
2484 wprintw(com_win
, create_file_fail_msg
, file_name
);
2492 wprintw(com_win
, writing_file_msg
, file_name
);
2495 out_line
= first_line
;
2496 while (out_line
!= NULL
)
2499 tmp_point
= out_line
->line
;
2500 while (temp_pos
< out_line
->line_length
)
2502 putc(*tmp_point
, temp_fp
);
2506 charac
+= out_line
->line_length
;
2507 out_line
= out_line
->next_line
;
2514 wprintw(com_win
, file_written_msg
, file_name
, lines
, charac
);
2524 search(int display_message
) /* search for string in srch_str */
2530 if ((srch_str
== NULL
) || (*srch_str
== 0))
2532 if (display_message
)
2534 wmove(com_win
, 0, 0);
2536 wprintw(com_win
, searching_msg
);
2538 clear_com_win
= TRUE
;
2542 srch_line
= curr_line
;
2544 if (position
< curr_line
->line_length
)
2546 iter
= position
+ 1;
2547 while ((!found
) && (srch_line
!= NULL
))
2549 while ((iter
< srch_line
->line_length
) && (!found
))
2552 if (case_sen
) /* if case sensitive */
2555 while ((*srch_2
== *srch_3
) && (*srch_3
!= 0))
2562 else /* if not case sensitive */
2564 srch_3
= u_srch_str
;
2565 while ((toupper(*srch_2
) == *srch_3
) && (*srch_3
!= 0))
2572 if (!((*srch_3
== 0) && (found
)))
2575 if (iter
< srch_line
->line_length
)
2582 srch_line
= srch_line
->next_line
;
2583 if (srch_line
!= NULL
)
2584 srch_1
= srch_line
->line
;
2591 if (display_message
)
2593 wmove(com_win
, 0, 0);
2597 if (lines_moved
== 0)
2599 while (position
< iter
)
2604 if (lines_moved
< 30)
2606 move_rel("d", lines_moved
);
2607 while (position
< iter
)
2612 curr_line
= srch_line
;
2617 midscreen((last_line
/ 2), point
);
2623 if (display_message
)
2625 wmove(com_win
, 0, 0);
2627 wprintw(com_win
, str_not_found_msg
, srch_str
);
2630 wmove(text_win
, scr_vert
,(scr_horz
- horiz_offset
));
2636 search_prompt(void) /* prompt and read search string (srch_str) */
2638 if (srch_str
!= NULL
)
2640 if ((u_srch_str
!= NULL
) && (*u_srch_str
!= 0))
2642 srch_str
= get_string(search_prompt_str
, FALSE
);
2645 srch_1
= u_srch_str
= malloc(strlen(srch_str
) + 1);
2646 while (*srch_3
!= 0)
2648 *srch_1
= toupper(*srch_3
);
2657 del_char(void) /* delete current character */
2659 in
= 8; /* backspace */
2660 if (position
< curr_line
->line_length
) /* if not end of line */
2662 if ((ee_chinese
) && (*point
> 127) &&
2663 ((curr_line
->line_length
- position
) >= 2))
2681 undel_char(void) /* undelete last deleted character */
2683 if (d_char
[0] == '\n') /* insert line if last del_char deleted eol */
2698 del_word(void) /* delete word in front of cursor */
2702 unsigned char *d_word2
;
2703 unsigned char *d_word3
;
2704 unsigned char tmp_char
[3];
2708 d_word
= malloc(curr_line
->line_length
);
2709 tmp_char
[0] = d_char
[0];
2710 tmp_char
[1] = d_char
[1];
2711 tmp_char
[2] = d_char
[2];
2715 while ((tposit
< curr_line
->line_length
) &&
2716 ((*d_word3
!= ' ') && (*d_word3
!= '\t')))
2719 *d_word2
= *d_word3
;
2723 while ((tposit
< curr_line
->line_length
) &&
2724 ((*d_word3
== ' ') || (*d_word3
== '\t')))
2727 *d_word2
= *d_word3
;
2732 d_wrd_len
= difference
= d_word2
- d_word
;
2734 while (tposit
< curr_line
->line_length
)
2737 *d_word2
= *d_word3
;
2741 curr_line
->line_length
-= difference
;
2743 draw_line(scr_vert
, scr_horz
,point
,position
,curr_line
->line_length
);
2744 d_char
[0] = tmp_char
[0];
2745 d_char
[1] = tmp_char
[1];
2746 d_char
[2] = tmp_char
[2];
2747 text_changes
= TRUE
;
2752 undel_word(void) /* undelete last deleted word */
2756 unsigned char *tmp_old_ptr
;
2757 unsigned char *tmp_space
;
2758 unsigned char *tmp_ptr
;
2759 unsigned char *d_word_ptr
;
2762 | resize line to handle undeleted word
2764 if ((curr_line
->max_length
- (curr_line
->line_length
+ d_wrd_len
)) < 5)
2765 point
= resiz_line(d_wrd_len
, curr_line
, position
);
2766 tmp_ptr
= tmp_space
= malloc(curr_line
->line_length
+ d_wrd_len
);
2767 d_word_ptr
= d_word
;
2770 | copy d_word contents into temp space
2772 while (temp
<= d_wrd_len
)
2775 *tmp_ptr
= *d_word_ptr
;
2779 tmp_old_ptr
= point
;
2782 | copy contents of line from curent position to eol into
2785 while (tposit
< curr_line
->line_length
)
2789 *tmp_ptr
= *tmp_old_ptr
;
2793 curr_line
->line_length
+= d_wrd_len
;
2794 tmp_old_ptr
= point
;
2796 tmp_ptr
= tmp_space
;
2799 | now copy contents from temp space back to original line
2801 while (tposit
< temp
)
2804 *tmp_old_ptr
= *tmp_ptr
;
2810 draw_line(scr_vert
, scr_horz
, point
, position
, curr_line
->line_length
);
2814 del_line(void) /* delete from cursor to end of line */
2822 d_line
= malloc(curr_line
->line_length
);
2826 while (tposit
< curr_line
->line_length
)
2833 dlt_line
->line_length
= 1 + tposit
- position
;
2836 curr_line
->line_length
= position
;
2837 wclrtoeol(text_win
);
2838 if (curr_line
->next_line
!= NULL
)
2843 text_changes
= TRUE
;
2847 undel_line(void) /* undelete last deleted line */
2853 if (dlt_line
->line_length
== 0)
2858 point
= resiz_line(dlt_line
->line_length
, curr_line
, position
);
2859 curr_line
->line_length
+= dlt_line
->line_length
- 1;
2863 while (tposit
< dlt_line
->line_length
)
2871 draw_line(scr_vert
, scr_horz
,point
,position
,curr_line
->line_length
);
2875 adv_word(void) /* advance to next word */
2877 while ((position
< curr_line
->line_length
) && ((*point
!= 32) && (*point
!= 9)))
2879 while ((position
< curr_line
->line_length
) && ((*point
== 32) || (*point
== 9)))
2884 move_rel(char *direction
, int lines
) /* move relative to current line */
2889 if (*direction
== 'u')
2892 while (position
> 1)
2894 for (i
= 0; i
< lines
; i
++)
2898 if ((last_line
> 5) && ( scr_vert
< 4))
2901 tmp_line
= curr_line
;
2902 for (i
= 0;(i
<5)&&(curr_line
->prev_line
!= NULL
); i
++)
2906 scr_vert
= scr_vert
+ i
;
2907 curr_line
= tmp_line
;
2914 if ((position
!= 1) && (curr_line
->next_line
!= NULL
))
2917 scr_pos
= scr_horz
= 0;
2921 midscreen(scr_vert
, point
);
2926 for (i
= 1; i
< lines
; i
++)
2930 if ((last_line
> 10) && (scr_vert
> (last_line
- 5)))
2933 tmp_line
= curr_line
;
2934 for (i
=0; (i
<5) && (curr_line
->next_line
!= NULL
); i
++)
2938 scr_vert
= scr_vert
- i
;
2939 curr_line
= tmp_line
;
2944 wmove(text_win
, scr_vert
, (scr_horz
- horiz_offset
));
2948 eol(void) /* go to end of line */
2950 if (position
< curr_line
->line_length
)
2952 while (position
< curr_line
->line_length
)
2955 else if (curr_line
->next_line
!= NULL
)
2958 while (position
< curr_line
->line_length
)
2964 bol(void) /* move to beginning of line */
2966 if (point
!= curr_line
->line
)
2968 while (point
!= curr_line
->line
)
2971 else if (curr_line
->prev_line
!= NULL
)
2979 adv_line(void) /* advance to beginning of next line */
2981 if ((point
!= curr_line
->line
) || (scr_pos
> 0))
2983 while (position
< curr_line
->line_length
)
2987 else if (curr_line
->next_line
!= NULL
)
2994 /* string: string containing user command */
2996 sh_command(char *string
) /* execute shell command */
3000 char *path
; /* directory path to executable */
3001 int parent
; /* zero if child, child's pid if parent */
3004 struct text
*line_holder
;
3006 if (restrict_mode())
3011 if (!(path
= getenv("SHELL")))
3013 last_slash
= temp_point
= path
;
3014 while (*temp_point
!= 0)
3016 if (*temp_point
== '/')
3017 last_slash
= ++temp_point
;
3023 | if in_pipe is true, then output of the shell operation will be
3024 | read by the editor, and curses doesn't need to be turned off
3029 keypad(com_win
, FALSE
);
3030 keypad(text_win
, FALSE
);
3043 pipe(pipe_in
); /* create a pipe */
3045 if (!parent
) /* if the child */
3048 | child process which will fork and exec shell command (if shell output is
3049 | to be read by editor)
3053 | redirect stdout to pipe
3055 temp_stdout
= dup(1);
3059 | redirect stderr to pipe
3061 temp_stderr
= dup(2);
3066 | child will now continue down 'if (!in_pipe)'
3070 else /* if the parent */
3073 | prepare editor to read from the pipe
3075 signal(SIGCHLD
, SIG_IGN
);
3076 line_holder
= curr_line
;
3077 tmp_vert
= scr_vert
;
3079 get_fd
= pipe_in
[0];
3082 scr_vert
= tmp_vert
;
3083 scr_horz
= scr_pos
= 0;
3085 curr_line
= line_holder
;
3086 point
= curr_line
->line
;
3088 signal(SIGCHLD
, SIG_DFL
);
3090 | since flag "in_pipe" is still TRUE, the path which waits for the child
3091 | process to die will be avoided.
3092 | (the pipe is closed, no more output can be expected)
3098 signal(SIGINT
, SIG_IGN
);
3104 | fork process which will exec command
3107 if (!parent
) /* if the child */
3114 | prepare the child process (soon to exec a shell command) to read from the
3115 | pipe (which will be output from the editor's buffer)
3122 for (value
= 1; value
< 24; value
++)
3123 signal(value
, SIG_DFL
);
3124 execl(path
, last_slash
, "-c", string
, NULL
);
3125 errx(1, exec_err_msg
, path
);
3127 else /* if the parent */
3132 | output the contents of the buffer to the pipe (to be read by the
3133 | process forked and exec'd above as stdin)
3136 line_holder
= first_line
;
3137 while (line_holder
!= NULL
)
3139 write(pipe_out
[1], line_holder
->line
, (line_holder
->line_length
-1));
3140 write(pipe_out
[1], "\n", 1);
3141 line_holder
= line_holder
->next_line
;
3148 return_val
= wait(NULL
);
3150 while ((return_val
!= parent
) && (return_val
!= -1));
3152 | if this process is actually the child of the editor, exit. Here's how it
3154 | The editor forks a process. If output must be sent to the command to be
3155 | exec'd another process is forked, and that process (the child's child)
3156 | will exec the command. In this case, "shell_fork" will be FALSE. If no
3157 | output is to be performed to the shell command, "shell_fork" will be TRUE.
3158 | If this is the editor process, shell_fork will be true, otherwise this is
3159 | the child of the edit process.
3164 signal(SIGINT
, edit_abort
);
3168 printf("%s", continue_msg
);
3170 while ((in
= getchar()) != '\n')
3180 keypad(text_win
, TRUE
);
3181 keypad(com_win
, TRUE
);
3183 clearok(info_win
, TRUE
);
3190 set_up_term(void) /* set up the terminal for operating with ae */
3192 if (!curses_initialized
)
3199 curses_initialized
= TRUE
;
3202 if (((LINES
> 15) && (COLS
>= 80)) && info_window
)
3203 last_line
= LINES
- 8;
3206 info_window
= FALSE
;
3207 last_line
= LINES
- 2;
3210 idlok(stdscr
, TRUE
);
3211 com_win
= newwin(1, COLS
, (LINES
- 1), 0);
3212 keypad(com_win
, TRUE
);
3213 idlok(com_win
, TRUE
);
3216 text_win
= newwin((LINES
- 1), COLS
, 0, 0);
3218 text_win
= newwin((LINES
- 7), COLS
, 6, 0);
3219 keypad(text_win
, TRUE
);
3220 idlok(text_win
, TRUE
);
3222 help_win
= newwin((LINES
- 1), COLS
, 0, 0);
3223 keypad(help_win
, TRUE
);
3224 idlok(help_win
, TRUE
);
3227 info_type
= CONTROL_KEYS
;
3228 info_win
= newwin(5, COLS
, 0, 0);
3231 count_win
= newwin(1, COLS
, 5, 0);
3232 leaveok(count_win
, TRUE
);
3233 wrefresh(count_win
);
3236 last_col
= COLS
- 1;
3237 local_LINES
= LINES
;
3242 nc_setattrib(A_NC_BIG5
);
3250 if ((LINES
== local_LINES
) && (COLS
== local_COLS
))
3264 static char item_alpha
[] = "abcdefghijklmnopqrstuvwxyz0123456789 ";
3267 menu_op(struct menu_entries
*menu_list
)
3270 int max_width
, max_height
;
3277 int top_offset
; /* offset from top where menu items start */
3278 int vert_pos
; /* vertical position */
3279 int vert_size
; /* vertical size for menu list item display */
3280 int off_start
= 1; /* offset from start of menu items to start display */
3284 | determine number and width of menu items
3288 while (menu_list
[list_size
+ 1].item_string
!= NULL
)
3291 for (counter
= 0; counter
<= list_size
; counter
++)
3293 if ((length
= strlen(menu_list
[counter
].item_string
)) > max_width
)
3297 max_width
= max(max_width
, strlen(menu_cancel_msg
));
3298 max_width
= max(max_width
, max(strlen(more_above_str
), strlen(more_below_str
)));
3302 | make sure that window is large enough to handle menu
3303 | if not, print error message and return to calling function
3306 if (max_width
> COLS
)
3308 wmove(com_win
, 0, 0);
3310 wprintw(com_win
, menu_too_lrg_msg
);
3312 clear_com_win
= TRUE
;
3318 if (list_size
> LINES
)
3321 if (max_height
> 11)
3322 vert_size
= max_height
- 8;
3324 vert_size
= max_height
;
3328 vert_size
= list_size
;
3329 max_height
= list_size
;
3332 if (LINES
>= (vert_size
+ 8))
3334 if (menu_list
[0].argument
!= MENU_WARN
)
3335 max_height
= vert_size
+ 8;
3337 max_height
= vert_size
+ 7;
3340 x_off
= (COLS
- max_width
) / 2;
3341 y_off
= (LINES
- max_height
- 1) / 2;
3342 temp_win
= newwin(max_height
, max_width
, y_off
, x_off
);
3343 keypad(temp_win
, TRUE
);
3345 paint_menu(menu_list
, max_width
, max_height
, list_size
, top_offset
, temp_win
, off_start
, vert_size
);
3352 wmove(temp_win
, (1 + counter
+ top_offset
- off_start
), 3);
3354 wmove(temp_win
, (counter
+ top_offset
- off_start
), 3);
3357 input
= wgetch(temp_win
);
3359 if (((tolower(input
) >= 'a') && (tolower(input
) <= 'z')) ||
3360 ((input
>= '0') && (input
<= '9')))
3362 if ((tolower(input
) >= 'a') && (tolower(input
) <= 'z'))
3364 temp
= 1 + tolower(input
) - 'a';
3366 else if ((input
>= '0') && (input
<= '9'))
3368 temp
= (2 + 'z' - 'a') + (input
- '0');
3371 if (temp
<= list_size
)
3381 case ' ': /* space */
3382 case '\004': /* ^d, down */
3386 if (counter
> list_size
)
3389 case '\010': /* ^h, backspace*/
3390 case '\025': /* ^u, up */
3391 case 127: /* ^?, delete */
3397 counter
= list_size
;
3399 case '\033': /* escape key */
3400 if (menu_list
[0].argument
!= MENU_WARN
)
3403 case '\014': /* ^l */
3404 case '\022': /* ^r, redraw */
3405 paint_menu(menu_list
, max_width
, max_height
,
3406 list_size
, top_offset
, temp_win
,
3407 off_start
, vert_size
);
3414 if (((list_size
- off_start
) >= (vert_size
- 1)) &&
3415 (counter
> (off_start
+ vert_size
- 3)) &&
3418 if (counter
== list_size
)
3419 off_start
= (list_size
- vert_size
) + 2;
3423 paint_menu(menu_list
, max_width
, max_height
,
3424 list_size
, top_offset
, temp_win
, off_start
,
3427 else if ((list_size
!= vert_size
) &&
3428 (counter
> (off_start
+ vert_size
- 2)))
3430 if (counter
== list_size
)
3431 off_start
= 2 + (list_size
- vert_size
);
3432 else if (off_start
== 1)
3437 paint_menu(menu_list
, max_width
, max_height
,
3438 list_size
, top_offset
, temp_win
, off_start
,
3441 else if (counter
< off_start
)
3446 off_start
= counter
;
3448 paint_menu(menu_list
, max_width
, max_height
,
3449 list_size
, top_offset
, temp_win
, off_start
,
3453 while ((input
!= '\r') && (input
!= '\n') && (counter
!= 0));
3459 if ((menu_list
[counter
].procedure
!= NULL
) ||
3460 (menu_list
[counter
].iprocedure
!= NULL
) ||
3461 (menu_list
[counter
].nprocedure
!= NULL
))
3463 if (menu_list
[counter
].argument
!= -1)
3464 (*menu_list
[counter
].iprocedure
)(menu_list
[counter
].argument
);
3465 else if (menu_list
[counter
].ptr_argument
!= NULL
)
3466 (*menu_list
[counter
].procedure
)(menu_list
[counter
].ptr_argument
);
3468 (*menu_list
[counter
].nprocedure
)();
3479 paint_menu(struct menu_entries
*menu_list
, int max_width
, int max_height
,
3480 int list_size
, int top_offset
, WINDOW
*menu_win
, int off_start
,
3483 int counter
, temp_int
;
3488 | output top and bottom portions of menu box only if window
3492 if (max_height
> vert_size
)
3494 wmove(menu_win
, 1, 1);
3496 wstandout(menu_win
);
3497 waddch(menu_win
, '+');
3498 for (counter
= 0; counter
< (max_width
- 4); counter
++)
3499 waddch(menu_win
, '-');
3500 waddch(menu_win
, '+');
3502 wmove(menu_win
, (max_height
- 2), 1);
3503 waddch(menu_win
, '+');
3504 for (counter
= 0; counter
< (max_width
- 4); counter
++)
3505 waddch(menu_win
, '-');
3506 waddch(menu_win
, '+');
3507 wstandend(menu_win
);
3508 wmove(menu_win
, 2, 3);
3509 waddstr(menu_win
, menu_list
[0].item_string
);
3510 wmove(menu_win
, (max_height
- 3), 3);
3511 if (menu_list
[0].argument
!= MENU_WARN
)
3512 waddstr(menu_win
, menu_cancel_msg
);
3515 wstandout(menu_win
);
3517 for (counter
= 0; counter
< (vert_size
+ top_offset
); counter
++)
3519 if (top_offset
== 4)
3521 temp_int
= counter
+ 2;
3526 wmove(menu_win
, temp_int
, 1);
3527 waddch(menu_win
, '|');
3528 wmove(menu_win
, temp_int
, (max_width
- 2));
3529 waddch(menu_win
, '|');
3531 wstandend(menu_win
);
3533 if (list_size
> vert_size
)
3538 wmove(menu_win
, top_offset
, 3);
3539 waddstr(menu_win
, more_above_str
);
3544 for (counter
= off_start
;
3545 ((temp_int
+ counter
- off_start
) < (vert_size
- 1));
3548 wmove(menu_win
, (top_offset
+ temp_int
+
3549 (counter
- off_start
)), 3);
3551 wprintw(menu_win
, "%c) ", item_alpha
[min((counter
- 1), max_alpha_char
)]);
3552 waddstr(menu_win
, menu_list
[counter
].item_string
);
3555 wmove(menu_win
, (top_offset
+ (vert_size
- 1)), 3);
3557 if (counter
== list_size
)
3560 wprintw(menu_win
, "%c) ", item_alpha
[min((counter
- 1), max_alpha_char
)]);
3561 wprintw(menu_win
, menu_list
[counter
].item_string
);
3564 wprintw(menu_win
, more_below_str
);
3568 for (counter
= 1; counter
<= list_size
; counter
++)
3570 wmove(menu_win
, (top_offset
+ counter
- 1), 3);
3572 wprintw(menu_win
, "%c) ", item_alpha
[min((counter
- 1), max_alpha_char
)]);
3573 waddstr(menu_win
, menu_list
[counter
].item_string
);
3584 clearok(help_win
, TRUE
);
3585 for (counter
= 0; counter
< 22; counter
++)
3587 wmove(help_win
, counter
, 0);
3588 waddstr(help_win
, (emacs_keys_mode
) ?
3589 emacs_help_text
[counter
] : help_text
[counter
]);
3593 wmove(com_win
, 0, 0);
3594 wprintw(com_win
, press_any_key_msg
);
3596 counter
= wgetch(com_win
);
3598 wmove(com_win
, 0, 0);
3606 paint_info_win(void)
3614 for (counter
= 0; counter
< 5; counter
++)
3616 wmove(info_win
, counter
, 0);
3617 wclrtoeol(info_win
);
3618 if (info_type
== CONTROL_KEYS
)
3619 waddstr(info_win
, (emacs_keys_mode
) ?
3620 emacs_control_keys
[counter
] : control_keys
[counter
]);
3621 else if (info_type
== COMMANDS
)
3622 waddstr(info_win
, command_strings
[counter
]);
3628 no_info_window(void)
3634 info_window
= FALSE
;
3635 last_line
= LINES
- 2;
3636 text_win
= newwin((LINES
- 1), COLS
, 0, 0);
3637 keypad(text_win
, TRUE
);
3638 idlok(text_win
, TRUE
);
3639 clearok(text_win
, TRUE
);
3640 midscreen(scr_vert
, point
);
3642 clear_com_win
= TRUE
;
3646 create_info_window(void)
3650 last_line
= LINES
- 8;
3652 text_win
= newwin((LINES
- 7), COLS
, 6, 0);
3653 keypad(text_win
, TRUE
);
3654 idlok(text_win
, TRUE
);
3657 info_win
= newwin(5, COLS
, 0, 0);
3659 info_type
= CONTROL_KEYS
;
3660 midscreen(min(scr_vert
, last_line
), point
);
3661 clearok(info_win
, TRUE
);
3663 count_win
= newwin(1, COLS
, 5, 0);
3664 leaveok(count_win
, TRUE
);
3665 wrefresh(count_win
);
3667 clear_com_win
= TRUE
;
3676 if (restrict_mode())
3681 if (arg
== READ_FILE
)
3683 string
= get_string(file_read_prompt_str
, TRUE
);
3685 tmp_file
= resolve_name(string
);
3687 if (tmp_file
!= string
)
3691 else if (arg
== WRITE_FILE
)
3693 string
= get_string(file_write_prompt_str
, TRUE
);
3694 tmp_file
= resolve_name(string
);
3695 write_file(tmp_file
, 1);
3696 if (tmp_file
!= string
)
3700 else if (arg
== SAVE_FILE
)
3703 | changes made here should be reflected in finish()
3711 string
= in_file_name
;
3712 if ((string
== NULL
) || (*string
== 0))
3713 string
= get_string(save_file_name_prompt
, TRUE
);
3714 if ((string
== NULL
) || (*string
== 0))
3716 wmove(com_win
, 0, 0);
3717 wprintw(com_win
, file_not_saved_msg
);
3720 clear_com_win
= TRUE
;
3725 tmp_file
= resolve_name(string
);
3726 if (tmp_file
!= string
)
3732 if (write_file(string
, 1))
3734 in_file_name
= string
;
3735 text_changes
= FALSE
;
3748 if (((string
= get_string(shell_prompt
, TRUE
)) != NULL
) &&
3761 menu_op(leave_menu
);
3772 clearok(info_win
, TRUE
);
3776 clearok(text_win
, TRUE
);
3777 midscreen(scr_vert
, point
);
3781 | The following routines will "format" a paragraph (as defined by a
3782 | block of text with blank lines before and after the block).
3786 Blank_Line(struct text
*test_line
)
3787 /* test if line has any non-space characters */
3789 unsigned char *line
;
3792 if (test_line
== NULL
)
3796 line
= test_line
->line
;
3799 | To handle troff/nroff documents, consider a line with a
3800 | period ('.') in the first column to be blank. To handle mail
3801 | messages with included text, consider a line with a '>' blank.
3804 if ((*line
== '.') || (*line
== '>'))
3807 while (((*line
== ' ') || (*line
== '\t')) && (length
< test_line
->line_length
))
3812 if (length
!= test_line
->line_length
)
3819 Format(void) /* format the paragraph according to set margins */
3827 unsigned char *line
;
3828 unsigned char *tmp_srchstr
;
3829 unsigned char *temp1
, *temp2
;
3830 unsigned char *temp_dword
;
3831 unsigned char temp_d_char
[3];
3833 temp_d_char
[0] = d_char
[0];
3834 temp_d_char
[1] = d_char
[1];
3835 temp_d_char
[2] = d_char
[2];
3838 | if observ_margins is not set, or the current line is blank,
3839 | do not format the current paragraph
3842 if ((!observ_margins
) || (Blank_Line(curr_line
)))
3846 | save the currently set flags, and clear them
3849 wmove(com_win
, 0, 0);
3851 wprintw(com_win
, formatting_msg
);
3855 | get current position in paragraph, so after formatting, the cursor
3856 | will be in the same relative position
3859 tmp_af
= auto_format
;
3860 auto_format
= FALSE
;
3864 temp_dword
= d_word
;
3866 temp_case
= case_sen
;
3868 tmp_srchstr
= srch_str
;
3869 temp2
= srch_str
= (unsigned char *) malloc(1 + curr_line
->line_length
- position
);
3870 if ((*point
== ' ') || (*point
== '\t'))
3874 line
= temp1
= point
;
3875 while ((*temp1
!= 0) && (*temp1
!= ' ') && (*temp1
!= '\t') && (counter
< curr_line
->line_length
))
3885 while (!Blank_Line(curr_line
->prev_line
))
3889 while ((line
!= point
) && (status
))
3891 status
= search(FALSE
);
3895 wmove(com_win
, 0, 0);
3897 wprintw(com_win
, formatting_msg
);
3901 | now get back to the start of the paragraph to start formatting
3906 while (!Blank_Line(curr_line
->prev_line
))
3909 observ_margins
= FALSE
;
3912 | Start going through lines, putting spaces at end of lines if they do
3913 | not already exist. Append lines together to get one long line, and
3914 | eliminate spacing at begin of lines.
3917 while (!Blank_Line(curr_line
->next_line
))
3929 if ((*point
== ' ') || (*point
== '\t'))
3934 | Now there is one long line. Eliminate extra spaces within the line
3935 | after the first word (so as not to blow away any indenting the user
3941 while (position
< curr_line
->line_length
)
3943 if ((*point
== ' ') && (*(point
+ 1) == ' '))
3950 | Now make sure there are two spaces after a '.'.
3954 while (position
< curr_line
->line_length
)
3956 if ((*point
== '.') && (*(point
+ 1) == ' '))
3961 while (*point
== ' ')
3967 observ_margins
= TRUE
;
3970 wmove(com_win
, 0, 0);
3972 wprintw(com_win
, formatting_msg
);
3976 | create lines between margins
3979 while (position
< curr_line
->line_length
)
3981 while ((scr_pos
< right_margin
) && (position
< curr_line
->line_length
))
3983 if (position
< curr_line
->line_length
)
3993 | go back to begin of paragraph, put cursor back to original position
3997 while (!Blank_Line(curr_line
->prev_line
))
4001 | find word cursor was in
4004 while ((status
) && (string_count
> 0))
4011 | offset the cursor to where it was before from the start of the word
4021 | reset flags and strings to what they were before formatting
4026 d_word
= temp_dword
;
4027 case_sen
= temp_case
;
4029 srch_str
= tmp_srchstr
;
4030 d_char
[0] = temp_d_char
[0];
4031 d_char
[1] = temp_d_char
[1];
4032 d_char
[2] = temp_d_char
[2];
4033 auto_format
= tmp_af
;
4035 midscreen(scr_vert
, point
);
4040 unsigned char *init_name
[3] = {
4041 "/usr/share/misc/init.ee",
4047 ee_init(void) /* check for init file and read it if it exists */
4050 unsigned char *string
;
4051 unsigned char *str1
;
4052 unsigned char *str2
;
4057 string
= getenv("HOME");
4059 string
= "/root"; /* Set to reasonable default so we don't crash */
4060 str1
= home
= malloc(strlen(string
)+10);
4061 strcpy(home
, string
);
4062 strcat(home
, "/.init.ee");
4063 init_name
[1] = home
;
4064 string
= malloc(512);
4066 for (counter
= 0; counter
< 3; counter
++)
4068 if (!(access(init_name
[counter
], 4)))
4070 init_file
= fopen(init_name
[counter
], "r");
4071 while ((str2
= fgets(string
, 512, init_file
)) != NULL
)
4073 str1
= str2
= string
;
4074 while (*str2
!= '\n')
4078 if (unique_test(string
, init_strings
) != 1)
4081 if (compare(str1
, CASE
, FALSE
))
4083 else if (compare(str1
, NOCASE
, FALSE
))
4085 else if (compare(str1
, EXPAND
, FALSE
))
4087 else if (compare(str1
, NOEXPAND
, FALSE
))
4088 expand_tabs
= FALSE
;
4089 else if (compare(str1
, INFO
, FALSE
))
4091 else if (compare(str1
, NOINFO
, FALSE
))
4092 info_window
= FALSE
;
4093 else if (compare(str1
, MARGINS
, FALSE
))
4094 observ_margins
= TRUE
;
4095 else if (compare(str1
, NOMARGINS
, FALSE
))
4096 observ_margins
= FALSE
;
4097 else if (compare(str1
, AUTOFORMAT
, FALSE
))
4100 observ_margins
= TRUE
;
4102 else if (compare(str1
, NOAUTOFORMAT
, FALSE
))
4103 auto_format
= FALSE
;
4104 else if (compare(str1
, Echo
, FALSE
))
4106 str1
= next_word(str1
);
4110 else if (compare(str1
, PRINTCOMMAND
, FALSE
))
4112 str1
= next_word(str1
);
4113 print_command
= malloc(strlen(str1
)+1);
4114 strcpy(print_command
, str1
);
4116 else if (compare(str1
, RIGHTMARGIN
, FALSE
))
4118 str1
= next_word(str1
);
4119 if ((*str1
>= '0') && (*str1
<= '9'))
4121 temp_int
= atoi(str1
);
4123 right_margin
= temp_int
;
4126 else if (compare(str1
, HIGHLIGHT
, FALSE
))
4127 nohighlight
= FALSE
;
4128 else if (compare(str1
, NOHIGHLIGHT
, FALSE
))
4130 else if (compare(str1
, EIGHTBIT
, FALSE
))
4132 else if (compare(str1
, NOEIGHTBIT
, FALSE
))
4137 else if (compare(str1
, EMACS_string
, FALSE
))
4138 emacs_keys_mode
= TRUE
;
4139 else if (compare(str1
, NOEMACS_string
, FALSE
))
4140 emacs_keys_mode
= FALSE
;
4141 else if (compare(str1
, chinese_cmd
, FALSE
))
4146 else if (compare(str1
, nochinese_cmd
, FALSE
))
4155 string
= getenv("LANG");
4158 if (strcmp(string
, "zh_TW.big5") == 0)
4167 | Save current configuration to .init.ee file in the current directory.
4174 FILE *old_init_file
= NULL
;
4175 char *file_name
= ".init.ee";
4176 char *home_dir
= "~/.init.ee";
4183 if (restrict_mode())
4188 option
= menu_op(config_dump_menu
);
4191 wmove(com_win
, 0, 0);
4195 wprintw(com_win
, conf_not_saved_msg
);
4199 else if (option
== 2)
4200 file_name
= resolve_name(home_dir
);
4203 | If a .init.ee file exists, move it to .init.ee.old.
4206 if (stat(file_name
, &buf
) != -1)
4208 sprintf(buffer
, "%s.old", file_name
);
4210 link(file_name
, buffer
);
4212 old_init_file
= fopen(buffer
, "r");
4215 init_file
= fopen(file_name
, "w");
4216 if (init_file
== NULL
)
4218 wprintw(com_win
, conf_dump_err_msg
);
4223 if (old_init_file
!= NULL
)
4226 | Copy non-configuration info into new .init.ee file.
4228 while ((string
= fgets(buffer
, 512, old_init_file
)) != NULL
)
4230 length
= strlen(string
);
4231 string
[length
- 1] = 0;
4233 if (unique_test(string
, init_strings
) == 1)
4235 if (compare(string
, Echo
, FALSE
))
4237 fprintf(init_file
, "%s\n", string
);
4241 fprintf(init_file
, "%s\n", string
);
4244 fclose(old_init_file
);
4247 fprintf(init_file
, "%s\n", case_sen
? CASE
: NOCASE
);
4248 fprintf(init_file
, "%s\n", expand_tabs
? EXPAND
: NOEXPAND
);
4249 fprintf(init_file
, "%s\n", info_window
? INFO
: NOINFO
);
4250 fprintf(init_file
, "%s\n", observ_margins
? MARGINS
: NOMARGINS
);
4251 fprintf(init_file
, "%s\n", auto_format
? AUTOFORMAT
: NOAUTOFORMAT
);
4252 fprintf(init_file
, "%s %s\n", PRINTCOMMAND
, print_command
);
4253 fprintf(init_file
, "%s %d\n", RIGHTMARGIN
, right_margin
);
4254 fprintf(init_file
, "%s\n", nohighlight
? NOHIGHLIGHT
: HIGHLIGHT
);
4255 fprintf(init_file
, "%s\n", eightbit
? EIGHTBIT
: NOEIGHTBIT
);
4256 fprintf(init_file
, "%s\n", emacs_keys_mode
? EMACS_string
: NOEMACS_string
);
4257 fprintf(init_file
, "%s\n", ee_chinese
? chinese_cmd
: nochinese_cmd
);
4261 wprintw(com_win
, conf_dump_success_msg
, file_name
);
4264 if ((option
== 2) && (file_name
!= home_dir
))
4271 echo_string(char *string
) /* echo the given string */
4284 else if (*temp
== 't')
4286 else if (*temp
== 'b')
4288 else if (*temp
== 'r')
4290 else if (*temp
== 'f')
4292 else if ((*temp
== 'e') || (*temp
== 'E'))
4293 putchar('\033'); /* escape */
4294 else if (*temp
== '\\')
4296 else if (*temp
== '\'')
4298 else if ((*temp
>= '0') && (*temp
<= '9'))
4301 while ((*temp
>= '0') && (*temp
<= '9'))
4303 Counter
= (8 * Counter
) + (*temp
- '0');
4322 spell_op(void) /* check spelling of words in the editor */
4324 if (restrict_mode())
4328 top(); /* go to top of file */
4329 insert_line(FALSE
); /* create two blank lines */
4332 command(shell_echo_msg
);
4334 wmove(com_win
, 0, 0);
4335 wprintw(com_win
, spell_in_prog_msg
);
4337 command("<>!spell"); /* send contents of buffer to command 'spell'
4338 and read the results back into the editor */
4344 char template[128], *name
;
4348 if (restrict_mode())
4352 (void)sprintf(template, "/tmp/ee.XXXXXXXX");
4353 name
= mktemp(&template[0]);
4354 fd
= open(name
, O_CREAT
| O_EXCL
| O_RDWR
, 0600);
4356 wmove(com_win
, 0, 0);
4357 wprintw(com_win
, create_file_fail_msg
, name
);
4362 if (write_file(name
, 0))
4364 sprintf(string
, "ispell %s", name
);
4375 first_word_len(struct text
*test_line
)
4380 if (test_line
== NULL
)
4383 pnt
= test_line
->line
;
4384 if ((pnt
== NULL
) || (*pnt
== 0) ||
4385 (*pnt
== '.') || (*pnt
== '>'))
4388 if ((*pnt
== ' ') || (*pnt
== '\t'))
4390 pnt
= next_word(pnt
);
4397 while ((*pnt
!= 0) && ((*pnt
!= ' ') && (*pnt
!= '\t')))
4402 while ((*pnt
!= 0) && ((*pnt
== ' ') || (*pnt
== '\t')))
4411 Auto_Format(void) /* format the paragraph according to set margins */
4418 int tmp_d_line_length
;
4419 int leave_loop
= FALSE
;
4423 unsigned char *line
;
4424 unsigned char *tmp_srchstr
;
4425 unsigned char *temp1
, *temp2
;
4426 unsigned char *temp_dword
;
4427 unsigned char temp_d_char
[3];
4428 unsigned char *tmp_d_line
;
4431 temp_d_char
[0] = d_char
[0];
4432 temp_d_char
[1] = d_char
[1];
4433 temp_d_char
[2] = d_char
[2];
4436 | if observ_margins is not set, or the current line is blank,
4437 | do not format the current paragraph
4440 if ((!observ_margins
) || (Blank_Line(curr_line
)))
4444 | get current position in paragraph, so after formatting, the cursor
4445 | will be in the same relative position
4448 tmp_d_line
= d_line
;
4449 tmp_d_line_length
= dlt_line
->line_length
;
4451 auto_format
= FALSE
;
4453 if ((position
!= 1) && ((*point
== ' ') || (*point
== '\t') || (position
== curr_line
->line_length
) || (*point
== 0)))
4455 temp_dword
= d_word
;
4456 temp_dwl
= d_wrd_len
;
4459 temp_case
= case_sen
;
4461 tmp_srchstr
= srch_str
;
4462 temp2
= srch_str
= (unsigned char *) malloc(1 + curr_line
->line_length
- position
);
4463 if ((*point
== ' ') || (*point
== '\t'))
4467 line
= temp1
= point
;
4468 while ((*temp1
!= 0) && (*temp1
!= ' ') && (*temp1
!= '\t') && (counter
< curr_line
->line_length
))
4478 while (!Blank_Line(curr_line
->prev_line
))
4482 while ((line
!= point
) && (status
))
4484 status
= search(FALSE
);
4489 | now get back to the start of the paragraph to start checking
4494 while (!Blank_Line(curr_line
->prev_line
))
4498 | Start going through lines, putting spaces at end of lines if they do
4499 | not already exist. Check line length, and move words to the next line
4500 | if they cross the margin. Then get words from the next line if they
4501 | will fit in before the margin.
4508 if (position
!= curr_line
->line_length
)
4522 | fill line if first word on next line will fit
4523 | in the line without crossing the margin
4526 while ((curr_line
->next_line
!= NULL
) &&
4527 ((word_len
= first_word_len(curr_line
->next_line
)) > 0)
4528 && ((scr_pos
+ word_len
) < right_margin
))
4531 if ((*point
== ' ') || (*point
== '\t'))
4538 | We know this line was not blank before, so
4539 | make sure that it doesn't have one of the
4540 | leading characters that indicate the line
4541 | should not be modified.
4543 | We also know that this character should not
4544 | be left as the first character of this line.
4547 if ((Blank_Line(curr_line
)) &&
4548 (curr_line
->line
[0] != '.') &&
4549 (curr_line
->line
[0] != '>'))
4558 | go to end of previous line
4564 | make sure there's a space at the end of the line
4577 | make sure line does not cross right margin
4580 while (right_margin
<= scr_pos
)
4586 if (Blank_Line(curr_line
->next_line
))
4590 if ((*point
== ' ') || (*point
== '\t'))
4600 if ((!Blank_Line(curr_line
->next_line
)) || (not_blank
))
4610 | go back to begin of paragraph, put cursor back to original position
4615 while ((counter
-- > 0) || (!Blank_Line(curr_line
->prev_line
)))
4619 | find word cursor was in
4623 while ((status
) && (string_count
> 0))
4625 status
= search(FALSE
);
4630 | offset the cursor to where it was before from the start of the word
4639 if ((string_count
> 0) && (offset
< 0))
4649 | reset flags and strings to what they were before formatting
4654 d_word
= temp_dword
;
4655 d_wrd_len
= temp_dwl
;
4656 case_sen
= temp_case
;
4658 srch_str
= tmp_srchstr
;
4659 d_char
[0] = temp_d_char
[0];
4660 d_char
[1] = temp_d_char
[1];
4661 d_char
[2] = temp_d_char
[2];
4663 dlt_line
->line_length
= tmp_d_line_length
;
4664 d_line
= tmp_d_line
;
4667 midscreen(scr_vert
, point
);
4679 sprintf(modes_menu
[1].item_string
, "%s %s", mode_strings
[1],
4680 (expand_tabs
? ON
: OFF
));
4681 sprintf(modes_menu
[2].item_string
, "%s %s", mode_strings
[2],
4682 (case_sen
? ON
: OFF
));
4683 sprintf(modes_menu
[3].item_string
, "%s %s", mode_strings
[3],
4684 (observ_margins
? ON
: OFF
));
4685 sprintf(modes_menu
[4].item_string
, "%s %s", mode_strings
[4],
4686 (auto_format
? ON
: OFF
));
4687 sprintf(modes_menu
[5].item_string
, "%s %s", mode_strings
[5],
4688 (eightbit
? ON
: OFF
));
4689 sprintf(modes_menu
[6].item_string
, "%s %s", mode_strings
[6],
4690 (info_window
? ON
: OFF
));
4691 sprintf(modes_menu
[7].item_string
, "%s %s", mode_strings
[7],
4692 (emacs_keys_mode
? ON
: OFF
));
4693 sprintf(modes_menu
[8].item_string
, "%s %d", mode_strings
[8],
4695 sprintf(modes_menu
[9].item_string
, "%s %s", mode_strings
[9],
4696 (ee_chinese
? ON
: OFF
));
4698 ret_value
= menu_op(modes_menu
);
4703 expand_tabs
= !expand_tabs
;
4706 case_sen
= !case_sen
;
4709 observ_margins
= !observ_margins
;
4712 auto_format
= !auto_format
;
4714 observ_margins
= TRUE
;
4717 eightbit
= !eightbit
;
4722 nc_setattrib(A_NC_BIG5
);
4724 nc_clearattrib(A_NC_BIG5
);
4728 wnoutrefresh(text_win
);
4734 create_info_window();
4737 emacs_keys_mode
= !emacs_keys_mode
;
4742 string
= get_string(margin_prompt
, TRUE
);
4745 counter
= atoi(string
);
4747 right_margin
= counter
;
4752 ee_chinese
= !ee_chinese
;
4753 if (ee_chinese
!= FALSE
)
4757 nc_setattrib(A_NC_BIG5
);
4759 nc_clearattrib(A_NC_BIG5
);
4767 while (ret_value
!= 0);
4771 is_in_string(char *string
, char *substring
)
4772 /* a strchr() look-alike for systems without strchr() */
4776 for (sub
= substring
; (sub
!= NULL
) && (*sub
!= 0); sub
++)
4778 for (full
= string
; (full
!= NULL
) && (*full
!= 0);
4789 | handle names of the form "~/file", "~user/file",
4790 | "$HOME/foo", "~/$FOO", etc.
4794 resolve_name(char *name
)
4796 char long_buffer
[1024];
4797 char short_buffer
[128];
4805 struct passwd
*user
;
4812 user
= (struct passwd
*) getpwuid(index
);
4817 slash
= strchr(name
, '/');
4821 user
= (struct passwd
*) getpwnam((name
+ 1));
4828 buffer
= malloc(strlen(user
->pw_dir
) + strlen(slash
) + 1);
4829 strcpy(buffer
, user
->pw_dir
);
4830 strcat(buffer
, slash
);
4835 if (is_in_string(buffer
, "$"))
4840 while ((*tmp
!= 0) && (index
< 1024))
4843 while ((*tmp
!= 0) && (*tmp
!= '$') &&
4846 long_buffer
[index
] = *tmp
;
4851 if ((*tmp
== '$') && (index
< 1024))
4856 if (*tmp
== '{') /* } */ /* bracketed variable name */
4859 while ((*tmp
!= 0) &&
4863 short_buffer
[counter
] = *tmp
;
4872 while ((*tmp
!= 0) &&
4877 short_buffer
[counter
] = *tmp
;
4882 short_buffer
[counter
] = 0;
4883 if ((slash
= getenv(short_buffer
)) != NULL
)
4885 offset
= strlen(slash
);
4886 if ((offset
+ index
) < 1024)
4887 strcpy(&long_buffer
[index
], slash
);
4892 while ((start_of_var
!= tmp
) && (index
< 1024))
4894 long_buffer
[index
] = *start_of_var
;
4905 long_buffer
[index
] = 0;
4909 buffer
= malloc(index
+ 1);
4910 strcpy(buffer
, long_buffer
);
4922 wmove(com_win
, 0, 0);
4923 wprintw(com_win
, restricted_msg
);
4926 clear_com_win
= TRUE
;
4931 | The following routine tests the input string against the list of
4932 | strings, to determine if the string is a unique match with one of the
4937 unique_test(char *string
, char **list
)
4945 while (list
[counter
] != NULL
)
4947 result
= compare(string
, list
[counter
], FALSE
);
4956 renumber_lines(struct text
*firstline
, int startnumber
)
4958 struct text
*lineptr
;
4962 for (lineptr
= firstline
; lineptr
!= NULL
; lineptr
= lineptr
->next_line
)
4963 lineptr
->line_number
= i
++;
4968 | Get the catalog entry, and if it got it from the catalog,
4969 | make a copy, since the buffer will be overwritten by the
4970 | next call to catgets().
4974 catgetlocal(int number
, char *string
)
4979 temp1
= catgets(catalog
, 1, number
, string
);
4980 if (temp1
!= string
)
4982 temp2
= malloc(strlen(temp1
) + 1);
4983 strcpy(temp2
, temp1
);
4988 #endif /* NO_CATGETS */
4991 | The following is to allow for using message catalogs which allow
4992 | the software to be 'localized', that is, to use different languages
4993 | all with the same binary. For more information, see your system
4994 | documentation, or the X/Open Internationalization Guide.
5003 setlocale(LC_ALL
, "");
5004 catalog
= catopen("ee", NL_CAT_LOCALE
);
5005 #endif /* NO_CATGETS */
5007 modes_menu
[0].item_string
= catgetlocal( 1, "modes menu");
5008 mode_strings
[1] = catgetlocal( 2, "tabs to spaces ");
5009 mode_strings
[2] = catgetlocal( 3, "case sensitive search");
5010 mode_strings
[3] = catgetlocal( 4, "margins observed ");
5011 mode_strings
[4] = catgetlocal( 5, "auto-paragraph format");
5012 mode_strings
[5] = catgetlocal( 6, "eightbit characters ");
5013 mode_strings
[6] = catgetlocal( 7, "info window ");
5014 mode_strings
[8] = catgetlocal( 8, "right margin ");
5015 leave_menu
[0].item_string
= catgetlocal( 9, "leave menu");
5016 leave_menu
[1].item_string
= catgetlocal( 10, "save changes");
5017 leave_menu
[2].item_string
= catgetlocal( 11, "no save");
5018 file_menu
[0].item_string
= catgetlocal( 12, "file menu");
5019 file_menu
[1].item_string
= catgetlocal( 13, "read a file");
5020 file_menu
[2].item_string
= catgetlocal( 14, "write a file");
5021 file_menu
[3].item_string
= catgetlocal( 15, "save file");
5022 file_menu
[4].item_string
= catgetlocal( 16, "print editor contents");
5023 search_menu
[0].item_string
= catgetlocal( 17, "search menu");
5024 search_menu
[1].item_string
= catgetlocal( 18, "search for ...");
5025 search_menu
[2].item_string
= catgetlocal( 19, "search");
5026 spell_menu
[0].item_string
= catgetlocal( 20, "spell menu");
5027 spell_menu
[1].item_string
= catgetlocal( 21, "use 'spell'");
5028 spell_menu
[2].item_string
= catgetlocal( 22, "use 'ispell'");
5029 misc_menu
[0].item_string
= catgetlocal( 23, "miscellaneous menu");
5030 misc_menu
[1].item_string
= catgetlocal( 24, "format paragraph");
5031 misc_menu
[2].item_string
= catgetlocal( 25, "shell command");
5032 misc_menu
[3].item_string
= catgetlocal( 26, "check spelling");
5033 main_menu
[0].item_string
= catgetlocal( 27, "main menu");
5034 main_menu
[1].item_string
= catgetlocal( 28, "leave editor");
5035 main_menu
[2].item_string
= catgetlocal( 29, "help");
5036 main_menu
[3].item_string
= catgetlocal( 30, "file operations");
5037 main_menu
[4].item_string
= catgetlocal( 31, "redraw screen");
5038 main_menu
[5].item_string
= catgetlocal( 32, "settings");
5039 main_menu
[6].item_string
= catgetlocal( 33, "search");
5040 main_menu
[7].item_string
= catgetlocal( 34, "miscellaneous");
5041 help_text
[0] = catgetlocal( 35, "Control keys: ");
5042 help_text
[1] = catgetlocal( 36, "^a ascii code ^i tab ^r right ");
5043 help_text
[2] = catgetlocal( 37, "^b bottom of text ^j newline ^t top of text ");
5044 help_text
[3] = catgetlocal( 38, "^c command ^k delete char ^u up ");
5045 help_text
[4] = catgetlocal( 39, "^d down ^l left ^v undelete word ");
5046 help_text
[5] = catgetlocal( 40, "^e search prompt ^m newline ^w delete word ");
5047 help_text
[6] = catgetlocal( 41, "^f undelete char ^n next page ^x search ");
5048 help_text
[7] = catgetlocal( 42, "^g begin of line ^o end of line ^y delete line ");
5049 help_text
[8] = catgetlocal( 43, "^h backspace ^p prev page ^z undelete line ");
5050 help_text
[9] = catgetlocal( 44, "^[ (escape) menu ESC-Enter: exit ee ");
5051 help_text
[10] = catgetlocal( 45, " ");
5052 help_text
[11] = catgetlocal( 46, "Commands: ");
5053 help_text
[12] = catgetlocal( 47, "help : get this info file : print file name ");
5054 help_text
[13] = catgetlocal( 48, "read : read a file char : ascii code of char ");
5055 help_text
[14] = catgetlocal( 49, "write : write a file case : case sensitive search ");
5056 help_text
[15] = catgetlocal( 50, "exit : leave and save nocase : case insensitive search ");
5057 help_text
[16] = catgetlocal( 51, "quit : leave, no save !cmd : execute \"cmd\" in shell ");
5058 help_text
[17] = catgetlocal( 52, "line : display line # 0-9 : go to line \"#\" ");
5059 help_text
[18] = catgetlocal( 53, "expand : expand tabs noexpand: do not expand tabs ");
5060 help_text
[19] = catgetlocal( 54, " ");
5061 help_text
[20] = catgetlocal( 55, " ee [+#] [-i] [-e] [-h] [file(s)] ");
5062 help_text
[21] = catgetlocal( 56, "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight");
5063 control_keys
[0] = catgetlocal( 57, "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page ");
5064 control_keys
[1] = catgetlocal( 58, "^a ascii code ^x search ^z undelete line ^d down ^n next page ");
5065 control_keys
[2] = catgetlocal( 59, "^b bottom of text ^g begin of line ^w delete word ^l left ");
5066 control_keys
[3] = catgetlocal( 60, "^t top of text ^o end of line ^v undelete word ^r right ");
5067 control_keys
[4] = catgetlocal( 61, "^c command ^k delete char ^f undelete char ESC-Enter: exit ee ");
5068 command_strings
[0] = catgetlocal( 62, "help : get help info |file : print file name |line : print line # ");
5069 command_strings
[1] = catgetlocal( 63, "read : read a file |char : ascii code of char |0-9 : go to line \"#\"");
5070 command_strings
[2] = catgetlocal( 64, "write: write a file |case : case sensitive search |exit : leave and save ");
5071 command_strings
[3] = catgetlocal( 65, "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save");
5072 command_strings
[4] = catgetlocal( 66, "expand: expand tabs |noexpand: do not expand tabs ");
5073 com_win_message
= catgetlocal( 67, " press Escape (^[) for menu");
5074 no_file_string
= catgetlocal( 68, "no file");
5075 ascii_code_str
= catgetlocal( 69, "ascii code: ");
5076 printer_msg_str
= catgetlocal( 70, "sending contents of buffer to \"%s\" ");
5077 command_str
= catgetlocal( 71, "command: ");
5078 file_write_prompt_str
= catgetlocal( 72, "name of file to write: ");
5079 file_read_prompt_str
= catgetlocal( 73, "name of file to read: ");
5080 char_str
= catgetlocal( 74, "character = %d");
5081 unkn_cmd_str
= catgetlocal( 75, "unknown command \"%s\"");
5082 non_unique_cmd_msg
= catgetlocal( 76, "entered command is not unique");
5083 line_num_str
= catgetlocal( 77, "line %d ");
5084 line_len_str
= catgetlocal( 78, "length = %d");
5085 current_file_str
= catgetlocal( 79, "current file is \"%s\" ");
5086 usage0
= catgetlocal( 80, "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n");
5087 usage1
= catgetlocal( 81, " -i turn off info window\n");
5088 usage2
= catgetlocal( 82, " -e do not convert tabs to spaces\n");
5089 usage3
= catgetlocal( 83, " -h do not use highlighting\n");
5090 file_is_dir_msg
= catgetlocal( 84, "file \"%s\" is a directory");
5091 new_file_msg
= catgetlocal( 85, "new file \"%s\"");
5092 cant_open_msg
= catgetlocal( 86, "can't open \"%s\"");
5093 open_file_msg
= catgetlocal( 87, "file \"%s\", %d lines");
5094 file_read_fin_msg
= catgetlocal( 88, "finished reading file \"%s\"");
5095 reading_file_msg
= catgetlocal( 89, "reading file \"%s\"");
5096 read_only_msg
= catgetlocal( 90, ", read only");
5097 file_read_lines_msg
= catgetlocal( 91, "file \"%s\", %d lines");
5098 save_file_name_prompt
= catgetlocal( 92, "enter name of file: ");
5099 file_not_saved_msg
= catgetlocal( 93, "no filename entered: file not saved");
5100 changes_made_prompt
= catgetlocal( 94, "changes have been made, are you sure? (y/n [n]) ");
5101 yes_char
= catgetlocal( 95, "y");
5102 file_exists_prompt
= catgetlocal( 96, "file already exists, overwrite? (y/n) [n] ");
5103 create_file_fail_msg
= catgetlocal( 97, "unable to create file \"%s\"");
5104 writing_file_msg
= catgetlocal( 98, "writing file \"%s\"");
5105 file_written_msg
= catgetlocal( 99, "\"%s\" %d lines, %d characters");
5106 searching_msg
= catgetlocal( 100, " ...searching");
5107 str_not_found_msg
= catgetlocal( 101, "string \"%s\" not found");
5108 search_prompt_str
= catgetlocal( 102, "search for: ");
5109 exec_err_msg
= catgetlocal( 103, "could not exec %s");
5110 continue_msg
= catgetlocal( 104, "press return to continue ");
5111 menu_cancel_msg
= catgetlocal( 105, "press Esc to cancel");
5112 menu_size_err_msg
= catgetlocal( 106, "menu too large for window");
5113 press_any_key_msg
= catgetlocal( 107, "press any key to continue ");
5114 shell_prompt
= catgetlocal( 108, "shell command: ");
5115 formatting_msg
= catgetlocal( 109, "...formatting paragraph...");
5116 shell_echo_msg
= catgetlocal( 110, "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-");
5117 spell_in_prog_msg
= catgetlocal( 111, "sending contents of edit buffer to 'spell'");
5118 margin_prompt
= catgetlocal( 112, "right margin is: ");
5119 restricted_msg
= catgetlocal( 113, "restricted mode: unable to perform requested operation");
5120 ON
= catgetlocal( 114, "ON");
5121 OFF
= catgetlocal( 115, "OFF");
5122 HELP
= catgetlocal( 116, "HELP");
5123 WRITE
= catgetlocal( 117, "WRITE");
5124 READ
= catgetlocal( 118, "READ");
5125 LINE
= catgetlocal( 119, "LINE");
5126 FILE_str
= catgetlocal( 120, "FILE");
5127 CHARACTER
= catgetlocal( 121, "CHARACTER");
5128 REDRAW
= catgetlocal( 122, "REDRAW");
5129 RESEQUENCE
= catgetlocal( 123, "RESEQUENCE");
5130 AUTHOR
= catgetlocal( 124, "AUTHOR");
5131 VERSION
= catgetlocal( 125, "VERSION");
5132 CASE
= catgetlocal( 126, "CASE");
5133 NOCASE
= catgetlocal( 127, "NOCASE");
5134 EXPAND
= catgetlocal( 128, "EXPAND");
5135 NOEXPAND
= catgetlocal( 129, "NOEXPAND");
5136 Exit_string
= catgetlocal( 130, "EXIT");
5137 QUIT_string
= catgetlocal( 131, "QUIT");
5138 INFO
= catgetlocal( 132, "INFO");
5139 NOINFO
= catgetlocal( 133, "NOINFO");
5140 MARGINS
= catgetlocal( 134, "MARGINS");
5141 NOMARGINS
= catgetlocal( 135, "NOMARGINS");
5142 AUTOFORMAT
= catgetlocal( 136, "AUTOFORMAT");
5143 NOAUTOFORMAT
= catgetlocal( 137, "NOAUTOFORMAT");
5144 Echo
= catgetlocal( 138, "ECHO");
5145 PRINTCOMMAND
= catgetlocal( 139, "PRINTCOMMAND");
5146 RIGHTMARGIN
= catgetlocal( 140, "RIGHTMARGIN");
5147 HIGHLIGHT
= catgetlocal( 141, "HIGHLIGHT");
5148 NOHIGHLIGHT
= catgetlocal( 142, "NOHIGHLIGHT");
5149 EIGHTBIT
= catgetlocal( 143, "EIGHTBIT");
5150 NOEIGHTBIT
= catgetlocal( 144, "NOEIGHTBIT");
5154 mode_strings
[7] = catgetlocal( 145, "emacs key bindings ");
5155 emacs_help_text
[0] = help_text
[0];
5156 emacs_help_text
[1] = catgetlocal( 146, "^a beginning of line ^i tab ^r restore word ");
5157 emacs_help_text
[2] = catgetlocal( 147, "^b back 1 char ^j undel char ^t begin of file ");
5158 emacs_help_text
[3] = catgetlocal( 148, "^c command ^k delete line ^u end of file ");
5159 emacs_help_text
[4] = catgetlocal( 149, "^d delete char ^l undelete line ^v next page ");
5160 emacs_help_text
[5] = catgetlocal( 150, "^e end of line ^m newline ^w delete word ");
5161 emacs_help_text
[6] = catgetlocal( 151, "^f forward 1 char ^n next line ^x search ");
5162 emacs_help_text
[7] = catgetlocal( 152, "^g go back 1 page ^o ascii char insert ^y search prompt ");
5163 emacs_help_text
[8] = catgetlocal( 153, "^h backspace ^p prev line ^z next word ");
5164 emacs_help_text
[9] = help_text
[9];
5165 emacs_help_text
[10] = help_text
[10];
5166 emacs_help_text
[11] = help_text
[11];
5167 emacs_help_text
[12] = help_text
[12];
5168 emacs_help_text
[13] = help_text
[13];
5169 emacs_help_text
[14] = help_text
[14];
5170 emacs_help_text
[15] = help_text
[15];
5171 emacs_help_text
[16] = help_text
[16];
5172 emacs_help_text
[17] = help_text
[17];
5173 emacs_help_text
[18] = help_text
[18];
5174 emacs_help_text
[19] = help_text
[19];
5175 emacs_help_text
[20] = help_text
[20];
5176 emacs_help_text
[21] = help_text
[21];
5177 emacs_control_keys
[0] = catgetlocal( 154, "^[ (escape) menu ^y search prompt ^k delete line ^p prev line ^g prev page");
5178 emacs_control_keys
[1] = catgetlocal( 155, "^o ascii code ^x search ^l undelete line ^n next line ^v next page");
5179 emacs_control_keys
[2] = catgetlocal( 156, "^u end of file ^a begin of line ^w delete word ^b back char ^z next word");
5180 emacs_control_keys
[3] = catgetlocal( 157, "^t begin of file ^e end of line ^r restore word ^f forward char ");
5181 emacs_control_keys
[4] = catgetlocal( 158, "^c command ^d delete char ^j undelete char ESC-Enter: exit");
5182 EMACS_string
= catgetlocal( 159, "EMACS");
5183 NOEMACS_string
= catgetlocal( 160, "NOEMACS");
5184 usage4
= catgetlocal( 161, " +# put cursor at line #\n");
5185 conf_dump_err_msg
= catgetlocal( 162, "unable to open .init.ee for writing, no configuration saved!");
5186 conf_dump_success_msg
= catgetlocal( 163, "ee configuration saved in file %s");
5187 modes_menu
[10].item_string
= catgetlocal( 164, "save editor configuration");
5188 config_dump_menu
[0].item_string
= catgetlocal( 165, "save ee configuration");
5189 config_dump_menu
[1].item_string
= catgetlocal( 166, "save in current directory");
5190 config_dump_menu
[2].item_string
= catgetlocal( 167, "save in home directory");
5191 conf_not_saved_msg
= catgetlocal( 168, "ee configuration not saved");
5192 ree_no_file_msg
= catgetlocal( 169, "must specify a file when invoking ree");
5193 menu_too_lrg_msg
= catgetlocal( 180, "menu too large for window");
5194 more_above_str
= catgetlocal( 181, "^^more^^");
5195 more_below_str
= catgetlocal( 182, "VVmoreVV");
5196 mode_strings
[9] = catgetlocal( 183, "16 bit characters ");
5197 chinese_cmd
= catgetlocal( 184, "16BIT");
5198 nochinese_cmd
= catgetlocal( 185, "NO16BIT");
5201 commands
[1] = WRITE
;
5204 commands
[4] = FILE_str
;
5205 commands
[5] = REDRAW
;
5206 commands
[6] = RESEQUENCE
;
5207 commands
[7] = AUTHOR
;
5208 commands
[8] = VERSION
;
5210 commands
[10] = NOCASE
;
5211 commands
[11] = EXPAND
;
5212 commands
[12] = NOEXPAND
;
5213 commands
[13] = Exit_string
;
5214 commands
[14] = QUIT_string
;
5228 commands
[28] = CHARACTER
;
5229 commands
[29] = chinese_cmd
;
5230 commands
[30] = nochinese_cmd
;
5231 commands
[31] = NULL
;
5232 init_strings
[0] = CASE
;
5233 init_strings
[1] = NOCASE
;
5234 init_strings
[2] = EXPAND
;
5235 init_strings
[3] = NOEXPAND
;
5236 init_strings
[4] = INFO
;
5237 init_strings
[5] = NOINFO
;
5238 init_strings
[6] = MARGINS
;
5239 init_strings
[7] = NOMARGINS
;
5240 init_strings
[8] = AUTOFORMAT
;
5241 init_strings
[9] = NOAUTOFORMAT
;
5242 init_strings
[10] = Echo
;
5243 init_strings
[11] = PRINTCOMMAND
;
5244 init_strings
[12] = RIGHTMARGIN
;
5245 init_strings
[13] = HIGHLIGHT
;
5246 init_strings
[14] = NOHIGHLIGHT
;
5247 init_strings
[15] = EIGHTBIT
;
5248 init_strings
[16] = NOEIGHTBIT
;
5249 init_strings
[17] = EMACS_string
;
5250 init_strings
[18] = NOEMACS_string
;
5251 init_strings
[19] = chinese_cmd
;
5252 init_strings
[20] = nochinese_cmd
;
5253 init_strings
[21] = NULL
;
5256 | allocate space for strings here for settings menu
5259 for (counter
= 1; counter
< NUM_MODES_ITEMS
; counter
++)
5261 modes_menu
[counter
].item_string
= malloc(80);
5266 #endif /* NO_CATGETS */