Edit word dialog

cvs
Slava Pestov 2004-09-01 02:22:47 +00:00
parent 5df49666de
commit bc204614ae
10 changed files with 442 additions and 189 deletions

View File

@ -9,14 +9,14 @@
if(sel == null)
view.toolkit.beep();
else
factorEval(view,sel);
FactorPlugin.eval(view,sel);
</CODE>
</ACTION>
<ACTION NAME="factor-run-file">
<CODE>
buffer.save(view,null);
VFSManager.waitForRequests();
factorEval(view,
FactorPlugin.eval(view,
"\""
+ factor.FactorReader.charsToEscapes(buffer.path)
+ "\" run-file");
@ -26,7 +26,7 @@
<CODE>
if(textArea.selectionCount == 0)
textArea.selectWord();
factorEval(view,
FactorPlugin.eval(view,
"\""
+ factor.FactorReader.charsToEscapes(
textArea.selectedText)
@ -35,35 +35,29 @@
</ACTION>
<ACTION NAME="factor-see">
<CODE>
factorWordOperation(view,"see");
FactorPlugin.factorWordOperation(view,"see");
</CODE>
</ACTION>
<ACTION NAME="factor-edit">
<CODE>
factorWordOperation(view,"jedit");
FactorPlugin.factorWordOperation(view,"jedit");
</CODE>
</ACTION>
<ACTION NAME="factor-edit-dialog">
<CODE>
new EditWordDialog(view,FactorPlugin.getInterpreter());
</CODE>
</ACTION>
<ACTION NAME="factor-usages">
<CODE>
factorWordOperation(view,"usages.");
</CODE>
</ACTION>
<ACTION NAME="factor-balance">
<CODE>
if(textArea.selectionCount == 0)
textArea.toolkit.beep();
else
{
factorEval(view,
"[ " + textArea.selectedText + " ] balance .");
}
FactorPlugin.factorWordOperation(view,"usages.");
</CODE>
</ACTION>
<ACTION NAME="factor-insert-use">
<CODE>
if(textArea.selectionCount == 0)
textArea.selectWord();
factor.jedit.FactorPlugin.insertUseDialog(view,
FactorPlugin.insertUseDialog(view,
textArea.selectedText);
</CODE>
</ACTION>

View File

@ -487,7 +487,6 @@ public class FactorInterpreter implements FactorObject, Runnable
//{{{ getVocabulary() method
public FactorNamespace getVocabulary(String name)
throws Exception
{
Object value = vocabularies.getVariable(name);
if(value instanceof FactorNamespace)
@ -498,7 +497,6 @@ public class FactorInterpreter implements FactorObject, Runnable
//{{{ defineVocabulary() method
public void defineVocabulary(String name)
throws Exception
{
Object value = vocabularies.getVariable(name);
if(value == null)
@ -569,31 +567,23 @@ public class FactorInterpreter implements FactorObject, Runnable
if(isUninterned(name))
return new FactorWord(null,name);
try
FactorNamespace v = getVocabulary(vocabulary);
if(v == null)
{
FactorNamespace v = getVocabulary(vocabulary);
if(v == null)
{
v = new FactorNamespace();
vocabularies.setVariable(vocabulary,v);
}
Object value = v.getVariable(name);
if(value instanceof FactorWord)
return (FactorWord)value;
else
{
// save to same workspace as vocabulary,
// or no workspace if vocabulary is builtins
FactorWord word = new FactorWord(
vocabulary,name,null);
v.setVariable(name,word);
return word;
}
v = new FactorNamespace();
vocabularies.setVariable(vocabulary,v);
}
catch(Exception e)
Object value = v.getVariable(name);
if(value instanceof FactorWord)
return (FactorWord)value;
else
{
// should not happen!
throw new RuntimeException(e);
// save to same workspace as vocabulary,
// or no workspace if vocabulary is builtins
FactorWord word = new FactorWord(
vocabulary,name,null);
v.setVariable(name,word);
return word;
}
} //}}}

View File

@ -89,7 +89,7 @@ public class FactorWord implements FactorExternalizable, FactorObject
* intern() method instead.
*/
public FactorWord(String vocabulary, String name,
FactorWordDefinition def) throws Exception
FactorWordDefinition def)
{
this.vocabulary = vocabulary;
this.name = name;

View File

@ -0,0 +1,192 @@
/* :folding=explicit:collapseFolds=1: */
/*
* $Id$
*
* Copyright (C) 2004 Slava Pestov.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package factor.jedit;
import factor.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.text.Document;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.List;
import org.gjt.sp.jedit.gui.EnhancedDialog;
import org.gjt.sp.jedit.*;
public class EditWordDialog extends WordListDialog
{
private JTextField field;
private Timer timer;
//{{{ EditWordDialog constructor
public EditWordDialog(View view, FactorInterpreter interp)
{
super(view,interp,jEdit.getProperty("factor.edit-word.title"));
Box top = new Box(BoxLayout.X_AXIS);
top.add(new JLabel(jEdit.getProperty(
"factor.edit-word.caption")));
top.add(Box.createHorizontalStrut(12));
top.add(field = new JTextField(16));
field.getDocument().addDocumentListener(new DocumentHandler());
field.addKeyListener(new KeyHandler());
getContentPane().add(BorderLayout.NORTH,top);
list.setFixedCellHeight(list.getFontMetrics(list.getFont())
.getHeight());
list.addKeyListener(new KeyHandler());
timer = new Timer(0,new UpdateTimer());
pack();
setLocationRelativeTo(view);
setVisible(true);
} //}}}
//{{{ ok() method
public void ok()
{
FactorWord word = (FactorWord)list.getSelectedValue();
if(word == null)
{
getToolkit().beep();
return;
}
String code = FactorPlugin.factorWord(word);
FactorPlugin.eval(view,code + " jedit");
dispose();
} //}}}
//{{{ cancel() method
public void cancel()
{
dispose();
} //}}}
//{{{ updateListWithDelay() method
private void updateListWithDelay()
{
timer.stop();
String text = field.getText();
if(text.length() <= 1)
list.setListData(new Object[0]);
else
{
timer.setInitialDelay(100);
timer.setRepeats(false);
timer.start();
}
} //}}}
//{{{ updateList() method
private void updateList()
{
List completions = FactorPlugin.getCompletions(
field.getText(),true);
FactorWord[] completionArray
= (FactorWord[])completions.toArray(
new FactorWord[completions.size()]);
list.setListData(completionArray);
if(completionArray.length != 0)
{
list.setSelectedIndex(0);
list.ensureIndexIsVisible(0);
}
} //}}}
//{{{ UpdateTimer class
class UpdateTimer implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
updateList();
}
} //}}}
//{{{ KeyHandler class
class KeyHandler extends KeyAdapter
{
public void keyPressed(KeyEvent evt)
{
switch(evt.getKeyCode())
{
case KeyEvent.VK_UP:
int selected = list.getSelectedIndex();
if(selected == 0)
selected = list.getModel().getSize() - 1;
else if(getFocusOwner() == list)
return;
else
selected = selected - 1;
list.setSelectedIndex(selected);
list.ensureIndexIsVisible(selected);
evt.consume();
break;
case KeyEvent.VK_DOWN:
/* int */ selected = list.getSelectedIndex();
if(selected == list.getModel().getSize() - 1)
selected = 0;
else if(getFocusOwner() == list)
return;
else
selected = selected + 1;
list.setSelectedIndex(selected);
list.ensureIndexIsVisible(selected);
evt.consume();
break;
}
}
} //}}}
//{{{ DocumentHandler class
class DocumentHandler implements DocumentListener
{
public void insertUpdate(DocumentEvent evt)
{
updateListWithDelay();
}
public void removeUpdate(DocumentEvent evt)
{
updateListWithDelay();
}
public void changedUpdate(DocumentEvent evt)
{
}
} //}}}
}

View File

@ -32,7 +32,7 @@ package factor.jedit;
import factor.listener.FactorListenerPanel;
import factor.*;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.*;
import org.gjt.sp.jedit.gui.*;
import org.gjt.sp.jedit.textarea.*;
import org.gjt.sp.jedit.*;
@ -44,14 +44,6 @@ public class FactorPlugin extends EditPlugin
private static FactorInterpreter interp;
//{{{ start() method
public void start()
{
String path = "/factor/jedit/factor.bsh";
BeanShell.runScript(null,path,new InputStreamReader(
getClass().getResourceAsStream(path)),false);
} //}}}
//{{{ getInterpreter() method
/**
* This can be called from the SideKick thread and must be thread safe.
@ -77,6 +69,117 @@ public class FactorPlugin extends EditPlugin
panel.getListener().eval(cmd);
} //}}}
//{{{ factorWord() method
/**
* Build a Factor expression for pushing the selected word on the stack
*/
public static String factorWord(FactorWord word)
{
return FactorReader.unparseObject(word.name)
+ " [ " + FactorReader.unparseObject(word.vocabulary)
+ " ] search";
} //}}}
//{{{ factorWord() method
/**
* Build a Factor expression for pushing the selected word on the stack
*/
public static String factorWord(View view)
{
JEditTextArea textArea = view.getTextArea();
SideKickParsedData data = SideKickParsedData
.getParsedData(view);
if(data instanceof FactorParsedData)
{
FactorParsedData fdata = (FactorParsedData)data;
String word = FactorPlugin.getWordAtCaret(textArea);
if(word == null)
return null;
return "\""
+ FactorReader.charsToEscapes(word)
+ "\" " + FactorReader.unparseObject(fdata.use)
+ " search";
}
else
return null;
} //}}}
//{{{ factorWordOperation() method
/**
* Apply a Factor word to the selected word.
*/
public static void factorWordOperation(View view, String op)
{
String word = factorWord(view);
if(word == null)
view.getToolkit().beep();
else
eval(view,word + " " + op);
} //}}}
//{{{ getCompletions() method
/**
* Returns all words in all vocabularies.
*
* @param anywhere If true, matches anywhere in the word name are
* returned; otherwise, only matches from beginning.
*/
public static List getCompletions(String word, boolean anywhere)
{
return getCompletions(interp.vocabularies.toVarList(),word,
anywhere);
} //}}}
//{{{ getCompletions() method
/**
* @param anywhere If true, matches anywhere in the word name are
* returned; otherwise, only matches from beginning.
*/
public static List getCompletions(Cons use,
String word, boolean anywhere)
{
List completions = new ArrayList();
FactorInterpreter interp = FactorPlugin.getInterpreter();
while(use != null)
{
String vocab = (String)use.car;
getCompletions(interp,vocab,word,completions,anywhere);
use = use.next();
}
Collections.sort(completions,
new MiscUtilities.StringICaseCompare());
return completions;
} //}}}
//{{{ getCompletions() method
private static void getCompletions(FactorInterpreter interp,
String vocab, String word, List completions, boolean anywhere)
{
FactorNamespace v = interp.getVocabulary(vocab);
Cons words = v.toValueList();
while(words != null)
{
FactorWord w = (FactorWord)words.car;
if(anywhere)
{
if(w.name.indexOf(word) != -1)
completions.add(w);
}
else
{
if(w.name.startsWith(word))
completions.add(w);
}
words = words.next();
}
} //}}}
//{{{ getWordAtCaret() method
public static String getWordAtCaret(JEditTextArea textArea)
{
@ -148,7 +251,7 @@ public class FactorPlugin extends EditPlugin
else if(words.length == 1)
insertUse(view,words[0].vocabulary);
else
new InsertUseDialog(view,words);
new InsertUseDialog(view,getInterpreter(),words);
} //}}}
//{{{ insertUse() method
@ -179,5 +282,5 @@ public class FactorPlugin extends EditPlugin
String decl = "USE: " + vocab + "\n";
buffer.insert(lastUseOffset,decl);
showStatus(view,"inserted-use",decl);
} //}}]
} //}}}
}

View File

@ -20,10 +20,9 @@ plugin.factor.jedit.FactorPlugin.menu=factor \
factor-insert-use \
- \
factor-edit \
factor-edit-dialog \
factor-see \
factor-usages \
- \
factor-balance
factor.label=Factor Listener
factor-run-file.label=Run current file
@ -32,15 +31,15 @@ factor-apropos.label=Apropos at caret
factor-insert-use.label=Use word at caret
factor-see.label=See word at caret
factor-edit.label=Edit word at caret
factor-edit-dialog.label=Edit word...
factor-usages.label=Word usages at caret
factor-balance.label=Balance selection
factor.title=Factor
sidekick.parser.factor.label=Factor
mode.factor.sidekick.parser=factor
factor.completion.in=<font color="#eeeeee">IN: {0}</font>
factor.completion.in=<font color="#a0a0a0">IN: {0}</font>\
factor.completion.plain=: <b>{0}</b>
factor.completion.defer=DEFER: <b>{0}</b>
factor.completion.parsing=PARSING: <b>{0}</b>
@ -52,3 +51,6 @@ factor.status.already-used=Already used {0}
factor.insert-use.title=Insert USE: Declaration
factor.insert-use.caption=There are multiple words named "{0}". Select the one to use:
factor.edit-word.title=Edit Word Definition
factor.edit-word.caption=Word name:

View File

@ -231,57 +231,15 @@ public class FactorSideKickParser extends SideKickParser
if(word.length() == 0)
return null;
List completions = getCompletions(data.use,word);
List completions = FactorPlugin.getCompletions(
data.use,word,false);
if(completions.size() == 0)
return null;
else
{
Collections.sort(completions,
new MiscUtilities.StringICaseCompare());
return new FactorCompletion(editPane.getView(),
completions,word,data);
}
} //}}}
//{{{ getCompletions() method
private List getCompletions(Cons use, String word)
{
List completions = new ArrayList();
FactorInterpreter interp = FactorPlugin.getInterpreter();
while(use != null)
{
String vocab = (String)use.car;
getCompletions(interp,vocab,word,completions);
use = use.next();
}
return completions;
} //}}}
//{{{ getCompletions() method
private void getCompletions(FactorInterpreter interp, String vocab,
String word, List completions)
{
try
{
FactorNamespace v = interp.getVocabulary(vocab);
Cons words = v.toValueList();
while(words != null)
{
FactorWord w = (FactorWord)words.car;
if(w.name.startsWith(word))
completions.add(w);
words = words.next();
}
}
catch(Exception e)
{
Log.log(Log.ERROR,this,e);
}
} //}}}
}

View File

@ -29,7 +29,7 @@
package factor.jedit;
import factor.FactorWord;
import factor.*;
import javax.swing.border.*;
import javax.swing.*;
import java.awt.event.*;
@ -37,57 +37,25 @@ import java.awt.*;
import org.gjt.sp.jedit.gui.EnhancedDialog;
import org.gjt.sp.jedit.*;
public class InsertUseDialog extends EnhancedDialog
public class InsertUseDialog extends WordListDialog
{
private View view;
private JList list;
private JButton ok, cancel;
//{{{ InsertUseDialog constructor
public InsertUseDialog(View view, FactorWord[] words)
public InsertUseDialog(View view, FactorInterpreter interp,
FactorWord[] words)
{
super(view,jEdit.getProperty("factor.insert-use.title"),true);
super(view,interp,jEdit.getProperty("factor.insert-use.title"));
this.view = view;
JPanel content = new JPanel(new BorderLayout());
content.setBorder(new EmptyBorder(12,12,12,12));
setContentPane(content);
content.add(BorderLayout.NORTH,new JLabel(
getContentPane().add(BorderLayout.NORTH,new JLabel(
jEdit.getProperty("factor.insert-use.caption",
new String[] { words[0].name })));
content.add(BorderLayout.CENTER,new JScrollPane(
list = new JList(words)));
list.setCellRenderer(new FactorWordRenderer(
FactorPlugin.getInterpreter(),true));
list.setListData(words);
list.setSelectedIndex(0);
content.add(BorderLayout.SOUTH,createButtonPanel());
setLocationRelativeTo(view);
pack();
setLocationRelativeTo(view);
setVisible(true);
} //}}}
//{{{ createButtonPanel() method
private Box createButtonPanel()
{
Box buttons = new Box(BoxLayout.X_AXIS);
buttons.add(Box.createGlue());
buttons.add(ok = new JButton(jEdit.getProperty(
"common.ok")));
getRootPane().setDefaultButton(ok);
ok.addActionListener(new ActionHandler());
buttons.add(Box.createHorizontalStrut(12));
buttons.add(cancel = new JButton(jEdit.getProperty(
"common.cancel")));
cancel.addActionListener(new ActionHandler());
buttons.add(Box.createGlue());
return buttons;
} //}}}
//{{{ ok() method
public void ok()
@ -102,16 +70,4 @@ public class InsertUseDialog extends EnhancedDialog
{
dispose();
} //}}}
//{{{ ActionHandler class
class ActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
if(evt.getSource() == ok)
ok();
else if(evt.getSource() == cancel)
cancel();
}
} //}}}
}

View File

@ -0,0 +1,93 @@
/* :folding=explicit:collapseFolds=1: */
/*
* $Id$
*
* Copyright (C) 2004 Slava Pestov.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package factor.jedit;
import factor.*;
import javax.swing.border.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import org.gjt.sp.jedit.gui.EnhancedDialog;
import org.gjt.sp.jedit.*;
public abstract class WordListDialog extends EnhancedDialog
{
protected View view;
protected JList list;
protected JButton ok, cancel;
//{{{ WordListDialog constructor
public WordListDialog(View view, FactorInterpreter interp, String title)
{
super(view,title,true);
this.view = view;
JPanel content = new JPanel(new BorderLayout(12,12));
content.setBorder(new EmptyBorder(12,12,12,12));
setContentPane(content);
content.add(BorderLayout.CENTER,new JScrollPane(
list = new JList()));
list.setCellRenderer(new FactorWordRenderer(interp,true));
content.add(BorderLayout.SOUTH,createButtonPanel());
} //}}}
//{{{ createButtonPanel() method
private Box createButtonPanel()
{
Box buttons = new Box(BoxLayout.X_AXIS);
buttons.add(Box.createGlue());
buttons.add(ok = new JButton(jEdit.getProperty(
"common.ok")));
getRootPane().setDefaultButton(ok);
ok.addActionListener(new ActionHandler());
buttons.add(Box.createHorizontalStrut(12));
buttons.add(cancel = new JButton(jEdit.getProperty(
"common.cancel")));
cancel.addActionListener(new ActionHandler());
buttons.add(Box.createGlue());
return buttons;
} //}}}
//{{{ ActionHandler class
class ActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
if(evt.getSource() == ok)
ok();
else if(evt.getSource() == cancel)
cancel();
}
} //}}}
}

View File

@ -1,35 +0,0 @@
import factor.jedit.*;
factorEval(view,str)
{
FactorPlugin.eval(view,str);
}
/* Build a Factor expression for pushing the selected word on the stack */
factorWord(view)
{
textArea = view.textArea;
data = sidekick.SideKickParsedData.getParsedData(view);
if(data instanceof factor.jedit.FactorParsedData)
{
word = FactorPlugin.getWordAtCaret(textArea);
if(word == null)
return null;
return "\""
+ factor.FactorReader.charsToEscapes(word)
+ "\" " + factor.FactorReader.unparseObject(data.use)
+ " search";
}
else
return null;
}
/* Apply a Factor word to the selected word */
factorWordOperation(view,op)
{
word = factorWord(view);
if(word == null)
view.toolkit.beep();
else
factorEval(view,word + " " + op);
}