~ubuntu-branches/ubuntu/quantal/less/quantal

« back to all changes in this revision

Viewing changes to mark.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Schoepf
  • Date: 2002-04-04 16:43:52 UTC
  • Revision ID: james.westby@ubuntu.com-20020404164352-qldq048yoc7x5sd5
Tags: upstream-374
ImportĀ upstreamĀ versionĀ 374

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1984-2000  Mark Nudelman
 
3
 *
 
4
 * You may distribute under the terms of either the GNU General Public
 
5
 * License or the Less License, as specified in the README file.
 
6
 *
 
7
 * For more information about less, or for information on how to 
 
8
 * contact the author, see the README file.
 
9
 */
 
10
 
 
11
 
 
12
#include "less.h"
 
13
 
 
14
extern IFILE curr_ifile;
 
15
extern int sc_height;
 
16
extern int jump_sline;
 
17
 
 
18
/*
 
19
 * A mark is an ifile (input file) plus a position within the file.
 
20
 */
 
21
struct mark {
 
22
        IFILE m_ifile;
 
23
        struct scrpos m_scrpos;
 
24
};
 
25
 
 
26
/*
 
27
 * The table of marks.
 
28
 * Each mark is identified by a lowercase or uppercase letter.
 
29
 * The final one is lmark, for the "last mark"; addressed by the apostrophe.
 
30
 */
 
31
#define NMARKS          ((2*26)+1)      /* a-z, A-Z, lastmark */
 
32
#define LASTMARK        (NMARKS-1)
 
33
static struct mark marks[NMARKS];
 
34
 
 
35
/*
 
36
 * Initialize the mark table to show no marks are set.
 
37
 */
 
38
        public void
 
39
init_mark()
 
40
{
 
41
        int i;
 
42
 
 
43
        for (i = 0;  i < NMARKS;  i++)
 
44
                marks[i].m_scrpos.pos = NULL_POSITION;
 
45
}
 
46
 
 
47
/*
 
48
 * See if a mark letter is valid (between a and z).
 
49
 */
 
50
        static struct mark *
 
51
getumark(c)
 
52
        int c;
 
53
{
 
54
        if (c >= 'a' && c <= 'z')
 
55
                return (&marks[c-'a']);
 
56
 
 
57
        if (c >= 'A' && c <= 'Z')
 
58
                return (&marks[c-'A'+26]);
 
59
 
 
60
        error("Invalid mark letter", NULL_PARG);
 
61
        return (NULL);
 
62
}
 
63
 
 
64
/*
 
65
 * Get the mark structure identified by a character.
 
66
 * The mark struct may come either from the mark table
 
67
 * or may be constructed on the fly for certain characters like ^, $.
 
68
 */
 
69
        static struct mark *
 
70
getmark(c)
 
71
        int c;
 
72
{
 
73
        register struct mark *m;
 
74
        static struct mark sm;
 
75
 
 
76
        switch (c)
 
77
        {
 
78
        case '^':
 
79
                /*
 
80
                 * Beginning of the current file.
 
81
                 */
 
82
                m = &sm;
 
83
                m->m_scrpos.pos = ch_zero();
 
84
                m->m_scrpos.ln = 0;
 
85
                m->m_ifile = curr_ifile;
 
86
                break;
 
87
        case '$':
 
88
                /*
 
89
                 * End of the current file.
 
90
                 */
 
91
                if (ch_end_seek())
 
92
                {
 
93
                        error("Cannot seek to end of file", NULL_PARG);
 
94
                        return (NULL);
 
95
                }
 
96
                m = &sm;
 
97
                m->m_scrpos.pos = ch_tell();
 
98
                m->m_scrpos.ln = sc_height-1;
 
99
                m->m_ifile = curr_ifile;
 
100
                break;
 
101
        case '.':
 
102
                /*
 
103
                 * Current position in the current file.
 
104
                 */
 
105
                m = &sm;
 
106
                get_scrpos(&m->m_scrpos);
 
107
                m->m_ifile = curr_ifile;
 
108
                break;
 
109
        case '\'':
 
110
                /*
 
111
                 * The "last mark".
 
112
                 */
 
113
                m = &marks[LASTMARK];
 
114
                break;
 
115
        default:
 
116
                /*
 
117
                 * Must be a user-defined mark.
 
118
                 */
 
119
                m = getumark(c);
 
120
                if (m == NULL)
 
121
                        break;
 
122
                if (m->m_scrpos.pos == NULL_POSITION)
 
123
                {
 
124
                        error("Mark not set", NULL_PARG);
 
125
                        return (NULL);
 
126
                }
 
127
                break;
 
128
        }
 
129
        return (m);
 
130
}
 
131
 
 
132
/*
 
133
 * Is a mark letter is invalid?
 
134
 */
 
135
        public int
 
136
badmark(c)
 
137
        int c;
 
138
{
 
139
        return (getmark(c) == NULL);
 
140
}
 
141
 
 
142
/*
 
143
 * Set a user-defined mark.
 
144
 */
 
145
        public void
 
146
setmark(c)
 
147
        int c;
 
148
{
 
149
        register struct mark *m;
 
150
        struct scrpos scrpos;
 
151
 
 
152
        m = getumark(c);
 
153
        if (m == NULL)
 
154
                return;
 
155
        get_scrpos(&scrpos);
 
156
        m->m_scrpos = scrpos;
 
157
        m->m_ifile = curr_ifile;
 
158
}
 
159
 
 
160
/*
 
161
 * Set lmark (the mark named by the apostrophe).
 
162
 */
 
163
        public void
 
164
lastmark()
 
165
{
 
166
        struct scrpos scrpos;
 
167
 
 
168
        if (ch_getflags() & CH_HELPFILE)
 
169
                return;
 
170
        get_scrpos(&scrpos);
 
171
        if (scrpos.pos == NULL_POSITION)
 
172
                return;
 
173
        marks[LASTMARK].m_scrpos = scrpos;
 
174
        marks[LASTMARK].m_ifile = curr_ifile;
 
175
}
 
176
 
 
177
/*
 
178
 * Go to a mark.
 
179
 */
 
180
        public void
 
181
gomark(c)
 
182
        int c;
 
183
{
 
184
        register struct mark *m;
 
185
        struct scrpos scrpos;
 
186
 
 
187
        m = getmark(c);
 
188
        if (m == NULL)
 
189
                return;
 
190
 
 
191
        /*
 
192
         * If we're trying to go to the lastmark and 
 
193
         * it has not been set to anything yet,
 
194
         * set it to the beginning of the current file.
 
195
         */
 
196
        if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION)
 
197
        {
 
198
                m->m_ifile = curr_ifile;
 
199
                m->m_scrpos.pos = ch_zero();
 
200
                m->m_scrpos.ln = jump_sline;
 
201
        }
 
202
 
 
203
        /*
 
204
         * If we're using lmark, we must save the screen position now,
 
205
         * because if we call edit_ifile() below, lmark will change.
 
206
         * (We save the screen position even if we're not using lmark.)
 
207
         */
 
208
        scrpos = m->m_scrpos;
 
209
        if (m->m_ifile != curr_ifile)
 
210
        {
 
211
                /*
 
212
                 * Not in the current file; edit the correct file.
 
213
                 */
 
214
                if (edit_ifile(m->m_ifile))
 
215
                        return;
 
216
        }
 
217
 
 
218
        jump_loc(scrpos.pos, scrpos.ln);
 
219
}
 
220
 
 
221
/*
 
222
 * Return the position associated with a given mark letter.
 
223
 *
 
224
 * We don't return which screen line the position 
 
225
 * is associated with, but this doesn't matter much,
 
226
 * because it's always the first non-blank line on the screen.
 
227
 */
 
228
        public POSITION
 
229
markpos(c)
 
230
        int c;
 
231
{
 
232
        register struct mark *m;
 
233
 
 
234
        m = getmark(c);
 
235
        if (m == NULL)
 
236
                return (NULL_POSITION);
 
237
 
 
238
        if (m->m_ifile != curr_ifile)
 
239
        {
 
240
                error("Mark not in current file", NULL_PARG);
 
241
                return (NULL_POSITION);
 
242
        }
 
243
        return (m->m_scrpos.pos);
 
244
}
 
245
 
 
246
/*
 
247
 * Clear the marks associated with a specified ifile.
 
248
 */
 
249
        public void
 
250
unmark(ifile)
 
251
        IFILE ifile;
 
252
{
 
253
        int i;
 
254
 
 
255
        for (i = 0;  i < NMARKS;  i++)
 
256
                if (marks[i].m_ifile == ifile)
 
257
                        marks[i].m_scrpos.pos = NULL_POSITION;
 
258
}