Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

relative line numbers does not play well with folding #6536

Closed
ninrod opened this issue Jul 9, 2016 · 47 comments
Closed

relative line numbers does not play well with folding #6536

ninrod opened this issue Jul 9, 2016 · 47 comments

Comments

@ninrod
Copy link

ninrod commented Jul 9, 2016

I've set this on my .spacemacs.d/init.el, as per the documentation:

dotspacemacs-line-numbers 'relative

All works well until you get some folding in:

screen shot 2016-07-09 at 8 40 12 am

The whole point of relative line numbers is to give you an exact line offset to operate vertically inside the window.

Suppose I want to jump to function user-config in the screenshot above. A simple 4j would suffice. But I don't know that because spacemacs is saying that the line I want is 194 lines below the current line, which would be true if the file had no folding on. With folding on, it is not true anymore.

So folding is rendering relative line numbers unusable at the present moment.

bonus: here's a side by side relative line number comparation between spacemacs (left) and vim (right):

screen shot 2016-07-09 at 9 12 23 am

@d12frosted
Copy link
Collaborator

Hey @ninrod,

Thank you for your report. I would like to ask you to share output of SPC h d s so it's easier to understand and reproduce the problem.

@TheBB
Copy link
Collaborator

TheBB commented Jul 11, 2016

You should report this upstream to the relative linum package.

I should note that due to how folding and line numbers work in Emacs this would be nigh impossible to fix.

@ninrod
Copy link
Author

ninrod commented Jul 11, 2016

@d12frosted here it is:

#### System Info
- OS: darwin
- Emacs: 24.5.1
- Spacemacs: 0.105.21
- Spacemacs branch: master (rev. 0283f64)
- Graphic display: nil
- Distribution: spacemacs
- Editing style: hybrid
- Completion: helm
- Layers:
elisp:
(emacs-lisp git markdown org)

@ninrod
Copy link
Author

ninrod commented Jul 11, 2016

@TheBB That's interesting, I find that difficult to believe because everyone in emacs community says emacs is infinitelly customizable and elisp is awesome, way better than vimscript, etc..., So I'd think that getting this feature right would be trivial.

@ninrod
Copy link
Author

ninrod commented Jul 13, 2016

reported upstream (that's emacs itself) http://lists.gnu.org/archive/html/help-gnu-emacs/2016-07/msg00106.html

@TheBB
Copy link
Collaborator

TheBB commented Jul 13, 2016

I don't think they can help you. Relative linum is an external package, not part of emacs proper.

@ninrod
Copy link
Author

ninrod commented Jul 13, 2016

Well, emacs should really provide a stock way to do this in 2016 I think. So if they can't help me do this from emacs -Q I'll file a feature request.

@TheBB
Copy link
Collaborator

TheBB commented Jul 13, 2016

Not to burst your bubble, but the most likely way that would happen is for Emacs to come packaged with relative-linum, in which case you'll still need a feature request/bug fix there.

@ninrod
Copy link
Author

ninrod commented Jul 13, 2016

Yeah there's like 3 packages that try to do this. nlinum, linum-relative, relative-line-numbers. and no one accounts for folding. maybe I'll have to file an issue to each one of them.

Now, I don't know if they don't account for folding because it can't be done or because noone has never thought about this (which I find difficult to believe).

@TheBB
Copy link
Collaborator

TheBB commented Jul 13, 2016

Probably because getting information about how a buffer will be displayed in the end is quite tricky. There's many folding packages and since (I believe) most or all of them use overlays to do what they need, and overlays don't necessarily cover whole lines, it's even more complicated.

@jmromer
Copy link
Contributor

jmromer commented Jul 13, 2016

@ninrod Just to clarify: Is the issue that neither 4j nor 194j work, or just that the former doesn't (i.e., that the behavior deviates from Vim's)?

Update: disregard -- I just tested it locally. I see the problem now -- it's that the relative line numbers displayed are inconsistent with how the jump behavior is working. (which, agreed -- renders them useless when code folding is enabled)

jumping

@ninrod
Copy link
Author

ninrod commented Jul 13, 2016

correct. in your example, suppose you want to jump from the line with user-init to the line with defun buffer exists. If rel line numbers would display correct information when folding is on, you should see a number 13 displayed next to the aforementioned line to which you want to jump to. But you don't know that, because emacs shows you instead the number 151, which does not help you with jumping to the refered line, rendering relative line numbers useless in this scenario.

@ninrod
Copy link
Author

ninrod commented Jul 13, 2016

also note that you are pressing 2j and 2k go to back and forth those lines, but emacs is showing that you should press 3j and 3k, which is also wrong information.

@Fanael
Copy link
Contributor

Fanael commented Jul 14, 2016

Yeah there's like 3 packages that try to do this. nlinum, linum-relative, relative-line-numbers. and no one accounts for folding.

Have you tried relative-line-numbers with relative-line-numbers-motion-function set to forward-visible-line?

numbers

Disclaimer: as the author of relative-line-numbers, I feel obliged to mention that this package is buggy and pretty much abandoned.

@ninrod
Copy link
Author

ninrod commented Jul 14, 2016

Yes! that works! but I get the following when starting emacs:

Invalid face reference: font-lock-comment-delimiter-face
Invalid face reference: font-lock-comment-face
Invalid face reference: font-lock-comment-delimiter-face
Invalid face reference: font-lock-comment-face
Invalid face reference: font-lock-comment-delimiter-face
Invalid face reference: font-lock-comment-face
When done with a buffer, type C-x #

@Fanael You package is great. It's pitty that you are not maintaining it anymore.

So it is indeed possible to get relative-visible-line-numbers. But other relative-line-number package authors seem to find it difficult to implement. see coldnew/linum-relative#18, xcodebuild/nlinum-relative#12

nlinum-relative author specific reply was:

Sorry we don't have visual line supported at now, I have no idea about how to implement it.

And that reply was given 9 days ago.

@Fanael could you explain the specifics of why getting support for relative-visual-lines seems so difficult?

@Fanael
Copy link
Contributor

Fanael commented Jul 14, 2016

@Fanael You package is great.

It's not. Trust me.

It's pitty that you are not maintaining it anymore.

You can always take over if you want.

@Fanael could you explain the specifics of why getting support for relative-visual-lines seems so difficult?

Visual lines, or visible physical lines? Because I thought we're talking about the latter. If so, it's not difficult, it's just that (n)linum-relative use (n)linum, which are ill-suited for the job; relative-line-numbers is completely standalone and implements all the logic itself.

Visual lines, now that's hard without serious help from the rendering engine, which is not there.

@ninrod
Copy link
Author

ninrod commented Jul 14, 2016

@Fanael what is the difference between visual lines and visible physical lines?

I want the line numbering scheme to consider as visible the current lines that are shown on the screen, folded or not. So if a line is representing a folded section, that line counts as 1 line only.

In other words, say a buffer is displayed at the moment and it has 4 visible lines and those 4 visible lines represent folded sections. From the point of view of the plugin, there should be only 4 lines currently shown on the buffer, even if the physical file has more lines than that (it could have 4k lines, 1000 lines to each folded section). So if my cursor is on the first line, the mode should number the second line as 1, the third as 2, and the fourth as 3.

Does that description fit visual lines or physical lines?

@Fanael
Copy link
Contributor

Fanael commented Jul 14, 2016

Both, the difference lies in line wrapping.

In the following example, the as are a single physical line, but two visual lines. The bs are a single physical and visual line.

visual-physical

@ninrod
Copy link
Author

ninrod commented Jul 14, 2016

@Fanael, now I see your point. We're talking about the latter, visible physical lines.

@ninrod
Copy link
Author

ninrod commented Jul 14, 2016

@Fanael, you mentioned that you don't use any form of line numbers anymore. What do you use to navigate vertically?

@nixmaniack
Copy link
Contributor

What do you use to navigate vertically?

I know it's not for me, but for me SPC j l or SPC j j serves the purpose almost all the time.

@ninrod
Copy link
Author

ninrod commented Jul 15, 2016

SPC j l = push mark and goto end of line
SPC j j = sp-newline

How is that of help to navigate vertically

@TheBB
Copy link
Collaborator

TheBB commented Jul 15, 2016

Those bindings are on the develop branch. On master they're bound to something else.

@ninrod
Copy link
Author

ninrod commented Jul 4, 2017

people, the emacs mantainer is almost landing a fix for this in master. Checkout the scratch/line-numbers branch in emacs git repo. Here is a screenshot.

@ninrod
Copy link
Author

ninrod commented Jul 4, 2017

here's another screenshot:

screenshot

@ninrod
Copy link
Author

ninrod commented Jul 10, 2017

People, I think we can close this an maybe reopen another issue to add support to the new native line numbers that just landed on master: https://lists.gnu.org/archive/html/emacs-devel/2017-07/msg00236.html

@d12frosted
Copy link
Collaborator

@ninrod, I agree that we should move to built-in solution that works better than third-party tools. But we must maintain support of third-party solutions until new version of Emacs is released. Despite the fact that develop branch is err... development branch, many develop branch users use non HEAD version of Emacs. So... we still have time 😸

P. S. https://github.com/syl20bnr/spacemacs/issues?q=is%3Aopen+is%3Aissue+label%3A%22Line+numbers%22

@tbrodbeck
Copy link

Two years later the problem still seems to persist :/
lineNumberProblem

People, I think we can close this an maybe reopen another issue to add support to the new native line numbers that just landed on master: https://lists.gnu.org/archive/html/emacs-devel/2017-07/msg00236.html

How do I install this function? I cannot even find the branch.

@ninrod
Copy link
Author

ninrod commented Jun 20, 2019

you don't need this anymore. emacs 26 already comes with this feature built in.

in emacs 26:

(defun ninrod/toggle-relative-line-numbers ()

  "Toogle showing relative line numbers."
  (interactive)
  (if display-line-numbers
      (setq display-line-numbers nil)
    (progn
      (setq  display-line-numbers-current-absolute nil)
      (setq display-line-numbers 'visual))))

@ninrod ninrod closed this as completed Jun 20, 2019
@tbrodbeck
Copy link

tbrodbeck commented Jun 21, 2019

Thanks! But there seems to be a bug when I use it with a certain window size. The lines suddenly seem to take up more space and the line numbering gets shifted upwards.

lineNumberBug

@ninrod
Copy link
Author

ninrod commented Jun 21, 2019

Your theme should account for relative line numbers giving it the space it needs to display line number xyz. You can see that when emacs displays line 1, which has 1 char of spacing, emacs can display your line in a certain way. When you go down, that relative line number changes, for like 21, which has 2 char spacing, so emacs has to find another way to display your line. I think that is what is happening.

@tbrodbeck
Copy link

Your theme should account for relative line numbers giving it the space it needs to display line number xyz. You can see that when emacs displays line 1, which has 1 char of spacing, emacs can display your line in a certain way. When you go down, that relative line number changes, for like 21, which has 2 char spacing, so emacs has to find another way to display your line. I think that is what is happening.

I do not see how that would make sense, since the linenumbers are displaying 2 char numbers all the time in this example. 🤔

@ninrod
Copy link
Author

ninrod commented Jun 21, 2019

I see your point but in this case I guess you are not using just mono fonts for all bullets.

@tbrodbeck
Copy link

tbrodbeck commented Jun 22, 2019

Actually I use the default monospaced font and theme of spacemacs. 🤔

lineNumberBug
It really only happens in a certain small layout.

@tbrodbeck
Copy link

you don't need this anymore. emacs 26 already comes with this feature built in.

in emacs 26:

(defun ninrod/toggle-relative-line-numbers ()

  "Toogle showing relative line numbers."
  (interactive)
  (if display-line-numbers
      (setq display-line-numbers nil)
    (progn
      (setq  display-line-numbers-current-absolute nil)
      (setq display-line-numbers 'visual))))

I am a bit of a emacs-beginner, as you can maybe tell. I would really want that function to run by default but I cannot make it happen.
I tried to put (ninrod/toggle-relative-line-numbers) or (setq display-line-numbers 'visual) into my dotspacemacs/user-config but it does not work everytime I start my emacs. So how would I do this?

@duianto
Copy link
Collaborator

duianto commented Jun 23, 2019

@tbrodbeck There's an open PR about this:
Add support for visual line numbers #12450

When it's pushed, then you can enable visual line numbers on startup from your .spacemacs by changing the existing variable dotspacemacs-line-numbers to 'visual.

Update

The PR is now on the develop branch.

@tbrodbeck
Copy link

tbrodbeck commented Jun 24, 2019

@tbrodbeck There's an open PR about this:
Add support for visual line numbers #12450

When it's pushed, then you can enable visual line numbers on startup from your .spacemacs by changing the existing variable dotspacemacs-line-numbers to 'visual.

Thanks, but how can I access it, now the commit is done? I tried the development channel, can't find it there. And how long would it take to reach the master channel that I usually use?

What can I do till this happens? I tried to put something like (add-hook 'org-mode-hook ninrod/toggle-relative-line-numbers) in my user-config but it does not work.

@ninrod
Copy link
Author

ninrod commented Jun 24, 2019

@tbrodbeck you could try to use another theme, a simpler one and see if the problem persists. Also, try in other modes, like text mode.

@tbrodbeck
Copy link

@tbrodbeck you could try to use another theme, a simpler one and see if the problem persists. Also, try in other modes, like text mode.

The bug is not too terrible actually and only happens in a small window size. First of all it would be nice to be able to activate this function by default (I am not a very experienced emacs user, as you can maybe tell ;), probably its quite easy to do that )

@duianto
Copy link
Collaborator

duianto commented Jun 24, 2019

@tbrodbeck

On the develop branch the key binding to toggle visual line numbers is SPC t V (upper case v).
It was missing, but it's listed in the documentation now:
https://github.com/syl20bnr/spacemacs/blob/develop/doc/DOCUMENTATION.org#gui-toggles

If you want to enable it by default in prog-mode and text-mode buffers, then the
dotspacemacs-line-numbers variable already exists on the master branch, therefore if you switched to the develop branch with your current .spacemacs file, then it should work to just change:
dotspacemacs-line-numbers nil
to:
dotspacemacs-line-numbers 'visual

Updating your .spacemacs to match the develop branch template

The .spacemacs file is generated from a .spacemacs.template on the current Spacemacs branch, when you first start Spacemacs, therefore it will use the master branch template by default.

The develop branch template has added some variables, and and there has been some formatting/rewriting of comments, etc., since the latest master branch release.

There are at least three ways to update the .spacemacs file to match the current Spacemacs branch template.

Remember to backup your current .spacemacs

Before updating your match .spacemacs with the template, make sure to backup your current .spacemacs file, so that you can revert back to it easily if something gets screwed up.

Using ediff

Pro:
You'll find out about new variables that have been added to the develop branch.

Con:
Empty lines have been added between each variable, so it will take some time to go through the whole file. But on the other hand, if you've never used ediff, then it might be the perfect exercise to learn how it works.

Press SPC f e D to open an ediff session with three windows:
- The top left window (marked as A:) shows your current .spacemacs file.
- The top right window (marked as B:) shows the .spacemacs.template file for your current branch.
- The bottom window shows the ediff control panel.

As long as the cursor is in the bottom ediff control panel window, then you can use the ediff keys to navigate between the two files differences, and copy a change from one file to the other. In this case we only want to copy from the template to our .spacemacs file (from B to A).

The basic ediff key bindings are:

  • n next diff
  • p previous diff
  • b copy the current difference from window B (template) to window A.
  • ra restore (undo) the change to your .spacemacs file in window A
  • rb restore the change to the .spacemacs.template, if you press a by mistake and copy from your .spacemacs to the template.

Don't worry if you accidentally modify and save the template, you can always get the latest version from:
https://github.com/syl20bnr/spacemacs/blob/develop/core/templates/.spacemacs.template

You can view additional ediff keys by pressing ?.

If you want to modify your .spacemacs manually, then you can move the cursor to the top left window and edit/save it directly.

Just remember to select the bottom window again when you want to continue to use the ediff keys to jump to the next/prev diff, etc.

If you make manual modifications, and want to compare them to the template, then you can update the diff regions by pressing ! (exclamation mark).

Recreating the .spacemacs file

Pro:
It's faster than adding each change individually.

Con:
Any packages that are not part of the default layers, meaning any layer you've added to your previous .spacemacs, those packages will be deleted as orphans, and you'll have to download them again when you add back your desired layers.

If you haven't done so as instructed above, backup your .spacemacs by moving it from it's default location.

Start Spacemacs and a new .spacemacs file will be generated from your current branch (you'll be asked the setup questions again).

Copy the whole template and add your modifications

Pro:
It's faster than the ediff method.
You don't have to redownload the packages that are part of any layers you've added.

Con:
Can't think of any at the moment.

If you haven't backed up your .spacemacs, then do so now by moving it somewhere else.

Copy the .spacemacs.template to the default .spacemacs location, and rename your copy to .spacemacs (in Windows 7 or 10 you'll have to add a . (period) at the end of the filename, the last period will be removed automatically).

Now copy/add the layers you had enabled in your backed up .spacemacs to the new one that you copied from the template.

This is optional:
There shouldn't be any problems, but it might be best to start Spacemacs after adding the layers, to make sure that everything works before continuing to add anything to the init or user config sections.

@tbrodbeck
Copy link

(add-hook 'org-mode-hook (lambda () (spacemacs/toggle-line-numbers-off)))
(add-hook 'org-mode-hook (lambda () (ninrod/toggle-relative-line-numbers)))

Finally found the solution I was looking for btw.

@IngvarListard
Copy link

IngvarListard commented Feb 27, 2020

There is another problem with visual line numbers:
Screenshot_20200227_224126

When line is wrapped there is still numbering for wrapped line. And when I try jump to 3 in example, cursor jumps to 4th.

@ninrod
Copy link
Author

ninrod commented Feb 28, 2020

Guys, this is issue irrelevant now that we have native relative line numbers in emacs.

@albertfgu
Copy link

albertfgu commented Jul 16, 2020

Hi, how can I use the native relative line numbers in emacs? What is its behavior?
I've played with both dotspacemacs-line-numbers options (relative and visual) and they both have drawbacks: relative does not work with folding, and visual does not work with physical lines. The latter is the problem that @IngvarListard raised; I guess it's actually working as intended, but it's not desired behavior.

Is there any current solution that combines the best of both worlds (namely, display relative numbers for physical lines that are visually present), which is the intuitive behavior most of us want?

I also played with SPC j l or avy line which was mentioned in this thread, and that package correctly only lists the visually available physical lines; so it seems like the correct behavior should be feasible

@ninrod
Copy link
Author

ninrod commented Jul 16, 2020

Hi, how can I use the native relative line numbers in emacs? What is its behavior?

I think that the spacemacs folks can help you with that, but I can show you how I do it, directly:

from https://github.com/ninrod/dotfiles/blob/master/emacs/boot.org#line-number-bootstrap

(when (>= emacs-major-version 26)
  (ninrod/add-to-hooks
   #'(lambda ()
       (setq-local display-line-numbers-current-absolute nil)
       (setq display-line-numbers 'visual))
   '(org-mode-hook
     prog-mode-hook
     markdown-mode-hook
     conf-unix-mode-hook)))

@IngvarListard
Copy link

IngvarListard commented Jul 16, 2020

Hi, how can I use the native relative line numbers in emacs? What is its behavior?

I found a working solution, actually.
Here's what I did:

  1. Set visual line numbers
   dotspacemacs-line-numbers 'visual
  1. Changed the behavior of evil j, k bindings so that the cursor moves over visible lines.
   ;; Make evil-mode up/down operate in screen lines instead of logical lines
   (define-key evil-motion-state-map "j" 'evil-next-visual-line)
   (define-key evil-motion-state-map "k" 'evil-previous-visual-line)
   ;; Also in visual mode
   (define-key evil-visual-state-map "j" 'evil-next-visual-line)
   (define-key evil-visual-state-map "k" 'evil-previous-visual-line)

Works almost perfect and as expected.

But! Most disappointment thing what I realized that, sadly, line numbers just destroy performance of emacs scrolling, even if you would move inside a buffer with Ctr+D, U. It just forced me to disable line numbers at all recently.

Peek 2020-07-17 02-14

@albertfgu
Copy link

Yeah, that's what I also do except I rebound <up> and <down> to preserve my j and k. I don't have your performance issues with scrolling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants