Skip to content

Commit

Permalink
Create pos_rehead to fix bugs when we go into chopline mode
Browse files Browse the repository at this point in the history
with a "beheaded" position table
(that is, when position(TOP) is not the first char in its line).
  • Loading branch information
gwsw committed Sep 12, 2023
1 parent 8ec8396 commit f548d98
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 8 deletions.
10 changes: 6 additions & 4 deletions command.c
Original file line number Diff line number Diff line change
Expand Up @@ -2043,10 +2043,10 @@ public void commands(void)
if (number > 0)
shift_count = number;
else
number = (shift_count > 0) ?
shift_count : sc_width / 2;
number = (shift_count > 0) ? shift_count : sc_width / 2;
if (number > hshift)
number = hshift;
pos_rehead();
hshift -= number;
screen_trashed = 1;
break;
Expand All @@ -2058,8 +2058,8 @@ public void commands(void)
if (number > 0)
shift_count = number;
else
number = (shift_count > 0) ?
shift_count : sc_width / 2;
number = (shift_count > 0) ? shift_count : sc_width / 2;
pos_rehead();
hshift += number;
screen_trashed = 1;
break;
Expand All @@ -2068,6 +2068,7 @@ public void commands(void)
/*
* Shift view left to margin.
*/
pos_rehead();
hshift = 0;
screen_trashed = 1;
break;
Expand All @@ -2076,6 +2077,7 @@ public void commands(void)
/*
* Shift view right to view rightmost char on screen.
*/
pos_rehead();
hshift = rrshift();
screen_trashed = 1;
break;
Expand Down
12 changes: 11 additions & 1 deletion line.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,7 +1329,7 @@ public void null_line(void)
* lines which are not split for screen width.
* {{ This is supposed to be more efficient than forw_line(). }}
*/
public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
public POSITION forw_raw_line_len(POSITION curr_pos, int read_len, char **linep, int *line_lenp)
{
int n;
int c;
Expand Down Expand Up @@ -1360,6 +1360,11 @@ public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
}
}
linebuf.buf[n++] = c;
if (read_len >= 0 && n >= read_len)
{
new_pos = ch_tell();
break;
}
c = ch_forw_get();
}
linebuf.buf[n] = '\0';
Expand All @@ -1370,6 +1375,11 @@ public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
return (new_pos);
}

public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
{
return forw_raw_line_len(curr_pos, -1, linep, line_lenp);
}

/*
* Analogous to back_line(), but deals with "raw lines".
* {{ This is supposed to be more efficient than back_line(). }}
Expand Down
13 changes: 13 additions & 0 deletions optfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,19 @@ public void opt_ks(int type, char *s)
#endif /* HAVE_LESSKEYSRC */
#endif /* USERFILE */

/*
* Handler for -S option.
*/
public void opt__S(int type, char *s)
{
switch (type)
{
case TOGGLE:
pos_rehead();
break;
}
}

#if TAGS
/*
* Handler for -t option.
Expand Down
2 changes: 1 addition & 1 deletion opttbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ static struct loption option[] =
}
},
{ 'S', &S__optname,
BOOL|REPAINT, OPT_OFF, &chopline, NULL,
BOOL|REPAINT, OPT_OFF, &chopline, opt__S,
{
"Fold long lines",
"Chop long lines",
Expand Down
73 changes: 73 additions & 0 deletions position.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ static int table_size = 0;

extern int sc_width, sc_height;
extern int header_lines;
extern int screen_trashed;
extern int hshift;
extern int chopline;

/*
* Return the starting file position of a line displayed on the screen.
Expand Down Expand Up @@ -236,3 +239,73 @@ public int sindex_from_sline(int sline)
*/
return (sline-1);
}

/*
* Given a line that starts at linepos,
* and the character at byte offset choff into that line,
* return the number of characters (not bytes) between the
* beginning of the line and the first byte of the choff character.
*/
static int pos_shift(POSITION linepos, int choff)
{
char *line;
int line_len;
POSITION pos;
int cvt_ops;
int cvt_len;
int *chpos;
char *cline;

pos = forw_raw_line_len(linepos, choff, &line, &line_len);
if (pos == NULL_POSITION || line_len != choff)
return -1;
cvt_ops = get_cvt_ops(0);
cvt_len = cvt_length(line_len, cvt_ops);
chpos = cvt_alloc_chpos(cvt_len);
cline = (char *) ecalloc(1, line_len);
cvt_text(cline, line, chpos, &line_len, cvt_ops);
free(cline);
free(chpos);
return line_len;
}

/*
* Return the position of the first char of the line containing tpos.
* Thus if tpos is the first char of its line, just return tpos.
*/
static POSITION beginning_of_line(POSITION tpos)
{
ch_seek(tpos);
while (ch_tell() != ch_zero())
{
int ch = ch_back_get();
if (ch == '\n')
{
(void) ch_forw_get();
break;
}
}
return ch_tell();
}

/*
* When viewing long lines, it may be that the first char in the top screen
* line is not the first char in its (file) line (the table is "beheaded").
* (The top line on the screen is the only one that can be in this state.)
* This function sets that entry to the position of the first char in the line.
*/
public void pos_rehead(void)
{
POSITION linepos;
POSITION tpos = table[TOP];
if (!chopline)
return;
if (tpos == NULL_POSITION)
return;
linepos = beginning_of_line(tpos);
if (linepos == tpos)
return;
table[TOP] = linepos;
hshift = pos_shift(linepos, tpos - linepos);
screen_trashed = 1;
}
4 changes: 2 additions & 2 deletions search.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void init_search(void)
/*
* Determine which text conversions to perform before pattern matching.
*/
static int get_cvt_ops(int search_type)
public int get_cvt_ops(int search_type)
{
int ops = 0;

Expand Down Expand Up @@ -580,7 +580,7 @@ static void shift_visible(int start_off, int end_off)
int swidth = sc_width - line_pfx_width();
if (start_off >= hshift && end_off < hshift + swidth)
return; /* already visible */
hshift = (end_off < swidth) ? 0 : start_off < found_shift ? 0 : start_off - found_shift;
hshift = (end_off < swidth) ? 0 : (start_off < found_shift) ? 0 : (start_off - found_shift);
screen_trashed = 1;
}

Expand Down

0 comments on commit f548d98

Please sign in to comment.