6

I love the relative numbers side-column in vim but when I have wrapped lines it becomes inaccurate (or less usable since I can't use that number directly in a j/k command). I have nnoremap j gj in my vimrc which is why I have that discrepancy but is there a way for the :rnu command to reflect the lines a wrapped number takes?

Thanks

*If that made no sense, I'd like wrapped line 4 and 6 to have numbers all the way down not not skipping visible lines.

4
  • 2
    This is not possible without some serious hackery, and also not really desirable, the definition of a "line" is 0 or more characters ended by a newline, if you change that definition, you change a lot in Vim. For example, what would you expect ,3s/A/B/ to do? Use the next 3 lines? Or the next 3 "wrapped lines"? I understand why you're asking this, but I think your proposed 'solution' will cause you more problems than you will solve. Aug 6, 2015 at 8:32
  • Perhaps consider (automatically) hardwrapping your lines: if you edit in markdown, or LaTeX, there's no difference; and you can also Join lines at any time. You get all the benefits, with none of the disadvantages.
    – VanLaser
    Aug 6, 2015 at 9:02
  • Thanks for both comments. I see your point carpetsmoker although I wish it were different. True, vanlaser but other languages aren't so kind and oftentimes I only want to sometimes see the end of the line (ie huge JavaScript arrays)
    – JZL003
    Aug 6, 2015 at 14:27
  • At the moment of writing vim unfortunately lacks the feature. But it is definitely a worthy one, and FWIW Emacs have had it since the very moment they merged hybrid line numbers (through visual value of display-line-numbers). So I reported it, you can subscribe, or vote for implementation (or maybe even implement it ;)) github.com/vim/vim/issues/3250
    – Hi-Angel
    Jul 25, 2018 at 21:25

2 Answers 2

4

You state that your current workflow is "inaccurate" and "less usable". You can solve the former (but arguably not the latter) by replacing your current j mapping with:

nnoremap <expr> j v:count == 0 ? 'gj' : "\<Esc>".v:count.'j'

With this mapping, you can still use a plain j to move down one screen line at a time, but if you use a count, then you will move down to the line indicated by the corresponding 'relativenumber' marker. Accurate! :)

However, because there are no markers on the later screen lines of single wrapped lines, you still cannot use Nj to jump to those lines. Still less usable :(.

How it works

This is an expression mapping, which maps to different commands depending on the current count.

If there is no count, it simply performs a gj. If there is a count it first clears the existing count with Esc, and then performs a regular j using the value of that count.

See:

  • :help :map-expr
  • :help v:count
  • :help expr1
1
  • Thanks! I'm going to try that now, this is a very clever solution
    – JZL003
    Aug 1, 2018 at 12:49
3

This is not possible without some serious hackery. In fact, I can't really think of a hack short of modifying the Vim source code.

I also doubt that you really want this. The definition of a "line" is 0 or more characters ended by a newline, if you change that definition, you change a lot in Vim. For example, what would you expect a command like :s/A/B/ to do? Change everything on the "real" line? Or only the "virtual" line? Or what about :,3s/A/B/? Use the next 3 lines? Or the next 3 "virtual" lines?

I understand why you're asking this, but I think your proposed 'solution' will cause you more problems than you will solve.

1
  • I have been using the "proposed solution" you're rejecting for at least a year in Emacs, and given I found this post for trying to make it work for gvim (which I'm using for quick browsing and as an external editor), I dare you it caused me no trouble.
    – Hi-Angel
    Jul 25, 2018 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.