2010-04-22 7 views
4

커맨드 라인에서 점진적 검색 (find-as-you-type) 기능이있는 작은 스크립트를 작성하고 싶습니다.커맨드 라인에서 증분 (find-as-you-type) 검색을 구현하려면 어떻게해야합니까?

사용 사례 : USB를 통해 휴대폰을 연결했습니다. gammu --sendsms TEXT를 사용하여 텍스트 메시지를 쓸 수 있습니다. 나는 CSV로 전화 번호부를 가지고 있고, 그것에 관해서는 검색 형으로하고 싶다.

가장 쉬운 방법은 무엇입니까? bash/zsh/Perl/Python 또는 다른 스크립팅 언어 일 수 있습니다.

편집 : 해결책 : 수정하려는 내용은 Term::Complete입니다. 대답은 아래를 참조하십시오.

답변

4

Aiden Bell의 힌트에 따라 Perl에서 Readline을 시도했습니다. 해결 방법 1 사용 기간 : 전체 (또한 CPAN에서 사용하는, 내가 생각하는) :

use Term::Complete; 
my $F; 
open($F,"<","bin/phonebook.csv"); 
my @terms = <$F>; chomp(@terms); 
close($F); 


my $input; 
while (!defined $input) { 
    $input = Complete("Enter a name or number: ",@terms); 
    my ($name,$number) = split(/\t/,$input); 
    print("Sending SMS to $name ($number).\n"); 
    system("sudo gammu --sendsms TEXT $number"); 
} 

을 눌러 \ 모든 가능성을 참조하려면 Ctrl-D를 완료합니다.

해결 방법 2 : Ctrl-D는 하나의 키 스트로크이기 때문에 표준 Term :: Readline을 사용하면 완료가 가능하고 \ 만 사용하여 가능한 완성을 표시 할 수 있습니다.

use Term::ReadLine; 

my $F; 
open($F,"<","bin/phonebook.csv"); 
my @terms = <$F>; chomp(@terms); 
close($F); 

my $term = new Term::ReadLine; 
$term->Attribs->{completion_function} = sub { return @terms; }; 

my $prompt = "Enter name or number >> "; 

my $OUT = $term->OUT || \*STDOUT; 
while (defined (my $input = $term->readline($prompt))) { 
    my ($name,$number) = split(/\t/,$input); 
    print("Sending SMS to $name ($number).\n"); 
    system("sudo gammu --sendsms TEXT $number"); 
} 

이 솔루션은 여전히 ​​완료해야합니다.

편집 : 최종 솔루션 수정 기간 : 전체 (http://search.cpan.org/~jesse/perl-5.12.0/lib/Term/Complete.pm)는 즉시 완료 나를 준다.

소스 코드 : http://search.cpan.org/CPAN/authors/id/J/JE/JESSE/perl-5.12.0.tar.gz 솔루션 번호 1이 수정되었습니다. 이것은 누군가에 의해 사용될 수 있다면 다른 곳에서 온라인으로 전체 샘플을 넣어 것입니다

Completion.pm (그냥 각 문자에 대한 제어-D와 \에 대한 코드의 재사용)의 수정 :

170c172,189

 my $redo=0; 

       @match = grep(/^\Q$return/, @cmp_lst); 
       unless ($#match < 0) { 
        $l = length($test = shift(@match)); 
        foreach $cmp (@match) { 
         until (substr($cmp, 0, $l) eq substr($test, 0, $l)) { 
          $l--; 
         } 
        } 
        print("\a"); 
        print($test = substr($test, $r, $l - $r)); 
          $redo = $l - $r == 0; 
          if ($redo) { print(join("\r\n", '', grep(/^\Q$return/, @cmp_lst)), "\r\n"); } 
        $r = length($return .= $test); 
       } 
        if ($redo) { redo LOOP; } else { last CASE; } 

+0

나는 모든 키 입력을 할 수 없다면 어렵게 눌렀을 것이라고 생각합니다. 이러한 것들은 완전한 절차를 호출하기위한 방아쇠가 필요합니다. –

+0

+1 멋진 작은 해킹. –

4

나는 이런 인상을받습니다. GNU Readline이 종류의 것을 지원합니다. 그러나, 나는 그것을 직접 사용하지 않았다. Here is a C++ example은 C에서 쉽게 수행 할 수있는 맞춤식 자동 완성 기능을 제공합니다. readline에 대해서도 Python API이 있습니다.

This StackOverflow question 배쉬 자동 완성에

import readline 
def completer(text, state): 
    options = [x in addrs where x.startswith(text)] 
    if state < options.length: 
     return options[state] 
    else 
     return None 
readline.set_completer(completer) 

this article 도움이 될 수 있습니다 ... 그 중 하나 파이썬에서 예제를 제공합니다. 이 기사는 또한 bash의 자동 완성 기능 프로그래밍 예제를 제공합니다.

+1

bash 자동 완성 기능을 사용하는 것은 흥미로운 아이디어입니다. 더군다나 나는 readline과 ncurses에 대한 링크를 좋아한다. (나는 때때로 zsh와 bash 사이를 전환한다.) 감사! –

+0

표준 readline은 완료하려면 이 필요합니다. readline을 사용하는 솔루션을 아직 찾지 못했지만 키 (즉석에서 검색)가 필요하지 않습니다. –

관련 문제