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