xref: /freebsd/contrib/less/input.c (revision 95270f73baf6fa95ae529bc2eb6a61f5c79f32c0)
1a5f0fb15SPaul Saab /*
2*95270f73SXin LI  * Copyright (C) 1984-2022  Mark Nudelman
3a5f0fb15SPaul Saab  *
4a5f0fb15SPaul Saab  * You may distribute under the terms of either the GNU General Public
5a5f0fb15SPaul Saab  * License or the Less License, as specified in the README file.
6a5f0fb15SPaul Saab  *
796e55cc7SXin LI  * For more information, see the README file.
8a5f0fb15SPaul Saab  */
9a5f0fb15SPaul Saab 
10a5f0fb15SPaul Saab /*
11a5f0fb15SPaul Saab  * High level routines dealing with getting lines of input
12a5f0fb15SPaul Saab  * from the file being viewed.
13a5f0fb15SPaul Saab  *
14a5f0fb15SPaul Saab  * When we speak of "lines" here, we mean PRINTABLE lines;
15a5f0fb15SPaul Saab  * lines processed with respect to the screen width.
16a5f0fb15SPaul Saab  * We use the term "raw line" to refer to lines simply
17a5f0fb15SPaul Saab  * delimited by newlines; not processed with respect to screen width.
18a5f0fb15SPaul Saab  */
19a5f0fb15SPaul Saab 
20a5f0fb15SPaul Saab #include "less.h"
21a5f0fb15SPaul Saab 
22a5f0fb15SPaul Saab extern int squeeze;
238ed69c6fSPaul Saab extern int hshift;
24a5f0fb15SPaul Saab extern int quit_if_one_screen;
25a5f0fb15SPaul Saab extern int sigs;
26a5f0fb15SPaul Saab extern int ignore_eoi;
276dcb072bSXin LI extern int status_col;
28a5f0fb15SPaul Saab extern POSITION start_attnpos;
29a5f0fb15SPaul Saab extern POSITION end_attnpos;
30a5f0fb15SPaul Saab #if HILITE_SEARCH
31a5f0fb15SPaul Saab extern int hilite_search;
32a5f0fb15SPaul Saab extern int size_linebuf;
332235c7feSXin LI extern int show_attn;
34a5f0fb15SPaul Saab #endif
35a5f0fb15SPaul Saab 
36a5f0fb15SPaul Saab /*
37a5f0fb15SPaul Saab  * Get the next line.
38a5f0fb15SPaul Saab  * A "current" position is passed and a "new" position is returned.
39a5f0fb15SPaul Saab  * The current position is the position of the first character of
40a5f0fb15SPaul Saab  * a line.  The new position is the position of the first character
41a5f0fb15SPaul Saab  * of the NEXT line.  The line obtained is the line starting at curr_pos.
42a5f0fb15SPaul Saab  */
43a5f0fb15SPaul Saab 	public POSITION
44*95270f73SXin LI forw_line_seg(curr_pos, skipeol, rscroll, nochop)
45f6b74a7dSXin LI 	POSITION curr_pos;
46*95270f73SXin LI 	int skipeol;
47*95270f73SXin LI 	int rscroll;
48*95270f73SXin LI 	int nochop;
49a5f0fb15SPaul Saab {
506dcb072bSXin LI 	POSITION base_pos;
51a5f0fb15SPaul Saab 	POSITION new_pos;
521ea31627SRobert Watson 	int c;
53a5f0fb15SPaul Saab 	int blankline;
54a5f0fb15SPaul Saab 	int endline;
55b2ea2440SXin LI 	int chopped;
566dcb072bSXin LI 	int backchars;
57a5f0fb15SPaul Saab 
587374caaaSXin LI get_forw_line:
59a5f0fb15SPaul Saab 	if (curr_pos == NULL_POSITION)
60a5f0fb15SPaul Saab 	{
61a5f0fb15SPaul Saab 		null_line();
62a5f0fb15SPaul Saab 		return (NULL_POSITION);
63a5f0fb15SPaul Saab 	}
64a5f0fb15SPaul Saab #if HILITE_SEARCH
657374caaaSXin LI 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
66a15691bfSXin LI 	{
67a5f0fb15SPaul Saab 		/*
68a5f0fb15SPaul Saab 		 * If we are ignoring EOI (command F), only prepare
69a5f0fb15SPaul Saab 		 * one line ahead, to avoid getting stuck waiting for
70a5f0fb15SPaul Saab 		 * slow data without displaying the data we already have.
71a5f0fb15SPaul Saab 		 * If we're not ignoring EOI, we *could* do the same, but
72a5f0fb15SPaul Saab 		 * for efficiency we prepare several lines ahead at once.
73a5f0fb15SPaul Saab 		 */
74a5f0fb15SPaul Saab 		prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
75a5f0fb15SPaul Saab 				ignore_eoi ? 1 : -1);
76a15691bfSXin LI 		curr_pos = next_unfiltered(curr_pos);
77a15691bfSXin LI 	}
78a5f0fb15SPaul Saab #endif
79a5f0fb15SPaul Saab 	if (ch_seek(curr_pos))
80a5f0fb15SPaul Saab 	{
81a5f0fb15SPaul Saab 		null_line();
82a5f0fb15SPaul Saab 		return (NULL_POSITION);
83a5f0fb15SPaul Saab 	}
84a5f0fb15SPaul Saab 
857374caaaSXin LI 	/*
867374caaaSXin LI 	 * Step back to the beginning of the line.
877374caaaSXin LI 	 */
886dcb072bSXin LI 	base_pos = curr_pos;
896dcb072bSXin LI 	for (;;)
906dcb072bSXin LI 	{
916dcb072bSXin LI 		if (ABORT_SIGS())
926dcb072bSXin LI 		{
936dcb072bSXin LI 			null_line();
946dcb072bSXin LI 			return (NULL_POSITION);
956dcb072bSXin LI 		}
966dcb072bSXin LI 		c = ch_back_get();
976dcb072bSXin LI 		if (c == EOI)
986dcb072bSXin LI 			break;
996dcb072bSXin LI 		if (c == '\n')
1006dcb072bSXin LI 		{
1016dcb072bSXin LI 			(void) ch_forw_get();
1026dcb072bSXin LI 			break;
1036dcb072bSXin LI 		}
1046dcb072bSXin LI 		--base_pos;
1056dcb072bSXin LI 	}
1066dcb072bSXin LI 
1077374caaaSXin LI 	/*
1087374caaaSXin LI 	 * Read forward again to the position we should start at.
1097374caaaSXin LI 	 */
110a5f0fb15SPaul Saab 	prewind();
1112235c7feSXin LI 	plinestart(base_pos);
1126dcb072bSXin LI 	(void) ch_seek(base_pos);
1137374caaaSXin LI 	new_pos = base_pos;
1147374caaaSXin LI 	while (new_pos < curr_pos)
1156dcb072bSXin LI 	{
1166dcb072bSXin LI 		if (ABORT_SIGS())
1176dcb072bSXin LI 		{
1186dcb072bSXin LI 			null_line();
1196dcb072bSXin LI 			return (NULL_POSITION);
1206dcb072bSXin LI 		}
1216dcb072bSXin LI 		c = ch_forw_get();
1227374caaaSXin LI 		backchars = pappend(c, new_pos);
1237374caaaSXin LI 		new_pos++;
1246dcb072bSXin LI 		if (backchars > 0)
1256dcb072bSXin LI 		{
1266dcb072bSXin LI 			pshift_all();
1277374caaaSXin LI 			new_pos -= backchars;
1286dcb072bSXin LI 			while (--backchars >= 0)
1296dcb072bSXin LI 				(void) ch_back_get();
1306dcb072bSXin LI 		}
1316dcb072bSXin LI 	}
1326dcb072bSXin LI 	(void) pflushmbc();
1336dcb072bSXin LI 	pshift_all();
134a5f0fb15SPaul Saab 
1357374caaaSXin LI 	/*
1367374caaaSXin LI 	 * Read the first character to display.
1377374caaaSXin LI 	 */
138a5f0fb15SPaul Saab 	c = ch_forw_get();
139a5f0fb15SPaul Saab 	if (c == EOI)
140a5f0fb15SPaul Saab 	{
141a5f0fb15SPaul Saab 		null_line();
142a5f0fb15SPaul Saab 		return (NULL_POSITION);
143a5f0fb15SPaul Saab 	}
144a5f0fb15SPaul Saab 	blankline = (c == '\n' || c == '\r');
145a5f0fb15SPaul Saab 
1467374caaaSXin LI 	/*
1477374caaaSXin LI 	 * Read each character in the line and append to the line buffer.
1487374caaaSXin LI 	 */
149b2ea2440SXin LI 	chopped = FALSE;
150a5f0fb15SPaul Saab 	for (;;)
151a5f0fb15SPaul Saab 	{
152a5f0fb15SPaul Saab 		if (ABORT_SIGS())
153a5f0fb15SPaul Saab 		{
154a5f0fb15SPaul Saab 			null_line();
155a5f0fb15SPaul Saab 			return (NULL_POSITION);
156a5f0fb15SPaul Saab 		}
157a5f0fb15SPaul Saab 		if (c == '\n' || c == EOI)
158a5f0fb15SPaul Saab 		{
159a5f0fb15SPaul Saab 			/*
160a5f0fb15SPaul Saab 			 * End of the line.
161a5f0fb15SPaul Saab 			 */
1626dcb072bSXin LI 			backchars = pflushmbc();
163a5f0fb15SPaul Saab 			new_pos = ch_tell();
164*95270f73SXin LI 			if (backchars > 0 && (nochop || !chop_line()) && hshift == 0)
1656dcb072bSXin LI 			{
1666dcb072bSXin LI 				new_pos -= backchars + 1;
1676dcb072bSXin LI 				endline = FALSE;
1686dcb072bSXin LI 			} else
169a5f0fb15SPaul Saab 				endline = TRUE;
170a5f0fb15SPaul Saab 			break;
171a5f0fb15SPaul Saab 		}
1726dcb072bSXin LI 		if (c != '\r')
1736dcb072bSXin LI 			blankline = 0;
174a5f0fb15SPaul Saab 
175a5f0fb15SPaul Saab 		/*
176a5f0fb15SPaul Saab 		 * Append the char to the line and get the next char.
177a5f0fb15SPaul Saab 		 */
1786dcb072bSXin LI 		backchars = pappend(c, ch_tell()-1);
1796dcb072bSXin LI 		if (backchars > 0)
180a5f0fb15SPaul Saab 		{
181a5f0fb15SPaul Saab 			/*
182a5f0fb15SPaul Saab 			 * The char won't fit in the line; the line
183a5f0fb15SPaul Saab 			 * is too long to print in the screen width.
184a5f0fb15SPaul Saab 			 * End the line here.
185a5f0fb15SPaul Saab 			 */
186*95270f73SXin LI 			if (skipeol)
187a5f0fb15SPaul Saab 			{
1882235c7feSXin LI 				/* Read to end of line. */
189a5f0fb15SPaul Saab 				do
190a5f0fb15SPaul Saab 				{
19133096f16SXin LI 					if (ABORT_SIGS())
19233096f16SXin LI 					{
19333096f16SXin LI 						null_line();
19433096f16SXin LI 						return (NULL_POSITION);
19533096f16SXin LI 					}
196a5f0fb15SPaul Saab 					c = ch_forw_get();
197a5f0fb15SPaul Saab 				} while (c != '\n' && c != EOI);
198a5f0fb15SPaul Saab 				new_pos = ch_tell();
199a5f0fb15SPaul Saab 				endline = TRUE;
200a5f0fb15SPaul Saab 				quit_if_one_screen = FALSE;
201b2ea2440SXin LI 				chopped = TRUE;
202a5f0fb15SPaul Saab 			} else
203a5f0fb15SPaul Saab 			{
2046dcb072bSXin LI 				new_pos = ch_tell() - backchars;
205a5f0fb15SPaul Saab 				endline = FALSE;
206a5f0fb15SPaul Saab 			}
207a5f0fb15SPaul Saab 			break;
208a5f0fb15SPaul Saab 		}
209a5f0fb15SPaul Saab 		c = ch_forw_get();
210a5f0fb15SPaul Saab 	}
2117374caaaSXin LI 
2122235c7feSXin LI #if HILITE_SEARCH
2132235c7feSXin LI 	if (blankline && show_attn)
2142235c7feSXin LI 	{
2152235c7feSXin LI 		/* Add spurious space to carry possible attn hilite. */
2162235c7feSXin LI 		pappend(' ', ch_tell()-1);
2172235c7feSXin LI 	}
2182235c7feSXin LI #endif
219*95270f73SXin LI 	pdone(endline, rscroll && chopped, 1);
2207374caaaSXin LI 
2217374caaaSXin LI #if HILITE_SEARCH
2227374caaaSXin LI 	if (is_filtered(base_pos))
2237374caaaSXin LI 	{
2247374caaaSXin LI 		/*
2257374caaaSXin LI 		 * We don't want to display this line.
2267374caaaSXin LI 		 * Get the next line.
2277374caaaSXin LI 		 */
2287374caaaSXin LI 		curr_pos = new_pos;
2297374caaaSXin LI 		goto get_forw_line;
2307374caaaSXin LI 	}
2317374caaaSXin LI 
2322235c7feSXin LI 	if (status_col)
2332235c7feSXin LI 	{
2342235c7feSXin LI 		int attr = is_hilited_attr(base_pos, ch_tell()-1, 1, NULL);
2352235c7feSXin LI 		if (attr)
2362235c7feSXin LI 			set_status_col('*', attr);
2372235c7feSXin LI 	}
2387374caaaSXin LI #endif
239a5f0fb15SPaul Saab 
240a5f0fb15SPaul Saab 	if (squeeze && blankline)
241a5f0fb15SPaul Saab 	{
242a5f0fb15SPaul Saab 		/*
243a5f0fb15SPaul Saab 		 * This line is blank.
244a5f0fb15SPaul Saab 		 * Skip down to the last contiguous blank line
245a5f0fb15SPaul Saab 		 * and pretend it is the one which we are returning.
246a5f0fb15SPaul Saab 		 */
247a5f0fb15SPaul Saab 		while ((c = ch_forw_get()) == '\n' || c == '\r')
248a5f0fb15SPaul Saab 			if (ABORT_SIGS())
249a5f0fb15SPaul Saab 			{
250a5f0fb15SPaul Saab 				null_line();
251a5f0fb15SPaul Saab 				return (NULL_POSITION);
252a5f0fb15SPaul Saab 			}
253a5f0fb15SPaul Saab 		if (c != EOI)
254a5f0fb15SPaul Saab 			(void) ch_back_get();
255a5f0fb15SPaul Saab 		new_pos = ch_tell();
256a5f0fb15SPaul Saab 	}
257a5f0fb15SPaul Saab 
258a5f0fb15SPaul Saab 	return (new_pos);
259a5f0fb15SPaul Saab }
260a5f0fb15SPaul Saab 
2612235c7feSXin LI 	public POSITION
2622235c7feSXin LI forw_line(curr_pos)
2632235c7feSXin LI 	POSITION curr_pos;
2642235c7feSXin LI {
265*95270f73SXin LI 
266*95270f73SXin LI 	return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE);
2672235c7feSXin LI }
2682235c7feSXin LI 
269a5f0fb15SPaul Saab /*
270a5f0fb15SPaul Saab  * Get the previous line.
271a5f0fb15SPaul Saab  * A "current" position is passed and a "new" position is returned.
272a5f0fb15SPaul Saab  * The current position is the position of the first character of
273a5f0fb15SPaul Saab  * a line.  The new position is the position of the first character
274a5f0fb15SPaul Saab  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
275a5f0fb15SPaul Saab  */
276a5f0fb15SPaul Saab 	public POSITION
277f6b74a7dSXin LI back_line(curr_pos)
278f6b74a7dSXin LI 	POSITION curr_pos;
279a5f0fb15SPaul Saab {
2807374caaaSXin LI 	POSITION new_pos, begin_new_pos, base_pos;
281a5f0fb15SPaul Saab 	int c;
282a5f0fb15SPaul Saab 	int endline;
283b2ea2440SXin LI 	int chopped;
2846dcb072bSXin LI 	int backchars;
285a5f0fb15SPaul Saab 
2867374caaaSXin LI get_back_line:
287a5f0fb15SPaul Saab 	if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
288a5f0fb15SPaul Saab 	{
289a5f0fb15SPaul Saab 		null_line();
290a5f0fb15SPaul Saab 		return (NULL_POSITION);
291a5f0fb15SPaul Saab 	}
292a5f0fb15SPaul Saab #if HILITE_SEARCH
2937374caaaSXin LI 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
294a5f0fb15SPaul Saab 		prep_hilite((curr_pos < 3*size_linebuf) ?
295a5f0fb15SPaul Saab 				0 : curr_pos - 3*size_linebuf, curr_pos, -1);
296a5f0fb15SPaul Saab #endif
297a5f0fb15SPaul Saab 	if (ch_seek(curr_pos-1))
298a5f0fb15SPaul Saab 	{
299a5f0fb15SPaul Saab 		null_line();
300a5f0fb15SPaul Saab 		return (NULL_POSITION);
301a5f0fb15SPaul Saab 	}
302a5f0fb15SPaul Saab 
303a5f0fb15SPaul Saab 	if (squeeze)
304a5f0fb15SPaul Saab 	{
305a5f0fb15SPaul Saab 		/*
306a5f0fb15SPaul Saab 		 * Find out if the "current" line was blank.
307a5f0fb15SPaul Saab 		 */
308a5f0fb15SPaul Saab 		(void) ch_forw_get();    /* Skip the newline */
309a5f0fb15SPaul Saab 		c = ch_forw_get();       /* First char of "current" line */
310a5f0fb15SPaul Saab 		(void) ch_back_get();    /* Restore our position */
311a5f0fb15SPaul Saab 		(void) ch_back_get();
312a5f0fb15SPaul Saab 
313a5f0fb15SPaul Saab 		if (c == '\n' || c == '\r')
314a5f0fb15SPaul Saab 		{
315a5f0fb15SPaul Saab 			/*
316a5f0fb15SPaul Saab 			 * The "current" line was blank.
317a5f0fb15SPaul Saab 			 * Skip over any preceding blank lines,
318a5f0fb15SPaul Saab 			 * since we skipped them in forw_line().
319a5f0fb15SPaul Saab 			 */
320a5f0fb15SPaul Saab 			while ((c = ch_back_get()) == '\n' || c == '\r')
321a5f0fb15SPaul Saab 				if (ABORT_SIGS())
322a5f0fb15SPaul Saab 				{
323a5f0fb15SPaul Saab 					null_line();
324a5f0fb15SPaul Saab 					return (NULL_POSITION);
325a5f0fb15SPaul Saab 				}
326a5f0fb15SPaul Saab 			if (c == EOI)
327a5f0fb15SPaul Saab 			{
328a5f0fb15SPaul Saab 				null_line();
329a5f0fb15SPaul Saab 				return (NULL_POSITION);
330a5f0fb15SPaul Saab 			}
331a5f0fb15SPaul Saab 			(void) ch_forw_get();
332a5f0fb15SPaul Saab 		}
333a5f0fb15SPaul Saab 	}
334a5f0fb15SPaul Saab 
335a5f0fb15SPaul Saab 	/*
336a5f0fb15SPaul Saab 	 * Scan backwards until we hit the beginning of the line.
337a5f0fb15SPaul Saab 	 */
338a5f0fb15SPaul Saab 	for (;;)
339a5f0fb15SPaul Saab 	{
340a5f0fb15SPaul Saab 		if (ABORT_SIGS())
341a5f0fb15SPaul Saab 		{
342a5f0fb15SPaul Saab 			null_line();
343a5f0fb15SPaul Saab 			return (NULL_POSITION);
344a5f0fb15SPaul Saab 		}
345a5f0fb15SPaul Saab 		c = ch_back_get();
346a5f0fb15SPaul Saab 		if (c == '\n')
347a5f0fb15SPaul Saab 		{
348a5f0fb15SPaul Saab 			/*
349a5f0fb15SPaul Saab 			 * This is the newline ending the previous line.
350a5f0fb15SPaul Saab 			 * We have hit the beginning of the line.
351a5f0fb15SPaul Saab 			 */
3527374caaaSXin LI 			base_pos = ch_tell() + 1;
353a5f0fb15SPaul Saab 			break;
354a5f0fb15SPaul Saab 		}
355a5f0fb15SPaul Saab 		if (c == EOI)
356a5f0fb15SPaul Saab 		{
357a5f0fb15SPaul Saab 			/*
358a5f0fb15SPaul Saab 			 * We have hit the beginning of the file.
359a5f0fb15SPaul Saab 			 * This must be the first line in the file.
360a5f0fb15SPaul Saab 			 * This must, of course, be the beginning of the line.
361a5f0fb15SPaul Saab 			 */
3627374caaaSXin LI 			base_pos = ch_tell();
363a5f0fb15SPaul Saab 			break;
364a5f0fb15SPaul Saab 		}
365a5f0fb15SPaul Saab 	}
366a5f0fb15SPaul Saab 
367a5f0fb15SPaul Saab 	/*
368a5f0fb15SPaul Saab 	 * Now scan forwards from the beginning of this line.
369a5f0fb15SPaul Saab 	 * We keep discarding "printable lines" (based on screen width)
370a5f0fb15SPaul Saab 	 * until we reach the curr_pos.
371a5f0fb15SPaul Saab 	 *
372a5f0fb15SPaul Saab 	 * {{ This algorithm is pretty inefficient if the lines
373a5f0fb15SPaul Saab 	 *    are much longer than the screen width,
374a5f0fb15SPaul Saab 	 *    but I don't know of any better way. }}
375a5f0fb15SPaul Saab 	 */
3767374caaaSXin LI 	new_pos = base_pos;
377a5f0fb15SPaul Saab 	if (ch_seek(new_pos))
378a5f0fb15SPaul Saab 	{
379a5f0fb15SPaul Saab 		null_line();
380a5f0fb15SPaul Saab 		return (NULL_POSITION);
381a5f0fb15SPaul Saab 	}
382a5f0fb15SPaul Saab 	endline = FALSE;
383a5f0fb15SPaul Saab 	prewind();
3842235c7feSXin LI 	plinestart(new_pos);
3856dcb072bSXin LI     loop:
3866dcb072bSXin LI 	begin_new_pos = new_pos;
387a5f0fb15SPaul Saab 	(void) ch_seek(new_pos);
388b2ea2440SXin LI 	chopped = FALSE;
389a5f0fb15SPaul Saab 
390a5f0fb15SPaul Saab 	do
391a5f0fb15SPaul Saab 	{
392a5f0fb15SPaul Saab 		c = ch_forw_get();
393a5f0fb15SPaul Saab 		if (c == EOI || ABORT_SIGS())
394a5f0fb15SPaul Saab 		{
395a5f0fb15SPaul Saab 			null_line();
396a5f0fb15SPaul Saab 			return (NULL_POSITION);
397a5f0fb15SPaul Saab 		}
398a5f0fb15SPaul Saab 		new_pos++;
399a5f0fb15SPaul Saab 		if (c == '\n')
400a5f0fb15SPaul Saab 		{
4016dcb072bSXin LI 			backchars = pflushmbc();
402*95270f73SXin LI 			if (backchars > 0 && !chop_line() && hshift == 0)
4036dcb072bSXin LI 			{
4046dcb072bSXin LI 				backchars++;
4056dcb072bSXin LI 				goto shift;
4066dcb072bSXin LI 			}
407a5f0fb15SPaul Saab 			endline = TRUE;
408a5f0fb15SPaul Saab 			break;
409a5f0fb15SPaul Saab 		}
4106dcb072bSXin LI 		backchars = pappend(c, ch_tell()-1);
4116dcb072bSXin LI 		if (backchars > 0)
412a5f0fb15SPaul Saab 		{
413a5f0fb15SPaul Saab 			/*
414a5f0fb15SPaul Saab 			 * Got a full printable line, but we haven't
415a5f0fb15SPaul Saab 			 * reached our curr_pos yet.  Discard the line
416a5f0fb15SPaul Saab 			 * and start a new one.
417a5f0fb15SPaul Saab 			 */
418*95270f73SXin LI 			if (chop_line() || hshift > 0)
419a5f0fb15SPaul Saab 			{
420a5f0fb15SPaul Saab 				endline = TRUE;
421b2ea2440SXin LI 				chopped = TRUE;
422a5f0fb15SPaul Saab 				quit_if_one_screen = FALSE;
423a5f0fb15SPaul Saab 				break;
424a5f0fb15SPaul Saab 			}
4256dcb072bSXin LI 		shift:
4266dcb072bSXin LI 			pshift_all();
4276dcb072bSXin LI 			while (backchars-- > 0)
4286dcb072bSXin LI 			{
429a5f0fb15SPaul Saab 				(void) ch_back_get();
430a5f0fb15SPaul Saab 				new_pos--;
4316dcb072bSXin LI 			}
432a5f0fb15SPaul Saab 			goto loop;
433a5f0fb15SPaul Saab 		}
434a5f0fb15SPaul Saab 	} while (new_pos < curr_pos);
435a5f0fb15SPaul Saab 
436b2ea2440SXin LI 	pdone(endline, chopped, 0);
4377374caaaSXin LI 
4387374caaaSXin LI #if HILITE_SEARCH
4397374caaaSXin LI 	if (is_filtered(base_pos))
4407374caaaSXin LI 	{
4417374caaaSXin LI 		/*
4427374caaaSXin LI 		 * We don't want to display this line.
4437374caaaSXin LI 		 * Get the previous line.
4447374caaaSXin LI 		 */
4457374caaaSXin LI 		curr_pos = begin_new_pos;
4467374caaaSXin LI 		goto get_back_line;
4477374caaaSXin LI 	}
4487374caaaSXin LI 
4492235c7feSXin LI 	if (status_col && curr_pos > 0)
4502235c7feSXin LI 	{
4512235c7feSXin LI 		int attr = is_hilited_attr(base_pos, curr_pos-1, 1, NULL);
4522235c7feSXin LI 		if (attr)
4532235c7feSXin LI 			set_status_col('*', attr);
4542235c7feSXin LI 	}
4557374caaaSXin LI #endif
456a5f0fb15SPaul Saab 
457a5f0fb15SPaul Saab 	return (begin_new_pos);
458a5f0fb15SPaul Saab }
459a5f0fb15SPaul Saab 
460a5f0fb15SPaul Saab /*
461a5f0fb15SPaul Saab  * Set attnpos.
462a5f0fb15SPaul Saab  */
463a5f0fb15SPaul Saab 	public void
464f6b74a7dSXin LI set_attnpos(pos)
465f6b74a7dSXin LI 	POSITION pos;
466a5f0fb15SPaul Saab {
467a5f0fb15SPaul Saab 	int c;
468a5f0fb15SPaul Saab 
469a5f0fb15SPaul Saab 	if (pos != NULL_POSITION)
470a5f0fb15SPaul Saab 	{
471a5f0fb15SPaul Saab 		if (ch_seek(pos))
472a5f0fb15SPaul Saab 			return;
473a5f0fb15SPaul Saab 		for (;;)
474a5f0fb15SPaul Saab 		{
475a5f0fb15SPaul Saab 			c = ch_forw_get();
476a5f0fb15SPaul Saab 			if (c == EOI)
477a5f0fb15SPaul Saab 				break;
478a15691bfSXin LI 			if (c == '\n' || c == '\r')
479a15691bfSXin LI 			{
480a15691bfSXin LI 				(void) ch_back_get();
481a15691bfSXin LI 				break;
482a15691bfSXin LI 			}
483a5f0fb15SPaul Saab 			pos++;
484a5f0fb15SPaul Saab 		}
485a15691bfSXin LI 		end_attnpos = pos;
486a15691bfSXin LI 		for (;;)
487a15691bfSXin LI 		{
488a15691bfSXin LI 			c = ch_back_get();
489a15691bfSXin LI 			if (c == EOI || c == '\n' || c == '\r')
490a15691bfSXin LI 				break;
491a15691bfSXin LI 			pos--;
492a15691bfSXin LI 		}
493a5f0fb15SPaul Saab 	}
494a5f0fb15SPaul Saab 	start_attnpos = pos;
495a5f0fb15SPaul Saab }
496