Source-Changes-HG archive

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

[src/trunk]: src/lib/libedit Handle filename autocompletion when the cursor i...



details:   https://anonhg.NetBSD.org/src/rev/755db68c067b
branches:  trunk
changeset: 832254:755db68c067b
user:      abhinav <abhinav%NetBSD.org@localhost>
date:      Fri May 04 16:39:14 2018 +0000

description:
Handle filename autocompletion when the cursor is at a backslash or quote character

For example, handle following case:
        $ touch 'foo bar'
        $ ls foo\<TAB> --> $ ls foo\ bar

Also add test cases for this.

Thanks to Christos for review

diffstat:

 lib/libedit/TEST/test_filecompletion.c |  23 ++++++++++++-
 lib/libedit/filecomplete.c             |  60 ++++++++++++++++++++++++++-------
 2 files changed, 68 insertions(+), 15 deletions(-)

diffs (135 lines):

diff -r b72094d61d12 -r 755db68c067b lib/libedit/TEST/test_filecompletion.c
--- a/lib/libedit/TEST/test_filecompletion.c    Fri May 04 15:51:53 2018 +0000
+++ b/lib/libedit/TEST/test_filecompletion.c    Fri May 04 16:39:14 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: test_filecompletion.c,v 1.2 2017/10/15 19:17:30 abhinav Exp $  */
+/*     $NetBSD: test_filecompletion.c,v 1.3 2018/05/04 16:39:15 abhinav Exp $  */
 
 /*-
  * Copyright (c) 2017 Abhinav Upadhyay <abhinav%NetBSD.org@localhost>
@@ -449,6 +449,27 @@
                "dampers&and",
                L"ls \"dampers&and\" "
        },
+       {
+               /* test completion when cursor at \ */
+               L"ls foo\\",
+               "foo",
+               "foo bar",
+               L"ls foo\\ bar "
+       },
+       {
+               /* test completion when cursor at single quote */
+               L"ls foo'",
+               "foo",
+               "foo bar",
+               L"ls foo\\ bar "
+       },
+       {
+               /* test completion when cursor at double quote */
+               L"ls foo\"",
+               "foo",
+               "foo bar",
+               L"ls foo\\ bar "
+       }
 };
 
 static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{(";
diff -r b72094d61d12 -r 755db68c067b lib/libedit/filecomplete.c
--- a/lib/libedit/filecomplete.c        Fri May 04 15:51:53 2018 +0000
+++ b/lib/libedit/filecomplete.c        Fri May 04 16:39:14 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: filecomplete.c,v 1.49 2018/05/02 08:45:03 abhinav Exp $        */
+/*     $NetBSD: filecomplete.c,v 1.50 2018/05/04 16:39:14 abhinav Exp $        */
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: filecomplete.c,v 1.49 2018/05/02 08:45:03 abhinav Exp $");
+__RCSID("$NetBSD: filecomplete.c,v 1.50 2018/05/04 16:39:14 abhinav Exp $");
 #endif /* not lint && not SCCSID */
 
 #include <sys/types.h>
@@ -528,6 +528,48 @@
        }
 }
 
+static wchar_t *
+find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
+    const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length)
+{
+       /* We now look backwards for the start of a filename/variable word */
+       const wchar_t *ctemp = cursor;
+       int cursor_at_quote;
+       size_t len;
+       wchar_t *temp;
+
+       /* if the cursor is placed at a slash or a quote, we need to find the
+        * word before it
+        */
+       if (ctemp > buffer) {
+               switch (ctemp[-1]) {
+               case '\\':
+               case '\'':
+               case '"':
+                       cursor_at_quote = 1;
+                       ctemp--;
+                       break;
+               default:
+                       cursor_at_quote = 0;
+               }
+       }
+       while (ctemp > buffer
+           && !wcschr(word_break, ctemp[-1])
+           && (!special_prefixes || !wcschr(special_prefixes, ctemp[-1])))
+               ctemp--;
+
+       len = (size_t) (cursor - ctemp - cursor_at_quote);
+       temp = el_malloc((len + 1) * sizeof(*temp));
+       if (temp == NULL)
+               return NULL;
+       (void) wcsncpy(temp, ctemp, len);
+       temp[len] = '\0';
+       if (cursor_at_quote)
+               len++;
+       *length = len;
+       return temp;
+}
+
 /*
  * Complete the word at or before point,
  * 'what_to_do' says what to do with the completion.
@@ -551,7 +593,6 @@
        const LineInfoW *li;
        wchar_t *temp;
        char **matches;
-       const wchar_t *ctemp;
        size_t len;
        int what_to_do = '\t';
        int retval = CC_NORM;
@@ -568,20 +609,11 @@
        if (!app_func)
                app_func = append_char_function;
 
-       /* We now look backwards for the start of a filename/variable word */
        li = el_wline(el);
-       ctemp = li->cursor;
-       while (ctemp > li->buffer
-           && !wcschr(word_break, ctemp[-1])
-           && (!special_prefixes || !wcschr(special_prefixes, ctemp[-1]) ) )
-               ctemp--;
-
-       len = (size_t)(li->cursor - ctemp);
-       temp = el_malloc((len + 1) * sizeof(*temp));
+       temp = find_word_to_complete(li->cursor,
+           li->buffer, word_break, special_prefixes, &len);
        if (temp == NULL)
                goto out;
-       (void)wcsncpy(temp, ctemp, len);
-       temp[len] = '\0';
 
        /* these can be used by function called in completion_matches() */
        /* or (*attempted_completion_function)() */



Home | Main Index | Thread Index | Old Index