forked from th-otto/gulam
-
Notifications
You must be signed in to change notification settings - Fork 1
/
region.c
136 lines (125 loc) · 2.97 KB
/
region.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
/*
region.c -- The routines in this file deal with the region, that
magic space between dot and mark. */
#include "ue.h"
/* Determine the bounds of the region in the current window, and fill
in the fields of the REGION structure pointed to by rp. Because the
dot and mark are usually very close together, we scan outward from dot
looking for mark. This should save time. Return a standard code. */
int getregion(REGION *rp)
{
ELINE *flp;
ELINE *blp;
ELINE *lastp;
int fsize;
int bsize;
if (curwp->w_markp == NULL)
{
mlwrite("No mark set in this window");
return FALSE;
}
if (curwp->w_dotp == curwp->w_markp)
{
rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko)
{
rp->r_offset = curwp->w_doto;
rp->r_size = curwp->w_marko - curwp->w_doto;
} else
{
rp->r_offset = curwp->w_marko;
rp->r_size = curwp->w_doto - curwp->w_marko;
}
return TRUE;
}
flp = blp = curwp->w_dotp;
lastp = curbp->b_linep;
bsize = curwp->w_doto;
fsize = llength(flp) - bsize + 1;
while (flp != lastp || lback(blp) != lastp)
{
if (flp != lastp)
{
flp = lforw(flp);
if (flp == curwp->w_markp)
{
rp->r_linep = curwp->w_dotp;
rp->r_offset = curwp->w_doto;
rp->r_size = fsize + curwp->w_marko;
return TRUE;
}
fsize += llength(flp) + 1;
}
if (lback(blp) != lastp)
{
blp = lback(blp);
bsize += llength(blp) + 1;
if (blp == curwp->w_markp)
{
rp->r_linep = blp;
rp->r_offset = curwp->w_marko;
rp->r_size = bsize - curwp->w_marko;
return TRUE;
}
}
}
mlwrite("Bug: lost mark");
return FALSE;
}
/* Kill the region. Ask getregion() to figure out the bounds of the
region. Move dot to the start, and kill the characters. Bound to
"C-W". */
int killregion(int f, int n)
{
int s;
REGION region;
UNUSED(f);
UNUSED(n);
s = getregion(®ion);
if (s != TRUE)
return s;
if ((lastflag & CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
curwp->w_dotp = region.r_linep;
curwp->w_doto = region.r_offset;
return ldelete(region.r_size, KFORW);
}
/* Copy all of the characters in the region to the kill buffer. Don't
move dot at all. This is a bit like a kill region followed by a yank.
Bound to "M-W". */
int copyregion(int f, int n)
{
ELINE *linep;
int loffs;
int s;
REGION region;
UNUSED(f);
UNUSED(n);
s = getregion(®ion);
if (s != TRUE)
return s;
if ((lastflag & CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
linep = region.r_linep; /* Current line. */
loffs = region.r_offset; /* Current offset. */
while (region.r_size--)
{
if (loffs == llength(linep)) /* End of line. */
{
s = kinsert('\n', KFORW);
if (s != TRUE)
return s;
linep = lforw(linep);
loffs = 0;
} else /* Middle of line. */
{
s = kinsert(lgetc(linep, loffs), KFORW);
if (s != TRUE)
return s;
++loffs;
}
}
return TRUE;
}