forsyth20121205-174063a80cc13 years agoHistory
92 lines · 1.8 KB · Brainfuck
RawDownload
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);  	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);}