pericmd 033: More on tab completion (5): Hash answer

Simpler complete_*() functions will just return the list of words as an array, e.g.:

complete_array_elem(word=>"a", array=>[qw/an apple a day keeps the doctor away/]);
# -> ["a", "an", "apple", "away"]

But actually completion routine can also return a hash structure. This is described in Complete. For example:

{words=>["a", "an", "apple", "away"]}

Aside from words which is the meat of the answer, a hash can contain some other keys for metadata/hints for formatting. I’m just going to mention 2 of such keys. The others you can read for yourself in the Complete or Complete::Bash’s POD (or will perhaps be discussed in later posts.)

path_sep

As you probably noticed from the previous blog post (pericmd 032), complete_module() function from Complete::Module routines return a hash with path_sep key set to the path separator:

complete_module(word=>"Complete::P");
# -> {words=>["Complete::Path", "Complete::Pod::Weaver"], path_sep=>"::"}

complete_module(word=>"Complete/Po", dig_leaf=>0);
# -> {words=>["Complete/Pod/"], path_sep=>"/"}

The path_sep key is useful to give hints for, e.g. Complete::Bash (the module that formats the completion answer to stdout for bash). In bash, when a completion routine returns a single entry, bash will add a space to let user move to the next word since the completion is already unambiguous. For example, you already type “Cha” before pressing Tab, and there is only a single file that begins with “Cha” (“Changes”). bash will then change the current word “Cha” to “Changes” and add a space. This is fine when we are completing file/non-folder entity, but suppose the single completion you have for “li” is the directory “lib/”, and bash automatically adds a space after “lib/”. Normally you’d want to have “lib/” right before cursor and without any space, so you can press Tab again to drill down inside that directory. Bash does not provide a way for programs to hint this behavior, so the Complete::Bash employs a trick of returning ["lib/", "lib/ "] instead of just ["lib/"]. This makes the completion ambiguous (there are two candidates) and bash replaces current word “li” with the common substring of the answers “lib/” without any space.

So path_sep will make Complete::Bash format the output of complete_module() in the previous example:

complete_module(word=>"Complete/Po", dig_leaf=>0);
# -> {words=>["Complete/Pod/"], path_sep=>"/"}

into this final output for bash (the second entry has an extra space at the end):

Complete/Pod/
Complete/Pod/ 

But this answer will not get an additional entry since it’s already ambiguous:

complete_module(word=>"Complete::P");
# -> {words=>["Complete::Path", "Complete::Pod::Weaver"], path_sep=>"::"}
Complete::Path
Complete::Pod::Weaver

In short, you can a path_sep key if you are returning a path-like thing and you want to let user drill down. If you do have a custom path-like completion, though, consider using Complete::Path which provides some other nice features like previously discussed (pericmd 032).

esc_mode

This key gives hints to Complete::Bash on how to escape the output, as there are some possible variant depending on what the user expects. A value of shellvar tells Complete::Bash not to escape “$” (dollar sign) to “\$”. Normally if we are completing filenames, for example, we’d want dollar signs to be escaped to avoid shell variable interpretation. But if we are completing shell variables, we do want the “$” to stay as “$”.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s