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