Here's an improved patch that also sorts ]LIB output.


On Sun, Jun 29, 2014 at 7:34 PM, David B. Lamkins <[email protected]>
wrote:

> Since )LIB and ]LIB will accept path names, I thought that it would be
> useful for them to display directories.
>
> Patch attached.
>
> Notes:
>
> 1) You must specify an absolute path. This is existing behavior,
> unchanged by the patch.
>
> 2) While the )LIB output is sorted, the ]LIB output is not. This is
> existing behavior, unchanged by the patch.
>
>


-- 
"Far out in the uncharted backwaters of the unfashionable end of the
Western Spiral arm of the Galaxy lies a small unregarded yellow sun.
Orbiting this at a distance of roughly ninety-eight million miles is an
utterly insignificant little blue-green planet whose ape-descended life
forms are so amazingly primitive that they still think programming in Java
is a pretty neat idea."

 -- With apologies to Douglas Adams, who I like to think would have
appreciated this.


http://soundcloud.com/davidlamkins
http://reverbnation.com/lamkins
http://reverbnation.com/lcw
http://lamkins-guitar.com/
http://lamkins.net/
http://successful-lisp.com/
Index: src/Command.cc
===================================================================
--- src/Command.cc	(revision 351)
+++ src/Command.cc	(working copy)
@@ -763,7 +763,7 @@
 }
 //-----------------------------------------------------------------------------
 void 
-Command::cmd_LIB1(ostream & out, const UCS_string & arg)
+Command::lib_common(ostream & out, const UCS_string & arg, int variant)
 {
    // 1. open directory
    //
@@ -771,10 +771,11 @@
 DIR * dir = open_LIB_dir(path, out, arg);
    if (dir == 0)   return;
 
-   // 2. collect .apl and .xml files
+   // 2. collect files and directories
    //
 vector<UCS_string> apl_files;
 vector<UCS_string> xml_files;
+vector<UCS_string> directories;
 
    for (;;)
        {
@@ -782,25 +783,50 @@
          if (entry == 0)   break;   // directory done
 
          UCS_string filename(entry->d_name);
+#ifdef _DIRENT_HAVE_D_TYPE
+         if (entry->d_type == DT_DIR)
+            {
+              if (filename[0] == '.') continue;
+              filename.append(UNI_ASCII_SLASH);
+              directories.push_back(filename);
+              continue;
+            }
+#endif
+
          const int dlen = strlen(entry->d_name);
-         if (filename[dlen - 1] != 'l')   continue;   // not .apl or .xml
-         if (filename[dlen - 4] != '.')   continue;   // not .apl or .xml
+         if (variant == 1)
+            {
+              if (filename[dlen - 1] != 'l')   continue;   // not .apl or .xml
+              if (filename[dlen - 4] != '.')   continue;   // not .apl or .xml
 
-         if (filename[dlen - 3] == 'a' && filename[dlen - 2] == 'p')
+              if (filename[dlen - 3] == 'a' && filename[dlen - 2] == 'p')
+                {
+                   filename.shrink(filename.size() - 4);   // skip extension
+                   apl_files.push_back(filename);
+                 }
+              else if (filename[dlen - 3] == 'x' && filename[dlen - 2] == 'm')
+                 {
+                   filename.shrink(filename.size() - 4);   // skip extension
+                   xml_files.push_back(filename);
+                 }
+            }
+         else
             {
-              filename.shrink(filename.size() - 4);   // skip extension
+              if (filename[0] == '.')   continue;         // skip dot files ...
+              if (filename[dlen - 1] == '~')   continue;  // and editor backups
               apl_files.push_back(filename);
             }
-         else if (filename[dlen - 3] == 'x' && filename[dlen - 2] == 'm')
-            {
-              filename.shrink(filename.size() - 4);   // skip extension
-              xml_files.push_back(filename);
-            }
        }
    closedir(dir);
 
-   // 3. sort filenames alphabetically
+   // 3. sort directories and filenames alphabetically
    //
+#ifdef _DIRENT_HAVE_D_TYPE
+DynArray(const UCS_string *, directory_names, directories.size());
+   loop(a, directories.size())   directory_names[a] = &directories[a];
+   UCS_string::sort_names(directory_names, directories.size());
+#endif
+
 DynArray(const UCS_string *, apl_filenames, apl_files.size());
    loop(a, apl_files.size())   apl_filenames[a] = &apl_files[a];
    UCS_string::sort_names(apl_filenames, apl_files.size());
@@ -809,11 +835,18 @@
    loop(x, xml_files.size())   xml_filenames[x] = &xml_files[x];
    UCS_string::sort_names(xml_filenames, xml_files.size());
 
-   // 4. merge APL and XML files, adding a + if both exist
+   // 4. list directories first, then files
    //
-DynArray(const UCS_string *, filenames, apl_files.size() + xml_files.size());
+DynArray(const UCS_string *, filenames, apl_files.size() + xml_files.size()
+#ifdef _DIRENT_HAVE_D_TYPE
+                                        + directories.size()
+#endif
+         );
 
 int count = 0;
+   loop(dd, directories.size())
+       filenames[count++] = directory_names[dd];
+
    for (int a = 0, x = 0;;)
        {
          if (a >= apl_files.size())   // end of apl_files reached
@@ -877,50 +910,15 @@
 }
 //-----------------------------------------------------------------------------
 void 
+Command::cmd_LIB1(ostream & out, const UCS_string & arg)
+{
+   Command::lib_common(out, arg, 1);
+}
+//-----------------------------------------------------------------------------
+void 
 Command::cmd_LIB2(ostream & out, const UCS_string & arg)
 {
-   // 1. open directory
-   //
-UTF8_string path;
-DIR * dir = open_LIB_dir(path, out, arg);
-   if (dir == 0)   return;
-
-   out << path << ":" << endl << endl;
-
-const int print_width = Workspace::get_PrintContext().get_PW();
-   for (int col = 0;;)   // scan files in directory
-       {
-         dirent * entry = readdir(dir);
-         if (entry == 0)   break;   // directory done
-
-         const int dlen = strlen(entry->d_name);
-
-#ifdef _DIRENT_HAVE_D_TYPE
-         if (entry->d_type != DT_REG &&
-             entry->d_type != DT_LNK)            continue; // not a regular file
-#else
-         if (dlen == 1 && entry->d_name[0] == '.')   continue;
-         if (dlen == 2 && entry->d_name[0] == '.'
-                       && entry->d_name[1] == '.')   continue;
-#endif
-
-         int next_col = ((col + 9)/9)*9;
-         if (col && (next_col + dlen) > print_width)
-            {
-              out << endl;
-              col = 0;
-            }
-
-         if (col)
-            {
-              do  out << " ";   while (++col % 9);
-            }
-          out << entry->d_name;
-          col += dlen;
-       }
-
-   out << endl;
-   closedir(dir);
+   Command::lib_common(out, arg, 2);
 }
 //-----------------------------------------------------------------------------
 void 
Index: src/Command.hh
===================================================================
--- src/Command.hh	(revision 351)
+++ src/Command.hh	(working copy)
@@ -109,6 +109,9 @@
    static DIR * open_LIB_dir(UTF8_string & path, ostream & out,
                             const UCS_string & arg);
 
+   /// list library: common helper
+   static void lib_common(ostream & out, const UCS_string & args, int variant);
+
    /// list content of workspace and wslib directories: )LIB [N]
    static void cmd_LIB1(ostream & out, const UCS_string & args);
 

Reply via email to