hoaproject / Console

The Hoa\Console library.
https://hoa-project.net/
366 stars 32 forks source link

New autocompleters: aggregate and path #11

Closed Hywan closed 10 years ago

Hywan commented 10 years ago

Introduction

Firstly, an example:

<?php

require '/usr/local/lib/Hoa/Core/Core.php';

Hoa\Core::enableErrorHandler();
Hoa\Core::enableExceptionHandler();

$readline = new Hoa\Console\Readline\Readline();
$readline->setAutocompleter(
    new Hoa\Console\Readline\Autocompleter\Aggregate([
        new Hoa\Console\Readline\Autocompleter\Path(),
        new Hoa\Console\Readline\Autocompleter\Word(
            get_defined_functions()['internal']
        )
    ])
);

do {

    $rl = $readline->readLine('> ');
    echo '< ', $rl, "\n";

} while(true);

will produce: path_autocompleter This example is a mix between the Path and Word autocompleters, gathered into the Aggregate autocompleter.

“Regression”

The Hoa\Console\Readline\Autocompleter\Autocompleter::complete method sees its only argument passed by-reference (previously $prefix, now &$prefix). The impact is not important since the update is really easy and without any trivial side-effect. Moreover, this only concerns the readline when working on a regular STDIN, not a critical part of any applications.

Aggregate

The order of autocompleters is important. If an autocompleter is not able to recognize a word, we try another one. If it recognizes, but not able to autocomplete, then we try another one. Does it seem legit enough for you? We can go further and propose different menus for each autocompleters, but it starts to be difficult ;-) (and the code is so clean for now… :-]).

Pro tips: the getWordDefinition returns .* to get everything from the beginning of the line to the cursor.

Path

The Path autocompleter is able to autocomplete paths. I'm not sure about the word definition for a path. Can someone review it? It autocompletes based on a list of SplFileInfo instances (do we need to test with an instanceof in the code?) through an iterator. The iterator can be very sophisticated, e.g. Hoa\File\Finder, in order to select a subset of files based on their group, size, x time etc. However, a default iterator factory based on DirectoryIterator is provided. The factory takes the form of a simple closure. By default, the root is set to the current working directory. If we would like to work with absolute paths, we have to set the root to /.

Thoughts?

Hywan commented 10 years ago

Here is an example with an iterator factory:

<?php

require '/usr/local/lib/Hoa/Core/Core.php';

use Hoa\Core;
use Hoa\Console\Readline;
use Hoa\Console\Readline\Autocompleter;
use Hoa\File;

Core::enableErrorHandler();
Core::enableExceptionHandler();

$readline = new Readline();
$readline->setAutocompleter(
    new Autocompleter\Aggregate([
        new Autocompleter\Path(
            Autocompleter\Path::PWD,
            function ( $path ) {

                $finder = new File\Finder();
                $finder->in($path)
                       ->files()
                       ->directories()
                       ->maxDepth(1)
                       ->sortBySize();

                return $finder;
            }
        ),
        new Autocompleter\Word(
            get_defined_functions()['internal']
        )
    ])
);

do {

    $rl = $readline->readLine('> ');
    echo '< ', $rl, "\n";

} while(true);

It works great!

What about testing the instance of $fileinfo in the loop of $iterator? Do we add a test like $fileinfo instanceof \SplFileInfo? If it fails, what do we do? We just continue (we skip this element) or we throw an exception?

Also, @Guiled asked for the support of hoa:// in Path. It can be achieved easily with a finder on hoa://! Flexible enough.

jubianchi commented 10 years ago

@Hywan thanks for the fixes ;) I will continue to test it in the shell ;)

Hywan commented 10 years ago

Thanks for the review!