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);