Using with vim substitute command: lines created are not scanned in future steps. Can they be?
Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Using with vim substitute command: lines created are not scanned in future steps. Can they be?
Task: make a file made with long lines be wrapped to a desired width.
Bad solution:
1. Set textwidth variable with the desired width
2. Visually select the whole file: ggVG
3. Do the command gq
This is a horrible solution because it will join consecutive lines that are already smaller that the wanted maximum width we set up in step 1.
Soso solution:
1. Do the command :%s_^\(.\{44\}\)\([^.]\)\(.\+\)_\1\r \2\3_ge
This is not a complete solution because it will split each line just one time, each time the command is run. So, if a line is longer than 2 times the wanted width, you will end up with a line with the wanted width, and the rest of it in a line below it. To have this line also splitted, we have to repeat the command. But if the lines of our first run of the command are 3 times longer than the wanted width, we will still have longer lines, in the end. So, we run the command again, and again, and again... recursively, until all lines are good.
Do you know a solution in Vim for this?
Example file given below, with very long lines, good to use with the example command. Each line contain numbers from 00 to 99, to easierly seeing the results of tests:
Not a Vim solution (as you were already given one), but have you heard of fold? It can break at spaces and count each tab as eight characters. Well, you can invoke it from Vim with
It is great because it splits a line recursively. It is bad because it splits words.
Any of you know how to make a regex to improve the command above, so it splits the line in the last space character before 80 (for the given example), or in the 80th position, if there is no space in the line?
Or maybe a vim macro, which i use very limitedly) to the following algorithm?
1. Define desired width N.
2. If line is visually longer than N (tabs), it is a candidate. Else, go to next line, repeat this step. If no more lines, we finished.
3. Find the last space (space char or tab) before Nth character.
4.1. If no space was found, insert "\r " (newline + 4 spaces), and write the rest of the current line in it.
4.2. Else, a space was found. Remove this space and all spaces or tabs together, before it. Insert "\r " (newline + 4 spaces), and write the rest of the current line in it.
5. Change current line to the line created in 4. Go to step 2.
Any of you know how to make a regex to improve the command above, so it splits the line in the last space character before 80 (for the given example), or in the 80th position, if there is no space in the line?
Not a Vim solution (as you were already given one), but have you heard of fold? It can break at spaces and count each tab as eight characters. Well, you can invoke it from Vim with
Code:
:%!fold
More than that, i can invoke fold with
Code:
:%!fold -s -w [N]
and it seems to work almost like the algorithm i just listed:
1. File with 9 lines: first 3 with a word of 10 chars, a space, a word of 9 chars, a space, another word of 9 chars; next 3 lines with a word with 20 chars, a space, a word of 9 chars; 3 short lines with 3 words each. All lines in the file are consecutive.
3. First, the lines starting with a word longer than desired width had the word split, which is good. It is recursive (the lines are completely split, not just one time). The shorter lines were left untouched, and no consecutive lines were joined.
So, the only difference i want, is to put some tabbing to splitted parts of lines, to help us know when a line is possibly the continuation of a line we just read.
Can you explain me your regex? (72 "anything, even spaces", followed by at most 8 "not spaces")... so what what?
Yep. 72 characters is the soft limit. Or what the fmt man page calls goal. The splitting occurs after each 72 characters plus 0 to 8 non-spacing characters. So 80 characters is the hard limit. The {,8} quantifier is greedy, so it will try to consume as many characters as it can (up to 8). As soon as there's a white space among those 8 characters, the RE fires and splitting occurs. If there's no white space in that range, the splitting occurs after the 80th character anyway.
Additionally you can try sed, that will understand the same command - as vi (without :%)
I know regex well, for vim and a few other programs. But for sed, it is sometimes strange to use. I never try it, unless it is something ready to run, or with changes i understand how to do. Can you show something to me?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.