From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: Native line numbers, final testing Date: Sat, 01 Jul 2017 11:00:01 +0300 Message-ID: <83shigpoxq.fsf@gnu.org> References: <83y3s9pm2a.fsf@gnu.org> <87vandz7lw.fsf@lylat> <83wp7tpcav.fsf@gnu.org> <87r2y1z45o.fsf@lylat> <83vandp7wz.fsf@gnu.org> <87mv8pyy7f.fsf@lylat> Reply-To: Eli Zaretskii NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1498896030 20641 195.159.176.226 (1 Jul 2017 08:00:30 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 1 Jul 2017 08:00:30 +0000 (UTC) Cc: emacs-devel@gnu.org To: Alex Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Jul 01 10:00:24 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dRDKJ-0004s0-8a for ged-emacs-devel@m.gmane.org; Sat, 01 Jul 2017 10:00:23 +0200 Original-Received: from localhost ([::1]:47271 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dRDKL-0001IC-D3 for ged-emacs-devel@m.gmane.org; Sat, 01 Jul 2017 04:00:25 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56075) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dRDKC-0001Ht-L5 for emacs-devel@gnu.org; Sat, 01 Jul 2017 04:00:17 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dRDK9-00041M-Jx for emacs-devel@gnu.org; Sat, 01 Jul 2017 04:00:16 -0400 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:54051) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dRDK9-00041G-Fz; Sat, 01 Jul 2017 04:00:13 -0400 Original-Received: from 84.94.185.246.cable.012.net.il ([84.94.185.246]:1960 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1dRDK8-0002GD-Eh; Sat, 01 Jul 2017 04:00:13 -0400 In-reply-to: <87mv8pyy7f.fsf@lylat> (message from Alex on Fri, 30 Jun 2017 15:15:00 -0600) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:4830:134:3::e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:216073 Archived-At: > From: Alex > Cc: emacs-devel@gnu.org > Date: Fri, 30 Jun 2017 15:15:00 -0600 > > I noticed another bug. With `display-line-numbers' set to t or 'relative > in xdisp.c: > > M-g c 2970 RET > C-n > > Notice that C-n moved back one column. This does not happen with > 'visual, nor does it happen when the window is sufficiently small. This > is in emacs -Q, and only happens with non-nil line-move-visual. Such problems (which IMO are minor and quite rare) cannot be helped, unfortunately. They happen near the point where the line numbers will soon need one more or one less column. The underlying issue is how this feature calculates the number of columns required for displaying all the numbers in the visible portion of a window. The naïve method would be to perform the window display twice, because you only know the largest line number in view after actually displaying all the lines. But that is too slow, and would land us right back at the slow operation of linum-mode and friends. So instead we guess the maximum line number without actually counting the lines in the window. That guess must be conservative, otherwise you'll see the text shift to the right in the middle of a window. Therefore the guess uses the maximum number of screen lines a window could possibly display without resizing, by using the number of rows in the underlying display structure called the "glyph matrix". This assumes that (1) all of the glyph-matrix rows will be used (usually false, except on TTYs), and (2) that all the shown lines are non-continuation lines. This is why many times you see the number of columns grow before the additional column is actually needed by the last line number displayed at window's bottom. The same code, and the same guessing, is also used by various functions that simulate display, such as vertical-motion (which is called internally by C-n). Except that the vertical position of point in the virtual "window" they consider is taken as zero, because in general it cannot be known (the function could be called in the middle of a Lisp program that moved point, and the updated vertical position will not be determined until the next redisplay cycle). So the resulting number of columns these functions compute could be different from what actually is, or will be, on the screen. And therefore column calculations under line-move-visual will err by the same amount. IOW, these issues are a (small, IMO) fine we need to pay for having such fast line-number display. I will keep this issue in mind, in case some idea emerges for how to fix them, thanks for pointing it out. > >> P.S. I noticed that with display-line-numbers set to 'visual, goto-line > >> is much slower compared to 'relative. Is this expected? > > > > Yes. The initial naïve implementation was unbearably slow, but I was > > lucky to find a shortcut. It is still sometimes slow, and a few > > redisplay optimizations are disabled with this mode, because moving > > point vertically needs to redisplay the entire window, since the line > > numbers change. If someone has ideas for speeding it up, I'm all > > ears. > > I'm not planning to use 'visual, and I of course don't claim to know > anything about this, but I'm curious as to why it works like this. > goto-line in either style always goes to the same absolute line number, > right? Does the line number display calculation occur after the point is > already moved to this line? Yes. Line numbers are calculated as part of redisplay, and that happens when point already moved. > If so, then doesn't the display engine just need to calculate the > visual line numbers around this point? If so, then why does a large > jump like M-g g 25000 take so much longer comparatively than M-g g > 1000? If these assumptions are wrong (they likely are), why are they > wrong? Because the display engine employs a lot of optimizations, to try and shortcut expensive redrawing of the entire window, and to comply with user expectations. It doesn't, and cannot, know that buffer position 25000 is necessarily outside the window where the command was invoked. E.g., you could have some text-folding mode, such as Outline, active in the buffer; or you could have lines truncated with only a few very long lines between the window-start and position 25000. So redisplay first tries to reuse the same window-start point as it used in the previous cycle, because that's what you as a user would expect: if the new point is inside the same window, you don't expect the window to scroll. Deciding whether the previous window-start is still usable needs to check whether point will be shown inside the window, and that requires to try reaching point from the original window-start, in this case position 1, and counting screen lines as we do, until we either hit point or the window's bottom. It turns out that the 'visual' mode of line numbers made this test unnecessarily slow, so a simple heuristic was enough to avoid that. See the latest branch, where 'visual' and 'relative' should now redisplay at the same speed in this case.