* Bug #13154 - In shellmode, completion now separates Files from Directories. 32/18132/2
Paul Bignier [Mon, 2 May 2016 09:21:03 +0000 (11:21 +0200)]
 * In a shellmode console, type -->"c and press Tab for completion:
there now is a File and a Directory section instead of one "File or Directory".
This aims to simplify use of cd() and exec().

Change-Id: I08c3f26ae6b1ad5fd2fcad8b5165b732fe069289

scilab/CHANGES
scilab/modules/console/src/c/cmdLine/autoCompletionCli.c
scilab/modules/console/src/c/windows/TermCompletion.c
scilab/modules/console/src/java/org/scilab/modules/console/SciCompletionManager.java

index 5b70ce9..d6d4e52 100644 (file)
@@ -353,6 +353,8 @@ In 6.0.0:
 
 * Bug #12872       - help pages of else, elseif, end, try, sciargs, global, halt, empty and power were in wrong help sections
 
+* Bug #13154       - In shellmode, completion now separates Files from Directories.
+
 * Bug #13465 fixed - The display of polyline .display_function and .display_function properties was not conventional
 
 * Bug #13468 fixed - Scilab hanged when incorrect format was used for file reading using mfscanf.
index 1b40fca..9b5a43f 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <sys/stat.h>
 #include "charEncoding.h"
 #include "completion.h"
 #include "autoCompletionCli.h"
@@ -52,6 +53,7 @@ static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFile
                                   char *lineBeforeCaret, char *lineAfterCaret, char *filePattern, char *defaultPattern,
                                   char **wk_buf, unsigned int *cursor, unsigned int *cursor_max);
 static int CopyLineAtPrompt(char **wk_buf, char *line, unsigned int *cursor, unsigned int *cursor_max);
+static void separateFilesDirectories(char** dictionnary, int size, char*** files, int* sizeFiles, char*** directories, int* sizeDirectories);
 
 static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern, char **wk_buf, unsigned int *cursor,
                                 unsigned int *cursor_max);
@@ -224,7 +226,17 @@ static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFile
         {
             char *common = getCommonPart(dictionaryFiles, sizedictionaryFiles);
 
-            displayCompletionDictionary(dictionaryFiles, sizedictionaryFiles, gettext("File or Directory"));
+            char** files;
+            int sizeFiles;
+            char** directories;
+            int sizeDirectories;
+            separateFilesDirectories(dictionaryFiles, sizedictionaryFiles, &files, &sizeFiles, &directories, &sizeDirectories);
+
+            //displayCompletionDictionary(dictionaryFiles, sizedictionaryFiles, gettext("File or Directory"));
+            displayCompletionDictionary(files, sizeFiles, gettext("File"));
+            displayCompletionDictionary(directories, sizeDirectories, gettext("Directory"));
+            freeArrayOfString(files, sizeFiles);
+            freeArrayOfString(directories, sizeDirectories);
 
             printf("\n");
 
@@ -318,6 +330,35 @@ static int CopyLineAtPrompt(char **wk_buf, char *line, unsigned int *cursor, uns
     return 0;
 }
 
+static void separateFilesDirectories(char** dictionary, int size, char*** files, int* sizeFiles, char*** directories, int* sizeDirectories)
+{
+    int i;
+    *files = NULL;
+    *sizeFiles = 0;
+    *directories = NULL;
+    *sizeDirectories = 0;
+    for (i = 0; i < size; ++i)
+    {
+        struct stat statbuf;
+        if (stat(dictionary[i], &statbuf) != 0)
+        {
+            return;
+        }
+        if (S_ISDIR(statbuf.st_mode))
+        {
+            (*sizeDirectories)++;
+            *directories = (char **) REALLOC(*directories, sizeof(char *) * (*sizeDirectories));
+            (*directories)[*sizeDirectories - 1] = strdup(dictionary[i]);
+        }
+        else
+        {
+            (*sizeFiles)++;
+            *files = (char **) REALLOC(*files, sizeof(char *) * (*sizeFiles));
+            (*files)[*sizeFiles - 1] = strdup(dictionary[i]);
+        }
+    }
+}
+
 static char **concatenateStrings(int *sizearrayofstring, char *string1, char *string2, char *string3, char *string4, char *string5)
 {
     int newsize = 0;
index 05a6da1..0f5b87f 100644 (file)
@@ -1,7 +1,7 @@
 /*
-* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-* Copyright (C) 2008-2010 - DIGITEO - Allan CORNET
-*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2008-2010 - DIGITEO - Allan CORNET
+ *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * and continues to be available under such terms.
  * For more information, see the COPYING file which you should have received
  * along with this program.
-*
-*/
+ *
+ */
 
 /*--------------------------------------------------------------------------*/
 #include <string.h>
 #include <stdlib.h>
+#include <sys/stat.h>
 #include "TermCompletion.h"
 #include "sci_malloc.h"
 #include "freeArrayOfString.h"
 #include "os_string.h"
 #include "completeLine.h"
 /*--------------------------------------------------------------------------*/
+#define S_ISDIR(x) (x & _S_IFDIR)
+/*--------------------------------------------------------------------------*/
 static void displayCompletionDictionary(char **dictionary, int sizedictionary, char *namedictionary);
 static char **concatenateStrings(int *sizearrayofstring, char *string1,
                                  char *string2, char *string3,
                                  char *string4, char *string5);
 static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFiles,
                                   char *lineBeforeCaret, char *lineAfterCaret, char *filePattern, char *defaultPattern);
+static void separateFilesDirectories(char** dictionnary, int size, char*** files, int* sizeFiles, char*** directories, int* sizeDirectories);
 static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern);
 /*--------------------------------------------------------------------------*/
 static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFiles,
@@ -57,8 +61,17 @@ static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFile
         {
             char *common = getCommonPart(dictionaryFiles, sizedictionaryFiles);
 
-            displayCompletionDictionary(dictionaryFiles,
-                                        sizedictionaryFiles, gettext("File or Directory"));
+            char** files;
+            int sizeFiles;
+            char** directories;
+            int sizeDirectories;
+            separateFilesDirectories(dictionaryFiles, sizedictionaryFiles, &files, &sizeFiles, &directories, &sizeDirectories);
+
+            //displayCompletionDictionary(dictionaryFiles, sizedictionaryFiles, gettext("File or Directory"));
+            displayCompletionDictionary(files, sizeFiles, gettext("File"));
+            displayCompletionDictionary(directories, sizeDirectories, gettext("Directory"));
+            freeArrayOfString(files, sizeFiles);
+            freeArrayOfString(directories, sizeDirectories);
 
             displayPrompt();
             newLine();
@@ -111,6 +124,57 @@ static void TermCompletionOnFiles(char **dictionaryFiles, int sizedictionaryFile
     }
 }
 /*--------------------------------------------------------------------------*/
+static void separateFilesDirectories(char** dictionary, int size, char*** files, int* sizeFiles, char*** directories, int* sizeDirectories)
+{
+    int i;
+    *files = NULL;
+    *sizeFiles = 0;
+    *directories = NULL;
+    *sizeDirectories = 0;
+    for (i = 0; i < size; ++i)
+    {
+        // Check that the item is a file or a directory
+        char* dict = dictionary[i];
+        int isCopy = 0;
+        int len = (int) strlen(dict);
+        if (len && dict[len - 1] == '\\')
+        {
+            isCopy = 1;
+            dict = os_strdup(dict);
+            dict[len - 1] = '\0';
+        }
+
+        struct stat statbuf;
+        if (stat(dict, &statbuf) == -1)
+        {
+            if (isCopy)
+            {
+                free(dict);
+            }
+            return;
+        }
+
+        if (S_ISDIR(statbuf.st_mode))
+        {
+            (*sizeDirectories)++;
+            *directories = (char **) REALLOC(*directories, sizeof(char *) * (*sizeDirectories));
+            (*directories)[*sizeDirectories - 1] = strdup(dictionary[i]);
+        }
+        else
+        {
+            (*sizeFiles)++;
+            *files = (char **) REALLOC(*files, sizeof(char *) * (*sizeFiles));
+            (*files)[*sizeFiles - 1] = strdup(dictionary[i]);
+        }
+
+        if (isCopy)
+        {
+            free(dict);
+        }
+
+    }
+}
+/*--------------------------------------------------------------------------*/
 static void TermCompletionOnAll(char *lineBeforeCaret, char *lineAfterCaret, char *defaultPattern)
 {
     if (defaultPattern)
@@ -318,7 +382,7 @@ static void displayCompletionDictionary(char **dictionary, int sizedictionary, c
         for (i = 0; i < sizedictionary; i++)
         {
             int newlenLine = lenCurrentLine + (int)strlen(dictionary[i]) + (int)strlen(" ");
-            if ( newlenLine >= (getConsoleWidth() - 10) )
+            if (newlenLine >= (getConsoleWidth() - 10))
             {
                 TerminalPrintf("\n");
                 lenCurrentLine = 0;
index 282afc1..92af690 100644 (file)
@@ -17,6 +17,7 @@ package org.scilab.modules.console;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.io.File;
 
 import org.scilab.modules.completion.Completion;
 import org.scilab.modules.localization.Messages;
@@ -60,9 +61,18 @@ public class SciCompletionManager implements CompletionManager {
         String fileSearchedPattern = ((SciInputParsingManager) inputParsingManager).getFilePartLevel(compLevel);
 
         String[] scilabFilesDictionnary = Completion.searchFilesDictionary(fileSearchedPattern);
-        addItemsToDictionnary(Messages.gettext("File or Directory"), scilabFilesDictionnary);
-
-        if (scilabFilesDictionnary == null) {
+        //addItemsToDictionnary(Messages.gettext("File or Directory"), scilabFilesDictionnary);
+
+        if (scilabFilesDictionnary != null) {
+            ArrayList<String> files = new ArrayList<String>();
+            ArrayList<String> directories = new ArrayList<String>();
+            separateFilesDirectories(scilabFilesDictionnary, files, directories);
+            String[] filesDictionnary = files.toArray(new String[files.size()]);
+            String[] directoriesDictionnary = directories.toArray(new String[directories.size()]);
+
+            addItemsToDictionnary(Messages.gettext("File"), filesDictionnary);
+            addItemsToDictionnary(Messages.gettext("Directory"), directoriesDictionnary);
+        } else {
             // Get the completion part used to filter the dictionary
             String searchedPattern = inputParsingManager.getPartLevel(compLevel);
             String commandLine = inputParsingManager.getCommandLine();
@@ -118,7 +128,23 @@ public class SciCompletionManager implements CompletionManager {
                 dictionnary.add(new CompletionItemImpl(type, items[i] + " (" + type + ")", items[i], Messages.gettext("No help")));
             }
         }
+    }
 
+    /**
+     * Separate files from directories
+     * @param scilabFilesDictionnary the input containing both
+     * @param filesDictionnary output: only the files
+     * @param directoriesDictionnary output: only the directories
+     */
+    public void separateFilesDirectories(String[] scilabFilesDictionnary, ArrayList<String> filesDictionnary, ArrayList<String> directoriesDictionnary) {
+        for (int i = 0; i < scilabFilesDictionnary.length; ++i) {
+            File cur = new File(scilabFilesDictionnary[i]);
+            if (cur.isDirectory()) {
+                directoriesDictionnary.add(new String(scilabFilesDictionnary[i]));
+            } else {
+                filesDictionnary.add(new String(scilabFilesDictionnary[i]));
+            }
+        }
     }
 
 }