8 static void act_exit (void);
9 static void act_save (void);
10 static void act_exitsave (void);
11 static void act_top (void);
12 static void act_pgup (void);
13 static void act_up (void);
14 static void act_home (void);
15 static void act_left (void);
16 static void act_right (void);
17 static void act_end (void);
18 static void act_down (void);
19 static void act_pgdn (void);
20 static void act_bottom (void);
21 static void act_togins (void);
22 static void act_chmode (void);
23 extern void act_self_ins (void); /* this one must be external */
24 static void act_delete (void);
25 static void act_delch (void);
26 static void act_mark (void);
27 static void act_cut (void);
28 static void act_copy (void);
29 static void act_paste (void);
30 static void act_susp (void);
31 static void act_goto (void);
32 static void act_togstat (void);
33 static void act_search (void);
34 static void act_search_backwards (void);
35 static void act_recentre (void);
36 static void act_width (void);
37 static void act_offset (void);
39 static void act_diagnostics (void);
42 static Search
*last_search
= NULL
;
44 keyact
parse_action (char *name
) {
46 "exit", "top-of-file", "page-up", "move-up",
47 "begin-line", "move-left", "move-right", "end-line",
48 "move-down", "page-down", "bottom-of-file", "toggle-insert",
49 "change-mode", "delete-left", "delete-right", "mark-place",
50 "cut", "copy", "paste", "suspend", "goto-position",
51 "toggle-status", "search", "search-back", "save-file",
52 "exit-and-save", "screen-recentre", "new-width", "new-offset"
58 act_exit
, act_top
, act_pgup
, act_up
, act_home
, act_left
,
59 act_right
, act_end
, act_down
, act_pgdn
, act_bottom
,
60 act_togins
, act_chmode
, act_delete
, act_delch
, act_mark
,
61 act_cut
, act_copy
, act_paste
, act_susp
, act_goto
,
62 act_togstat
, act_search
, act_search_backwards
, act_save
,
63 act_exitsave
, act_recentre
, act_width
, act_offset
70 for (i
=0; i
<sizeof(names
)/sizeof(*names
); i
++)
71 if (!strcmp(name
, names
[i
]))
76 static fileoffset_t
begline(fileoffset_t x
) {
77 fileoffset_t y
= x
+ width
-offset
;
85 static fileoffset_t
endline(fileoffset_t x
) {
86 fileoffset_t y
= x
+ width
-offset
;
95 static void act_exit(void) {
96 static char question
[] = "File is modified. Save before quitting? [yn] ";
100 display_moveto (display_rows
-1, 0);
101 display_clear_to_eol ();
102 display_set_colour (COL_MINIBUF
);
103 display_write_str (question
);
106 #if defined(unix) && !defined(GO32)
107 if (update_required
) {
109 display_moveto (display_rows
-1, 0);
110 display_clear_to_eol ();
111 display_set_colour (COL_MINIBUF
);
112 display_write_str (question
);
117 c
= display_getkey();
118 #if defined(unix) && !defined(GO32)
121 if (c
>= 'a' && c
<= 'z')
123 } while (c
!= 'Y' && c
!= 'N' && c
!= '\007');
127 return; /* couldn't save, so don't quit */
128 draw_scr(); /* update the ** on status line! */
129 } else if (c
== '\007') {
130 return; /* don't even quit */
136 static void act_save(void) {
137 static int backed_up
= FALSE
;
140 if (!backup_file()) {
142 strcpy (message
, "Unable to back up file!");
149 strcpy (message
, "Unable to save file!");
155 static void act_exitsave(void) {
157 draw_scr(); /* update ** on status line */
161 static void act_top (void) {
162 cur_pos
= top_pos
= 0;
163 edit_type
= !!edit_type
;
166 static void act_pgup(void) {
167 cur_pos
-= (scrlines
-1)*width
;
170 edit_type
= !!edit_type
;
172 if (top_pos
> cur_pos
)
173 top_pos
= begline(cur_pos
);
176 static void act_up(void) {
180 edit_type
= !!edit_type
;
182 if (top_pos
> cur_pos
)
183 top_pos
= begline(cur_pos
);
186 static void act_home(void) {
187 cur_pos
= begline(cur_pos
);
190 if (top_pos
> cur_pos
)
191 top_pos
= begline(cur_pos
);
192 edit_type
= !!edit_type
;
195 static void act_left(void) {
196 if (edit_type
== 2) {
201 edit_type
= 2*!!edit_type
;
204 edit_type
= !!edit_type
;
206 if (top_pos
> cur_pos
)
207 top_pos
= begline(cur_pos
);
211 static void act_right(void) {
212 fileoffset_t new_top
;
214 if (edit_type
== 1) {
215 if (cur_pos
< file_size
)
220 if (cur_pos
> file_size
)
222 new_top
= cur_pos
- (scrlines
-1) * width
;
225 new_top
= begline(new_top
);
226 if (top_pos
< new_top
)
228 edit_type
= !!edit_type
;
232 static void act_end(void) {
233 fileoffset_t new_top
;
235 cur_pos
= endline(cur_pos
);
236 edit_type
= !!edit_type
;
237 if (cur_pos
>= file_size
)
239 new_top
= cur_pos
- (scrlines
-1) * width
;
242 new_top
= begline(new_top
);
243 if (top_pos
< new_top
)
247 static void act_down(void) {
248 fileoffset_t new_top
;
251 if (cur_pos
>= file_size
) {
253 edit_type
= !!edit_type
;
255 new_top
= cur_pos
- (scrlines
-1) * width
;
258 new_top
= begline(new_top
);
259 if (top_pos
< new_top
)
263 static void act_pgdn(void) {
264 fileoffset_t new_top
;
266 cur_pos
+= (scrlines
-1) * width
;
267 if (cur_pos
>= file_size
) {
269 edit_type
= !!edit_type
;
271 new_top
= cur_pos
- (scrlines
-1) * width
;
274 new_top
= begline(new_top
);
275 if (top_pos
< new_top
)
279 static void act_bottom (void) {
280 fileoffset_t new_top
;
283 edit_type
= !!edit_type
;
284 new_top
= cur_pos
- (scrlines
-1) * width
;
287 new_top
= begline(new_top
);
288 if (top_pos
< new_top
)
292 static void act_togins(void) {
293 if (look_mode
|| fix_mode
) {
295 sprintf(message
, "Can't engage Insert mode when in %s mode",
296 (look_mode ?
"LOOK" : "FIX"));
297 insert_mode
= FALSE
; /* safety! */
299 insert_mode
= !insert_mode
;
302 static void act_chmode(void) {
304 edit_type
= !edit_type
; /* 0 -> 1, [12] -> 0 */
305 else if (edit_type
== 0) /* just in case */
309 void act_self_ins(void) {
310 int insert
= insert_mode
;
315 strcpy (message
, "Can't modify file in LOOK mode");
320 if (last_char
>= '0' && last_char
<= '9')
322 else if (last_char
>= 'A' && last_char
<= 'F')
324 else if (last_char
>= 'a' && last_char
<= 'f')
328 strcpy(message
, "Not a valid character when in hex editing mode");
333 if ( (!insert
|| edit_type
== 2) && cur_pos
== file_size
) {
335 strcpy(message
, "End of file reached");
340 case 0: /* ascii mode */
343 case 1: /* hex, first digit */
347 buf_fetch_data(filedata
, &c
, 1, cur_pos
);
351 case 2: /* hex, second digit */
352 buf_fetch_data(filedata
, &c
, 1, cur_pos
);
360 buf_insert_data(filedata
, &c
, 1, cur_pos
);
363 } else if (cur_pos
< file_size
) {
364 buf_overwrite_data(filedata
, &c
, 1, cur_pos
);
368 strcpy(message
, "End of file reached");
373 static void act_delete(void) {
374 if (!insert_mode
|| (edit_type
!=2 && cur_pos
==0)) {
376 strcpy (message
, "Can't delete while not in Insert mode");
377 } else if (cur_pos
> 0 || edit_type
== 2) {
379 buf_delete (filedata
, 1, cur_pos
);
381 edit_type
= !!edit_type
;
386 static void act_delch(void) {
389 strcpy (message
, "Can't delete while not in Insert mode");
390 } else if (cur_pos
< file_size
) {
391 buf_delete (filedata
, 1, cur_pos
);
393 edit_type
= !!edit_type
;
398 static void act_mark (void) {
401 strcpy (message
, "Can't cut or paste in LOOK mode");
402 marking
= FALSE
; /* safety */
406 mark_point
= cur_pos
;
409 static void act_cut (void) {
410 fileoffset_t marktop
, marksize
;
412 if (!marking
|| mark_point
==cur_pos
) {
414 strcpy (message
, "Set mark first");
419 strcpy (message
, "Can't cut while not in Insert mode");
423 marksize
= mark_point
- cur_pos
;
426 marksize
= -marksize
;
429 buf_free (cutbuffer
);
430 cutbuffer
= buf_cut (filedata
, marksize
, marktop
);
431 file_size
-= marksize
;
435 if (top_pos
> cur_pos
)
436 top_pos
= begline(cur_pos
);
437 edit_type
= !!edit_type
;
442 static void act_copy (void) {
443 fileoffset_t marktop
, marksize
;
447 strcpy (message
, "Set mark first");
451 marksize
= mark_point
- cur_pos
;
454 marksize
= -marksize
;
457 buf_free (cutbuffer
);
458 cutbuffer
= buf_copy (filedata
, marksize
, marktop
);
462 static void act_paste (void) {
463 fileoffset_t cutsize
, new_top
;
467 cutsize
= buf_length (cutbuffer
);
469 if (cur_pos
+ cutsize
> file_size
) {
471 strcpy (message
, "Too close to end of file to paste");
474 buf_delete (filedata
, cutsize
, cur_pos
);
475 file_size
-= cutsize
;
477 buf_paste (filedata
, cutbuffer
, cur_pos
);
480 file_size
+= cutsize
;
481 edit_type
= !!edit_type
;
482 new_top
= cur_pos
- (scrlines
-1) * width
;
485 new_top
= begline(new_top
);
486 if (top_pos
< new_top
)
490 static void act_susp (void) {
494 static void act_goto (void) {
496 fileoffset_t position
, new_top
;
499 if (!get_str("Enter position to go to: ", buffer
, FALSE
))
500 return; /* user break */
502 position
= parse_num (buffer
, &error
);
505 strcpy (message
, "Unable to parse position value");
509 if (position
< 0 || position
> file_size
) {
511 strcpy (message
, "Position is outside bounds of file");
516 edit_type
= !!edit_type
;
517 new_top
= cur_pos
- (scrlines
-1) * width
;
520 new_top
= begline(new_top
);
521 if (top_pos
> cur_pos
)
522 top_pos
= begline(cur_pos
);
523 if (top_pos
< new_top
)
527 static void act_togstat (void) {
528 if (statfmt
== decstatus
)
534 static int search_prompt(char *withdef
, char *withoutdef
)
539 if (!get_str(last_search ? withdef
: withoutdef
, buffer
, TRUE
))
540 return 0; /* user break */
541 if (!last_search
&& !*buffer
) {
542 strcpy (message
, "Search aborted.");
547 len
= last_search
->len
;
549 len
= parse_quoted (buffer
);
552 strcpy (message
, "Invalid escape sequence in search string");
556 free_search(last_search
);
557 last_search
= build_search (buffer
, len
);
563 static void act_search (void) {
565 fileoffset_t posn
, dfapos
;
567 static unsigned char sblk
[SEARCH_BLK
];
568 static char withdef
[] = "Search forward (default=last): ";
569 static char withoutdef
[] = "Search forward: ";
571 if (!search_prompt(withdef
, withoutdef
))
574 dfa
= last_search
->forward
;
575 len
= last_search
->len
;
578 for (posn
= cur_pos
+1; posn
< file_size
; posn
++) {
580 int size
= SEARCH_BLK
;
582 if (size
> file_size
-posn
)
583 size
= file_size
-posn
;
584 buf_fetch_data (filedata
, sblk
, size
, posn
);
588 dfapos
= dfa
[dfapos
][*q
++];
590 fileoffset_t new_top
;
592 cur_pos
= posn
- len
;
593 edit_type
= !!edit_type
;
594 new_top
= cur_pos
- (scrlines
-1) * width
;
595 new_top
= begline(new_top
);
596 if (top_pos
< new_top
)
602 strcpy (message
, "Not found.");
605 static void act_search_backwards (void) {
607 fileoffset_t posn
, dfapos
;
609 static unsigned char sblk
[SEARCH_BLK
];
610 static char withdef
[] = "Search backward (default=last): ";
611 static char withoutdef
[] = "Search backward: ";
613 if (!search_prompt(withdef
, withoutdef
))
616 dfa
= last_search
->reverse
;
617 len
= last_search
->len
;
620 posn
= cur_pos
+ len
- 1;
621 if (posn
>= file_size
)
624 for (; posn
>= 0; posn
--) {
626 int size
= SEARCH_BLK
;
630 buf_fetch_data (filedata
, sblk
, size
, posn
-size
);
634 dfapos
= dfa
[dfapos
][*--q
];
636 fileoffset_t new_top
;
639 edit_type
= !!edit_type
;
640 new_top
= cur_pos
- (scrlines
-1) * width
;
641 new_top
= begline(new_top
);
642 if (top_pos
> new_top
)
648 strcpy (message
, "Not found.");
651 static void act_recentre (void) {
652 top_pos
= cur_pos
- (display_rows
-2)/2 * width
;
655 top_pos
= begline(top_pos
);
658 static void act_width (void) {
662 fileoffset_t new_top
;
665 sprintf (prompt
, "Enter screen width in bytes (now %"OFF
"d): ", width
);
666 if (!get_str (prompt
, buffer
, FALSE
))
668 w
= parse_num (buffer
, &error
);
671 strcpy (message
, "Unable to parse width value");
677 new_top
= cur_pos
- (scrlines
-1) * width
;
678 new_top
= begline(new_top
);
679 if (top_pos
< new_top
)
684 static void act_offset (void) {
688 fileoffset_t new_top
;
691 sprintf (prompt
, "Enter start-of-file offset in bytes (now %"OFF
"d): ",
693 if (!get_str (prompt
, buffer
, FALSE
))
695 o
= parse_num (buffer
, &error
);
698 strcpy (message
, "Unable to parse offset value");
704 new_top
= cur_pos
- (scrlines
-1) * width
;
705 new_top
= begline(new_top
);
706 if (top_pos
< new_top
)
712 static void act_diagnostics(void)
714 extern void buffer_diagnostic(buffer
*buf
, char *title
);
716 buffer_diagnostic(filedata
, "filedata");
717 buffer_diagnostic(cutbuffer
, "cutbuffer");