less: restore TAB display (was showing as inverse I after prev changes :)

This commit is contained in:
Denis Vlasenko 2006-12-21 15:23:45 +00:00
parent d51d14e36f
commit f65d1338dc

View File

@ -191,11 +191,10 @@ static void print_hilite(const char *str)
static void data_readlines(void) static void data_readlines(void)
{ {
unsigned i; unsigned i, pos;
unsigned n = 1; unsigned lineno = 1;
int w = width; int w = width;
/* "remained unused space" in a line (0 if line fills entire width) */ char terminated, last_terminated = 1;
int rem, last_rem = 1; /* "not 0" */
char *current_line, *p; char *current_line, *p;
FILE *fp; FILE *fp;
@ -210,41 +209,47 @@ static void data_readlines(void)
flines = NULL; flines = NULL;
if (option_mask32 & FLAG_N) { if (option_mask32 & FLAG_N) {
w -= 6; w -= 8;
} }
for (i = 0; !feof(fp) && i <= MAXLINES; i++) { for (i = 0; !feof(fp) && i <= MAXLINES; i++) {
flines = xrealloc(flines, (i+1) * sizeof(char *)); flines = xrealloc(flines, (i+1) * sizeof(char *));
current_line = xmalloc(w); current_line = xmalloc(w);
again: again:
p = current_line; p = current_line;
rem = w - 1; pos = 0;
do { terminated = 0;
while (1) {
int c = getc(fp); int c = getc(fp);
if (c == '\t') pos += (pos^7) & 7;
pos++;
if (pos >= w) { ungetc(c, fp); break; }
if (c == EOF) break; if (c == EOF) break;
if (c == '\n') break; if (c == '\n') { terminated = 1; break; }
/* NUL is substituted by '\n'! */ /* NUL is substituted by '\n'! */
if (c == '\0') c = '\n'; if (c == '\0') c = '\n';
*p++ = c; *p++ = c;
} while (--rem); }
*p = '\0'; *p = '\0';
if (fp != stdin) if (fp != stdin)
die_if_ferror(fp, filename); die_if_ferror(fp, filename);
/* Corner case: linewrap with only "" wrapping to next line */ /* Corner case: linewrap with only "" wrapping to next line */
/* Looks ugly on screen, so we do not store this empty line */ /* Looks ugly on screen, so we do not store this empty line */
if (!last_rem && !current_line[0]) { if (!last_terminated && !current_line[0]) {
last_rem = 1; /* "not 0" */ last_terminated = 1;
n++; lineno++;
goto again; goto again;
} }
last_rem = rem; last_terminated = terminated;
if (option_mask32 & FLAG_N) { if (option_mask32 & FLAG_N) {
flines[i] = xasprintf((n <= 99999) ? "%5u %s" : "%05u %s", /* Width of 7 preserves tab spacing in the text */
n % 100000, current_line); flines[i] = xasprintf(
(lineno <= 9999999) ? "%7u %s" : "%07u %s",
lineno % 10000000, current_line);
free(current_line); free(current_line);
if (rem) if (terminated)
n++; lineno++;
} else { } else {
flines[i] = xrealloc(current_line, strlen(current_line)+1); flines[i] = xrealloc(current_line, strlen(current_line)+1);
} }
@ -339,12 +344,12 @@ static void status_print(void)
} }
static char controls[] = static char controls[] =
/**/"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" /* NUL: never encountered; TAB: not converted */
/**/"\x01\x02\x03\x04\x05\x06\x07\x08" "\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x7f\x9b"; /* DEL and infamous Meta-ESC :( */ "\x7f\x9b"; /* DEL and infamous Meta-ESC :( */
static char ctrlconv[] = static char ctrlconv[] =
/* Note that on input NUL is converted to '\n' ('\x0a') */ /* '\n': it's a former NUL - subst with '@', not 'J' */
/* Therefore we subst '\n' with '@', not 'J' */
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f"
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"; "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f";
@ -402,10 +407,10 @@ static void print_found(const char *line)
} }
if (!growline) { if (!growline) {
printf("%s"CLEAR_2_EOL"\n", str); printf(CLEAR_2_EOL"%s\n", str);
return; return;
} }
printf("%s%s"CLEAR_2_EOL"\n", growline, str); printf(CLEAR_2_EOL"%s%s\n", growline, str);
free(growline); free(growline);
} }
@ -415,6 +420,7 @@ static void print_ascii(const char *str)
char *p; char *p;
size_t n; size_t n;
printf(CLEAR_2_EOL);
while (*str) { while (*str) {
n = strcspn(str, controls); n = strcspn(str, controls);
if (n) { if (n) {
@ -438,7 +444,7 @@ static void print_ascii(const char *str)
*p = '\0'; *p = '\0';
print_hilite(buf); print_hilite(buf);
} }
printf("%s"CLEAR_2_EOL"\n", str); puts(str);
} }
/* Print the buffer */ /* Print the buffer */
@ -578,7 +584,7 @@ static void change_file(int direction)
reinitialise(); reinitialise();
} else { } else {
clear_line(); clear_line();
print_hilite((direction > 0) ? "No next file" : "No previous file"); print_hilite(direction > 0 ? "No next file" : "No previous file");
} }
} }
@ -644,18 +650,17 @@ static void colon_process(void)
static int normalize_match_pos(int match) static int normalize_match_pos(int match)
{ {
match_pos = match; match_pos = match;
if (match >= num_matches)
match_pos = num_matches - 1;
if (match < 0) if (match < 0)
return (match_pos = 0); return (match_pos = 0);
if (match >= num_matches)
{
match_pos = num_matches - 1;
}
return match_pos; return match_pos;
} }
#if ENABLE_FEATURE_LESS_REGEXP #if ENABLE_FEATURE_LESS_REGEXP
static void goto_match(int match) static void goto_match(int match)
{ {
if (num_matches)
buffer_line(match_lines[normalize_match_pos(match)]); buffer_line(match_lines[normalize_match_pos(match)]);
} }
@ -1063,6 +1068,7 @@ static void keypress_process(int keypress)
regex_process(); regex_process();
break; break;
case 'n': case 'n':
//printf("HERE 3\n");sleep(1);
goto_match(match_pos + 1); goto_match(match_pos + 1);
break; break;
case 'N': case 'N':