Skip to content

Instantly share code, notes, and snippets.

@tpope
Created January 26, 2010 19:51
Show Gist options
  • Select an option

  • Save tpope/287147 to your computer and use it in GitHub Desktop.

Select an option

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
@roman

roman commented Feb 23, 2011

Copy link
Copy Markdown

I'm wondering, what does the "l1" option on the match of the Tabularize?

@tpope

tpope commented Feb 27, 2011

Copy link
Copy Markdown
Author

l means left align; 1 means one space of padding.

@agibralter

Copy link
Copy Markdown

Would you recommend putting this in a ftplugin so as to not slow down non-cucumber-related file editing?

@tpope

tpope commented Mar 29, 2011

Copy link
Copy Markdown
Author

If you do, make sure you add <buffer> to the map. In practice, I haven't had any issues with it being global.

@agibralter

Copy link
Copy Markdown

Ah cool, thank you!

@tswicegood

Copy link
Copy Markdown

FYI: I just added this to my after/ftplugin/cucumber.vim and it works like a charm. Very nice.

@nmunson

nmunson commented May 17, 2011

Copy link
Copy Markdown

Thanks! Added this to my vimrc and it works perfectly.

@jznhljg

jznhljg commented Jul 28, 2011

Copy link
Copy Markdown

I copied this into my .vimrc. And I have installed Tabular.vim successfully.
But it doesn't work. I input ab | cd | ef and nothing happened. What's wrong?!

@tpope

tpope commented Jul 28, 2011

Copy link
Copy Markdown
Author

@jznhljg, that doesn't look like a valid Cucumber table to me.

@jznhljg

jznhljg commented Jul 28, 2011

Copy link
Copy Markdown

@tpope, I just want to edit some plain text, can I use this function to automatically adjust the padding space?

@tpope

tpope commented Jul 28, 2011

Copy link
Copy Markdown
Author

Sure, if you relax the regex a bit. As it stands now, it's hell bent on avoiding false positives.

@jznhljg

jznhljg commented Jul 28, 2011 via email

Copy link
Copy Markdown

@ests

ests commented Sep 7, 2011

Copy link
Copy Markdown

I was looking for some solution for dealing with Cuke tables in gVIM similar or close to the one TextMate bundle for Cucumber has.
But this is so much better, thanks a lot Tim, as usual :)

@MaienM

MaienM commented Oct 2, 2011

Copy link
Copy Markdown

For those interested, I made a modified version of this that does the same for equals (=) signs. You can find it in the list of forks to the right, or here: https://gist.github.com/1258015
Credits still go to Tim for the awesome original, I just made a few small changes.

@quentindecock

Copy link
Copy Markdown

For those who are interested I made a little plugin that you can use easily with pathogen, it is available here: https://github.com/quentindecock/vim-cucumber-align-pipes

Feedback are welcome,

Enjoy,

@dhruvasagar

Copy link
Copy Markdown

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=0 in 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.txt for more information. Feedback is welcome :).

Thanks.

@wildskyf

Copy link
Copy Markdown

This is really useful!
Thx a lot!

@timabell

Copy link
Copy Markdown

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

@eternalcyan

Copy link
Copy Markdown

this function really awesome! thanks

@zoliky

zoliky commented Mar 26, 2020

Copy link
Copy Markdown

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!

@tpope

tpope commented Mar 26, 2020

Copy link
Copy Markdown
Author

Sure, make it a <buffer> map and unmap it in b:undo_ftplugin.

@namjul

namjul commented Feb 19, 2021

Copy link
Copy Markdown

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
end

@rodhash

rodhash commented May 23, 2022

Copy link
Copy Markdown

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 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.

@Harsha9554

Copy link
Copy Markdown

@namjul hey thank you so much, worked like a charm.

@rockyzhang24

Copy link
Copy Markdown

@namjul it works perfectly. Thanks a lot.

@antoniopaolini

Copy link
Copy Markdown

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?

@antoniopaolini

Copy link
Copy Markdown

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment