diff options
-rw-r--r-- | editors/vi.c | 518 |
1 files changed, 258 insertions, 260 deletions
diff --git a/editors/vi.c b/editors/vi.c index 9bdee5928..406119371 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -483,7 +483,6 @@ struct globals { | |||
483 | } while (0) | 483 | } while (0) |
484 | 484 | ||
485 | 485 | ||
486 | static void edit_file(char *); // edit one file | ||
487 | static void do_cmd(int); // execute a command | 486 | static void do_cmd(int); // execute a command |
488 | static int next_tabstop(int); | 487 | static int next_tabstop(int); |
489 | static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot | 488 | static void sync_cursor(char *, int *, int *); // synchronize the screen cursor to dot |
@@ -527,7 +526,6 @@ static uintptr_t text_hole_make(char *, int); // at "p", make a 'size' byte hole | |||
527 | #define yank_delete(a,b,c,d,e) yank_delete(a,b,c,d) | 526 | #define yank_delete(a,b,c,d,e) yank_delete(a,b,c,d) |
528 | #endif | 527 | #endif |
529 | static char *yank_delete(char *, char *, int, int, int); // yank text[] into register then delete | 528 | static char *yank_delete(char *, char *, int, int, int); // yank text[] into register then delete |
530 | static void show_help(void); // display some help info | ||
531 | static void rawmode(void); // set "raw" mode on tty | 529 | static void rawmode(void); // set "raw" mode on tty |
532 | static void cookmode(void); // return to "cooked" mode on tty | 530 | static void cookmode(void); // return to "cooked" mode on tty |
533 | // sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready) | 531 | // sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready) |
@@ -610,94 +608,42 @@ static void crash_test(); | |||
610 | static int crashme = 0; | 608 | static int crashme = 0; |
611 | #endif | 609 | #endif |
612 | 610 | ||
613 | static void write1(const char *out) | 611 | static void show_help(void) |
614 | { | ||
615 | fputs(out, stdout); | ||
616 | } | ||
617 | |||
618 | int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
619 | int vi_main(int argc, char **argv) | ||
620 | { | 612 | { |
621 | int c; | 613 | puts("These features are available:" |
622 | 614 | #if ENABLE_FEATURE_VI_SEARCH | |
623 | INIT_G(); | 615 | "\n\tPattern searches with / and ?" |
624 | |||
625 | #if ENABLE_FEATURE_VI_UNDO | ||
626 | /* undo_stack_tail = NULL; - already is */ | ||
627 | #if ENABLE_FEATURE_VI_UNDO_QUEUE | ||
628 | undo_queue_state = UNDO_EMPTY; | ||
629 | /* undo_q = 0; - already is */ | ||
630 | #endif | 616 | #endif |
617 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
618 | "\n\tLast command repeat with ." | ||
631 | #endif | 619 | #endif |
632 | 620 | #if ENABLE_FEATURE_VI_YANKMARK | |
633 | #if ENABLE_FEATURE_VI_CRASHME | 621 | "\n\tLine marking with 'x" |
634 | srand((long) getpid()); | 622 | "\n\tNamed buffers with \"x" |
635 | #endif | 623 | #endif |
636 | #ifdef NO_SUCH_APPLET_YET | 624 | #if ENABLE_FEATURE_VI_READONLY |
637 | // if we aren't "vi", we are "view" | 625 | //not implemented: "\n\tReadonly if vi is called as \"view\"" |
638 | if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) { | 626 | //redundant: usage text says this too: "\n\tReadonly with -R command line arg" |
639 | SET_READONLY_MODE(readonly_mode); | ||
640 | } | ||
641 | #endif | 627 | #endif |
642 | 628 | #if ENABLE_FEATURE_VI_SET | |
643 | // autoindent is not default in vim 7.3 | 629 | "\n\tSome colon mode commands with :" |
644 | vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE; | ||
645 | // 1- process $HOME/.exrc file (not inplemented yet) | ||
646 | // 2- process EXINIT variable from environment | ||
647 | // 3- process command line args | ||
648 | #if ENABLE_FEATURE_VI_COLON | ||
649 | { | ||
650 | char *p = getenv("EXINIT"); | ||
651 | if (p && *p) | ||
652 | initial_cmds[0] = xstrndup(p, MAX_INPUT_LEN); | ||
653 | } | ||
654 | #endif | 630 | #endif |
655 | while ((c = getopt(argc, argv, "hCRH" IF_FEATURE_VI_COLON("c:"))) != -1) { | 631 | #if ENABLE_FEATURE_VI_SETOPTS |
656 | switch (c) { | 632 | "\n\tSettable options with \":set\"" |
657 | #if ENABLE_FEATURE_VI_CRASHME | ||
658 | case 'C': | ||
659 | crashme = 1; | ||
660 | break; | ||
661 | #endif | 633 | #endif |
662 | #if ENABLE_FEATURE_VI_READONLY | 634 | #if ENABLE_FEATURE_VI_USE_SIGNALS |
663 | case 'R': // Read-only flag | 635 | "\n\tSignal catching- ^C" |
664 | SET_READONLY_MODE(readonly_mode); | 636 | "\n\tJob suspend and resume with ^Z" |
665 | break; | ||
666 | #endif | 637 | #endif |
667 | #if ENABLE_FEATURE_VI_COLON | 638 | #if ENABLE_FEATURE_VI_WIN_RESIZE |
668 | case 'c': // cmd line vi command | 639 | "\n\tAdapt to window re-sizes" |
669 | if (*optarg) | ||
670 | initial_cmds[initial_cmds[0] != NULL] = xstrndup(optarg, MAX_INPUT_LEN); | ||
671 | break; | ||
672 | #endif | 640 | #endif |
673 | case 'H': | 641 | ); |
674 | show_help(); | 642 | } |
675 | // fall through | ||
676 | default: | ||
677 | bb_show_usage(); | ||
678 | return 1; | ||
679 | } | ||
680 | } | ||
681 | |||
682 | // The argv array can be used by the ":next" and ":rewind" commands | ||
683 | argv += optind; | ||
684 | argc -= optind; | ||
685 | |||
686 | //----- This is the main file handling loop -------------- | ||
687 | save_argc = argc; | ||
688 | optind = 0; | ||
689 | // "Save cursor, use alternate screen buffer, clear screen" | ||
690 | write1(ESC"[?1049h"); | ||
691 | while (1) { | ||
692 | edit_file(argv[optind]); // param might be NULL | ||
693 | if (++optind >= argc) | ||
694 | break; | ||
695 | } | ||
696 | // "Use normal screen buffer, restore cursor" | ||
697 | write1(ESC"[?1049l"); | ||
698 | //----------------------------------------------------------- | ||
699 | 643 | ||
700 | return 0; | 644 | static void write1(const char *out) |
645 | { | ||
646 | fputs(out, stdout); | ||
701 | } | 647 | } |
702 | 648 | ||
703 | /* read text from file or create an empty buf */ | 649 | /* read text from file or create an empty buf */ |
@@ -748,153 +694,6 @@ static ALWAYS_INLINE int query_screen_dimensions(void) | |||
748 | } | 694 | } |
749 | #endif | 695 | #endif |
750 | 696 | ||
751 | static void edit_file(char *fn) | ||
752 | { | ||
753 | #if ENABLE_FEATURE_VI_YANKMARK | ||
754 | #define cur_line edit_file__cur_line | ||
755 | #endif | ||
756 | int c; | ||
757 | #if ENABLE_FEATURE_VI_USE_SIGNALS | ||
758 | int sig; | ||
759 | #endif | ||
760 | |||
761 | editing = 1; // 0 = exit, 1 = one file, 2 = multiple files | ||
762 | rawmode(); | ||
763 | rows = 24; | ||
764 | columns = 80; | ||
765 | IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions(); | ||
766 | #if ENABLE_FEATURE_VI_ASK_TERMINAL | ||
767 | if (G.get_rowcol_error /* TODO? && no input on stdin */) { | ||
768 | uint64_t k; | ||
769 | write1(ESC"[999;999H" ESC"[6n"); | ||
770 | fflush_all(); | ||
771 | k = read_key(STDIN_FILENO, readbuffer, /*timeout_ms:*/ 100); | ||
772 | if ((int32_t)k == KEYCODE_CURSOR_POS) { | ||
773 | uint32_t rc = (k >> 32); | ||
774 | columns = (rc & 0x7fff); | ||
775 | if (columns > MAX_SCR_COLS) | ||
776 | columns = MAX_SCR_COLS; | ||
777 | rows = ((rc >> 16) & 0x7fff); | ||
778 | if (rows > MAX_SCR_ROWS) | ||
779 | rows = MAX_SCR_ROWS; | ||
780 | } | ||
781 | } | ||
782 | #endif | ||
783 | new_screen(rows, columns); // get memory for virtual screen | ||
784 | init_text_buffer(fn); | ||
785 | |||
786 | #if ENABLE_FEATURE_VI_YANKMARK | ||
787 | YDreg = 26; // default Yank/Delete reg | ||
788 | // Ureg = 27; - const // hold orig line for "U" cmd | ||
789 | mark[26] = mark[27] = text; // init "previous context" | ||
790 | #endif | ||
791 | |||
792 | last_forward_char = last_input_char = '\0'; | ||
793 | crow = 0; | ||
794 | ccol = 0; | ||
795 | |||
796 | #if ENABLE_FEATURE_VI_USE_SIGNALS | ||
797 | signal(SIGWINCH, winch_handler); | ||
798 | signal(SIGTSTP, tstp_handler); | ||
799 | sig = sigsetjmp(restart, 1); | ||
800 | if (sig != 0) { | ||
801 | screenbegin = dot = text; | ||
802 | } | ||
803 | // int_handler() can jump to "restart", | ||
804 | // must install handler *after* initializing "restart" | ||
805 | signal(SIGINT, int_handler); | ||
806 | #endif | ||
807 | |||
808 | cmd_mode = 0; // 0=command 1=insert 2='R'eplace | ||
809 | cmdcnt = 0; | ||
810 | tabstop = 8; | ||
811 | offset = 0; // no horizontal offset | ||
812 | c = '\0'; | ||
813 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
814 | free(ioq_start); | ||
815 | ioq = ioq_start = NULL; | ||
816 | lmc_len = 0; | ||
817 | adding2q = 0; | ||
818 | #endif | ||
819 | |||
820 | #if ENABLE_FEATURE_VI_COLON | ||
821 | { | ||
822 | char *p, *q; | ||
823 | int n = 0; | ||
824 | |||
825 | while ((p = initial_cmds[n]) != NULL) { | ||
826 | do { | ||
827 | q = p; | ||
828 | p = strchr(q, '\n'); | ||
829 | if (p) | ||
830 | while (*p == '\n') | ||
831 | *p++ = '\0'; | ||
832 | if (*q) | ||
833 | colon(q); | ||
834 | } while (p); | ||
835 | free(initial_cmds[n]); | ||
836 | initial_cmds[n] = NULL; | ||
837 | n++; | ||
838 | } | ||
839 | } | ||
840 | #endif | ||
841 | redraw(FALSE); // dont force every col re-draw | ||
842 | //------This is the main Vi cmd handling loop ----------------------- | ||
843 | while (editing > 0) { | ||
844 | #if ENABLE_FEATURE_VI_CRASHME | ||
845 | if (crashme > 0) { | ||
846 | if ((end - text) > 1) { | ||
847 | crash_dummy(); // generate a random command | ||
848 | } else { | ||
849 | crashme = 0; | ||
850 | string_insert(text, "\n\n##### Ran out of text to work on. #####\n\n", NO_UNDO); // insert the string | ||
851 | dot = text; | ||
852 | refresh(FALSE); | ||
853 | } | ||
854 | } | ||
855 | #endif | ||
856 | last_input_char = c = get_one_char(); // get a cmd from user | ||
857 | #if ENABLE_FEATURE_VI_YANKMARK | ||
858 | // save a copy of the current line- for the 'U" command | ||
859 | if (begin_line(dot) != cur_line) { | ||
860 | cur_line = begin_line(dot); | ||
861 | text_yank(begin_line(dot), end_line(dot), Ureg); | ||
862 | } | ||
863 | #endif | ||
864 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
865 | // These are commands that change text[]. | ||
866 | // Remember the input for the "." command | ||
867 | if (!adding2q && ioq_start == NULL | ||
868 | && cmd_mode == 0 // command mode | ||
869 | && c > '\0' // exclude NUL and non-ASCII chars | ||
870 | && c < 0x7f // (Unicode and such) | ||
871 | && strchr(modifying_cmds, c) | ||
872 | ) { | ||
873 | start_new_cmd_q(c); | ||
874 | } | ||
875 | #endif | ||
876 | do_cmd(c); // execute the user command | ||
877 | |||
878 | // poll to see if there is input already waiting. if we are | ||
879 | // not able to display output fast enough to keep up, skip | ||
880 | // the display update until we catch up with input. | ||
881 | if (!readbuffer[0] && mysleep(0) == 0) { | ||
882 | // no input pending - so update output | ||
883 | refresh(FALSE); | ||
884 | show_status_line(); | ||
885 | } | ||
886 | #if ENABLE_FEATURE_VI_CRASHME | ||
887 | if (crashme > 0) | ||
888 | crash_test(); // test editor variables | ||
889 | #endif | ||
890 | } | ||
891 | //------------------------------------------------------------------- | ||
892 | |||
893 | go_bottom_and_clear_to_eol(); | ||
894 | cookmode(); | ||
895 | #undef cur_line | ||
896 | } | ||
897 | |||
898 | //----- The Colon commands ------------------------------------- | 697 | //----- The Colon commands ------------------------------------- |
899 | #if ENABLE_FEATURE_VI_COLON | 698 | #if ENABLE_FEATURE_VI_COLON |
900 | static char *get_one_address(char *p, int *addr) // get colon addr, if present | 699 | static char *get_one_address(char *p, int *addr) // get colon addr, if present |
@@ -2589,39 +2388,6 @@ static char *yank_delete(char *start, char *stop, int dist, int yf, int undo) | |||
2589 | return p; | 2388 | return p; |
2590 | } | 2389 | } |
2591 | 2390 | ||
2592 | static void show_help(void) | ||
2593 | { | ||
2594 | puts("These features are available:" | ||
2595 | #if ENABLE_FEATURE_VI_SEARCH | ||
2596 | "\n\tPattern searches with / and ?" | ||
2597 | #endif | ||
2598 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
2599 | "\n\tLast command repeat with ." | ||
2600 | #endif | ||
2601 | #if ENABLE_FEATURE_VI_YANKMARK | ||
2602 | "\n\tLine marking with 'x" | ||
2603 | "\n\tNamed buffers with \"x" | ||
2604 | #endif | ||
2605 | #if ENABLE_FEATURE_VI_READONLY | ||
2606 | //not implemented: "\n\tReadonly if vi is called as \"view\"" | ||
2607 | //redundant: usage text says this too: "\n\tReadonly with -R command line arg" | ||
2608 | #endif | ||
2609 | #if ENABLE_FEATURE_VI_SET | ||
2610 | "\n\tSome colon mode commands with :" | ||
2611 | #endif | ||
2612 | #if ENABLE_FEATURE_VI_SETOPTS | ||
2613 | "\n\tSettable options with \":set\"" | ||
2614 | #endif | ||
2615 | #if ENABLE_FEATURE_VI_USE_SIGNALS | ||
2616 | "\n\tSignal catching- ^C" | ||
2617 | "\n\tJob suspend and resume with ^Z" | ||
2618 | #endif | ||
2619 | #if ENABLE_FEATURE_VI_WIN_RESIZE | ||
2620 | "\n\tAdapt to window re-sizes" | ||
2621 | #endif | ||
2622 | ); | ||
2623 | } | ||
2624 | |||
2625 | #if ENABLE_FEATURE_VI_DOT_CMD | 2391 | #if ENABLE_FEATURE_VI_DOT_CMD |
2626 | static void start_new_cmd_q(char c) | 2392 | static void start_new_cmd_q(char c) |
2627 | { | 2393 | { |
@@ -4495,3 +4261,235 @@ static void crash_test() | |||
4495 | } | 4261 | } |
4496 | } | 4262 | } |
4497 | #endif | 4263 | #endif |
4264 | |||
4265 | static void edit_file(char *fn) | ||
4266 | { | ||
4267 | #if ENABLE_FEATURE_VI_YANKMARK | ||
4268 | #define cur_line edit_file__cur_line | ||
4269 | #endif | ||
4270 | int c; | ||
4271 | #if ENABLE_FEATURE_VI_USE_SIGNALS | ||
4272 | int sig; | ||
4273 | #endif | ||
4274 | |||
4275 | editing = 1; // 0 = exit, 1 = one file, 2 = multiple files | ||
4276 | rawmode(); | ||
4277 | rows = 24; | ||
4278 | columns = 80; | ||
4279 | IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions(); | ||
4280 | #if ENABLE_FEATURE_VI_ASK_TERMINAL | ||
4281 | if (G.get_rowcol_error /* TODO? && no input on stdin */) { | ||
4282 | uint64_t k; | ||
4283 | write1(ESC"[999;999H" ESC"[6n"); | ||
4284 | fflush_all(); | ||
4285 | k = read_key(STDIN_FILENO, readbuffer, /*timeout_ms:*/ 100); | ||
4286 | if ((int32_t)k == KEYCODE_CURSOR_POS) { | ||
4287 | uint32_t rc = (k >> 32); | ||
4288 | columns = (rc & 0x7fff); | ||
4289 | if (columns > MAX_SCR_COLS) | ||
4290 | columns = MAX_SCR_COLS; | ||
4291 | rows = ((rc >> 16) & 0x7fff); | ||
4292 | if (rows > MAX_SCR_ROWS) | ||
4293 | rows = MAX_SCR_ROWS; | ||
4294 | } | ||
4295 | } | ||
4296 | #endif | ||
4297 | new_screen(rows, columns); // get memory for virtual screen | ||
4298 | init_text_buffer(fn); | ||
4299 | |||
4300 | #if ENABLE_FEATURE_VI_YANKMARK | ||
4301 | YDreg = 26; // default Yank/Delete reg | ||
4302 | // Ureg = 27; - const // hold orig line for "U" cmd | ||
4303 | mark[26] = mark[27] = text; // init "previous context" | ||
4304 | #endif | ||
4305 | |||
4306 | last_forward_char = last_input_char = '\0'; | ||
4307 | crow = 0; | ||
4308 | ccol = 0; | ||
4309 | |||
4310 | #if ENABLE_FEATURE_VI_USE_SIGNALS | ||
4311 | signal(SIGWINCH, winch_handler); | ||
4312 | signal(SIGTSTP, tstp_handler); | ||
4313 | sig = sigsetjmp(restart, 1); | ||
4314 | if (sig != 0) { | ||
4315 | screenbegin = dot = text; | ||
4316 | } | ||
4317 | // int_handler() can jump to "restart", | ||
4318 | // must install handler *after* initializing "restart" | ||
4319 | signal(SIGINT, int_handler); | ||
4320 | #endif | ||
4321 | |||
4322 | cmd_mode = 0; // 0=command 1=insert 2='R'eplace | ||
4323 | cmdcnt = 0; | ||
4324 | tabstop = 8; | ||
4325 | offset = 0; // no horizontal offset | ||
4326 | c = '\0'; | ||
4327 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
4328 | free(ioq_start); | ||
4329 | ioq = ioq_start = NULL; | ||
4330 | lmc_len = 0; | ||
4331 | adding2q = 0; | ||
4332 | #endif | ||
4333 | |||
4334 | #if ENABLE_FEATURE_VI_COLON | ||
4335 | { | ||
4336 | char *p, *q; | ||
4337 | int n = 0; | ||
4338 | |||
4339 | while ((p = initial_cmds[n]) != NULL) { | ||
4340 | do { | ||
4341 | q = p; | ||
4342 | p = strchr(q, '\n'); | ||
4343 | if (p) | ||
4344 | while (*p == '\n') | ||
4345 | *p++ = '\0'; | ||
4346 | if (*q) | ||
4347 | colon(q); | ||
4348 | } while (p); | ||
4349 | free(initial_cmds[n]); | ||
4350 | initial_cmds[n] = NULL; | ||
4351 | n++; | ||
4352 | } | ||
4353 | } | ||
4354 | #endif | ||
4355 | redraw(FALSE); // dont force every col re-draw | ||
4356 | //------This is the main Vi cmd handling loop ----------------------- | ||
4357 | while (editing > 0) { | ||
4358 | #if ENABLE_FEATURE_VI_CRASHME | ||
4359 | if (crashme > 0) { | ||
4360 | if ((end - text) > 1) { | ||
4361 | crash_dummy(); // generate a random command | ||
4362 | } else { | ||
4363 | crashme = 0; | ||
4364 | string_insert(text, "\n\n##### Ran out of text to work on. #####\n\n", NO_UNDO); // insert the string | ||
4365 | dot = text; | ||
4366 | refresh(FALSE); | ||
4367 | } | ||
4368 | } | ||
4369 | #endif | ||
4370 | last_input_char = c = get_one_char(); // get a cmd from user | ||
4371 | #if ENABLE_FEATURE_VI_YANKMARK | ||
4372 | // save a copy of the current line- for the 'U" command | ||
4373 | if (begin_line(dot) != cur_line) { | ||
4374 | cur_line = begin_line(dot); | ||
4375 | text_yank(begin_line(dot), end_line(dot), Ureg); | ||
4376 | } | ||
4377 | #endif | ||
4378 | #if ENABLE_FEATURE_VI_DOT_CMD | ||
4379 | // These are commands that change text[]. | ||
4380 | // Remember the input for the "." command | ||
4381 | if (!adding2q && ioq_start == NULL | ||
4382 | && cmd_mode == 0 // command mode | ||
4383 | && c > '\0' // exclude NUL and non-ASCII chars | ||
4384 | && c < 0x7f // (Unicode and such) | ||
4385 | && strchr(modifying_cmds, c) | ||
4386 | ) { | ||
4387 | start_new_cmd_q(c); | ||
4388 | } | ||
4389 | #endif | ||
4390 | do_cmd(c); // execute the user command | ||
4391 | |||
4392 | // poll to see if there is input already waiting. if we are | ||
4393 | // not able to display output fast enough to keep up, skip | ||
4394 | // the display update until we catch up with input. | ||
4395 | if (!readbuffer[0] && mysleep(0) == 0) { | ||
4396 | // no input pending - so update output | ||
4397 | refresh(FALSE); | ||
4398 | show_status_line(); | ||
4399 | } | ||
4400 | #if ENABLE_FEATURE_VI_CRASHME | ||
4401 | if (crashme > 0) | ||
4402 | crash_test(); // test editor variables | ||
4403 | #endif | ||
4404 | } | ||
4405 | //------------------------------------------------------------------- | ||
4406 | |||
4407 | go_bottom_and_clear_to_eol(); | ||
4408 | cookmode(); | ||
4409 | #undef cur_line | ||
4410 | } | ||
4411 | |||
4412 | int vi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
4413 | int vi_main(int argc, char **argv) | ||
4414 | { | ||
4415 | int c; | ||
4416 | |||
4417 | INIT_G(); | ||
4418 | |||
4419 | #if ENABLE_FEATURE_VI_UNDO | ||
4420 | /* undo_stack_tail = NULL; - already is */ | ||
4421 | #if ENABLE_FEATURE_VI_UNDO_QUEUE | ||
4422 | undo_queue_state = UNDO_EMPTY; | ||
4423 | /* undo_q = 0; - already is */ | ||
4424 | #endif | ||
4425 | #endif | ||
4426 | |||
4427 | #if ENABLE_FEATURE_VI_CRASHME | ||
4428 | srand((long) getpid()); | ||
4429 | #endif | ||
4430 | #ifdef NO_SUCH_APPLET_YET | ||
4431 | // if we aren't "vi", we are "view" | ||
4432 | if (ENABLE_FEATURE_VI_READONLY && applet_name[2]) { | ||
4433 | SET_READONLY_MODE(readonly_mode); | ||
4434 | } | ||
4435 | #endif | ||
4436 | |||
4437 | // autoindent is not default in vim 7.3 | ||
4438 | vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE; | ||
4439 | // 1- process $HOME/.exrc file (not inplemented yet) | ||
4440 | // 2- process EXINIT variable from environment | ||
4441 | // 3- process command line args | ||
4442 | #if ENABLE_FEATURE_VI_COLON | ||
4443 | { | ||
4444 | char *p = getenv("EXINIT"); | ||
4445 | if (p && *p) | ||
4446 | initial_cmds[0] = xstrndup(p, MAX_INPUT_LEN); | ||
4447 | } | ||
4448 | #endif | ||
4449 | while ((c = getopt(argc, argv, "hCRH" IF_FEATURE_VI_COLON("c:"))) != -1) { | ||
4450 | switch (c) { | ||
4451 | #if ENABLE_FEATURE_VI_CRASHME | ||
4452 | case 'C': | ||
4453 | crashme = 1; | ||
4454 | break; | ||
4455 | #endif | ||
4456 | #if ENABLE_FEATURE_VI_READONLY | ||
4457 | case 'R': // Read-only flag | ||
4458 | SET_READONLY_MODE(readonly_mode); | ||
4459 | break; | ||
4460 | #endif | ||
4461 | #if ENABLE_FEATURE_VI_COLON | ||
4462 | case 'c': // cmd line vi command | ||
4463 | if (*optarg) | ||
4464 | initial_cmds[initial_cmds[0] != NULL] = xstrndup(optarg, MAX_INPUT_LEN); | ||
4465 | break; | ||
4466 | #endif | ||
4467 | case 'H': | ||
4468 | show_help(); | ||
4469 | // fall through | ||
4470 | default: | ||
4471 | bb_show_usage(); | ||
4472 | return 1; | ||
4473 | } | ||
4474 | } | ||
4475 | |||
4476 | // The argv array can be used by the ":next" and ":rewind" commands | ||
4477 | argv += optind; | ||
4478 | argc -= optind; | ||
4479 | |||
4480 | //----- This is the main file handling loop -------------- | ||
4481 | save_argc = argc; | ||
4482 | optind = 0; | ||
4483 | // "Save cursor, use alternate screen buffer, clear screen" | ||
4484 | write1(ESC"[?1049h"); | ||
4485 | while (1) { | ||
4486 | edit_file(argv[optind]); // param might be NULL | ||
4487 | if (++optind >= argc) | ||
4488 | break; | ||
4489 | } | ||
4490 | // "Use normal screen buffer, restore cursor" | ||
4491 | write1(ESC"[?1049l"); | ||
4492 | //----------------------------------------------------------- | ||
4493 | |||
4494 | return 0; | ||
4495 | } | ||