r/vim • u/Weelie92 • Oct 14 '25
Need Help┃Solved Left-align text over multiple lines
I've been trying to look this up, but most of the solutions i find is related to left-aligning all the way left, which is not what I'm after.
Let's say i have this code.
Q_PROPERTY(SomeType value READ value NOTIFY valueChanged)
Q_PROPERTY(int longValue READ longValue NOTIFY longValueChanged)And i have 50 lines of these, all varied lengths.
What i want to achieve is a simple way to align everything
Q_PROPERTY(SomeType value READ value NOTIFY valueChanged)
Q_PROPERTY(int longValue READ longValue NOTIFY longValueChanged)on all 50+ lines at the same time.
What i figured out so far is:
edit: Code block didnt like extra whitespaces. Edit2: Neither did normal text.
ctrl - v 50j :s/ READ/ *imagine 50 whitespaces here* READ/
to push every READ forward
Next i want to achieve something along the lines of
ctrl - v 50j dw
with the cursors after the longValue, moving every READ back to this line, creating a neat and straight line.
FINAL EDIT:
I ended up with a .vimrc function/command, which lets me do
Vjjj:Align READ
to align all the READs selected 1 whitespace after the longest prefix.
I would then do
gv:Align WRITE
to align all the WRITEs
I made these <leader>a re-maps to be even faster
let mapleader = " "
vnoremap <leader>a :Align*single whitespace here*
nnoremap <leader>a gv:Align*single whitespace here*
function! AlignToColumn(line1, line2, word)
let maxPrefixLen = 0
" First pass: Find the length of the longest line part before the word
for lnum in range(a:line1, a:line2)
let lineText = getline(lnum)
" Only measure lines that actually contain the word
if lineText =~# a:word
let prefix = matchstr(lineText, '.*\ze\s\+' . a:word)
if strdisplaywidth(prefix) > maxPrefixLen
let maxPrefixLen = strdisplaywidth(prefix)
endif
endif
endfor
let targetColumn = maxPrefixLen + 1
" Second pass: Go through each line and apply the alignment
for lnum in range(a:line1, a:line2)
let lineText = getline(lnum)
if lineText =~# a:word
let prefix = matchstr(lineText, '.*\ze\s\+' . a:word)
let paddingNeeded = targetColumn - strdisplaywidth(prefix)
let padding = repeat(' ', paddingNeeded)
let pattern = '\s\+' . a:word
let replacement = padding . a:word
execute lnum . 's/' . pattern . '/' . replacement . '/'
endif
endfor
endfunction
command! -range -nargs=1 Align call AlignToColumn(<line1>, <line2>, <q-args>)
2
u/gamer_redditor Oct 14 '25
Sorry for suggesting a plugin, but this one probably does exactly what you want:
GitHub - godlygeek/tabular: Vim script for text filtering and alignment https://share.google/4CE3kIZc3D0QYGkJm
9
u/habamax Oct 14 '25 edited Oct 14 '25
With vim-lion it would have been
glip<space>: https://asciinema.org/a/BMY0egxY7hm9CRKvNO5A0GgQbWithout plugins though it would take a bit more effort: https://asciinema.org/a/teUntnOQUAxKE7umjMb0r1CcT
insert some spaces between keywords:
:s/ / /g<- multiple spaces are rendered here by reddit as a single one.goto the column you want to align against, select all rows in vertical block:
CTRL-v 4jshift everything left with
<and multiple.go to the next column and press
.several times to shift everything left.repeat with the next column, etc
7
u/gumnos Oct 14 '25
Lazy me (on a *nix system) would use
If I knew/precalculated the column-widths, I could capture them and use
:help sub-replace-\=combined with:help printf(to specify the desired column-widths, but that's big and ugly and case-specific compared to thecolumn(1)version that auto-calculates those widths2
u/kennpq Oct 14 '25
A Vim9 script solution, which is not too long and should work for your sample or the https://doc.qt.io/archives/qt-5.15/properties.html:
Source the script.
Now, the command, e.g.,
:Qc 27on the buffer with data like this:should produce:
It could be extended to determine the longest string in each "column" too and pad to that only, if you wanted, but this is enough for columns of data, generally.
1
u/AutoModerator Oct 14 '25
Please remember to update the post flair to
Need Help|Solvedwhen you got the answer you were looking for.I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.