summaryrefslogtreecommitdiff
path: root/src/bidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bidi.c')
-rw-r--r--src/bidi.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/src/bidi.c b/src/bidi.c
index c31d208ecbc..7d082a94997 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -61,6 +61,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "character.h"
#include "buffer.h"
#include "dispextern.h"
+#include "region-cache.h"
static bool bidi_initialized = 0;
@@ -1085,6 +1086,29 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos)
return val;
}
+/* If the user has requested the long scans caching, make sure that
+ BIDI cache is enabled. Otherwise, make sure it's disabled. */
+
+static struct region_cache *
+bidi_paragraph_cache_on_off (void)
+{
+ if (NILP (BVAR (current_buffer, cache_long_scans)))
+ {
+ if (current_buffer->bidi_paragraph_cache)
+ {
+ free_region_cache (current_buffer->bidi_paragraph_cache);
+ current_buffer->bidi_paragraph_cache = 0;
+ }
+ return NULL;
+ }
+ else
+ {
+ if (!current_buffer->bidi_paragraph_cache)
+ current_buffer->bidi_paragraph_cache = new_region_cache ();
+ return current_buffer->bidi_paragraph_cache;
+ }
+}
+
/* On my 2005-vintage machine, searching back for paragraph start
takes ~1 ms per line. And bidi_paragraph_init is called 4 times
when user types C-p. The number below limits each call to
@@ -1100,7 +1124,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
{
Lisp_Object re = paragraph_start_re;
ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
- ptrdiff_t n = 0;
+ struct region_cache *bpc = bidi_paragraph_cache_on_off ();
+ ptrdiff_t n = 0, oldpos = pos, next;
while (pos_byte > BEGV_BYTE
&& n++ < MAX_PARAGRAPH_SEARCH
@@ -1111,10 +1136,18 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte)
of the text over which we scan back includes
paragraph_start_re? */
DEC_BOTH (pos, pos_byte);
- pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
+ if (bpc && region_cache_backward (current_buffer, bpc, pos, &next))
+ {
+ pos = next, pos_byte = CHAR_TO_BYTE (pos);
+ break;
+ }
+ else
+ pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
}
if (n >= MAX_PARAGRAPH_SEARCH)
- pos_byte = BEGV_BYTE;
+ pos = BEGV, pos_byte = BEGV_BYTE;
+ if (bpc)
+ know_region_cache (current_buffer, bpc, pos, oldpos);
return pos_byte;
}