-
Star
(137)
You must be signed in to star a gist -
Fork
(24)
You must be signed in to fork a gist
-
-
Save tpope/287147 to your computer and use it in GitHub Desktop.
| inoremap <silent> <Bar> <Bar><Esc>:call <SID>align()<CR>a | |
| function! s:align() | |
| let p = '^\s*|\s.*\s|\s*$' | |
| if exists(':Tabularize') && getline('.') =~# '^\s*|' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p) | |
| let column = strlen(substitute(getline('.')[0:col('.')],'[^|]','','g')) | |
| let position = strlen(matchstr(getline('.')[0:col('.')],'.*|\s*\zs.*')) | |
| Tabularize/|/l1 | |
| normal! 0 | |
| call search(repeat('[^|]*|',column).'\s\{-\}'.repeat('.',position),'ce',line('.')) | |
| endif | |
| endfunction |
This is really useful!
Thx a lot!
Thanks tpope for this and all your other amazing work. I ended up here after asking this question: http://vi.stackexchange.com/questions/6908/how-can-i-replace-a-word-in-a-column-without-changing-the-width
this function really awesome! thanks
Can I make this to work only on specific file formats such as AsciiDoc? Is it okay to add the code to ftplugin/asciidoc.vim? Thanks!
Sure, make it a <buffer> map and unmap it in b:undo_ftplugin.
I have recreated it in lua for anyone that is interested.
local cmd = vim.cmd
local fn = vim.fn
function _G.alignMdTable()
local pattern = '^%s*|%s.*%s|%s*$'
local lineNumber = fn.line('.')
local currentColumn = fn.col('.')
local previousLine = fn.getline(lineNumber - 1)
local currentLine = fn.getline('.')
local nextLine = fn.getline(lineNumber + 1)
if fn.exists(':Tabularize') and currentLine:match('^%s*|') and (previousLine:match(pattern) or nextLine:match(pattern)) then
local column = #currentLine:sub(1, currentColumn):gsub('[^|]', '')
local position = #fn.matchstr(currentLine:sub(1, currentColumn), ".*|\\s*\\zs.*")
cmd('Tabularize/|/l1') -- `l` means left aligned and `1` means one space of cell padding
cmd('normal! 0')
fn.search(('[^|]*|'):rep(column) .. ('\\s\\{-\\}'):rep(position), 'ce', lineNumber)
end
endlocal cmd = vim.cmd local fn = vim.fn function _G.alignMdTable() local pattern = '^%s*|%s.%s|%s$' local lineNumber = fn.line('.') local currentColumn = fn.col('.') local previousLine = fn.getline(lineNumber - 1) local currentLine = fn.getline('.') local nextLine = fn.getline(lineNumber + 1) if fn.exists(':Tabularize') and currentLine:match('^%s*|') and (previousLine:match(pattern) or nextLine:match(pattern)) then local column = #currentLine:sub(1, currentColumn):gsub('[^|]', '') local position = #fn.matchstr(currentLine:sub(1, currentColumn), ".|\s\zs.") cmd('Tabularize/|/l1') --
lmeans left aligned and1means one space of cell padding cmd('normal! 0') fn.search(('[^|]|'):rep(column) .. ('\s\{-\}'):rep(position), 'ce', lineNumber) end end
Thank you sir!
Recently moved all my config to lua, u know just playing around and getting to know it .. and this amazing piece of code was one of the missing parts on my new setup. Seems to work just fine.
@namjul hey thank you so much, worked like a charm.
@namjul it works perfectly. Thanks a lot.
In my case it doesn't works perfectly. The alignmet is correct but every pipe add a space at the start of the row.
For example, the first row is:
| pippo | pluto | paperino |
then I start the second row and hapens this:
␣ | pippo | pluto | paperino |
␣ |*
and when I start second column in the second row another space will be added:
␣ ␣ | pippo | pluto | paperino |
␣ ␣ | one |*
(I used " ␣ " to represent a single space and "*" to represent cursor position at the time)
Anyone could figure why?
I I thought that the space was inserted by Tabularize, then I solved with this little mod of the gist:
inoremap <silent> <Bar> <Bar><Esc>:call <SID>align()<CR>a
function! s:align()
let p = '^\s*|\s.*\s|\s*$'
if exists(':Tabularize') && getline('.') =~# '^\s*|' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p)
let column = strlen(substitute(getline('.')[0:col('.')],'[^|]','','g'))
let position = strlen(matchstr(getline('.')[0:col('.')],'.*|\s*\zs.*'))
let ln = line('.')
Tabularize/|/l1
"normal! 0
" Changed this row.
"but I have also to check if the table row was the last, in order to not mess the table under the row edited:
if getline('.') =~# '^\s*|' && getline(line('.')+1) =~# p
execute "normal }k\<C-v>".ln."Gjhx".ln."G"
endif
execute "normal {j\<C-v>".ln."Ghx".ln."G"
call search(repeat('[^|]*|',column).'\s\{-\}'.repeat('.',position),'ce',line('.'))
endif
endfunction
If someone would comment about mistakes or suggest anything I'll be happy.
For those interested, I made a little plugin that extends this concept to creating full fledged tables as you type :). It is available here - https://github.com/dhruvasagar/vim-table-mode. You can put
let g:table_mode_border=0in your vimrc to get the same behavior as this plugin.Also you can change the separator itself by
let g:table_mode_separator='='or whatever you need to achieve the same effect for other type of characters. Please refer to the:h table-mode.txtfor more information. Feedback is welcome :).Thanks.