1 /* m_4.c */
2
3 /* Author:
4 * Steve Kirkendall
5 * 16820 SW Tallac Way
6 * Beaverton, OR 97006
7 * kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
8 */
9
10
11 /* This file contains movement functions which are screen-relative */
12
13 #include "config.h"
14 #include "vi.h"
15
16 /* This m_s the cursor to a particular row on the screen */
17 /*ARGSUSED*/
m_row(m,cnt,key)18 MARK m_row(m, cnt, key)
19 MARK m; /* the cursor position */
20 long cnt; /* the row we'll move to */
21 int key; /* the keystroke of this move - H/L/M */
22 {
23 DEFAULT(1);
24
25 /* calculate destination line based on key */
26 cnt--;
27 switch (key)
28 {
29 case 'H':
30 cnt = topline + cnt;
31 break;
32
33 case 'M':
34 cnt = topline + (LINES - 1) / 2;
35 break;
36
37 case 'L':
38 cnt = botline - cnt;
39 break;
40 }
41
42 /* return the mark of the destination line */
43 return MARK_AT_LINE(cnt);
44 }
45
46
47 /* This function repositions the current line to show on a given row */
48 /*ARGSUSED*/
m_z(m,cnt,key)49 MARK m_z(m, cnt, key)
50 MARK m; /* the cursor */
51 long cnt; /* the line number we're repositioning */
52 int key; /* key struck after the z */
53 {
54 long newtop;
55
56 /* Which line are we talking about? */
57 if (cnt < 0 || cnt > nlines)
58 {
59 return MARK_UNSET;
60 }
61 if (cnt)
62 {
63 m = MARK_AT_LINE(cnt);
64 newtop = cnt;
65 }
66 else
67 {
68 newtop = markline(m);
69 }
70
71 /* allow a "window size" number to be entered, but ignore it */
72 while (key >= '0' && key <= '9')
73 {
74 key = getkey(0);
75 }
76
77 /* figure out which line will have to be at the top of the screen */
78 switch (key)
79 {
80 case '\n':
81 case '\r':
82 case '+':
83 break;
84
85 case '.':
86 case 'z':
87 newtop -= LINES / 2;
88 break;
89
90 case '-':
91 newtop -= LINES - 1;
92 break;
93
94 default:
95 return MARK_UNSET;
96 }
97
98 /* make the new topline take effect */
99 if (newtop >= 1)
100 {
101 topline = newtop;
102 }
103 else
104 {
105 topline = 1L;
106 }
107 mustredraw = TRUE;
108
109 /* The cursor doesn't move */
110 return m;
111 }
112
113
114 /* This function scrolls the screen. It does this by calling redraw() with
115 * an off-screen line as the argument. It will move the cursor if necessary
116 * so that the cursor is on the new screen.
117 */
118 /*ARGSUSED*/
m_scroll(m,cnt,key)119 MARK m_scroll(m, cnt, key)
120 MARK m; /* the cursor position */
121 long cnt; /* for some keys: the number of lines to scroll */
122 int key; /* keystroke that causes this movement */
123 {
124 MARK tmp; /* a temporary mark, used as arg to redraw() */
125
126 /* adjust cnt, and maybe *o_scroll, depending of key */
127 switch (key)
128 {
129 case ctrl('F'):
130 case ctrl('B'):
131 DEFAULT(1);
132 mustredraw = TRUE;
133 cnt = cnt * (LINES - 1) - 1; /* keeps one old line on screen */
134 break;
135
136 case ctrl('E'):
137 case ctrl('Y'):
138 DEFAULT(1);
139 break;
140
141 case ctrl('U'):
142 case ctrl('D'):
143 if (cnt == 0) /* default */
144 {
145 cnt = *o_scroll;
146 }
147 else
148 {
149 if (cnt > LINES - 1)
150 {
151 cnt = LINES - 1;
152 }
153 *o_scroll = cnt;
154 }
155 break;
156 }
157
158 /* scroll up or down, depending on key */
159 switch (key)
160 {
161 case ctrl('B'):
162 case ctrl('Y'):
163 case ctrl('U'):
164 cnt = topline - cnt;
165 if (cnt < 1L)
166 {
167 cnt = 1L;
168 m = MARK_FIRST;
169 }
170 tmp = MARK_AT_LINE(cnt) + markidx(m);
171 redraw(tmp, FALSE);
172 if (markline(m) > botline)
173 {
174 m = MARK_AT_LINE(botline);
175 }
176 break;
177
178 case ctrl('F'):
179 case ctrl('E'):
180 case ctrl('D'):
181 cnt = botline + cnt;
182 if (cnt > nlines)
183 {
184 cnt = nlines;
185 m = MARK_LAST;
186 }
187 tmp = MARK_AT_LINE(cnt) + markidx(m);
188 redraw(tmp, FALSE);
189 if (markline(m) < topline)
190 {
191 m = MARK_AT_LINE(topline);
192 }
193 break;
194 }
195
196 /* arrange for ctrl-B and ctrl-F to redraw the smart line */
197 if (key == ctrl('B') || key == ctrl('F'))
198 {
199 changes++;
200 }
201
202 return m;
203 }
204