xref: /freebsd/contrib/less/input.c (revision b2ea244070ff84eab79e04befb7aa30c982fc84d)
1a5f0fb15SPaul Saab /*
2f6b74a7dSXin LI  * Copyright (C) 1984-2017  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;
23a5f0fb15SPaul Saab extern int chopline;
248ed69c6fSPaul Saab extern int hshift;
25a5f0fb15SPaul Saab extern int quit_if_one_screen;
26a5f0fb15SPaul Saab extern int sigs;
27a5f0fb15SPaul Saab extern int ignore_eoi;
286dcb072bSXin LI extern int status_col;
29a5f0fb15SPaul Saab extern POSITION start_attnpos;
30a5f0fb15SPaul Saab extern POSITION end_attnpos;
31a5f0fb15SPaul Saab #if HILITE_SEARCH
32a5f0fb15SPaul Saab extern int hilite_search;
33a5f0fb15SPaul Saab extern int size_linebuf;
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
44f6b74a7dSXin LI forw_line(curr_pos)
45f6b74a7dSXin LI 	POSITION curr_pos;
46a5f0fb15SPaul Saab {
476dcb072bSXin LI 	POSITION base_pos;
48a5f0fb15SPaul Saab 	POSITION new_pos;
491ea31627SRobert Watson 	int c;
50a5f0fb15SPaul Saab 	int blankline;
51a5f0fb15SPaul Saab 	int endline;
52*b2ea2440SXin LI 	int chopped;
536dcb072bSXin LI 	int backchars;
54a5f0fb15SPaul Saab 
557374caaaSXin LI get_forw_line:
56a5f0fb15SPaul Saab 	if (curr_pos == NULL_POSITION)
57a5f0fb15SPaul Saab 	{
58a5f0fb15SPaul Saab 		null_line();
59a5f0fb15SPaul Saab 		return (NULL_POSITION);
60a5f0fb15SPaul Saab 	}
61a5f0fb15SPaul Saab #if HILITE_SEARCH
627374caaaSXin LI 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
63a15691bfSXin LI 	{
64a5f0fb15SPaul Saab 		/*
65a5f0fb15SPaul Saab 		 * If we are ignoring EOI (command F), only prepare
66a5f0fb15SPaul Saab 		 * one line ahead, to avoid getting stuck waiting for
67a5f0fb15SPaul Saab 		 * slow data without displaying the data we already have.
68a5f0fb15SPaul Saab 		 * If we're not ignoring EOI, we *could* do the same, but
69a5f0fb15SPaul Saab 		 * for efficiency we prepare several lines ahead at once.
70a5f0fb15SPaul Saab 		 */
71a5f0fb15SPaul Saab 		prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
72a5f0fb15SPaul Saab 				ignore_eoi ? 1 : -1);
73a15691bfSXin LI 		curr_pos = next_unfiltered(curr_pos);
74a15691bfSXin LI 	}
75a5f0fb15SPaul Saab #endif
76a5f0fb15SPaul Saab 	if (ch_seek(curr_pos))
77a5f0fb15SPaul Saab 	{
78a5f0fb15SPaul Saab 		null_line();
79a5f0fb15SPaul Saab 		return (NULL_POSITION);
80a5f0fb15SPaul Saab 	}
81a5f0fb15SPaul Saab 
827374caaaSXin LI 	/*
837374caaaSXin LI 	 * Step back to the beginning of the line.
847374caaaSXin LI 	 */
856dcb072bSXin LI 	base_pos = curr_pos;
866dcb072bSXin LI 	for (;;)
876dcb072bSXin LI 	{
886dcb072bSXin LI 		if (ABORT_SIGS())
896dcb072bSXin LI 		{
906dcb072bSXin LI 			null_line();
916dcb072bSXin LI 			return (NULL_POSITION);
926dcb072bSXin LI 		}
936dcb072bSXin LI 		c = ch_back_get();
946dcb072bSXin LI 		if (c == EOI)
956dcb072bSXin LI 			break;
966dcb072bSXin LI 		if (c == '\n')
976dcb072bSXin LI 		{
986dcb072bSXin LI 			(void) ch_forw_get();
996dcb072bSXin LI 			break;
1006dcb072bSXin LI 		}
1016dcb072bSXin LI 		--base_pos;
1026dcb072bSXin LI 	}
1036dcb072bSXin LI 
1047374caaaSXin LI 	/*
1057374caaaSXin LI 	 * Read forward again to the position we should start at.
1067374caaaSXin LI 	 */
107a5f0fb15SPaul Saab  	prewind();
1086dcb072bSXin LI 	plinenum(base_pos);
1096dcb072bSXin LI 	(void) ch_seek(base_pos);
1107374caaaSXin LI 	new_pos = base_pos;
1117374caaaSXin LI 	while (new_pos < curr_pos)
1126dcb072bSXin LI 	{
1136dcb072bSXin LI 		if (ABORT_SIGS())
1146dcb072bSXin LI 		{
1156dcb072bSXin LI 			null_line();
1166dcb072bSXin LI 			return (NULL_POSITION);
1176dcb072bSXin LI 		}
1186dcb072bSXin LI 		c = ch_forw_get();
1197374caaaSXin LI 		backchars = pappend(c, new_pos);
1207374caaaSXin LI 		new_pos++;
1216dcb072bSXin LI 		if (backchars > 0)
1226dcb072bSXin LI 		{
1236dcb072bSXin LI 			pshift_all();
1247374caaaSXin LI 			new_pos -= backchars;
1256dcb072bSXin LI 			while (--backchars >= 0)
1266dcb072bSXin LI 				(void) ch_back_get();
1276dcb072bSXin LI 		}
1286dcb072bSXin LI 	}
1296dcb072bSXin LI 	(void) pflushmbc();
1306dcb072bSXin LI 	pshift_all();
131a5f0fb15SPaul Saab 
1327374caaaSXin LI 	/*
1337374caaaSXin LI 	 * Read the first character to display.
1347374caaaSXin LI 	 */
135a5f0fb15SPaul Saab 	c = ch_forw_get();
136a5f0fb15SPaul Saab 	if (c == EOI)
137a5f0fb15SPaul Saab 	{
138a5f0fb15SPaul Saab 		null_line();
139a5f0fb15SPaul Saab 		return (NULL_POSITION);
140a5f0fb15SPaul Saab 	}
141a5f0fb15SPaul Saab 	blankline = (c == '\n' || c == '\r');
142a5f0fb15SPaul Saab 
1437374caaaSXin LI 	/*
1447374caaaSXin LI 	 * Read each character in the line and append to the line buffer.
1457374caaaSXin LI 	 */
146*b2ea2440SXin LI 	chopped = FALSE;
147a5f0fb15SPaul Saab 	for (;;)
148a5f0fb15SPaul Saab 	{
149a5f0fb15SPaul Saab 		if (ABORT_SIGS())
150a5f0fb15SPaul Saab 		{
151a5f0fb15SPaul Saab 			null_line();
152a5f0fb15SPaul Saab 			return (NULL_POSITION);
153a5f0fb15SPaul Saab 		}
154a5f0fb15SPaul Saab 		if (c == '\n' || c == EOI)
155a5f0fb15SPaul Saab 		{
156a5f0fb15SPaul Saab 			/*
157a5f0fb15SPaul Saab 			 * End of the line.
158a5f0fb15SPaul Saab 			 */
1596dcb072bSXin LI 			backchars = pflushmbc();
160a5f0fb15SPaul Saab 			new_pos = ch_tell();
1616dcb072bSXin LI 			if (backchars > 0 && !chopline && hshift == 0)
1626dcb072bSXin LI 			{
1636dcb072bSXin LI 				new_pos -= backchars + 1;
1646dcb072bSXin LI 				endline = FALSE;
1656dcb072bSXin LI 			} else
166a5f0fb15SPaul Saab 				endline = TRUE;
167a5f0fb15SPaul Saab 			break;
168a5f0fb15SPaul Saab 		}
1696dcb072bSXin LI 		if (c != '\r')
1706dcb072bSXin LI 			blankline = 0;
171a5f0fb15SPaul Saab 
172a5f0fb15SPaul Saab 		/*
173a5f0fb15SPaul Saab 		 * Append the char to the line and get the next char.
174a5f0fb15SPaul Saab 		 */
1756dcb072bSXin LI 		backchars = pappend(c, ch_tell()-1);
1766dcb072bSXin LI 		if (backchars > 0)
177a5f0fb15SPaul Saab 		{
178a5f0fb15SPaul Saab 			/*
179a5f0fb15SPaul Saab 			 * The char won't fit in the line; the line
180a5f0fb15SPaul Saab 			 * is too long to print in the screen width.
181a5f0fb15SPaul Saab 			 * End the line here.
182a5f0fb15SPaul Saab 			 */
1838ed69c6fSPaul Saab 			if (chopline || hshift > 0)
184a5f0fb15SPaul Saab 			{
185a5f0fb15SPaul Saab 				do
186a5f0fb15SPaul Saab 				{
18733096f16SXin LI 					if (ABORT_SIGS())
18833096f16SXin LI 					{
18933096f16SXin LI 						null_line();
19033096f16SXin LI 						return (NULL_POSITION);
19133096f16SXin LI 					}
192a5f0fb15SPaul Saab 					c = ch_forw_get();
193a5f0fb15SPaul Saab 				} while (c != '\n' && c != EOI);
194a5f0fb15SPaul Saab 				new_pos = ch_tell();
195a5f0fb15SPaul Saab 				endline = TRUE;
196a5f0fb15SPaul Saab 				quit_if_one_screen = FALSE;
197*b2ea2440SXin LI 				chopped = TRUE;
198a5f0fb15SPaul Saab 			} else
199a5f0fb15SPaul Saab 			{
2006dcb072bSXin LI 				new_pos = ch_tell() - backchars;
201a5f0fb15SPaul Saab 				endline = FALSE;
202a5f0fb15SPaul Saab 			}
203a5f0fb15SPaul Saab 			break;
204a5f0fb15SPaul Saab 		}
205a5f0fb15SPaul Saab 		c = ch_forw_get();
206a5f0fb15SPaul Saab 	}
2077374caaaSXin LI 
208*b2ea2440SXin LI 	pdone(endline, chopped, 1);
2097374caaaSXin LI 
2107374caaaSXin LI #if HILITE_SEARCH
2117374caaaSXin LI 	if (is_filtered(base_pos))
2127374caaaSXin LI 	{
2137374caaaSXin LI 		/*
2147374caaaSXin LI 		 * We don't want to display this line.
2157374caaaSXin LI 		 * Get the next line.
2167374caaaSXin LI 		 */
2177374caaaSXin LI 		curr_pos = new_pos;
2187374caaaSXin LI 		goto get_forw_line;
2197374caaaSXin LI 	}
2207374caaaSXin LI 
2217374caaaSXin LI 	if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL))
2227374caaaSXin LI 		set_status_col('*');
2237374caaaSXin LI #endif
224a5f0fb15SPaul Saab 
225a5f0fb15SPaul Saab 	if (squeeze && blankline)
226a5f0fb15SPaul Saab 	{
227a5f0fb15SPaul Saab 		/*
228a5f0fb15SPaul Saab 		 * This line is blank.
229a5f0fb15SPaul Saab 		 * Skip down to the last contiguous blank line
230a5f0fb15SPaul Saab 		 * and pretend it is the one which we are returning.
231a5f0fb15SPaul Saab 		 */
232a5f0fb15SPaul Saab 		while ((c = ch_forw_get()) == '\n' || c == '\r')
233a5f0fb15SPaul Saab 			if (ABORT_SIGS())
234a5f0fb15SPaul Saab 			{
235a5f0fb15SPaul Saab 				null_line();
236a5f0fb15SPaul Saab 				return (NULL_POSITION);
237a5f0fb15SPaul Saab 			}
238a5f0fb15SPaul Saab 		if (c != EOI)
239a5f0fb15SPaul Saab 			(void) ch_back_get();
240a5f0fb15SPaul Saab 		new_pos = ch_tell();
241a5f0fb15SPaul Saab 	}
242a5f0fb15SPaul Saab 
243a5f0fb15SPaul Saab 	return (new_pos);
244a5f0fb15SPaul Saab }
245a5f0fb15SPaul Saab 
246a5f0fb15SPaul Saab /*
247a5f0fb15SPaul Saab  * Get the previous line.
248a5f0fb15SPaul Saab  * A "current" position is passed and a "new" position is returned.
249a5f0fb15SPaul Saab  * The current position is the position of the first character of
250a5f0fb15SPaul Saab  * a line.  The new position is the position of the first character
251a5f0fb15SPaul Saab  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
252a5f0fb15SPaul Saab  */
253a5f0fb15SPaul Saab 	public POSITION
254f6b74a7dSXin LI back_line(curr_pos)
255f6b74a7dSXin LI 	POSITION curr_pos;
256a5f0fb15SPaul Saab {
2577374caaaSXin LI 	POSITION new_pos, begin_new_pos, base_pos;
258a5f0fb15SPaul Saab 	int c;
259a5f0fb15SPaul Saab 	int endline;
260*b2ea2440SXin LI 	int chopped;
2616dcb072bSXin LI 	int backchars;
262a5f0fb15SPaul Saab 
2637374caaaSXin LI get_back_line:
264a5f0fb15SPaul Saab 	if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
265a5f0fb15SPaul Saab 	{
266a5f0fb15SPaul Saab 		null_line();
267a5f0fb15SPaul Saab 		return (NULL_POSITION);
268a5f0fb15SPaul Saab 	}
269a5f0fb15SPaul Saab #if HILITE_SEARCH
2707374caaaSXin LI 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
271a5f0fb15SPaul Saab 		prep_hilite((curr_pos < 3*size_linebuf) ?
272a5f0fb15SPaul Saab 				0 : curr_pos - 3*size_linebuf, curr_pos, -1);
273a5f0fb15SPaul Saab #endif
274a5f0fb15SPaul Saab 	if (ch_seek(curr_pos-1))
275a5f0fb15SPaul Saab 	{
276a5f0fb15SPaul Saab 		null_line();
277a5f0fb15SPaul Saab 		return (NULL_POSITION);
278a5f0fb15SPaul Saab 	}
279a5f0fb15SPaul Saab 
280a5f0fb15SPaul Saab 	if (squeeze)
281a5f0fb15SPaul Saab 	{
282a5f0fb15SPaul Saab 		/*
283a5f0fb15SPaul Saab 		 * Find out if the "current" line was blank.
284a5f0fb15SPaul Saab 		 */
285a5f0fb15SPaul Saab 		(void) ch_forw_get();    /* Skip the newline */
286a5f0fb15SPaul Saab 		c = ch_forw_get();       /* First char of "current" line */
287a5f0fb15SPaul Saab 		(void) ch_back_get();    /* Restore our position */
288a5f0fb15SPaul Saab 		(void) ch_back_get();
289a5f0fb15SPaul Saab 
290a5f0fb15SPaul Saab 		if (c == '\n' || c == '\r')
291a5f0fb15SPaul Saab 		{
292a5f0fb15SPaul Saab 			/*
293a5f0fb15SPaul Saab 			 * The "current" line was blank.
294a5f0fb15SPaul Saab 			 * Skip over any preceding blank lines,
295a5f0fb15SPaul Saab 			 * since we skipped them in forw_line().
296a5f0fb15SPaul Saab 			 */
297a5f0fb15SPaul Saab 			while ((c = ch_back_get()) == '\n' || c == '\r')
298a5f0fb15SPaul Saab 				if (ABORT_SIGS())
299a5f0fb15SPaul Saab 				{
300a5f0fb15SPaul Saab 					null_line();
301a5f0fb15SPaul Saab 					return (NULL_POSITION);
302a5f0fb15SPaul Saab 				}
303a5f0fb15SPaul Saab 			if (c == EOI)
304a5f0fb15SPaul Saab 			{
305a5f0fb15SPaul Saab 				null_line();
306a5f0fb15SPaul Saab 				return (NULL_POSITION);
307a5f0fb15SPaul Saab 			}
308a5f0fb15SPaul Saab 			(void) ch_forw_get();
309a5f0fb15SPaul Saab 		}
310a5f0fb15SPaul Saab 	}
311a5f0fb15SPaul Saab 
312a5f0fb15SPaul Saab 	/*
313a5f0fb15SPaul Saab 	 * Scan backwards until we hit the beginning of the line.
314a5f0fb15SPaul Saab 	 */
315a5f0fb15SPaul Saab 	for (;;)
316a5f0fb15SPaul Saab 	{
317a5f0fb15SPaul Saab 		if (ABORT_SIGS())
318a5f0fb15SPaul Saab 		{
319a5f0fb15SPaul Saab 			null_line();
320a5f0fb15SPaul Saab 			return (NULL_POSITION);
321a5f0fb15SPaul Saab 		}
322a5f0fb15SPaul Saab 		c = ch_back_get();
323a5f0fb15SPaul Saab 		if (c == '\n')
324a5f0fb15SPaul Saab 		{
325a5f0fb15SPaul Saab 			/*
326a5f0fb15SPaul Saab 			 * This is the newline ending the previous line.
327a5f0fb15SPaul Saab 			 * We have hit the beginning of the line.
328a5f0fb15SPaul Saab 			 */
3297374caaaSXin LI 			base_pos = ch_tell() + 1;
330a5f0fb15SPaul Saab 			break;
331a5f0fb15SPaul Saab 		}
332a5f0fb15SPaul Saab 		if (c == EOI)
333a5f0fb15SPaul Saab 		{
334a5f0fb15SPaul Saab 			/*
335a5f0fb15SPaul Saab 			 * We have hit the beginning of the file.
336a5f0fb15SPaul Saab 			 * This must be the first line in the file.
337a5f0fb15SPaul Saab 			 * This must, of course, be the beginning of the line.
338a5f0fb15SPaul Saab 			 */
3397374caaaSXin LI 			base_pos = ch_tell();
340a5f0fb15SPaul Saab 			break;
341a5f0fb15SPaul Saab 		}
342a5f0fb15SPaul Saab 	}
343a5f0fb15SPaul Saab 
344a5f0fb15SPaul Saab 	/*
345a5f0fb15SPaul Saab 	 * Now scan forwards from the beginning of this line.
346a5f0fb15SPaul Saab 	 * We keep discarding "printable lines" (based on screen width)
347a5f0fb15SPaul Saab 	 * until we reach the curr_pos.
348a5f0fb15SPaul Saab 	 *
349a5f0fb15SPaul Saab 	 * {{ This algorithm is pretty inefficient if the lines
350a5f0fb15SPaul Saab 	 *    are much longer than the screen width,
351a5f0fb15SPaul Saab 	 *    but I don't know of any better way. }}
352a5f0fb15SPaul Saab 	 */
3537374caaaSXin LI 	new_pos = base_pos;
354a5f0fb15SPaul Saab 	if (ch_seek(new_pos))
355a5f0fb15SPaul Saab 	{
356a5f0fb15SPaul Saab 		null_line();
357a5f0fb15SPaul Saab 		return (NULL_POSITION);
358a5f0fb15SPaul Saab 	}
359a5f0fb15SPaul Saab 	endline = FALSE;
360a5f0fb15SPaul Saab 	prewind();
361a5f0fb15SPaul Saab 	plinenum(new_pos);
3626dcb072bSXin LI     loop:
3636dcb072bSXin LI 	begin_new_pos = new_pos;
364a5f0fb15SPaul Saab 	(void) ch_seek(new_pos);
365*b2ea2440SXin LI 	chopped = FALSE;
366a5f0fb15SPaul Saab 
367a5f0fb15SPaul Saab 	do
368a5f0fb15SPaul Saab 	{
369a5f0fb15SPaul Saab 		c = ch_forw_get();
370a5f0fb15SPaul Saab 		if (c == EOI || ABORT_SIGS())
371a5f0fb15SPaul Saab 		{
372a5f0fb15SPaul Saab 			null_line();
373a5f0fb15SPaul Saab 			return (NULL_POSITION);
374a5f0fb15SPaul Saab 		}
375a5f0fb15SPaul Saab 		new_pos++;
376a5f0fb15SPaul Saab 		if (c == '\n')
377a5f0fb15SPaul Saab 		{
3786dcb072bSXin LI 			backchars = pflushmbc();
3796dcb072bSXin LI 			if (backchars > 0 && !chopline && hshift == 0)
3806dcb072bSXin LI 			{
3816dcb072bSXin LI 				backchars++;
3826dcb072bSXin LI 				goto shift;
3836dcb072bSXin LI 			}
384a5f0fb15SPaul Saab 			endline = TRUE;
385a5f0fb15SPaul Saab 			break;
386a5f0fb15SPaul Saab 		}
3876dcb072bSXin LI 		backchars = pappend(c, ch_tell()-1);
3886dcb072bSXin LI 		if (backchars > 0)
389a5f0fb15SPaul Saab 		{
390a5f0fb15SPaul Saab 			/*
391a5f0fb15SPaul Saab 			 * Got a full printable line, but we haven't
392a5f0fb15SPaul Saab 			 * reached our curr_pos yet.  Discard the line
393a5f0fb15SPaul Saab 			 * and start a new one.
394a5f0fb15SPaul Saab 			 */
3958ed69c6fSPaul Saab 			if (chopline || hshift > 0)
396a5f0fb15SPaul Saab 			{
397a5f0fb15SPaul Saab 				endline = TRUE;
398*b2ea2440SXin LI 				chopped = TRUE;
399a5f0fb15SPaul Saab 				quit_if_one_screen = FALSE;
400a5f0fb15SPaul Saab 				break;
401a5f0fb15SPaul Saab 			}
4026dcb072bSXin LI 		shift:
4036dcb072bSXin LI 			pshift_all();
4046dcb072bSXin LI 			while (backchars-- > 0)
4056dcb072bSXin LI 			{
406a5f0fb15SPaul Saab 				(void) ch_back_get();
407a5f0fb15SPaul Saab 				new_pos--;
4086dcb072bSXin LI 			}
409a5f0fb15SPaul Saab 			goto loop;
410a5f0fb15SPaul Saab 		}
411a5f0fb15SPaul Saab 	} while (new_pos < curr_pos);
412a5f0fb15SPaul Saab 
413*b2ea2440SXin LI 	pdone(endline, chopped, 0);
4147374caaaSXin LI 
4157374caaaSXin LI #if HILITE_SEARCH
4167374caaaSXin LI 	if (is_filtered(base_pos))
4177374caaaSXin LI 	{
4187374caaaSXin LI 		/*
4197374caaaSXin LI 		 * We don't want to display this line.
4207374caaaSXin LI 		 * Get the previous line.
4217374caaaSXin LI 		 */
4227374caaaSXin LI 		curr_pos = begin_new_pos;
4237374caaaSXin LI 		goto get_back_line;
4247374caaaSXin LI 	}
4257374caaaSXin LI 
42696e55cc7SXin LI 	if (status_col && curr_pos > 0 && is_hilited(base_pos, curr_pos-1, 1, NULL))
4277374caaaSXin LI 		set_status_col('*');
4287374caaaSXin LI #endif
429a5f0fb15SPaul Saab 
430a5f0fb15SPaul Saab 	return (begin_new_pos);
431a5f0fb15SPaul Saab }
432a5f0fb15SPaul Saab 
433a5f0fb15SPaul Saab /*
434a5f0fb15SPaul Saab  * Set attnpos.
435a5f0fb15SPaul Saab  */
436a5f0fb15SPaul Saab 	public void
437f6b74a7dSXin LI set_attnpos(pos)
438f6b74a7dSXin LI 	POSITION pos;
439a5f0fb15SPaul Saab {
440a5f0fb15SPaul Saab 	int c;
441a5f0fb15SPaul Saab 
442a5f0fb15SPaul Saab 	if (pos != NULL_POSITION)
443a5f0fb15SPaul Saab 	{
444a5f0fb15SPaul Saab 		if (ch_seek(pos))
445a5f0fb15SPaul Saab 			return;
446a5f0fb15SPaul Saab 		for (;;)
447a5f0fb15SPaul Saab 		{
448a5f0fb15SPaul Saab 			c = ch_forw_get();
449a5f0fb15SPaul Saab 			if (c == EOI)
450a5f0fb15SPaul Saab 				break;
451a15691bfSXin LI 			if (c == '\n' || c == '\r')
452a15691bfSXin LI 			{
453a15691bfSXin LI 				(void) ch_back_get();
454a15691bfSXin LI 				break;
455a15691bfSXin LI 			}
456a5f0fb15SPaul Saab 			pos++;
457a5f0fb15SPaul Saab 		}
458a15691bfSXin LI 		end_attnpos = pos;
459a15691bfSXin LI 		for (;;)
460a15691bfSXin LI 		{
461a15691bfSXin LI 			c = ch_back_get();
462a15691bfSXin LI 			if (c == EOI || c == '\n' || c == '\r')
463a15691bfSXin LI 				break;
464a15691bfSXin LI 			pos--;
465a15691bfSXin LI 		}
466a5f0fb15SPaul Saab 	}
467a5f0fb15SPaul Saab 	start_attnpos = pos;
468a5f0fb15SPaul Saab }
469