less: experimental code to enable wrap/no-wrap

and adapting to resized xterm windows. disabled for now.
This commit is contained in:
Denis Vlasenko 2008-10-24 10:42:21 +00:00
parent 8f39b72aba
commit d908395eae

View File

@ -28,6 +28,9 @@
#include "xregex.h"
#endif
/* In progress */
#define ENABLE_FEATURE_LESS_REWRAP 0
/* FIXME: currently doesn't work right */
#undef ENABLE_FEATURE_LESS_FLAGCS
#define ENABLE_FEATURE_LESS_FLAGCS 0
@ -81,6 +84,7 @@ enum {
FLAG_TILDE = 1 << 4,
FLAG_I = 1 << 5,
/* hijack command line options variable for internal state vars */
LESS_STATE_NO_WRAP = 1 << 14,
LESS_STATE_MATCH_BACKWARDS = 1 << 15,
};
@ -214,6 +218,88 @@ static void less_exit(int code)
exit(code);
}
#if ENABLE_FEATURE_LESS_REWRAP
static void re_wrap(void)
{
int w = width;
int rem;
int src_idx;
int dst_idx;
int new_cur_fline = 0;
uint32_t lineno;
char linebuf[w + 1];
const char **old_flines = flines;
const char *s;
char **new_flines = NULL;
char *d;
if (option_mask32 & FLAG_N)
w -= 8;
src_idx = 0;
dst_idx = 0;
s = old_flines[0];
lineno = LINENO(s);
d = linebuf;
rem = w;
while (1) {
*d = *s;
if (*d != '\0') {
s++;
d++;
rem--;
if (rem == 0) {
int sz;
/* new line is full, create next one */
*d = '\0';
next_new:
sz = (d - linebuf) + 1; /* + 1: NUL */
d = ((char*)xmalloc(sz + 4)) + 4;
LINENO(d) = lineno;
memcpy(d, linebuf, sz);
new_flines = xrealloc_vector(new_flines, 8, dst_idx);
new_flines[dst_idx] = d;
dst_idx++;
if (rem) {
/* did we come here thru "goto next_new"? */
if (src_idx > max_fline)
break;
lineno = LINENO(s);
}
d = linebuf;
rem = w;
}
continue;
}
/* *d == NUL: old line ended, go to next old one */
free(MEMPTR(old_flines[src_idx]));
/* btw, convert cur_fline... */
if (cur_fline == src_idx) {
new_cur_fline = dst_idx;
}
src_idx++;
/* no more lines? finish last new line (and exit the loop) */
if (src_idx > max_fline) {
goto next_new;
}
s = old_flines[src_idx];
if (lineno != LINENO(s)) {
/* this is not a continuation line!
* create next _new_ line too */
goto next_new;
}
}
free(old_flines);
flines = (const char **)new_flines;
max_fline = dst_idx - 1;
linepos = 0; // XXX
cur_fline = new_cur_fline;
/* max_lineno is screen-size independent */
}
#endif
#if ENABLE_FEATURE_LESS_REGEXP
static void fill_match_lines(unsigned pos);
#else
@ -502,7 +588,7 @@ static void lineno_str(char *nbuf9, const char *line)
}
/* Width of 7 preserves tab spacing in the text */
fmt = "%7u ";
n = LINENO(line);
n = LINENO(line) + 1;
if (n > 9999999) {
n %= 10000000;
fmt = "%07u ";
@ -633,6 +719,35 @@ static void buffer_print(void)
status_print();
}
#if ENABLE_FEATURE_LESS_REWRAP
static void buffer_fill_and_print(void)
{
unsigned i = 0;
int fpos = cur_fline + i;
if (option_mask32 & LESS_STATE_NO_WRAP) {
/* Go back to the beginning of this line */
while (fpos && LINENO(flines[fpos]) == LINENO(flines[fpos-1]))
fpos--;
}
while (i <= max_displayed_line && fpos <= max_fline) {
int lineno = LINENO(flines[fpos]);
buffer[i] = flines[fpos];
i++;
do {
fpos++;
} while ((fpos <= max_fline)
&& (option_mask32 & LESS_STATE_NO_WRAP)
&& lineno == LINENO(flines[fpos])
);
}
for (; i <= max_displayed_line; i++) {
buffer[i] = empty_line_marker;
}
buffer_print();
}
#else
static void buffer_fill_and_print(void)
{
unsigned i;
@ -644,6 +759,7 @@ static void buffer_fill_and_print(void)
}
buffer_print();
}
#endif
/* Move the buffer up and down in the file in order to scroll */
static void buffer_down(int nlines)
@ -1371,6 +1487,25 @@ static void keypress_process(int keypress)
case ':':
colon_process();
break;
#if ENABLE_FEATURE_LESS_REWRAP
case '*':
option_mask32 ^= FLAG_N;
get_terminal_width_height(kbd_fd, &width, &max_displayed_line);
if (width < 20) /* 20: two tabstops + 4 */
width = 20;
if (max_displayed_line < 3)
max_displayed_line = 3;
max_displayed_line -= 2;
free(buffer);
buffer = xmalloc((max_displayed_line+1) * sizeof(char *));
re_wrap();
buffer_fill_and_print();
break;
case '&':
option_mask32 ^= LESS_STATE_NO_WRAP;
buffer_fill_and_print();
break;
#endif
}
if (isdigit(keypress))