Created
January 26, 2017 12:20
-
-
Save gregoryv/b4b95bca669556a6ea3561d0b0efc95e to your computer and use it in GitHub Desktop.
Find and got place in file script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
=head1 NAME - gogrep | |
Written by Gregory Vincic <g@7de.se> | |
=head1 DESCRIPTION | |
Looks for a statemet within files. If .gitignore is found in current | |
directory those files and directories are also excluded. Note that the syntax | |
is slightly different between greps exclude format and .gitignore. | |
Each found statement is numbered so the user can easily open the file on the specific line. | |
$EDITOR is used. | |
=head1 USAGE | |
gogrep REGEXP [GOTOINDEX] | |
=cut | |
use Term::ANSIColor qw(:constants); | |
# Build exclude from .gitignore if found | |
$exclude = ""; | |
if( -e ".gitignore" ) { | |
open(GI, ".gitignore"); | |
foreach(<GI>) { | |
chomp; | |
if(/\/$/) { | |
s/\/$//; | |
$exclude .= ' --exclude-dir="'. $_ . '"'; | |
} else { | |
$exclude .= ' --exclude="'. $_ . '"'; | |
} | |
} | |
close(GI); | |
} | |
# Search for todo expressions using grep | |
$statement = shift @ARGV; | |
$root = "."; | |
if( -d $statement ) { | |
$root = $statement; | |
$statement = shift @ARGV; | |
} | |
if(scalar(@ARGV) == 1 && $ARGV[0] =~ /(\d+)/) { | |
$gotoindex = $1; | |
} | |
$cmd='grep -rnIE ' . $exclude . ' --exclude-dir=".git" ' .'"' . $statement . '" ' . $root; | |
#print $cmd unless $gotoindex; | |
@changes=`$cmd`; | |
# Group lines by todo_NAME | |
%groups; | |
foreach(@changes) { | |
$line = $_; | |
$name = "No group\n"; | |
if(/.*todo_(\w+).*/) { | |
$name = $1; | |
} | |
if(!$groups{$name}) { | |
$groups{$name} = (); | |
} | |
push @{$groups{$name}}, $line; | |
} | |
# Print result | |
%same = (); | |
$count = 0; | |
sub parts { | |
$line = @_[0]; | |
$line =~ /([^:]+):(\d+):(.*)/; | |
$file = $1; | |
$no = $2; | |
$str = $3; | |
# Remove spaces at beginning of line | |
$str =~ s/^\s*//; | |
$str =~ s/^\/*//; | |
$str =~ s/^\**\s*//; | |
#$str =~ s/^[^#]+//; | |
$str =~ s/^#\s*//; | |
$str =~ s/^@//; | |
return $file, $no, $str; | |
} | |
my @found = (); | |
@sorted = sort(keys(%groups)); | |
push(@sorted, shift(@sorted)); # move no group last | |
foreach(@sorted) { | |
$name = $_; | |
print YELLOW, $name, RESET unless $gotoindex; | |
foreach(@{$groups{$name}}) { | |
$line = $_; | |
$file, $no, $str = &parts($line); | |
$found[$count] = "$file:$no"; | |
$count++; | |
if(!$same{$file}) { # Group all todos in the same file | |
$same{$file} = 1; | |
printf "\n %s:\n", $file unless $gotoindex; | |
} | |
printf " (%s%d%s) %4d: %s\n", WHITE, $count, RESET, $no, $str unless $gotoindex; | |
} | |
#print "\n"; | |
} | |
unless($gotoindex) { | |
# Let user select a match | |
my $range = ($count == 1) ? 1 : "1-$count"; | |
print "\nSelect $range: "; | |
$gotoindex = <STDIN>; | |
chomp ($gotoindex); | |
} | |
exit 0 unless($gotoindex); | |
# Open selected todo | |
if ( $gotoindex =~ /\d+/) { | |
$gotoindex--; | |
$entry = $found[$gotoindex]; | |
my ($path, $line) = split(':', $entry); | |
`emacsclient -n +$line $path`; | |
exit 0; | |
} | |
if ($gotoindex) { | |
$all = join(" ", @found); | |
print $all, "\n"; | |
foreach $entry (@found) { | |
my ($path, $line) = split(':', $entry); | |
`emacsclient -n +$line $path`; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment