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
;
465 cutsize
= buf_length (cutbuffer
);
467 if (cur_pos
+ cutsize
> file_size
) {
469 strcpy (message
, "Too close to end of file to paste");
472 buf_delete (filedata
, cutsize
, cur_pos
);
473 file_size
-= cutsize
;
475 buf_paste (filedata
, cutbuffer
, cur_pos
);
478 file_size
+= cutsize
;
479 edit_type
= !!edit_type
;
480 new_top
= cur_pos
- (scrlines
-1) * width
;
483 new_top
= begline(new_top
);
484 if (top_pos
< new_top
)
488 static void act_susp (void) {
492 static void act_goto (void) {
494 fileoffset_t position
, new_top
;
497 if (!get_str("Enter position to go to: ", buffer
, FALSE
))
498 return; /* user break */
500 position
= parse_num (buffer
, &error
);
503 strcpy (message
, "Unable to parse position value");
507 if (position
< 0 || position
> file_size
) {
509 strcpy (message
, "Position is outside bounds of file");
514 edit_type
= !!edit_type
;
515 new_top
= cur_pos
- (scrlines
-1) * width
;
518 new_top
= begline(new_top
);
519 if (top_pos
> cur_pos
)
520 top_pos
= begline(cur_pos
);
521 if (top_pos
< new_top
)
525 static void act_togstat (void) {
526 if (statfmt
== decstatus
)
532 static int search_prompt(char *withdef
, char *withoutdef
)
537 if (!get_str(last_search ? withdef
: withoutdef
, buffer
, TRUE
))
538 return 0; /* user break */
539 if (!last_search
&& !*buffer
) {
540 strcpy (message
, "Search aborted.");
545 len
= last_search
->len
;
547 len
= parse_quoted (buffer
);
550 strcpy (message
, "Invalid escape sequence in search string");
554 free_search(last_search
);
555 last_search
= build_search (buffer
, len
);
561 static void act_search (void) {
563 fileoffset_t posn
, dfapos
;
565 static unsigned char sblk
[SEARCH_BLK
];
566 static char withdef
[] = "Search forward (default=last): ";
567 static char withoutdef
[] = "Search forward: ";
569 if (!search_prompt(withdef
, withoutdef
))
572 dfa
= last_search
->forward
;
573 len
= last_search
->len
;
576 for (posn
= cur_pos
+1; posn
< file_size
; posn
++) {
578 int size
= SEARCH_BLK
;
580 if (size
> file_size
-posn
)
581 size
= file_size
-posn
;
582 buf_fetch_data (filedata
, sblk
, size
, posn
);
586 dfapos
= dfa
[dfapos
][*q
++];
588 fileoffset_t new_top
;
590 cur_pos
= posn
- len
;
591 edit_type
= !!edit_type
;
592 new_top
= cur_pos
- (scrlines
-1) * width
;
593 new_top
= begline(new_top
);
594 if (top_pos
< new_top
)
600 strcpy (message
, "Not found.");
603 static void act_search_backwards (void) {
605 fileoffset_t posn
, dfapos
;
607 static unsigned char sblk
[SEARCH_BLK
];
608 static char withdef
[] = "Search backward (default=last): ";
609 static char withoutdef
[] = "Search backward: ";
611 if (!search_prompt(withdef
, withoutdef
))
614 dfa
= last_search
->reverse
;
615 len
= last_search
->len
;
618 posn
= cur_pos
+ len
- 1;
619 if (posn
>= file_size
)
622 for (; posn
>= 0; posn
--) {
624 int size
= SEARCH_BLK
;
628 buf_fetch_data (filedata
, sblk
, size
, posn
-size
);
632 dfapos
= dfa
[dfapos
][*--q
];
634 fileoffset_t new_top
;
637 edit_type
= !!edit_type
;
638 new_top
= cur_pos
- (scrlines
-1) * width
;
639 new_top
= begline(new_top
);
640 if (top_pos
> new_top
)
646 strcpy (message
, "Not found.");
649 static void act_recentre (void) {
650 top_pos
= cur_pos
- (display_rows
-2)/2 * width
;
653 top_pos
= begline(top_pos
);
656 static void act_width (void) {
660 fileoffset_t new_top
;
663 sprintf (prompt
, "Enter screen width in bytes (now %"OFF
"d): ", width
);
664 if (!get_str (prompt
, buffer
, FALSE
))
666 w
= parse_num (buffer
, &error
);
669 strcpy (message
, "Unable to parse width value");
675 new_top
= cur_pos
- (scrlines
-1) * width
;
676 new_top
= begline(new_top
);
677 if (top_pos
< new_top
)
682 static void act_offset (void) {
686 fileoffset_t new_top
;
689 sprintf (prompt
, "Enter start-of-file offset in bytes (now %"OFF
"d): ",
691 if (!get_str (prompt
, buffer
, FALSE
))
693 o
= parse_num (buffer
, &error
);
696 strcpy (message
, "Unable to parse offset value");
702 new_top
= cur_pos
- (scrlines
-1) * width
;
703 new_top
= begline(new_top
);
704 if (top_pos
< new_top
)
710 static void act_diagnostics(void)
712 extern void buffer_diagnostic(buffer
*buf
, char *title
);
714 buffer_diagnostic(filedata
, "filedata");
715 buffer_diagnostic(cutbuffer
, "cutbuffer");