[pve-devel] r5609 - pve-manager/pve2/bin

svn-commits at proxmox.com svn-commits at proxmox.com
Thu Feb 24 09:57:26 CET 2011


Author: dietmar
Date: 2011-02-24 09:57:26 +0100 (Thu, 24 Feb 2011)
New Revision: 5609

Modified:
   pve-manager/pve2/bin/pvesh
Log:
fix path completion


Modified: pve-manager/pve2/bin/pvesh
===================================================================
--- pve-manager/pve2/bin/pvesh	2011-02-24 05:38:05 UTC (rev 5608)
+++ pve-manager/pve2/bin/pvesh	2011-02-24 08:57:26 UTC (rev 5609)
@@ -58,34 +58,74 @@
 my $term = new Term::ReadLine ('pvesh');
 my $attribs = $term->Attribs;
 
-$attribs->{completion_function} = sub {
-    my ($text, $line, $start) = @_;
+sub complete_path {
+    my($text) = @_;
 
-    my $prefix = substr($line, 0, $start);
-    if ($prefix =~ /^\s*$/) { # first word (command completeion)
-	return qw(help ls cd get set create delete quit);
-    }
+    my ($dir, undef, $rest) = $text =~ m|^(.+/)?(([^/]*))?$|;
 
-    if ($prefix =~ /^\s*\S+\s+$/) { # second word (path completion)
-	my ($dir, undef, $rest) = $text =~ m|^(.+/)?(([^/]*))?$|;
-    
-	my $path = abs_path($cdir, $dir);
+    my $path = abs_path($cdir, $dir);
 
-	my @res = ();
+    my @res = ();
 
-	my $di = dir_info($path);
-	if (my $children = $di->{children}) {
-	    foreach my $c (@$children) {
+    my $di = dir_info($path);
+    if (my $children = $di->{children}) {
+	foreach my $c (@$children) {
+	    if ($c =~ /^\Q$rest/) {
 		my $new =  $dir ? "$dir$c" : $c;
-		push @res, $new;
+		push @res, $new; 
 	    }
 	}
-	return @res;
     }
 
-    return qw();
+    if (scalar(@res) == 0) {
+	return undef;
+    } elsif (scalar(@res) == 1) {
+	return ($res[0], $res[0], "$res[0]/");
+    } 
+
+    # lcd : lowest common denominator
+    my $lcd = '';
+    my $tmp = $res[0];
+    for (my $i = 1; $i < length($tmp); $i++) {
+	my $found = 1;
+	foreach my $p (@res) {
+	    if (substr($tmp, 0, $i) ne substr($p, 0, $i)) {
+		$found = 0;
+		last;
+	    }
+	}
+	if ($found) {
+	    $lcd = substr($tmp, 0, $i);
+	} else {
+	    last;
+	}
+    }
+
+    return ($lcd, @res);
 };
 
+# just to avoid an endless loop (called by attempted_completion_function)
+$attribs->{completion_entry_function} = sub {
+    my($text, $state) = @_;
+    return undef;
+};
+
+$attribs->{attempted_completion_function} = sub {
+    my ($text, $line, $start) = @_;
+
+    my $prefix = substr($line, 0, $start);
+    if ($prefix =~ /^\s*$/) { # first word (command completeion)
+	$attribs->{completion_word} = [qw(help ls cd get set create delete quit)];
+	return $term->completion_matches($text, $attribs->{list_completion_function});
+    }
+
+    if ($prefix =~ /^\s*\S+\s+$/) { # second word (path completion)
+	return complete_path($text);
+    }
+
+    return ();   
+};
+
 sub abs_path {
     my ($current, $path) = @_;
 



More information about the pve-devel mailing list