summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-04-01 14:08:00 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-04-01 14:16:53 +0200
commitde69775838eed0acd02f40de5e988d80611557ab (patch)
tree4a254679d4d0c8c0ac4db955f90b92a8596b3070
parent616e4699d2d54518b6bdf5534a8b81bed9e63e77 (diff)
downloadbusybox-w32-de69775838eed0acd02f40de5e988d80611557ab.tar.gz
busybox-w32-de69775838eed0acd02f40de5e988d80611557ab.tar.bz2
busybox-w32-de69775838eed0acd02f40de5e988d80611557ab.zip
vi: rearrange functions, no logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c552
1 files changed, 276 insertions, 276 deletions
diff --git a/editors/vi.c b/editors/vi.c
index e960afc37..9db763ccd 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -693,6 +693,282 @@ static ALWAYS_INLINE int query_screen_dimensions(void)
693} 693}
694#endif 694#endif
695 695
696// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
697static int mysleep(int hund)
698{
699 struct pollfd pfd[1];
700
701 if (hund != 0)
702 fflush_all();
703
704 pfd[0].fd = STDIN_FILENO;
705 pfd[0].events = POLLIN;
706 return safe_poll(pfd, 1, hund*10) > 0;
707}
708
709//----- Set terminal attributes --------------------------------
710static void rawmode(void)
711{
712 // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals
713 set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL);
714 erase_char = term_orig.c_cc[VERASE];
715}
716
717static void cookmode(void)
718{
719 fflush_all();
720 tcsetattr_stdin_TCSANOW(&term_orig);
721}
722
723//----- Terminal Drawing ---------------------------------------
724// The terminal is made up of 'rows' line of 'columns' columns.
725// classically this would be 24 x 80.
726// screen coordinates
727// 0,0 ... 0,79
728// 1,0 ... 1,79
729// . ... .
730// . ... .
731// 22,0 ... 22,79
732// 23,0 ... 23,79 <- status line
733
734//----- Move the cursor to row x col (count from 0, not 1) -------
735static void place_cursor(int row, int col)
736{
737 char cm1[sizeof(ESC_SET_CURSOR_POS) + sizeof(int)*3 * 2];
738
739 if (row < 0) row = 0;
740 if (row >= rows) row = rows - 1;
741 if (col < 0) col = 0;
742 if (col >= columns) col = columns - 1;
743
744 sprintf(cm1, ESC_SET_CURSOR_POS, row + 1, col + 1);
745 write1(cm1);
746}
747
748//----- Erase from cursor to end of line -----------------------
749static void clear_to_eol(void)
750{
751 write1(ESC_CLEAR2EOL);
752}
753
754static void go_bottom_and_clear_to_eol(void)
755{
756 place_cursor(rows - 1, 0);
757 clear_to_eol();
758}
759
760//----- Start standout mode ------------------------------------
761static void standout_start(void)
762{
763 write1(ESC_BOLD_TEXT);
764}
765
766//----- End standout mode --------------------------------------
767static void standout_end(void)
768{
769 write1(ESC_NORM_TEXT);
770}
771
772//----- Text Movement Routines ---------------------------------
773static char *begin_line(char *p) // return pointer to first char cur line
774{
775 if (p > text) {
776 p = memrchr(text, '\n', p - text);
777 if (!p)
778 return text;
779 return p + 1;
780 }
781 return p;
782}
783
784static char *end_line(char *p) // return pointer to NL of cur line
785{
786 if (p < end - 1) {
787 p = memchr(p, '\n', end - p - 1);
788 if (!p)
789 return end - 1;
790 }
791 return p;
792}
793
794static char *dollar_line(char *p) // return pointer to just before NL line
795{
796 p = end_line(p);
797 // Try to stay off of the Newline
798 if (*p == '\n' && (p - begin_line(p)) > 0)
799 p--;
800 return p;
801}
802
803static char *prev_line(char *p) // return pointer first char prev line
804{
805 p = begin_line(p); // goto beginning of cur line
806 if (p > text && p[-1] == '\n')
807 p--; // step to prev line
808 p = begin_line(p); // goto beginning of prev line
809 return p;
810}
811
812static char *next_line(char *p) // return pointer first char next line
813{
814 p = end_line(p);
815 if (p < end - 1 && *p == '\n')
816 p++; // step to next line
817 return p;
818}
819
820//----- Text Information Routines ------------------------------
821static char *end_screen(void)
822{
823 char *q;
824 int cnt;
825
826 // find new bottom line
827 q = screenbegin;
828 for (cnt = 0; cnt < rows - 2; cnt++)
829 q = next_line(q);
830 q = end_line(q);
831 return q;
832}
833
834// count line from start to stop
835static int count_lines(char *start, char *stop)
836{
837 char *q;
838 int cnt;
839
840 if (stop < start) { // start and stop are backwards- reverse them
841 q = start;
842 start = stop;
843 stop = q;
844 }
845 cnt = 0;
846 stop = end_line(stop);
847 while (start <= stop && start <= end - 1) {
848 start = end_line(start);
849 if (*start == '\n')
850 cnt++;
851 start++;
852 }
853 return cnt;
854}
855
856static char *find_line(int li) // find beginning of line #li
857{
858 char *q;
859
860 for (q = text; li > 1; li--) {
861 q = next_line(q);
862 }
863 return q;
864}
865
866static int next_tabstop(int col)
867{
868 return col + ((tabstop - 1) - (col % tabstop));
869}
870
871//----- Erase the Screen[] memory ------------------------------
872static void screen_erase(void)
873{
874 memset(screen, ' ', screensize); // clear new screen
875}
876
877//----- Synchronize the cursor to Dot --------------------------
878static NOINLINE void sync_cursor(char *d, int *row, int *col)
879{
880 char *beg_cur; // begin and end of "d" line
881 char *tp;
882 int cnt, ro, co;
883
884 beg_cur = begin_line(d); // first char of cur line
885
886 if (beg_cur < screenbegin) {
887 // "d" is before top line on screen
888 // how many lines do we have to move
889 cnt = count_lines(beg_cur, screenbegin);
890 sc1:
891 screenbegin = beg_cur;
892 if (cnt > (rows - 1) / 2) {
893 // we moved too many lines. put "dot" in middle of screen
894 for (cnt = 0; cnt < (rows - 1) / 2; cnt++) {
895 screenbegin = prev_line(screenbegin);
896 }
897 }
898 } else {
899 char *end_scr; // begin and end of screen
900 end_scr = end_screen(); // last char of screen
901 if (beg_cur > end_scr) {
902 // "d" is after bottom line on screen
903 // how many lines do we have to move
904 cnt = count_lines(end_scr, beg_cur);
905 if (cnt > (rows - 1) / 2)
906 goto sc1; // too many lines
907 for (ro = 0; ro < cnt - 1; ro++) {
908 // move screen begin the same amount
909 screenbegin = next_line(screenbegin);
910 // now, move the end of screen
911 end_scr = next_line(end_scr);
912 end_scr = end_line(end_scr);
913 }
914 }
915 }
916 // "d" is on screen- find out which row
917 tp = screenbegin;
918 for (ro = 0; ro < rows - 1; ro++) { // drive "ro" to correct row
919 if (tp == beg_cur)
920 break;
921 tp = next_line(tp);
922 }
923
924 // find out what col "d" is on
925 co = 0;
926 while (tp < d) { // drive "co" to correct column
927 if (*tp == '\n') //vda || *tp == '\0')
928 break;
929 if (*tp == '\t') {
930 // handle tabs like real vi
931 if (d == tp && cmd_mode) {
932 break;
933 }
934 co = next_tabstop(co);
935 } else if ((unsigned char)*tp < ' ' || *tp == 0x7f) {
936 co++; // display as ^X, use 2 columns
937 }
938 co++;
939 tp++;
940 }
941
942 // "co" is the column where "dot" is.
943 // The screen has "columns" columns.
944 // The currently displayed columns are 0+offset -- columns+ofset
945 // |-------------------------------------------------------------|
946 // ^ ^ ^
947 // offset | |------- columns ----------------|
948 //
949 // If "co" is already in this range then we do not have to adjust offset
950 // but, we do have to subtract the "offset" bias from "co".
951 // If "co" is outside this range then we have to change "offset".
952 // If the first char of a line is a tab the cursor will try to stay
953 // in column 7, but we have to set offset to 0.
954
955 if (co < 0 + offset) {
956 offset = co;
957 }
958 if (co >= columns + offset) {
959 offset = co - columns + 1;
960 }
961 // if the first char of the line is a tab, and "dot" is sitting on it
962 // force offset to 0.
963 if (d == beg_cur && *d == '\t') {
964 offset = 0;
965 }
966 co -= offset;
967
968 *row = ro;
969 *col = co;
970}
971
696//----- The Colon commands ------------------------------------- 972//----- The Colon commands -------------------------------------
697#if ENABLE_FEATURE_VI_COLON 973#if ENABLE_FEATURE_VI_COLON
698static char *get_one_address(char *p, int *addr) // get colon addr, if present 974static char *get_one_address(char *p, int *addr) // get colon addr, if present
@@ -1355,200 +1631,6 @@ static void Hit_Return(void)
1355 redraw(TRUE); // force redraw all 1631 redraw(TRUE); // force redraw all
1356} 1632}
1357 1633
1358static int next_tabstop(int col)
1359{
1360 return col + ((tabstop - 1) - (col % tabstop));
1361}
1362
1363//----- Synchronize the cursor to Dot --------------------------
1364static NOINLINE void sync_cursor(char *d, int *row, int *col)
1365{
1366 char *beg_cur; // begin and end of "d" line
1367 char *tp;
1368 int cnt, ro, co;
1369
1370 beg_cur = begin_line(d); // first char of cur line
1371
1372 if (beg_cur < screenbegin) {
1373 // "d" is before top line on screen
1374 // how many lines do we have to move
1375 cnt = count_lines(beg_cur, screenbegin);
1376 sc1:
1377 screenbegin = beg_cur;
1378 if (cnt > (rows - 1) / 2) {
1379 // we moved too many lines. put "dot" in middle of screen
1380 for (cnt = 0; cnt < (rows - 1) / 2; cnt++) {
1381 screenbegin = prev_line(screenbegin);
1382 }
1383 }
1384 } else {
1385 char *end_scr; // begin and end of screen
1386 end_scr = end_screen(); // last char of screen
1387 if (beg_cur > end_scr) {
1388 // "d" is after bottom line on screen
1389 // how many lines do we have to move
1390 cnt = count_lines(end_scr, beg_cur);
1391 if (cnt > (rows - 1) / 2)
1392 goto sc1; // too many lines
1393 for (ro = 0; ro < cnt - 1; ro++) {
1394 // move screen begin the same amount
1395 screenbegin = next_line(screenbegin);
1396 // now, move the end of screen
1397 end_scr = next_line(end_scr);
1398 end_scr = end_line(end_scr);
1399 }
1400 }
1401 }
1402 // "d" is on screen- find out which row
1403 tp = screenbegin;
1404 for (ro = 0; ro < rows - 1; ro++) { // drive "ro" to correct row
1405 if (tp == beg_cur)
1406 break;
1407 tp = next_line(tp);
1408 }
1409
1410 // find out what col "d" is on
1411 co = 0;
1412 while (tp < d) { // drive "co" to correct column
1413 if (*tp == '\n') //vda || *tp == '\0')
1414 break;
1415 if (*tp == '\t') {
1416 // handle tabs like real vi
1417 if (d == tp && cmd_mode) {
1418 break;
1419 }
1420 co = next_tabstop(co);
1421 } else if ((unsigned char)*tp < ' ' || *tp == 0x7f) {
1422 co++; // display as ^X, use 2 columns
1423 }
1424 co++;
1425 tp++;
1426 }
1427
1428 // "co" is the column where "dot" is.
1429 // The screen has "columns" columns.
1430 // The currently displayed columns are 0+offset -- columns+ofset
1431 // |-------------------------------------------------------------|
1432 // ^ ^ ^
1433 // offset | |------- columns ----------------|
1434 //
1435 // If "co" is already in this range then we do not have to adjust offset
1436 // but, we do have to subtract the "offset" bias from "co".
1437 // If "co" is outside this range then we have to change "offset".
1438 // If the first char of a line is a tab the cursor will try to stay
1439 // in column 7, but we have to set offset to 0.
1440
1441 if (co < 0 + offset) {
1442 offset = co;
1443 }
1444 if (co >= columns + offset) {
1445 offset = co - columns + 1;
1446 }
1447 // if the first char of the line is a tab, and "dot" is sitting on it
1448 // force offset to 0.
1449 if (d == beg_cur && *d == '\t') {
1450 offset = 0;
1451 }
1452 co -= offset;
1453
1454 *row = ro;
1455 *col = co;
1456}
1457
1458//----- Text Movement Routines ---------------------------------
1459static char *begin_line(char *p) // return pointer to first char cur line
1460{
1461 if (p > text) {
1462 p = memrchr(text, '\n', p - text);
1463 if (!p)
1464 return text;
1465 return p + 1;
1466 }
1467 return p;
1468}
1469
1470static char *end_line(char *p) // return pointer to NL of cur line
1471{
1472 if (p < end - 1) {
1473 p = memchr(p, '\n', end - p - 1);
1474 if (!p)
1475 return end - 1;
1476 }
1477 return p;
1478}
1479
1480static char *dollar_line(char *p) // return pointer to just before NL line
1481{
1482 p = end_line(p);
1483 // Try to stay off of the Newline
1484 if (*p == '\n' && (p - begin_line(p)) > 0)
1485 p--;
1486 return p;
1487}
1488
1489static char *prev_line(char *p) // return pointer first char prev line
1490{
1491 p = begin_line(p); // goto beginning of cur line
1492 if (p > text && p[-1] == '\n')
1493 p--; // step to prev line
1494 p = begin_line(p); // goto beginning of prev line
1495 return p;
1496}
1497
1498static char *next_line(char *p) // return pointer first char next line
1499{
1500 p = end_line(p);
1501 if (p < end - 1 && *p == '\n')
1502 p++; // step to next line
1503 return p;
1504}
1505
1506//----- Text Information Routines ------------------------------
1507static char *end_screen(void)
1508{
1509 char *q;
1510 int cnt;
1511
1512 // find new bottom line
1513 q = screenbegin;
1514 for (cnt = 0; cnt < rows - 2; cnt++)
1515 q = next_line(q);
1516 q = end_line(q);
1517 return q;
1518}
1519
1520// count line from start to stop
1521static int count_lines(char *start, char *stop)
1522{
1523 char *q;
1524 int cnt;
1525
1526 if (stop < start) { // start and stop are backwards- reverse them
1527 q = start;
1528 start = stop;
1529 stop = q;
1530 }
1531 cnt = 0;
1532 stop = end_line(stop);
1533 while (start <= stop && start <= end - 1) {
1534 start = end_line(start);
1535 if (*start == '\n')
1536 cnt++;
1537 start++;
1538 }
1539 return cnt;
1540}
1541
1542static char *find_line(int li) // find beginning of line #li
1543{
1544 char *q;
1545
1546 for (q = text; li > 1; li--) {
1547 q = next_line(q);
1548 }
1549 return q;
1550}
1551
1552//----- Dot Movement Routines ---------------------------------- 1634//----- Dot Movement Routines ----------------------------------
1553static void dot_left(void) 1635static void dot_left(void)
1554{ 1636{
@@ -2430,32 +2512,6 @@ static char *swap_context(char *p) // goto new context for '' command make this
2430} 2512}
2431#endif /* FEATURE_VI_YANKMARK */ 2513#endif /* FEATURE_VI_YANKMARK */
2432 2514
2433//----- Set terminal attributes --------------------------------
2434static void rawmode(void)
2435{
2436 // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals
2437 set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL);
2438 erase_char = term_orig.c_cc[VERASE];
2439}
2440
2441static void cookmode(void)
2442{
2443 fflush_all();
2444 tcsetattr_stdin_TCSANOW(&term_orig);
2445}
2446
2447static int mysleep(int hund) // sleep for 'hund' 1/100 seconds or stdin ready
2448{
2449 struct pollfd pfd[1];
2450
2451 if (hund != 0)
2452 fflush_all();
2453
2454 pfd[0].fd = STDIN_FILENO;
2455 pfd[0].events = POLLIN;
2456 return safe_poll(pfd, 1, hund*10) > 0;
2457}
2458
2459//----- IO Routines -------------------------------------------- 2515//----- IO Routines --------------------------------------------
2460static int readit(void) // read (maybe cursor) key from stdin 2516static int readit(void) // read (maybe cursor) key from stdin
2461{ 2517{
@@ -2637,55 +2693,6 @@ static int file_write(char *fn, char *first, char *last)
2637 return charcnt; 2693 return charcnt;
2638} 2694}
2639 2695
2640//----- Terminal Drawing ---------------------------------------
2641// The terminal is made up of 'rows' line of 'columns' columns.
2642// classically this would be 24 x 80.
2643// screen coordinates
2644// 0,0 ... 0,79
2645// 1,0 ... 1,79
2646// . ... .
2647// . ... .
2648// 22,0 ... 22,79
2649// 23,0 ... 23,79 <- status line
2650
2651//----- Move the cursor to row x col (count from 0, not 1) -------
2652static void place_cursor(int row, int col)
2653{
2654 char cm1[sizeof(ESC_SET_CURSOR_POS) + sizeof(int)*3 * 2];
2655
2656 if (row < 0) row = 0;
2657 if (row >= rows) row = rows - 1;
2658 if (col < 0) col = 0;
2659 if (col >= columns) col = columns - 1;
2660
2661 sprintf(cm1, ESC_SET_CURSOR_POS, row + 1, col + 1);
2662 write1(cm1);
2663}
2664
2665//----- Erase from cursor to end of line -----------------------
2666static void clear_to_eol(void)
2667{
2668 write1(ESC_CLEAR2EOL);
2669}
2670
2671static void go_bottom_and_clear_to_eol(void)
2672{
2673 place_cursor(rows - 1, 0);
2674 clear_to_eol();
2675}
2676
2677//----- Start standout mode ------------------------------------
2678static void standout_start(void)
2679{
2680 write1(ESC_BOLD_TEXT);
2681}
2682
2683//----- End standout mode --------------------------------------
2684static void standout_end(void)
2685{
2686 write1(ESC_NORM_TEXT);
2687}
2688
2689//----- Flash the screen -------------------------------------- 2696//----- Flash the screen --------------------------------------
2690static void flash(int h) 2697static void flash(int h)
2691{ 2698{
@@ -2709,13 +2716,6 @@ static void indicate_error(void)
2709 } 2716 }
2710} 2717}
2711 2718
2712//----- Screen[] Routines --------------------------------------
2713//----- Erase the Screen[] memory ------------------------------
2714static void screen_erase(void)
2715{
2716 memset(screen, ' ', screensize); // clear new screen
2717}
2718
2719static int bufsum(char *buf, int count) 2719static int bufsum(char *buf, int count)
2720{ 2720{
2721 int sum = 0; 2721 int sum = 0;