[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Lost] [PATCH] sh - tab-completion für ?beliebige Befehle



On Tue, Sep 23 21:29, Nicolas Seufert wrote:
> Anbei mein erster und wenig erfolgreicher Versuch, apps/sh beizubringen,
> bei der tab-completion auch Programme in $PATH zu berücksichtigen.
> Das Ganze macht noch nicht ganz was erwünscht ist, würde es auch nicht
> wenn es funktionierte.
> - Der Inhalt von $PATH wird atm nur einmalig beim Start von sh gelesen.
> - Bei der Anzeige der zur Verfügung stehenden Befehle werden
> augenscheinlich die ersten 2 Zeichen des nächsten Befehlsnamens durch
> willkürliche ersetzt (?!)
> Kritik und natürlich Hinweise sind immer willkommen.
> 
> kaffeefilter

> Index: src/include/collections.h
> ===================================================================
> --- src/include/collections.h	(Revision 923)
> +++ src/include/collections.h	(Arbeitskopie)
> @@ -12,6 +12,7 @@
>  void list_destroy(list_t* list);
>  list_t* list_push(list_t* list, void* value);
>  void* list_pop(list_t* list);
> +void list_merge_into(list_t* target, list_t* to_merge);
>  bool list_is_empty(list_t* list);
>  void* list_get_element_at(list_t* list, int index);
>  list_t* list_insert(list_t* list, int index, void* value);
> Index: src/lib/collections/list.c
> ===================================================================
> --- src/lib/collections/list.c	(Revision 923)
> +++ src/lib/collections/list.c	(Arbeitskopie)
> @@ -163,7 +163,7 @@
>      }
>  
>      return value;
> -}
> +}    
>      
>  /**
>   * Gibt einen Knoten aus der Liste zur?ck. Wird von allen Funktionen benutzt,

Whitespace-Aenderungen sind grundsaetzlich nicht wirklich erwuenscht in
den Patches, und besonders wenn noch Trailing Spaces dazukommen, also
weg damit. ;-)

> @@ -212,6 +212,21 @@
>  }
>  
>  /**
> + * Vereinigt zwei Listen, indem eine Liste in die Ziel-Liste
> + * eingefuegt wird und das Quell-Listenhandle zerstoert wird.
> + * @param target Ziel-Liste
> + * @param to_merge Quell-Liste
> + */
> +void list_merge_into(list_t* target, list_t* to_merge)
> +{
> +    if ((!target) || (!to_merge)) return;
> +    (list_get_node_at(to_merge, ((to_merge->size)-1)))->next = target->anchor;
> +    target->anchor = to_merge->anchor;
> +    target->size += to_merge->size;
> +    free(to_merge);
> + }
void list_merge_into(list_t* dest, list_t* source)
{
    struct list_node* node;

    if (!dest || !source) {
        return;
    }

    node = list_get_node_at(source, source->size -1);
    node->next = dest->anchor;
    dest->size += source->size;

    free(source);
}

Für ein paar Klammern weniger und ein paar Leerzeilen sind wir immer dankbar. ;-)

> +
> +/**
>   * Fragt den Wert eines Listenelements ab.
>   *
>   * @param list Liste, deren Element abgefragt werden soll

Ich würde mal vorschlagen das du das hier in zwei Patches aufspaltest.


> Index: src/modules/c/shell/completion.c
> ===================================================================
> --- src/modules/c/shell/completion.c	(Revision 923)
> +++ src/modules/c/shell/completion.c	(Arbeitskopie)
> @@ -44,6 +44,8 @@
>  
>  #include "shell.h"
>  
> +static list_t* executables_in_path;
> +
>  /**
>   * Completion-Handler fuer Readline
>   *
> @@ -56,13 +58,23 @@
>  /**
>   * Matches in Befehlen suchen
>   *
> + * @param word  Wort, das vervollstaendigt werden soll
>   * @return Pointer auf Array oder NULL wenn keine Gefunden wurden
>   */
>  static char** shell_command_matches(const char* word);
>  
>  /**
> + * Matches in Befehlen suchen, die nicht in shell_commands[]
> + * vorhanden sind.
> + *
> + * @param word  Wort, das vervollstaendigt werden soll
> + * @return Pointer auf list_t oder NULL bei null Uebereinstimmungen
> + */
> +static list_t* shell_executable_matches(const char* word);
> +/**
>   * Matches in Umgebungsvariabeln suchen
>   *
> + * @param word  Wort, das vervollstaendigt werden soll
>   * @return Pointer auf Array oder NULL wenn keine Gefunden wurden
>   */
>  static char** shell_envvar_matches(const char* word);
> @@ -70,6 +82,7 @@
>  /**
>   * Matches in Dateien
>   *
> + * @param word  Wort, das vervollstaendigt werden soll
>   * @return Pointer auf Array oder NULL wenn keine Gefunden wurden
>   */
>  static char** shell_file_matches(const char* word);
> @@ -84,6 +97,7 @@
>   */
>  void completion_init()
>  {
> +    update_path_env();

Das wäre von mir aus gesehen praktischer wenn man das einfach in
update_path_env zusammensucht.

>      rl_attempted_completion_function = rl_completion;
>  }
>  
> @@ -110,6 +124,26 @@
>      return matches;
>  }
>  
> +void update_path_env(void)
> +{
> +    io_resource_t* dir;
> +    io_direntry_t* dentry;
> +    list_t* executables;
> +    
> +    const char* path = getenv("PATH");

Wenn wir hier mehrere Verzeichnisse haben, kommt das nicht gut raus.
Versuchs mal irgendwie so:

dirname = strtok(path, ";");
while (dirname != NULL) {
...
    dirname = strtok(NULL, ";");
}


> +    if ((dir = directory_open(path)) == NULL) return;

if (!(dir = directory_open(path))) {
	return;
}

> +    executables = list_create();
> +    while ((dentry = directory_read(dir))) {
> +        if (dentry->type == IO_DIRENTRY_DIR) continue;

if (dentry->type != IO_DIRENTRY_DIR) {

> +        list_push(executables, strdup (dentry->name));

}

> +    }
> +    
> +    list_destroy(executables_in_path);
> +    executables_in_path = executables;
> +}
> +    
> +    


So, genug für heute, ich gehe auch schlafen. ;-)

-- 
Antoine Kaufmann
<toni@xxxxxxxxxxxxxxxx>

Attachment: pgp9tklEJxWx5.pgp
Description: PGP signature