improved factor plugin

cvs
Slava Pestov 2004-12-20 00:36:10 +00:00
parent 12a09523d4
commit 8b0949dd8b
11 changed files with 167 additions and 97 deletions

View File

@ -11,15 +11,11 @@
- handle odd base cases, with code after ifte
- handle recursion with when, when* etc
+ linearizer/generator:
+ compiler:
- getenv/setenv: if literal arg, compile as a load/store
+ compiler frontend:
- assembler opcodes dispatch on operand types
- save code in image
- compile word twice; no more 'cannot compile' error!
+ oop:
@ -36,7 +32,6 @@
+ listener/plugin:
- use decl wrong
- faster completion
- sidekick: still parsing too much
- errors don't always disappear
@ -53,10 +48,9 @@
- cat, reverse-cat primitives
- first-class hashtables
- rewrite accessors and mutators in Factor, with slot/set-slot primitive
- replace -export-dynamic with sundry-xt
- add a socket timeout
- word, writes entire plist
- do transfer-word in fixup
- move dispatch getenv setenv to kernel-internals
+ misc:
@ -65,7 +59,6 @@
- perhaps /i should work with all numbers
- unit test weirdness: 2 lines appears at end
- jedit ==> jedit-word, jedit takes a file name
- command line parsing cleanup
- nicer way to combine two paths
- ditch object paths
- browser responder for word links in HTTPd; inspect responder for

View File

@ -207,8 +207,27 @@ public class DefaultVocabularyLookup implements VocabularyLookup
} //}}}
//{{{ getCompletions() method
public void getCompletions(String vocab, String word, Set completions,
boolean anywhere)
/**
* @param use A list of vocabularies.
* @param word A substring of the word name to complete
* @param anywhere If true, matches anywhere in the word name are
* returned; otherwise, only matches from beginning.
* @param completions Set to add completions to
*/
public void getCompletions(Cons use, String word, boolean anywhere,
Set completions) throws Exception
{
while(use != null)
{
String vocab = (String)use.car;
getCompletions(vocab,word,anywhere,completions);
use = use.next();
}
} //}}}
//{{{ getCompletions() method
public void getCompletions(String vocab, String word, boolean anywhere,
Set completions) throws Exception
{
Map v = (Map)vocabularies.get(vocab);
if(v == null)

View File

@ -178,6 +178,19 @@ public class ExternalFactor extends DefaultVocabularyLookup
return vocabs;
} //}}}
//{{{ makeWord() method
/**
* Make a word from an info list returned by Factor.
*/
public synchronized FactorWord makeWord(Cons info)
{
FactorWord w = new FactorWord(
(String)info.car,
(String)info.next().car);
w.stackEffect = (String)info.next().next().car;
return w;
} //}}}
//{{{ searchVocabulary() method
/**
* Search through the given vocabulary list for the given word.
@ -197,16 +210,11 @@ public class ExternalFactor extends DefaultVocabularyLookup
Cons result = parseObject(eval(FactorReader.unparseObject(name)
+ " "
+ FactorReader.unparseObject(vocabulary)
+ " jedit-lookup ."));
+ " search jedit-lookup ."));
if(result.car == null)
return null;
result = (Cons)result.car;
w = new FactorWord(
(String)result.car,
(String)result.next().car);
w.stackEffect = (String)result.next().next().car;
return w;
return makeWord((Cons)result.car);
}
catch(Exception e)
{
@ -216,40 +224,32 @@ public class ExternalFactor extends DefaultVocabularyLookup
} //}}}
//{{{ getCompletions() method
public synchronized void getCompletions(String vocab, String word, Set completions,
boolean anywhere)
public synchronized void getCompletions(Cons use, String word,
boolean anywhere, Set completions) throws Exception
{
super.getCompletions(vocab,word,completions,anywhere);
super.getCompletions(use,word,anywhere,completions);
if(closed)
return;
try
{
/* We can't send words across the socket at this point in
human history, because of USE: issues. so we send name/vocab
pairs. */
Cons moreCompletions = (Cons)parseObject(eval(
FactorReader.unparseObject(word)
+ " "
+ FactorReader.unparseObject(vocab)
+ " "
+ (anywhere ? "vocab-apropos" : "vocab-completions")
+ " [ dup word-name swap word-vocabulary 2list ] map .")).car;
/* We can't send words across the socket at this point in
human history, because of USE: issues. so we send name/vocab
pairs. */
Cons moreCompletions = (Cons)parseObject(eval(
FactorReader.unparseObject(word)
+ " "
+ FactorReader.unparseObject(Boolean.valueOf(anywhere))
+ " "
+ FactorReader.unparseObject(use)
+ " completions .")).car;
while(moreCompletions != null)
{
Cons completion = (Cons)moreCompletions.car;
FactorWord w = searchVocabulary(completion.next(),
(String)completion.car);
if(w != null)
completions.add(w);
moreCompletions = moreCompletions.next();
}
}
catch(Exception e)
while(moreCompletions != null)
{
Log.log(Log.ERROR,this,e);
Cons completion = (Cons)moreCompletions.car;
FactorWord w = makeWord(completion);
if(w != null)
completions.add(w);
moreCompletions = moreCompletions.next();
}
} //}}}

View File

@ -42,15 +42,25 @@ public interface VocabularyLookup
public void forget(FactorWord word);
/**
* @param use A list of vocabularies.
* @param word A substring of the word name to complete
* @param anywhere If true, matches anywhere in the word name are
* returned; otherwise, only matches from beginning.
* @param completions Set to add completions to
*/
public void getCompletions(Cons use, String word, boolean anywhere,
Set completions) throws Exception;
/**
* @param vocab The vocabulary name
* @param word A substring of the word name to complete
* @param completions List to add completions to
* @param anywhere If true, word name will be matched anywhere, otherwise, just at
* the beginning of the name.
* @param completions Set to add completions to
*/
public void getCompletions(String vocab, String word, Set completions,
boolean anywhere) throws Exception;
public void getCompletions(String vocab, String word, boolean anywhere,
Set completions) throws Exception;
public Cons getVocabularies() throws Exception;
}

View File

@ -126,6 +126,8 @@ public class EditWordDialog extends WordListDialog
list.setSelectedIndex(0);
list.ensureIndexIsVisible(0);
}
updatePreview();
} //}}}
//{{{ UpdateTimer class

View File

@ -61,14 +61,23 @@ public class FactorCompletion extends SideKickCompletion
public void insert(int index)
{
Macros.Recorder recorder = view.getMacroRecorder();
FactorWord selected = ((FactorWord)get(index));
String insert = selected.name.substring(word.length());
String insert = ((FactorWord)get(index)).name.substring(
word.length());
Buffer buffer = textArea.getBuffer();
if(recorder != null)
recorder.recordInput(insert,false);
textArea.setSelectedText(insert);
try
{
buffer.beginCompoundEdit();
textArea.setSelectedText(insert);
if(!FactorPlugin.isUsed(view,selected.vocabulary))
FactorPlugin.insertUse(view,selected.vocabulary);
}
finally
{
buffer.endCompoundEdit();
}
}
public int getTokenLength()
@ -81,13 +90,7 @@ public class FactorCompletion extends SideKickCompletion
if(keyChar == '\t' || keyChar == '\n')
insert(selectedIndex);
else
{
Macros.Recorder recorder = view.getMacroRecorder();
if(recorder != null)
recorder.recordInput(1,keyChar,false);
textArea.userInput(keyChar);
}
boolean ws = (ReadTable.DEFAULT_READTABLE
.getCharacterType(keyChar)

View File

@ -73,6 +73,13 @@ public class FactorPlugin extends EditPlugin
public void stop()
{
stopExternalInstance();
Buffer buffer = jEdit.getFirstBuffer();
while(buffer != null)
{
buffer.setProperty(FactorSideKickParser.PARSED_PROPERTY,null);
buffer = buffer.getNext();
}
} //}}}
//{{{ getExternalInstance() method
@ -165,9 +172,9 @@ public class FactorPlugin extends EditPlugin
} //}}}
//{{{ evalInWire() method
public static void evalInWire(String cmd) throws IOException
public static String evalInWire(String cmd) throws IOException
{
getExternalInstance().eval(cmd);
return getExternalInstance().eval(cmd);
} //}}}
//{{{ lookupWord() method
@ -275,37 +282,15 @@ public class FactorPlugin extends EditPlugin
* returned; otherwise, only matches from beginning.
*/
public static Set getCompletions(String word, boolean anywhere)
{
try
{
return getCompletions(getExternalInstance().getVocabularies(),word,
anywhere);
}
catch(Exception e)
{
throw new RuntimeException(e);
}
} //}}}
//{{{ getCompletions() method
/**
* @param anywhere If true, matches anywhere in the word name are
* returned; otherwise, only matches from beginning.
*/
public static Set getCompletions(Cons use, String word, boolean anywhere)
{
try
{
Set completions = new HashSet();
while(use != null)
{
String vocab = (String)use.car;
getExternalInstance().getCompletions(
vocab,word,completions,anywhere);
use = use.next();
}
getExternalInstance().getCompletions(
getExternalInstance().getVocabularies(),
word,
anywhere,
completions);
return completions;
}
catch(Exception e)
@ -375,7 +360,7 @@ public class FactorPlugin extends EditPlugin
} //}}}
//{{{ isUsed() method
private static boolean isUsed(View view, String vocab)
public static boolean isUsed(View view, String vocab)
{
SideKickParsedData data = SideKickParsedData
.getParsedData(view);

View File

@ -2,7 +2,7 @@
plugin.factor.jedit.FactorPlugin.activate=startup
plugin.factor.jedit.FactorPlugin.name=Factor
plugin.factor.jedit.FactorPlugin.version=0.70
plugin.factor.jedit.FactorPlugin.version=0.71
plugin.factor.jedit.FactorPlugin.author=Slava Pestov
plugin.factor.jedit.FactorPlugin.docs=/doc/jedit/index.html

View File

@ -290,8 +290,7 @@ public class FactorSideKickParser extends SideKickParser
return null;
FactorWord[] completions = FactorPlugin.toWordArray(
FactorPlugin.getCompletions(
data.use,word,false));
FactorPlugin.getCompletions(word,false));
if(completions.length == 0)
return null;

View File

@ -31,16 +31,19 @@ package factor.jedit;
import factor.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import org.gjt.sp.jedit.gui.EnhancedDialog;
import org.gjt.sp.jedit.*;
import org.gjt.sp.util.Log;
public abstract class WordListDialog extends EnhancedDialog
{
protected View view;
protected JList list;
protected JTextArea preview;
protected JButton ok, cancel;
//{{{ WordListDialog constructor
@ -55,13 +58,47 @@ public abstract class WordListDialog extends EnhancedDialog
content.setBorder(new EmptyBorder(12,12,12,12));
setContentPane(content);
content.add(BorderLayout.CENTER,new JScrollPane(
list = new JList()));
JScrollPane listScroll = new JScrollPane(
list = new JList());
list.setCellRenderer(new FactorWordRenderer(parser,true));
list.addListSelectionListener(new ListHandler());
JScrollPane previewScroll = new JScrollPane(
preview = new JTextArea(12,60));
preview.setEditable(false);
listScroll.setPreferredSize(previewScroll.getPreferredSize());
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
listScroll,previewScroll);
split.setDividerLocation(0.5);
split.setResizeWeight(0.5);
content.add(BorderLayout.CENTER,split);
content.add(BorderLayout.SOUTH,createButtonPanel());
} //}}}
//{{{ updatePreview() method
protected void updatePreview()
{
FactorWord word = (FactorWord)list.getSelectedValue();
if(word == null)
{
preview.setText("");
return;
}
try
{
preview.setText(FactorPlugin.evalInWire(
FactorPlugin.factorWord(word) + " see").trim());
}
catch(Exception e)
{
Log.log(Log.ERROR,this,e);
}
} //}}}
//{{{ createButtonPanel() method
private Box createButtonPanel()
{
@ -91,4 +128,13 @@ public abstract class WordListDialog extends EnhancedDialog
cancel();
}
} //}}}
//{{{ ListHandler class
class ListHandler implements ListSelectionListener
{
public void valueChanged(ListSelectionEvent evt)
{
updatePreview();
}
} //}}}
}

View File

@ -95,10 +95,10 @@ C: jedit-stream ( stream -- stream )
#! Execute this in the inferior Factor.
stdio [ <jedit-stream> ] change print-banner ;
: jedit-lookup ( word vocabs -- )
: jedit-lookup ( word -- list )
#! A utility word called by the Factor plugin to get some
#! required word info.
search dup [
dup [
[
"vocabulary"
"name"
@ -107,3 +107,16 @@ C: jedit-stream ( stream -- stream )
dupd word-property
] map nip
] when ;
: completions ( str anywhere vocabs -- list )
#! Make a list of completions. Each element of the list is
#! a name/vocabulary pair.
[
[
>r 2dup r> swap [
vocab-apropos
] [
vocab-completions
] ifte [ jedit-lookup , ] each
] each
] make-list ;