bug-zile
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-zile] [PATCH] {lua} redisplay: don't redraw the entire window on ev


From: Gary V. Vaughan
Subject: [Bug-zile] [PATCH] {lua} redisplay: don't redraw the entire window on every keypress.
Date: Fri, 24 Feb 2012 00:53:21 +0700

Zile redraws the entire screen on every keypress, which means that
as soon as we add in the overhead of running several regexps to
figure out what needs highlighting, and then the overhead of all
the addition term_setattrs() calls... the slowdown is compounding
enormously.

This changeset tries to be intelligent about updating, generally
only redrawing the line containing the cursor, except when insertions
deletions or keystrokes affect more than the current line, in which
case we fall-back to the full-redisplay case.

The speedup from applying this change, more than pays for the additional
overhead of syntax highlighting in the Zi fork.

Can you see any problems with this approach?  Or see any more commands
I missed that need to force a full redisplay?

Okay to push (in a couple of weeks when I get back to Zile)?


* src/term_redisplay (draw_window): Unless wp.display is true,
or start_column has changed since the last redisplay. then
redraw only the line containing bp.pt.
* src/buffer.lua (replace_estr): If any eol characters are being
added or deleted in the current buffer, set wp.redisplay on all
windows visiting it.
* src/basic.lua (scroll_up, scroll_down): Force redisplay of all
lines in the scrolled window.
* src/redisplay.lua (recenter): Likewise.
---
 src/basic.lua          |    2 ++
 src/buffer.lua         |   16 ++++++++++++++--
 src/redisplay.lua      |    2 ++
 src/term_redisplay.lua |   40 ++++++++++++++++++++++++++++++----------
 4 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/src/basic.lua b/src/basic.lua
index e34024e..6ff481d 100644
--- a/src/basic.lua
+++ b/src/basic.lua
@@ -189,6 +189,7 @@ Move point to the end of the buffer; leave mark at previous 
position.
 
 local function scroll_down ()
   if not window_top_visible (cur_wp) then
+    cur_wp.redisplay = true
     return move_line (-cur_wp.eheight)
   end
 
@@ -197,6 +198,7 @@ end
 
 local function scroll_up ()
   if not window_bottom_visible (cur_wp) then
+    cur_wp.redisplay = true
     return move_line (cur_wp.eheight)
   end
 
diff --git a/src/buffer.lua b/src/buffer.lua
index 7d3ed85..02c06db 100644
--- a/src/buffer.lua
+++ b/src/buffer.lua
@@ -76,8 +76,20 @@ function replace_estr (del, newtext)
   end
 
   -- Convert inserted string to correct line ending
-  if newtext.eol ~= get_buffer_eol (cur_bp) then
-    newtext = estr_cat ({s = "", eol = get_buffer_eol (cur_bp)}, newtext)
+  local eol = get_buffer_eol (cur_bp)
+  if newtext.eol ~= eol then
+    newtext = estr_cat ({s = "", eol = eol}, newtext)
+  end
+
+  -- If we are inserting or removing newlines, then redisplay
+  -- all windows showing the changed buffer.
+  local b,e = cur_bp.text.s:find (eol, cur_bp.pt + cur_bp.gap +1)
+  if newtext.s:find (eol) or (b ~= nil and e <= cur_bp.pt + cur_bp.gap + del) 
then
+    for _, wp in ipairs (windows) do
+      if wp.bp == cur_bp then
+        wp.redisplay = true
+      end
+    end
   end
 
   undo_save_block (cur_bp.pt, del, #newtext.s)
diff --git a/src/redisplay.lua b/src/redisplay.lua
index aaebbac..27fdbbc 100644
--- a/src/redisplay.lua
+++ b/src/redisplay.lua
@@ -25,6 +25,8 @@ function recenter (wp)
   else
     wp.topdelta = n
   end
+
+  wp.redisplay = true
 end
 
 Defun ("recenter",
diff --git a/src/term_redisplay.lua b/src/term_redisplay.lua
index aacd3c5..93fc3f0 100644
--- a/src/term_redisplay.lua
+++ b/src/term_redisplay.lua
@@ -148,30 +148,48 @@ end
 
 local function draw_window (topline, wp)
   local highlight, rp = calculate_highlight_region (wp)
+  local bp = wp.bp
+
+  -- begin and end offsets for the current line
+  local b = buffer_start_of_line (bp, window_o (wp))
+  local e = buffer_next_line (bp, b)
 
   -- Find the first line to display on the first screen line.
-  local o = buffer_start_of_line (wp.bp, window_o (wp))
+  local o = b
   local i = wp.topdelta
   while i > 0 and o > 0 do
-    o = buffer_prev_line (wp.bp, o)
+    o = buffer_prev_line (bp, o)
     assert (o)
     i = i - 1
   end
 
+  -- Always redisplay if the start_column has changed
+  if wp.last_start_column ~= wp.start_column then
+    wp.redisplay = true
+    wp.last_start_column = wp.start_column
+  end
+
   -- Draw the window lines.
-  local cur_tab_width = tab_width (wp.bp)
+  local cur_tab_width = tab_width (bp)
   for i = topline, wp.eheight + topline do
-    -- Clear the line.
-    term_move (i, 0)
-    term_clrtoeol ()
+    -- Do we need to redraw this line?
+    local redraw = wp.redisplay or (o ~= nil and o >= b and o < e)
+
+    if redraw then
+      -- Clear the line.
+      term_move (i, 0)
+      term_clrtoeol ()
+    end
 
     -- If at the end of the buffer, don't write any text.
     if o ~= nil then
-      draw_line (i, wp.start_column, wp, o, rp, highlight, cur_tab_width)
+      if redraw then
+        draw_line (i, wp.start_column, wp, o, rp, highlight, cur_tab_width)
 
-      if wp.start_column > 0 then
-        term_move (i, 0)
-        term_addstr ('$')
+        if wp.start_column > 0 then
+          term_move (i, 0)
+          term_addstr ('$')
+       end
       end
 
       o = buffer_next_line (wp.bp, o)
@@ -185,6 +203,8 @@ local function draw_window (topline, wp)
   if wp.fheight > wp.eheight then
     draw_status_line (topline + wp.eheight, wp)
   end
+
+  wp.redisplay = false
 end
 
 local cur_topline, col = 0, 0
-- 
1.7.9.1

Cheers,
-- 
Gary V. Vaughan (gary AT gnu DOT org)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]