On Tue, Jan 6, 2009 at 7:10 AM, Tim Chase <[email protected]> wrote:
>
> > Normally '/' in normal mode starts to search for the pattern horizontally
> > (line after line, left to right). Is it possible to search text
> vertically
> > (column after column, top to bottom) in vim?
> >
> > For example, the pattern 01100010 should highlight the second column of
> the
> > below text.
> >
> > 1001
> > 1111
> > 1111
> > 0011
> > 0000
> > 0010
> > 1111
> > 0000
>
> Assuming constant line-length...
>
> While it's a bit of an uuuuuuuuugly hack of a generated regexp,
> in vim7 (where List native types and join/split functions were
> added) you can use
>
> :let @/=join(split('01100010', '....@='), '\_.\{4}')
>
> where {4} is the number of characters per line. If all the lines
> in your file have the same length, you can pull that length in
> automatically by sniffing the length of the current line you're on:
>
> :let @/=join(split('01100010', '....@='),
> '\_.\{'.strlen(getline('.')).'}')
>
> which makes this nice for a mapping/command/function.
>
> As a bit of explanation, this sets your search register to the
> following regexp:
>
> 0\_.\{4}1\_.\{4}1\_.\{4}0\_.\{4}0\_.\{4}0\_.\{4}1\_.\{4}0
>
> You can then use n/N to search forward/backward for the pattern
> you've unceremoniously shoved in your search register. It should
> find the first character of the match, and if you have 'hls' set,
> will highlight through the last character (though it highlights
> it character-wise which looks a little funny).
>
> -tim
>
>
>
>
>
> >
>
Thanks for the ideas. Inspired by some of the above algorithms, I wrote a
small vim function using the perl interface to accomplish vertical
searching.
if( has( 'perl' ) )
function! VerticalSearch( pattern )
perl << END_OF_PERL_CODE
( $ok, $pattern ) = VIM::Eval( 'a:pattern' );
if( not $ok )
{
VIM::Msg( "Please provide a pattern", "Error" );
return;
}
use Data::Dumper;
$nLines = $curbuf->Count();
@transpose = ();
foreach $lineNumber ( 1 .. $nLines )
{
$line = $curbuf->Get( $lineNumber );
@lineArray = split //, $line;
$lineLength = scalar @lineArray;
$index = 0;
foreach my $row ( 0 .. $#lineArray )
{
$transpose[$index] .= $lineArray[ $row ];
$index++;
}
}
foreach my $column ( 0 .. $#transpose )
{
my $text = $transpose[ $column ];
$columnPlus1 = $column + 1;
while( $text =~ m/$pattern/g )
{
#VIM::Msg( "Text [$text] Prematch $`" );
$lineNumber = ( length $` ) + 1;
VIM::Msg( "Matched at line $lineNumber column $columnPlus1",
"Comment" );
$curwin->Cursor( $lineNumber, $column );
}
}
END_OF_PERL_CODE
endfunction
endif
Its possible improvements are:
- Handling empty lines
- Support for search, pause, continue search again when multiple matches
are found
- Highlighting matched text
- etc.
Gowtham
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---