diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-04-01 13:55:27 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-04-01 13:55:27 +0200 |
| commit | 24bd350aaa3cd593a9a8304042cea689d716aba2 (patch) | |
| tree | 7435059a14e98ba0c827a7b9e3f7deacca587b88 | |
| parent | c3193104049186bd28203801e8fd7d9d4ff2b547 (diff) | |
| download | busybox-w32-24bd350aaa3cd593a9a8304042cea689d716aba2.tar.gz busybox-w32-24bd350aaa3cd593a9a8304042cea689d716aba2.tar.bz2 busybox-w32-24bd350aaa3cd593a9a8304042cea689d716aba2.zip | |
vi: rearrange functions, no logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -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 | } | ||
