Piece of cake: Just give rlwrap a file with all the words and you can call it like this:
rlwrap -f factor.words ./f -shell=tty
where all Factor words have been written in the file "factor.words".
So the question is: how do you get all the Factor words. Nothing easier than that. Factor is very reflective. What you have to do in the Factor listener is this:
all-words
[ word-name ] map
"allcomms.txt" <file-writer>
swap
[ dupd swap stream-write stream-terpri ] each-with
stream-flush
Just for cosmetic reasons I sorted this file with "sort" in the GNU/Linux shell:
sort allcomms.txt > factor.words
Per default some characters are word separators in rlwrap. Unfortunately "-" too which is heavily used in Factor. Therefore just define all word breaking characters leaving out the dash. I put the whole thing in a file called "rf" and that's it's content:
rlwrap -b '(){}[],+=&^%$#@"";|\' -f factor.words -r ./f -shell=tty
(Added also the -r option which remembers words you type that are not in the completion file.)
I run Factor from the command-line by invoking "rf" and when I need the user interface I call "ui" in the Factor listener.
In the Factor listener you can also complete words. It's actually much better because its fuzzier. Whereas in the command-line with rlwrap you have to type in the first correct letters.
6 comments:
Hi Schmidt,
Thanks for the tips on using the Factor interface with readline. On my computer, the GUI is broken for some reason and I can't figure out why, so I use the CLI. Hopefully this will help. But why do you need to list all Factor words to make that work? The problem with that is that, if you define a new word, it won't be in there unless you rewrite all the words to the file. The words file would have to be updated very frequently to be at all accurate, and sometimes, you'd have to quit factor to update it, wouldn't you?
--LittleDan
PS. you could best respond to be over IRC or by email (microdan at gmail dot com)
Hi Daniel,
yes you are right. Introspection is not dynamic in this case. GNU readline has a C interface which allows one to have any dynamic completion one wishes. So if Factor would use readline it could call a function/word in Factor and Factor could return all possible completions. But rlwrap doesn't/can't provide that. But the remember functionality in rlwrap is a good workaround. All in all rlwrap saves a lot of typing but is't very dynamic.
Nice work! You can sort the words in Factor using 'sort'. It takes a quotation that returns -1, 0, or 1 depeding on whether the two items passed to it are lesser, equal or greater. So for example:
all-words [ word-name ] map [ <=> ] sort
The 'with-stream' word is also useful. It calls a quotation with a stream bound as stdio. So it means less stack manipulation: Something like (untested):
"foo.txt" <file-writer> [
word-names [ . ] each
] with-stream
(Where 'word-names' returns your sequence of names).
Hi Chris,
thanks again for your comments. It's really helpful for me as a Factor beginner. I also found out that [ <=> ] sort is natural-sort in the standard. It's so much fun exploring Factor. with-stream is also very helpful. I thought I needed something like this when I did the little Factor scriptlets but didn't find something appropriate.
Thanks again,
Hans :-)
As a one-liner:
"foo.txt" <file-writer> [ all-words [ word-name ] map natural-sort [ . ] each ] with-stream
This might be better:
: word-names [ word-name ] map ;
: pprint-each [ . ] each ;
: file-output ( quot path -- )
swap <file-writer> swap with-stream ;
: allwords ( path -- )
[ all-words word-names natural-sort pprint-each ] file-output ;
Post a Comment