annotate src/line-number.c @ 5814:a216b3c2b09e

Add TLS support. See xemacs-patches message with ID <CAHCOHQk6FNm2xf=XiGEpPq43+7WOzNZ=SuD9V79o3wb9WVCTrQ@mail.gmail.com>.
author Jerry James <james@xemacs.org>
date Tue, 07 Oct 2014 21:16:10 -0600
parents 56144c8593a8
children bd4d2c8ef9cc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 /* Line number cache.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2 Copyright (C) 1997 Free Software Foundation, Inc.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
4 This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 867
diff changeset
6 XEmacs is free software: you can redistribute it and/or modify it
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 867
diff changeset
8 Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 867
diff changeset
9 option) any later version.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 867
diff changeset
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 /* Synched up with: Not in FSF. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 /* To calculate the line numbers, redisplay must count the newlines
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22 from a known position. This used to be BUF_BEGV, but this made the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 line numbering extremely slow for large buffers, because Emacs had
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 to rescan the whole buffer at each redisplay.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 To make line numbering efficient, we maintain a buffer-local cache
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27 of recently used positions and their line numbers. The cache is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 implemented as a small ring of cache positions. A cache position
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29 is either nil or a cons of a buffer position (marker) and the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 corresponding line number.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 When calculating the line numbers, this cache is consulted if it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33 would otherwise take too much time to count the newlines in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 buffer (see the comment to buffer_line_number().)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36 Insertion and deletions that contain/delete newlines invalidate the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 cached positions after the insertion point. This guarantees
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 relatively fast line numbers caching (even in buffers where point
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 moves a lot), and low memory usage. All of this is done only in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 the buffers where the cache is actually initialized -- i.e. where
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 line-numbering is on, and you move the point farther than
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 LINE_NUMBER_FAR from the beginning of buffer. In this sense, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 cache is lazy -- if you don't use it, you don't pay for it.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 NOTE: line-number cache should not be confused with line-start
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 cache. Line-start cache (a part of redisplay) works with the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 display lines, whereas this works with the buffer lines (literally
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 counting the newlines). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50 #include <config.h>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 #include "lisp.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52 #include "buffer.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
53
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
54 #include "line-number.h"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56 /* #### The following three values could stand more exploration for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 best performance. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 /* Size of the ring. The current code expects this to be a small
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 number. If you make it larger, you should probably optimize the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61 code below to keep it sorted. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
62 #define LINE_NUMBER_RING_SIZE 8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
63
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 /* How much traversal has to be exceeded for two points to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 considered "far" from each other. When two points are far, cache
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 will be used. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 #define LINE_NUMBER_FAR 16384
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 /* How large a string has to be to give up searching it for newlines,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
70 before change. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
71 #define LINE_NUMBER_LARGE_STRING 256
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 /* To be used only when you *know* the cache has been allocated! */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 #define LINE_NUMBER_RING(b) (XCAR ((b)->text->line_number_cache))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 #define LINE_NUMBER_BEGV(b) (XCDR ((b)->text->line_number_cache))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 /* Initialize the cache. Cache is (in pseudo-BNF):
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 CACHE = nil | INITIALIZED-CACHE
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 INITIALIZED-CACHE = cons (RING, BEGV-LINE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82 RING = vector (*RING-ELEMENT)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 RING-ELEMENT = nil | RING-PAIR
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 RING-PAIR = cons (marker, integer)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85 BEGV-LINE = integer
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 Line number cache should never, ever, be visible to Lisp (because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 destructively modifying its elements can cause crashes.) Debug it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 using debug_print (current_buffer->text->last_number_cache). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90 static void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 allocate_line_number_cache (struct buffer *b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 b->text->line_number_cache = Fcons (make_vector (LINE_NUMBER_RING_SIZE, Qnil),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 Qzero);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 narrow_line_number_cache (b);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 /* Flag LINE_NUMBER_BEGV (b) as dirty. Do it only if the line number
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
99 cache is already initialized. */
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 void
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101 narrow_line_number_cache (struct buffer *b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 if (NILP (b->text->line_number_cache))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 if (BUF_BEG (b) == BUF_BEGV (b))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107 /* The is the case Fwiden and save_restriction_restore. Since we
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 know the correct value, we can update it now. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 LINE_NUMBER_BEGV (b) = Qzero;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 /* Calculating the line number of BUF_BEGV here is a bad idea,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112 because there is absolutely no reason to do it before the next
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 redisplay. We simply mark it as dirty instead. */
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
114 LINE_NUMBER_BEGV (b) = make_fixnum (-1);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117 /* Invalidate the line number cache positions that lie after POS. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 static void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
119 invalidate_line_number_cache (struct buffer *b, Charbpos pos)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 EMACS_INT i, j;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122 Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 for (i = 0; i < LINE_NUMBER_RING_SIZE; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 if (!CONSP (ring[i]))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128 /* As the marker stays behind the insertions, this check might
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 as well be `>'. However, Finsert_before_markers can advance
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 the marker anyway, which bites in shell buffers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 #### This forces recreation of the cached marker (and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133 recalculation of newlines) every time a newline is inserted
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 at point, which is way losing. Isn't there a way to make a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 marker impervious to Finsert_before_markers()?? Maybe I
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136 should convert the code to use extents. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 if (marker_position (XCAR (ring[i])) >= pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 /* Get the marker out of the way. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 Fset_marker (XCAR (ring[i]), Qnil, Qnil);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 /* ...and shift the ring elements, up to the first nil. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 for (j = i; !NILP (ring[j]) && j < LINE_NUMBER_RING_SIZE - 1; j++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ring[j] = ring[j + 1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 ring[j] = Qnil;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145 /* Must recheck position i. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 i--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151 /* Invalidate the cache positions after POS, if the string to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 inserted contains a newline. If the string is too large (larger
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 than LINE_NUMBER_LARGE_STRING), invalidate the cache positions
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 after POS without prior search.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 This will do nothing if the cache is uninitialized. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
158 insert_invalidate_line_number_cache (struct buffer *b, Charbpos pos,
867
804517e16990 [xemacs-hg @ 2002-06-05 09:54:39 by ben]
ben
parents: 771
diff changeset
159 const Ibyte *nonreloc, Bytecount length)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 if (NILP (b->text->line_number_cache))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 if (length > LINE_NUMBER_LARGE_STRING
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ||
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 /* We could also count how many newlines there are in the string
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 and update the cache accordingly, but it would be too much
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 work for too little gain. */
647
b39c14581166 [xemacs-hg @ 2001-08-13 04:45:47 by ben]
ben
parents: 442
diff changeset
169 memchr ((void *)nonreloc, '\n', length))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 invalidate_line_number_cache (b, pos);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 /* Invalidate the cache positions after FROM, if the region to be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 deleted contains a newline. If the region-to-be-deleted is larger
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175 than LINE_NUMBER_LARGE_STRING, invalidate the cache positions after
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 FROM without unconditionally.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178 This will do nothing if the cache is uninitialized. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
180 delete_invalidate_line_number_cache (struct buffer *b, Charbpos from, Charbpos to)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 if (NILP (b->text->line_number_cache))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183 return;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 if ((to - from) > LINE_NUMBER_LARGE_STRING)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 invalidate_line_number_cache (b, from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 EMACS_INT shortage;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 scan_buffer (b, '\n', from, to, 1, &shortage, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 if (!shortage)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 invalidate_line_number_cache (b, from);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 /* Get the nearest known position we know the line number of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 (i.e. BUF_BEGV, and cached positions). The return position will be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 either closer than BEG, or BEG. The line of this known position
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 will be stored in LINE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 *LINE should be initialized to the line number of BEG (normally,
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
202 BEG will be BUF_BEGV, and *LINE will be XFIXNUM (LINE_NUMBER_BEGV).
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 This will initialize the cache, if necessary. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 static void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
205 get_nearest_line_number (struct buffer *b, Charbpos *beg, Charbpos pos,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 EMACS_INT *line)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 EMACS_INT i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 Charcount length = pos - *beg;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 if (length < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 length = -length;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215 /* Find the ring entry closest to POS, if it is closer than BEG. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 for (i = 0; i < LINE_NUMBER_RING_SIZE && CONSP (ring[i]); i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
218 Charbpos newpos = marker_position (XCAR (ring[i]));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 Charcount howfar = newpos - pos;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 if (howfar < 0)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221 howfar = -howfar;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 if (howfar < length)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 length = howfar;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 *beg = newpos;
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
226 *line = XFIXNUM (XCDR (ring[i]));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 /* Add a (POS . LINE) pair to the ring, and rotate it. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232 static void
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
233 add_position_to_cache (struct buffer *b, Charbpos pos, EMACS_INT line)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 Lisp_Object *ring = XVECTOR_DATA (LINE_NUMBER_RING (b));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 int i = LINE_NUMBER_RING_SIZE - 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 /* Set the last marker in the ring to point nowhere. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 if (CONSP (ring[i]))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 Fset_marker (XCAR (ring[i]), Qnil, Qnil);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 /* Rotate the ring... */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243 for (; i > 0; i--)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 ring[i] = ring[i - 1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 /* ...and update it. */
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
247 ring[0] = Fcons (Fset_marker (Fmake_marker (), make_fixnum (pos),
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
248 wrap_buffer (b)),
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
249 make_fixnum (line));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 /* Calculate the line number in buffer B at position POS. If CACHEP
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 is non-zero, initialize and facilitate the line-number cache. The
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 line number of the first line is 0. If narrowing is in effect,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 count the lines are counted from the beginning of the visible
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 portion of the buffer.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 The cache works as follows: To calculate the line number, we need
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 two positions: position of point (POS) and the position from which
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 to count newlines (BEG). We start by setting BEG to BUF_BEGV. If
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 this would require too much searching (i.e. pos - BUF_BEGV >
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 LINE_NUMBER_FAR), try to find a closer position in the ring. If it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 is found, use that position for BEG, and increment the line number
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 appropriately.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 If the calculation (with or without the cache lookup) required more
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 than LINE_NUMBER_FAR characters of traversal, update the cache. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 EMACS_INT
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
269 buffer_line_number (struct buffer *b, Charbpos pos, int cachep)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270 {
665
fdefd0186b75 [xemacs-hg @ 2001-09-20 06:28:42 by ben]
ben
parents: 647
diff changeset
271 Charbpos beg = BUF_BEGV (b);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 EMACS_INT cached_lines = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273 EMACS_INT shortage, line;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 if ((pos > beg ? pos - beg : beg - pos) <= LINE_NUMBER_FAR)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 cachep = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 if (cachep)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 if (NILP (b->text->line_number_cache))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 allocate_line_number_cache (b);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
282 /* If we don't know the line number of BUF_BEGV, calculate it now. */
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
283 if (XFIXNUM (LINE_NUMBER_BEGV (b)) == -1)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
284 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
285 LINE_NUMBER_BEGV (b) = Qzero;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
286 /* #### This has a side-effect of changing the cache. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
287 LINE_NUMBER_BEGV (b) =
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
288 make_fixnum (buffer_line_number (b, BUF_BEGV (b), 1));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 }
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
290 cached_lines = XFIXNUM (LINE_NUMBER_BEGV (b));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
291 get_nearest_line_number (b, &beg, pos, &cached_lines);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
292 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
293
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
294 scan_buffer (b, '\n', beg, pos, pos > beg ? MOST_POSITIVE_FIXNUM : -MOST_POSITIVE_FIXNUM,
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
295 &shortage, 0);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
297 line = MOST_POSITIVE_FIXNUM - shortage;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
298 if (beg > pos)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
299 line = -line;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
300 line += cached_lines;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
301
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
302 if (cachep)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
303 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304 /* If too far, update the cache. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 if ((pos > beg ? pos - beg : beg - pos) > LINE_NUMBER_FAR)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 add_position_to_cache (b, pos, line);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 /* Account for narrowing. If cache is not used, this is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 unnecessary, because we counted from BUF_BEGV anyway. */
5581
56144c8593a8 Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents: 5402
diff changeset
309 line -= XFIXNUM (LINE_NUMBER_BEGV (b));
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 return line;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 }