3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: vs_relative.c,v 8.6 1993/11/29 14:15:46 bostic Exp $ (Berkeley) $Date: 1993/11/29 14:15:46 $";
12 #include <sys/types.h>
17 #include "svi_screen.h"
21 * Return the logical column of the cursor.
24 svi_column(sp
, ep
, cp
)
31 col
= SVP(sp
)->sc_col
;
32 if (O_ISSET(sp
, O_NUMBER
))
33 col
-= O_NUMBER_LENGTH
;
40 * Return the physical column from the line that will display a
41 * character closest to the currently most attractive character
42 * position. If it's not easy, uses the underlying routine that
43 * really figures it out. It's broken into two parts because the
44 * svi_lrelative routine handles "logical" offsets, which nobody
45 * but the screen routines understand.
48 svi_relative(sp
, ep
, lno
)
55 /* First non-blank character. */
56 if (sp
->rcmflags
== RCM_FNB
) {
58 (void)nonblank(sp
, ep
, lno
, &cno
);
62 /* First character is easy, and common. */
63 if (sp
->rcmflags
!= RCM_LAST
&& sp
->rcm
== 0)
66 return (svi_lrelative(sp
, ep
, lno
, 1));
71 * Return the physical column from the line that will display a
72 * character closest to the currently most attractive character
73 * position. The offset is for the commands that move logical
74 * distances, i.e. if it's a logical scroll the closest physical
75 * distance is based on the logical line, not the physical line.
78 svi_lrelative(sp
, ep
, lno
, off
)
85 size_t len
, llen
, scno
;
89 /* Need the line to go any further. */
90 if ((lp
= file_gline(sp
, ep
, lno
, &len
)) == NULL
)
93 /* Empty lines are easy. */
97 /* Last character is easy, and common. */
98 if (sp
->rcmflags
== RCM_LAST
)
101 /* Set scno to the right initial value. */
102 scno
= O_ISSET(sp
, O_NUMBER
) ? O_NUMBER_LENGTH
: 0;
104 /* Discard logical lines. */
105 cname
= sp
->gp
->cname
;
106 listset
= O_ISSET(sp
, O_LIST
);
107 for (p
= lp
, llen
= len
; --off
;) {
108 for (; len
&& scno
< sp
->cols
; --len
)
115 /* Step through the line until reach the right character. */
118 if (scno
>= sp
->rcm
) {
119 /* Get the offset of this character. */
123 * May be the next character, not this one,
124 * so check to see if we've gone too far.
127 return (len
< llen
- 1 ? len
: llen
- 1);
128 /* It's this character. */
132 /* No such character; return start of last character. */
138 * Return the physical column from the line that will display a
139 * character closest to the specified column.
142 svi_chposition(sp
, ep
, lno
, cno
)
149 size_t len
, llen
, scno
;
153 /* Need the line to go any further. */
154 if ((lp
= file_gline(sp
, ep
, lno
, &llen
)) == NULL
)
157 /* Empty lines are easy. */
161 /* Step through the line until reach the right character. */
162 cname
= sp
->gp
->cname
;
163 listset
= O_ISSET(sp
, O_LIST
);
164 for (scno
= 0, len
= llen
, p
= lp
; len
--;) {
167 /* Get the offset of this character. */
171 * May be the next character, not this one,
172 * so check to see if we've gone too far.
175 return (len
< llen
- 1 ? len
: llen
- 1);
176 /* It's this character. */
180 /* No such character; return start of last character. */