diff options
-rw-r--r-- | miscutils/less.c | 119 |
1 files changed, 82 insertions, 37 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 2a1797c7b..5c53cbdbf 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -711,23 +711,6 @@ static void status_print(void) | |||
711 | print_hilite(p); | 711 | print_hilite(p); |
712 | } | 712 | } |
713 | 713 | ||
714 | static void cap_cur_fline(int nlines) | ||
715 | { | ||
716 | int diff; | ||
717 | if (cur_fline < 0) | ||
718 | cur_fline = 0; | ||
719 | if (cur_fline + max_displayed_line > max_fline + TILDES) { | ||
720 | cur_fline -= nlines; | ||
721 | if (cur_fline < 0) | ||
722 | cur_fline = 0; | ||
723 | diff = max_fline - (cur_fline + max_displayed_line) + TILDES; | ||
724 | /* As the number of lines requested was too large, we just move | ||
725 | * to the end of the file */ | ||
726 | if (diff > 0) | ||
727 | cur_fline += diff; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | static const char controls[] ALIGN1 = | 714 | static const char controls[] ALIGN1 = |
732 | /* NUL: never encountered; TAB: not converted */ | 715 | /* NUL: never encountered; TAB: not converted */ |
733 | /**/"\x01\x02\x03\x04\x05\x06\x07\x08" "\x0a\x0b\x0c\x0d\x0e\x0f" | 716 | /**/"\x01\x02\x03\x04\x05\x06\x07\x08" "\x0a\x0b\x0c\x0d\x0e\x0f" |
@@ -913,37 +896,98 @@ static void buffer_fill_and_print(void) | |||
913 | buffer_print(); | 896 | buffer_print(); |
914 | } | 897 | } |
915 | 898 | ||
899 | /* move cur_fline to a given line number, reading lines if necessary */ | ||
900 | static void goto_lineno(int target) | ||
901 | { | ||
902 | if (target <= 0 ) { | ||
903 | cur_fline = 0; | ||
904 | } | ||
905 | else if (target > LINENO(flines[cur_fline])) { | ||
906 | retry: | ||
907 | while (LINENO(flines[cur_fline]) != target && cur_fline < max_fline) | ||
908 | ++cur_fline; | ||
909 | /* target not reached but more input is available */ | ||
910 | if (LINENO(flines[cur_fline]) != target && eof_error > 0) { | ||
911 | read_lines(); | ||
912 | goto retry; | ||
913 | } | ||
914 | } | ||
915 | else { | ||
916 | /* search backwards through already-read lines */ | ||
917 | while (LINENO(flines[cur_fline]) != target && cur_fline > 0) | ||
918 | --cur_fline; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | static void cap_cur_fline(void) | ||
923 | { | ||
924 | if ((option_mask32 & FLAG_S)) { | ||
925 | if (cur_fline > max_fline) | ||
926 | cur_fline = max_fline; | ||
927 | if (LINENO(flines[cur_fline]) + max_displayed_line > max_lineno + TILDES) { | ||
928 | goto_lineno(max_lineno - max_displayed_line + TILDES); | ||
929 | read_lines(); | ||
930 | } | ||
931 | } | ||
932 | else { | ||
933 | if (cur_fline + max_displayed_line > max_fline + TILDES) | ||
934 | cur_fline = max_fline - max_displayed_line + TILDES; | ||
935 | if (cur_fline < 0) | ||
936 | cur_fline = 0; | ||
937 | } | ||
938 | } | ||
939 | |||
916 | /* Move the buffer up and down in the file in order to scroll */ | 940 | /* Move the buffer up and down in the file in order to scroll */ |
917 | static void buffer_down(int nlines) | 941 | static void buffer_down(int nlines) |
918 | { | 942 | { |
919 | cur_fline += nlines; | 943 | if ((option_mask32 & FLAG_S)) |
944 | goto_lineno(LINENO(flines[cur_fline]) + nlines); | ||
945 | else | ||
946 | cur_fline += nlines; | ||
920 | read_lines(); | 947 | read_lines(); |
921 | cap_cur_fline(nlines); | 948 | cap_cur_fline(); |
922 | buffer_fill_and_print(); | 949 | buffer_fill_and_print(); |
923 | } | 950 | } |
924 | 951 | ||
925 | static void buffer_up(int nlines) | 952 | static void buffer_up(int nlines) |
926 | { | 953 | { |
927 | cur_fline -= nlines; | 954 | if ((option_mask32 & FLAG_S)) { |
928 | if (cur_fline < 0) cur_fline = 0; | 955 | goto_lineno(LINENO(flines[cur_fline]) - nlines); |
956 | } | ||
957 | else { | ||
958 | cur_fline -= nlines; | ||
959 | if (cur_fline < 0) | ||
960 | cur_fline = 0; | ||
961 | } | ||
929 | read_lines(); | 962 | read_lines(); |
930 | buffer_fill_and_print(); | 963 | buffer_fill_and_print(); |
931 | } | 964 | } |
932 | 965 | ||
933 | static void buffer_line(int linenum) | 966 | /* display a given line where the argument can be either an index into |
967 | * the flines array or a line number */ | ||
968 | static void buffer_to_line(int linenum, int is_lineno) | ||
934 | { | 969 | { |
935 | if (linenum < 0) | 970 | if (linenum <= 0) |
936 | linenum = 0; | 971 | cur_fline = 0; |
937 | cur_fline = linenum; | 972 | else if (is_lineno) |
973 | goto_lineno(linenum); | ||
974 | else | ||
975 | cur_fline = linenum; | ||
938 | read_lines(); | 976 | read_lines(); |
939 | if (linenum + max_displayed_line > max_fline) | 977 | cap_cur_fline(); |
940 | linenum = max_fline - max_displayed_line + TILDES; | ||
941 | if (linenum < 0) | ||
942 | linenum = 0; | ||
943 | cur_fline = linenum; | ||
944 | buffer_fill_and_print(); | 978 | buffer_fill_and_print(); |
945 | } | 979 | } |
946 | 980 | ||
981 | static void buffer_line(int linenum) | ||
982 | { | ||
983 | buffer_to_line(linenum, FALSE); | ||
984 | } | ||
985 | |||
986 | static void buffer_lineno(int lineno) | ||
987 | { | ||
988 | buffer_to_line(lineno, TRUE); | ||
989 | } | ||
990 | |||
947 | static void open_file_and_read_lines(void) | 991 | static void open_file_and_read_lines(void) |
948 | { | 992 | { |
949 | if (filename) { | 993 | if (filename) { |
@@ -1348,15 +1392,16 @@ static void number_process(int first_digit) | |||
1348 | buffer_up(num); | 1392 | buffer_up(num); |
1349 | break; | 1393 | break; |
1350 | case 'g': case '<': case 'G': case '>': | 1394 | case 'g': case '<': case 'G': case '>': |
1351 | cur_fline = num + max_displayed_line; | 1395 | buffer_lineno(num - 1); |
1352 | read_lines(); | ||
1353 | buffer_line(num - 1); | ||
1354 | break; | 1396 | break; |
1355 | case 'p': case '%': | 1397 | case 'p': case '%': |
1356 | num = num * (max_fline / 100); /* + max_fline / 2; */ | 1398 | #if ENABLE_FEATURE_LESS_FLAGS |
1357 | cur_fline = num + max_displayed_line; | 1399 | update_num_lines(); |
1358 | read_lines(); | 1400 | num = num * (num_lines > 0 ? num_lines : max_lineno) / 100; |
1359 | buffer_line(num); | 1401 | #else |
1402 | num = num * max_lineno / 100; | ||
1403 | #endif | ||
1404 | buffer_lineno(num); | ||
1360 | break; | 1405 | break; |
1361 | #if ENABLE_FEATURE_LESS_REGEXP | 1406 | #if ENABLE_FEATURE_LESS_REGEXP |
1362 | case 'n': | 1407 | case 'n': |