This is an automated email from Gerrit.

Tarek BOCHKATI (tarek.bouchk...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/6311

-- gerrit

commit 57414fb25b54d4a0454866137101f51c86b0d9dd
Author: Tarek BOCHKATI <tarek.bouchk...@gmail.com>
Date:   Wed Jun 9 22:47:46 2021 +0100

    telnet: add path auto-completion [RFC/WIP]
    
    limitations:
      give path hints only if the string starts with '/', './'
        (maybe '~/', PS: tcl glob do not support it)
      no windows support
      incomplete double quote support
      clean-up c code
    
    
    Change-Id: Iadd859d7c3ea7b090a9f7cb668b7a3eb30927444
    Signed-off-by: Tarek BOCHKATI <tarek.bouchk...@gmail.com>

diff --git a/src/server/startup.tcl b/src/server/startup.tcl
index 447b57c..c9fc2d4 100644
--- a/src/server/startup.tcl
+++ b/src/server/startup.tcl
@@ -24,10 +24,11 @@ proc POST {args} { prevent_cps }
 proc Host: {args} { prevent_cps }
 
 # list of commands we don't want to appear in autocomplete
+lappend _telnet_autocomplete_skip _telnet_cmd_autocomplete_helper
+lappend _telnet_autocomplete_skip _telnet_path_autocomplete_helper
 lappend _telnet_autocomplete_skip _telnet_autocomplete_helper
 
-# helper for telnet autocomplete
-proc _telnet_autocomplete_helper pattern {
+proc _telnet_cmd_autocomplete_helper pattern {
        set cmds [info commands $pattern]
 
        # skip matches in variable '_telnet_autocomplete_skip'
@@ -39,3 +40,47 @@ proc _telnet_autocomplete_helper pattern {
 
        return [lsort $cmds]
 }
+
+proc _telnet_path_autocomplete_helper pattern {
+       # TODO: IMPORTANT: quoted paths are not supported correctly
+
+       # get the last argument
+       # FIXME linux accepts double quotes in file names
+
+       if {[regexp -indices {["'][^"']+$} $pattern indices]} {
+               set offset [expr [lindex $indices 0] + 1]
+       } elseif {[regexp -indices {\S+$} $pattern indices]} {
+               set offset [lindex $indices 0]
+       } else {
+               return {}
+       }
+
+       set path_prefix [string range $pattern 0 [expr $offset - 1]]
+       set path_pattern [string range $pattern $offset end]
+
+       # TODO check windows support
+
+       set paths [glob -nocomplain $path_pattern]
+
+       # if it is a directorry append '/'
+       foreach path $paths {
+               if {[file isdirectory $path]} {
+                       append path /
+               }
+
+               lappend completions $path_prefix$path
+       }
+
+       return [lsort $completions]
+}
+
+# helper for telnet autocomplete
+proc _telnet_autocomplete_helper pattern {
+       set cmds [_telnet_cmd_autocomplete_helper $pattern]
+
+       if {[llength $cmds] > 0} {
+               return $cmds
+       }
+
+       return [_telnet_path_autocomplete_helper $pattern]
+}
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 2ad3791..faf656c 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -497,12 +497,14 @@ static void telnet_auto_complete(struct connection 
*connection)
                char *name = (char *)Jim_GetString(elem, NULL);
 
                /* validate the command */
+               /* TODO: rename variable with cmd prefix/suffix, because it 
contains paths as well */
                bool ignore_cmd = false;
                Jim_Cmd *jim_cmd = Jim_GetCommand(command_context->interp, 
elem, JIM_NONE);
 
                if (!jim_cmd) {
                        /* Why we are here? Let's ignore it! */
-                       ignore_cmd = true;
+                       /* TODO: maybe the TCL knows better
+                        * ignore_cmd = true; */
                } else if (jimcmd_is_oocd_command(jim_cmd)) {
                        struct command *cmd = jimcmd_privdata(jim_cmd);
 
@@ -545,16 +547,19 @@ static void telnet_auto_complete(struct connection 
*connection)
        /* end of command filtering */
 
        /* proceed with auto-completion */
-       if (list_empty(&matches))
+       if (list_empty(&matches)) {
                telnet_bell(connection);
-       else if (common_len == usr_cmd_len && list_is_singular(&matches) && 
t_con->line_cursor == t_con->line_size)
+       } else if (common_len == usr_cmd_len && list_is_singular(&matches) && 
t_con->line_cursor == t_con->line_size) {
                telnet_insert(connection, " ", 1);
-       else if (common_len > usr_cmd_len) {
+       } else if (common_len > usr_cmd_len) {
                int completion_size = common_len - usr_cmd_len;
                if (telnet_insert(connection, first_match + usr_cmd_len, 
completion_size)) {
                        /* in bash this extra space is only added when the 
cursor in at the end of line */
-                       if (list_is_singular(&matches) && t_con->line_cursor == 
t_con->line_size)
-                               telnet_insert(connection, " ", 1);
+                       if (list_is_singular(&matches) && t_con->line_cursor == 
t_con->line_size) {
+                               /* do not insert a whitespace if it's a 
directory */
+                               if (first_match[common_len - 1] != '/')
+                                       telnet_insert(connection, " ", 1);
+                       }
                }
        } else if (!list_is_singular(&matches)) {
                telnet_write(connection, "\n\r", 2);

-- 

Reply via email to