File: more.c

package info (click to toggle)
elvis 2.1i-3
  • links: PTS
  • area: non-free
  • in suites: hamm
  • size: 4,120 kB
  • ctags: 5,838
  • sloc: ansic: 53,854; sh: 811; makefile: 263
file content (138 lines) | stat: -rw-r--r-- 4,366 bytes parent folder | download
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
/* more.c */
/* Copyright 1995 by Steve Kirkendall */

char id_more[] = "$Id: more.c,v 2.14 1997/07/17 17:06:31 steve Exp $";


/* This file contains code which implements the "Hit <Enter> to continue"
 * message.  For the sake of uniformity, this is implemented as a special
 * key processing state, applied to a buffer which just happens to contain
 * the "Hit.." message.
 * 
 * Any single character causes this edit mode to exit, so that editing can
 * resume on the real edit buffer.
 *
 * When this key state is pushed, one character can be designated for
 * special treatment.  If that character is pressed, it will be re-inserted
 * into the type-ahead queue.  This is intended to support the use of <:>
 * to start one ex command after another.
 */

#include "elvis.h"

#if USE_PROTOTYPES
static RESULT perform(WINDOW win);
static RESULT enter(WINDOW win);
static RESULT parse(_CHAR_ key, void *info);
static ELVCURSOR shape(WINDOW win);
#endif


typedef struct
{
	CHAR	special;	/* character to receive special processing */
} MOREINFO;

/* This function performs a "[More]" command.  It doesn't really do much;
 * we really only wanted to wait for the user to hit a key.
 */
static RESULT perform(win)
	WINDOW	win;	/* window where <Enter> was hit */
{
	MARKBUF	from;

	/* Erase the "Hit..." message.  Why is that so hard? */
	bufreplace(marktmp(from, markbuffer(win->state->cursor), 0),
		   win->state->cursor, NULL, 0);
	drawopenedit(win);
	win->di->drawstate = DRAW_VISUAL;
	msg(MSG_STATUS, "");
	win->di->drawstate = DRAW_OPENEDIT;

	return RESULT_COMPLETE;
}

/* If the user really does hit <Enter> at the "Hit <Enter> to continue" prompt,
 * then this function is called after perform().  This function is a stub,
 * because perform() does everything that needs to be done.  In fact, the only
 * reason we even bother to have an enter() function is so that the state.c
 * module will know that the "Hit <Enter>..." prompt is a separate stratum.
 */
static RESULT enter(win)
	WINDOW	win;	/* window where <Enter> was hit */
{
	return RESULT_MORE;
	/* Note RESULT_COMPLETE, because RESULT_COMPLETE interferes with the
	 * perform() function, some how.  I may be working around a bug here.
	 */
}


/* This function parses a command.  For "[More]", any single key completes the
 * command, so this is trivial.  If it is the special character, then the
 * character is pushed back onto the typeahead queue.
 */
static RESULT parse(key, info)
	_CHAR_	key;	/* the key that the user hit */
	void	*info;	/* struct, contains the special character */
{
	MOREINFO *mi = (MOREINFO *)info;
	CHAR	keyarray[1];

	/* if this is the special key, push it back into the type-ahead queue */
	if (mi->special != '\0' && key == mi->special)
	{
		keyarray[0] = key;
		mapunget(keyarray, 1, False);
	}

	return RESULT_COMPLETE;
}

/* This function decides on a cursor shape */
static ELVCURSOR shape(win)
	WINDOW	win;	/* window waiting for <Enter> to be hit */
{
	return CURSOR_COMMAND;
}


/* This function causes elvis to display "Hit <Enter> to continue", and
 * then wait for a keystroke.  Any keystroke is acceptable.  If the keystroke
 * happens to match the "special" argument, then it will be placed back in
 * the type-ahead queue for further processing.
 */
void morepush(win, special)
	WINDOW	win;	/* window that should wait for <Enter> */
	_CHAR_	special;/* a special character, or '\0' if none */
{
	BUFFER	buf;
	MARKBUF	from, to;

	/* if we're in the middle of a macro, never wait for <Enter> */
	if (mapbusy())
		return;

	/* Create the "more" buffer, and put the prompt into it */
	buf = bufalloc(toCHAR(MORE_BUF), 0, True);
	bufreplace(marktmp(from, buf, 0), marktmp(to, buf, o_bufchars(buf)),
		toCHAR("Hit <Enter> to continue\n"), 24);

	/* Push the state.  Make sure this keystate will be popped after
	 * a single command (keystroke)
	 */
	statepush(win, ELVIS_POP|ELVIS_BOTTOM);

	/* initialize the state */
	win->state->enter = enter;
	win->state->perform = perform;
	win->state->parse = parse;
	win->state->shape = shape;
	win->state->info = safealloc(1, sizeof (MOREINFO));
	((MOREINFO *)win->state->info)->special = special;
	win->state->modename = "More";
	win->state->top = markalloc(buf, 0);
	win->state->bottom = markalloc(buf, o_bufchars(buf));
	win->state->cursor = markalloc(buf, o_bufchars(buf) - 1);
	win->state->acton = win->state->pop;
}