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

Formatting can break links #262

Closed
arisolt opened this issue Jan 3, 2023 · 12 comments
Closed

Formatting can break links #262

arisolt opened this issue Jan 3, 2023 · 12 comments

Comments

@arisolt
Copy link

arisolt commented Jan 3, 2023

In a situation in which the outcome of executing gq (the Vim command for formatting) splits a long line of text in the middle of a link tag, the introduction of the newline character into the link breaks that link. Can this be mitigated? For example, by stripping the new line character from links in the detection function, since it is never part of a filename anyway? Alternatively, is there a way to prevent Vim from breaking new lines mid-tag?

Example

Original:

The quick brown fox jumps over [[the lazy dog.md]].

After formatting with gq, the link is no longer recognised:

The quick brown fox jumps over [[the
lazy dog.md]].
@lervag
Copy link
Owner

lervag commented Jan 3, 2023

wiki.vim does not currently have any support for the gq operator. I don't think it would be right to add such a feature to wiki.vim, because wiki.vim should not attempt to be a filetype plugin.

It can be mitigated. gq respects the formatexpr option (see :help gq), which allows to customize how lines are formatted. However, writing such a function can be challenging, especially if you don't have any experience with vimscript (or lua for neovim).

I assume you use gq because you want to reformat and adjust lines to meet a specific column width. My current way of doing this (when I need to; not so often) is first format a paragraph with gqip, then, from start to end of the paragraph, manually adjust where necessary and reformat from the cursor to the end of the paragraph with gq}.

@lervag
Copy link
Owner

lervag commented Jan 3, 2023

Regarding link recognition: There is an open issue #147 on supporting multi-line links. I plan to work on this at some point, when I get the time. Solving it would probably also be relevant for you and possibly be a viable solution.

@arisolt
Copy link
Author

arisolt commented Jan 3, 2023

Regarding link recognition: There is an open issue #147 on supporting multi-line links. I plan to work on this at some point, when I get the time. Solving it would probably also be relevant for you and possibly be a viable solution.

Yes I agree, this would be the ideal solution. Thank you for your thoughts!

@lervag
Copy link
Owner

lervag commented Jan 4, 2023

Is it OK by you to follow #147 and that we close this issue, then?

@lervag lervag closed this as completed Jan 4, 2023
@lervag lervag reopened this Jan 4, 2023
@arisolt
Copy link
Author

arisolt commented Jan 4, 2023

Is it OK by you to follow #147 and that we close this issue, then?

I just wanted to add, in the meantime I discovered a workaround which, at least, achieves the visual effect of formatting and doesn't break the links. I think in general this is important in a wiki, because long paragraphs are common and they end up counting as "one line".

So using this configuration in .vimrc:

autocmd FileType wiki set columns=79
autocmd FileType wiki set wrap 

This configuration will only apply to the wiki files. It sets the number of visual columns to 79 (a "classic" value for terminals, also assumed by gq) and wraps lines longer than that.

But with this method, wrapping happens where it happens, i.e even in the middle of a word and even has an intentional glitch where the character at wrap point is duplicated (vim/vim#6022 (comment)). It can be mitigated with the additional settings:

autocmd FileType wiki set linebreak
autocmd FileType wiki set breakat=\  " here the space after the escape character \ is important

This tells vim to only wrap at the characters in the breakat set, which in this case is one space (\ ). You can add additional characters of course, see :h breakat.

Alternatively, just omit the set columns instruction and Vim will wrap depending on the dimensions of your vim window.

While this method makes long paragraphs readable, the downside is that it remains tedious to navigate them, since in reality there is still just one line and therefore you can only jump left/right; you cannot jump up/down on the visual lines. Edit: actually it is very easy to jump on the visual lines natively, have a look at :h gj or https://vim.fandom.com/wiki/Move_cursor_by_display_lines_when_wrapping

Hopefully those notes are helpful. I think it basically solves my problem and it's actually the more sensible solution, rather than modifying the plugin :)

@arisolt arisolt closed this as completed Jan 4, 2023
@lervag
Copy link
Owner

lervag commented Jan 4, 2023

Thanks! I agree with most of what you write, except:

autocmd FileType wiki set columns=79

I don't agree this is what you want. Or, at least, I think it is important for anyone who uses this to fully understand what it does! See :help 'columns':

'columns' 'co'          number  (default 80 or terminal width)
                        global
        Number of columns of the screen.  Normally this is set by the terminal
        initialization and does not have to be set by hand.
        When Vim is running in the GUI or in a resizable window, setting this
        option will cause the window size to be changed.  When you only want
        to use the size for the GUI, put the command in your |ginit.vim| file.
        When you set this option and Vim is unable to change the physical
        number of columns of the display, the display may be messed up.  For
        the GUI it is always possible and Vim limits the number of columns to
        what fits on the screen.  You can use this command to get the widest
        window possible:
                :set columns=9999
        Minimum value is 12, maximum value is 10000.

Basically, it is a way to specify how many columns your screen has. Sometimes (but not always) it will change the number of columns in your screen/terminal/gui, but sometimes it won't. And if it won't, then doing this will mess up your display.

I think, instead, you want set textwidth=0, which specifies to not add any hard breaks (see :help 'textwidth').

@arisolt
Copy link
Author

arisolt commented Jan 5, 2023

I think textwidth is set to 0 by default, no? In what way do you mean it could help?

I've played with the columns setting and I agree it's not ideal, because it limits the entire Vim screen to that size; for example, a new split window would be created within the same constrained screen. However, there doesn't seem to be any other way to do soft wrapping without adjusting the window size: vim/vim#1847

The only alternative seems to be to just create a vertical split, so that the size of the window is reduced and you still get a soft wrap, without sacrificing the size of the overall Vim screen.

@lervag
Copy link
Owner

lervag commented Jan 5, 2023

I think textwidth is set to 0 by default, no? In what way do you mean it could help?

textwidth is very relevant to gq. I just realized that with textwidth 0, gq will format according to the current window width. If textwidth is already 0, then you don't need to change it.

I've played with the columns setting and I agree it's not ideal, because it limits the entire Vim screen to that size; for example, a new split window would be created within the same constrained screen. However, there doesn't seem to be any other way to do soft wrapping without adjusting the window size: vim/vim#1847

No, you are right, soft wrapping will always be relative to your current window width. My point was that you should be careful with changing the columns option to adjust the width of your terminal. Commonly, a terminal would have 80 columns. Is that not the case for you? If so, you could try to just resize it manually?

Another option could be to use a plugin like goyo.vim?

@arisolt
Copy link
Author

arisolt commented Jan 5, 2023

textwidth is very relevant to gq. I just realized that with textwidth 0, gq will format according to the current window width. If textwidth is already 0, then you don't need to change it.

Ah right, but I already decided not to use formatting after all, it's not worth it to introduce the line breaks, as they potentially break markdown links and create export issues later down the line.

Commonly, a terminal would have 80 columns. Is that not the case for you? If so, you could try to just resize it manually?

I use iTerm on OSX, basically new terminal windows default to 80 columns, but I usually prefer to have the terminal window full screen, for the additional real estate. I agree that resizing the terminal window can be a quick workaround.

Another option could be to use a plugin like goyo.vim?

I've seen it, it's nice. From what I can tell from the plugin source code, it actually creates a number of splits with empty buffers, which it calls pads, in order to constrain the main window with the text (https://github.com/junegunn/goyo.vim/blob/master/autoload/goyo.vim#L253).

I think this remains fundamentally a Vim limitation. It's odd, as there are popular questions on Stackoverflow as old as 13 years, where people have requested this precise feature. I've bumped the related thread on github.

@lervag
Copy link
Owner

lervag commented Jan 5, 2023

I think this remains fundamentally a Vim limitation. It's odd, as there are popular questions on Stackoverflow as old as 13 years, where people have requested this precise feature. I've bumped the related thread on github.

Yes, this is a Vim limitation. I believe it is also a limitation in neovim, but you could open a feature request at either of the repositories and ask if it may be of interest to implement an option like textwidth specifically for soft wrapping. It would be interesting to hear the reasoning for deciding against such a feature.

@arisolt
Copy link
Author

arisolt commented Jan 6, 2023

It would be interesting to hear the reasoning for deciding against such a feature.

As far as I can see, no reasoning was provided, although it's being brought up regularly. (See a couple of messages above for a link to the open issue on the Vim github.)

@lervag
Copy link
Owner

lervag commented Jan 6, 2023

Thanks; I've subscribed to the threads. I hope this may gain some traction and be implemented in the not too far future!

Perhaps it's worth a question on Reddit (r/vim and/or r/neovim)?

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

No branches or pull requests

2 participants