source: perl/lib/BarnOwl/Completion.pm @ f907cf0

release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since f907cf0 was f907cf0, checked in by Nelson Elhage <nelhage@mit.edu>, 12 years ago
Show an error message if a completion module fails to load.
  • Property mode set to 100644
File size: 3.0 KB
RevLine 
[8eac1a5]1use warnings;
2use strict;
3
4=head1 NAME
5
6BarnOwl::Completion
7
8=head1 DESCRIPTION
9
10Hooks for tab-completion support in BarnOwl.
11
12=cut
13
14package BarnOwl::Completion;
15
16use BarnOwl::Completion::Context;
[5368d75]17use BarnOwl::Editwin qw(save_excursion text_before_point text_after_point
18                        point_move replace_region);
[8eac1a5]19
[c4efb46]20use List::Util qw(min first);
[8eac1a5]21
[b73bcbb]22our %completers = ();
23
[6e48560]24sub do_complete {
25    my $cmd = shift;
26    my $before = text_before_point();
27    my $after  = text_after_point();
28    BarnOwl::debug("Completing: $before-|-$after");
29    my $ctx = BarnOwl::Completion::Context->new($before, $after);
30
31    my @words = get_completions($ctx);
32    return unless @words;
33    my $prefix = common_prefix(@words);
34
[5368d75]35    if($prefix) {
36        insert_completion($ctx, $prefix, scalar @words == 1);
[6e48560]37    }
38
39    if(scalar @words > 1) {
40        show_completions(@words);
[5368d75]41    } else {
42        BarnOwl::message('');
43    }
44}
45
46sub insert_completion {
47    my $ctx = shift;
[f987504]48    my $completion = BarnOwl::quote(shift);
[5368d75]49    my $unique = shift;
50
[f987504]51    if($unique) {
52        $completion .= " ";
53    }
54
[5368d75]55    save_excursion {
56        point_move($ctx->word_start - $ctx->point);
57        BarnOwl::Editwin::set_mark();
58        point_move($ctx->word_end - $ctx->word_start);
[f987504]59        replace_region($completion);
[5368d75]60    };
[f987504]61    if(!length($ctx->words->[$ctx->word])) {
62        point_move(length($completion));
[6e48560]63    }
64}
65
66sub show_completions {
67    my @words = @_;
68    my $all = join(" ", map {BarnOwl::quote($_)} @words);
69    my $width = BarnOwl::getnumcols();
70    if (length($all) > $width-1) {
71        $all = substr($all, 0, $width-4) . "...";
72    }
73    BarnOwl::message($all);
74}
75
76sub common_prefix {
77    my @words = @_;
[c4efb46]78    my $len   = min(map {length($_)} @words);
[6e48560]79    my $pfx = '';
80    for my $i (1..$len) {
81        $pfx = substr($words[0], 0, $i);
82        if(first {substr($_, 0, $i) ne $pfx} @words) {
83            $pfx = substr($pfx, 0, $i-1);
84            last;
85        }
86    }
87
88    return $pfx;
89}
[8eac1a5]90
[b73bcbb]91
92sub get_completions {
93    my $ctx = shift;
94    my @words = ();
95    if($ctx->word == 0) {
96        return complete_command($ctx->words->[0]);
97    } else {
98        my $cmd = $ctx->words->[0];
99        my $word = $ctx->words->[$ctx->word];
100        if(exists($completers{$cmd})) {
101            return grep {$_ =~ m{^\Q$word\E}} $completers{$cmd}->($ctx);
102        }
103        return;
104    }
105}
106
107sub complete_command {
108    my $cmd = shift;
109    return grep {$_ =~ m{^\Q$cmd\E}} @BarnOwl::all_commands;
110}
111
112sub register_completer {
113    my $cmd = shift;
114    my $completer = shift;
115    $completers{$cmd} = $completer;
116}
117
118sub load_completers {
119    opendir(my $dh, BarnOwl::get_data_dir() . "/" . "lib/BarnOwl/Complete/") or return;
120    while(my $name = readdir($dh)) {
121        next if $name =~ m{^\.};
122        next unless $name =~ m{[.]pm$};
123        $name =~ s{[.]pm$}{};
124        eval "use BarnOwl::Complete::$name";
[f907cf0]125        if($@) {
126            BarnOwl::error("Loading completion module $name:\n$@\n");
127        }
[b73bcbb]128    }
129}
130
131$BarnOwl::Hooks::startup->add("BarnOwl::Completion::load_completers");
132
[8eac1a5]1331;
Note: See TracBrowser for help on using the repository browser.