less: experimental code to enable wrap/no-wrap
and adapting to resized xterm windows. disabled for now.
This commit is contained in:
parent
8f39b72aba
commit
d908395eae
137
miscutils/less.c
137
miscutils/less.c
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user