annotate src/line-number.c @ 5518:3cc7470ea71c

gnuclient: if TMPDIR was set and connect failed, try again with /tmp 2011-06-03 Aidan Kehoe <kehoea@parhasard.net> * gnuslib.c (connect_to_unix_server): Retry with /tmp as a directory in which to search for Unix sockets if an attempt to connect with some other directory failed (which may be because gnuclient and gnuserv don't share an environment value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR turned off).
author Aidan Kehoe <kehoea@parhasard.net>
date Fri, 03 Jun 2011 18:40:57 +0100
parents 308d34e9f07d
children 56144c8593a8
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. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 LINE_NUMBER_BEGV (b) = make_int (-1);
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,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 BEG will be BUF_BEGV, and *LINE will be XINT (LINE_NUMBER_BEGV).
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;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 *line = XINT (XCDR (ring[i]));
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. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 ring[0] = Fcons (Fset_marker (Fmake_marker (), make_int (pos),
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 665
diff changeset
248 wrap_buffer (b)),
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249 make_int (line));
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. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
283 if (XINT (LINE_NUMBER_BEGV (b)) == -1)
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) =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
288 make_int (buffer_line_number (b, BUF_BEGV (b), 1));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
289 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
290 cached_lines = XINT (LINE_NUMBER_BEGV (b));
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
294 scan_buffer (b, '\n', beg, pos, pos > beg ? EMACS_INT_MAX : -EMACS_INT_MAX,
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
297 line = EMACS_INT_MAX - shortage;
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. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 line -= XINT (LINE_NUMBER_BEGV (b));
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 }