diff options
Diffstat (limited to 'appl/lib')
| -rw-r--r-- | appl/lib/complete.b | 93 | ||||
| -rw-r--r-- | appl/lib/mkfile | 3 | ||||
| -rw-r--r-- | appl/lib/readdir.b | 2 |
3 files changed, 97 insertions, 1 deletions
diff --git a/appl/lib/complete.b b/appl/lib/complete.b new file mode 100644 index 00000000..1a2e7713 --- /dev/null +++ b/appl/lib/complete.b @@ -0,0 +1,93 @@ +implement Complete; + +# Limbo translation by caerwyn of libcomplete on Plan 9 +# Subject to the Lucent Public License 1.02 + +include "sys.m"; + sys: Sys; + +include "string.m"; + str: String; + +include "complete.m"; + +include "readdir.m"; + readdir: Readdir; + +init() +{ + sys = load Sys Sys->PATH; + str = load String String->PATH; + readdir = load Readdir Readdir->PATH; +} + + +longestprefixlength(a, b: string, n: int): int +{ + for(i := 0; i < n; i++) + if(a[i] != b[i]) + break; + return i; +} + +complete(dir, s: string): (ref Completion, string) +{ + if(str->splitl(s, "/").t1 != nil) + return (nil, "slash character in name argument to complete()"); + + (da, n) := readdir->init(dir, Readdir->COMPACT); + if(n < 0) + return (nil, sys->sprint("%r")); + if(n == 0) + return (nil, nil); + + readdir = nil; + + c := ref Completion(0, 0, nil, 0, nil); + + name := array[n] of string; + mode := array[n] of int; + length := len s; + nfile := 0; + minlen := 1000000; + for(i := 0; i < n; i++) + if(str->prefix(s,da[i].name)){ + name[nfile] = da[i].name; + mode[nfile] = da[i].mode; + if(minlen > len da[i].name) + minlen = len da[i].name; + nfile++; + } + + if(nfile > 0){ + # report interesting results + # trim length back to longest common initial string + for(i = 1; i < nfile; i++) + minlen = longestprefixlength(name[0], name[i], minlen); + + c.complete = (nfile == 1); + c.advance = c.complete || (minlen > length); + c.str = name[0][length:minlen]; + if(c.complete){ + if(mode[0]&Sys->DMDIR) + c.str[minlen++ - length] = '/'; + else + c.str[minlen++ - length] = ' '; + } + c.nmatch = nfile; + }else{ + # no match: return all names + for(i = 0; i < n; i++){ + name[i] = da[i].name; + mode[i] = da[i].mode; + } + nfile = n; + c.nmatch = 0; + } + c.filename = name; + for(i = 0; i < nfile; i++) + if(mode[i] & Sys->DMDIR) + c.filename[i] += "/"; + + return (c, nil); +} diff --git a/appl/lib/mkfile b/appl/lib/mkfile index f414732d..7ef57b48 100644 --- a/appl/lib/mkfile +++ b/appl/lib/mkfile @@ -5,6 +5,7 @@ DIRS=\ crypt\ ecmascript\ encoding\ + ida\ print\ spki\ strokes\ @@ -24,6 +25,7 @@ TARG=\ cfg.dis\ cfgfile.dis\ chanfill.dis\ + complete.dis\ crc.dis\ csv.dis\ daytime.dis\ @@ -92,6 +94,7 @@ TARG=\ regex.dis\ regexutils.dis\ registries.dis\ + rfc822.dis\ riff.dis\ scoretable.dis\ scsiio.dis\ diff --git a/appl/lib/readdir.b b/appl/lib/readdir.b index 8b8ad276..4de58a4f 100644 --- a/appl/lib/readdir.b +++ b/appl/lib/readdir.b @@ -8,7 +8,7 @@ include "readdir.m"; init(path: string, sortkey: int): (array of ref Dir, int) { sys = load Sys Sys->PATH; - fd := sys->open(path, sys->OREAD); + fd := sys->open(path, Sys->OREAD); if(fd == nil) return (nil, -1); return readall(fd, sortkey); |
