diff --git a/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java b/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java index c110eb24..d3a321d0 100644 --- a/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java +++ b/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java @@ -14,227 +14,178 @@ import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; +import java.util.ServiceLoader; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; - /** - * Provides language support (code completion, etc.) for programming - * languages in RSyntaxTextArea. Different languages may have varying - * levels of "support." + * Provides language support (code completion, etc.) for programming languages + * in RSyntaxTextArea. Different languages may have varying levels of "support." * * @author Robert Futrell * @version 1.0 */ -public class LanguageSupportFactory implements PropertyChangeListener { - - private static final LanguageSupportFactory INSTANCE = - new LanguageSupportFactory(); - - /** - * Maps styles to class-names-for-language-supports; this way we can lazily - * create the LanguageSupports when necessary. - */ - private Map styleToSupportClass; - - /** - * Maps syntax styles to language supports for them. - */ - private Map styleToSupport; - - - /** - * Client property set on RSyntaxTextAreas that points to the current - * language support for that text area. - */ - private static final String LANGUAGE_SUPPORT_PROPERTY = - "org.fife.rsta.ac.LanguageSupport"; - - - /** - * Constructor. - */ - private LanguageSupportFactory() { - createSupportMap(); - } - - - /** - * Adds language support for a language. This is a hook for applications - * using this library to add language support for custom languages. - * - * @param style The language to add support for. This should be one of - * the values defined in {@link SyntaxConstants}. Any previous - * language support for this language is removed. - * @param lsClassName The class name of the LanguageSupport. - */ - public void addLanguageSupport(String style, String lsClassName) { - styleToSupportClass.put(style, lsClassName); - } - - - /** - * Creates the mapping of syntax styles to language supports. - */ - private void createSupportMap() { - - styleToSupport = new HashMap(); - styleToSupportClass = new HashMap(); - - String prefix = "org.fife.rsta.ac."; - - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_C, - prefix + "c.CLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_CSS, - prefix + "css.CssLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_GROOVY, - prefix + "groovy.GroovyLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_HTML, - prefix + "html.HtmlLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_JAVA, - prefix + "java.JavaLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, - prefix + "js.JavaScriptLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_JSP, - prefix + "jsp.JspLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_LESS, - prefix + "less.LessLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_PERL, - prefix + "perl.PerlLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_PHP, - prefix + "php.PhpLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_TYPESCRIPT, - prefix + "ts.TypeScriptLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL, - prefix + "sh.ShellLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_XML, - prefix + "xml.XmlLanguageSupport"); - - } - - - /** - * Returns the singleton instance of this class. - * - * @return The singleton instance. - */ - public static LanguageSupportFactory get() { - return INSTANCE; - } - - - /** - * Returns the language support for a programming language. - * - * @param style The language. This should be one of the constants defined - * in {@link SyntaxConstants}. - * @return The language support, or null if none is registered - * for the language specified. - */ - public LanguageSupport getSupportFor(String style) { - - LanguageSupport support = styleToSupport.get(style); - - if (support==null) { - String supportClazz = styleToSupportClass.get(style); - if (supportClazz!=null) { - try { - Class clazz = Class.forName(supportClazz); - support = (LanguageSupport)clazz.newInstance(); - } catch (RuntimeException re) { // FindBugs - throw re; - } catch (Exception e) { - e.printStackTrace(); - } - styleToSupport.put(style, support); - // Always remove from classes to load, so we don't try again - styleToSupportClass.remove(style); - } - } - - return support; - - } - - - /** - * Installs language support on an RSTA depending on its syntax style. - * - * @param textArea The text area to install language support on. - * @see #uninstallSupport(RSyntaxTextArea) - */ - private void installSupport(RSyntaxTextArea textArea) { - String style = textArea.getSyntaxEditingStyle(); - LanguageSupport support = getSupportFor(style); - if (support!=null) { - support.install(textArea); - } - textArea.putClientProperty(LANGUAGE_SUPPORT_PROPERTY, support); - } - - - /** - * Listens for RSyntaxTextAreas to change what language they're - * highlighting, so language support can be updated appropriately. - * - * @param e The event. - */ - @Override - public void propertyChange(PropertyChangeEvent e) { - - RSyntaxTextArea source = (RSyntaxTextArea)e.getSource(); - String name = e.getPropertyName(); - if (RSyntaxTextArea.SYNTAX_STYLE_PROPERTY.equals(name)) { - uninstallSupport(source); - installSupport(source); - } - - } - - - /** - * Registers an RSyntaxTextArea to receive language support. The text area - * will get support for the currently highlighted language, and if it - * changes what language it is highlighting, the support will change as - * appropriate. - * - * @param textArea The text area to register. - */ - public void register(RSyntaxTextArea textArea) { - installSupport(textArea); - textArea.addPropertyChangeListener( - RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); - } - - - /** - * Uninstalls the language support on an RSyntaxTextArea, if any. - * - * @param textArea The text area. - * @see #installSupport(RSyntaxTextArea) - */ - private void uninstallSupport(RSyntaxTextArea textArea) { - LanguageSupport support = (LanguageSupport)textArea.getClientProperty( - LANGUAGE_SUPPORT_PROPERTY); - if (support!=null) { - support.uninstall(textArea); - } - } - - - /** - * Un-registers an RSyntaxTextArea. This removes any language support - * on it. - * - * @param textArea The text area. - * @see #register(RSyntaxTextArea) - */ - public void unregister(RSyntaxTextArea textArea) { - uninstallSupport(textArea); - textArea.removePropertyChangeListener( - RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); - } - - -} \ No newline at end of file +public final class LanguageSupportFactory implements PropertyChangeListener { + + private static final LanguageSupportFactory INSTANCE + = new LanguageSupportFactory(); + + /** + * Maps styles to class-names-for-language-supports; this way we can lazily + * create the LanguageSupports when necessary. + */ + private final Map styleToSupportClass; + + /** + * Maps syntax styles to language supports for them. + */ + private final Map styleToSupport; + + /** + * Client property set on RSyntaxTextAreas that points to the current + * language support for that text area. + */ + private static final String LANGUAGE_SUPPORT_PROPERTY + = "org.fife.rsta.ac.LanguageSupport"; + + /** + * Constructor. + */ + private LanguageSupportFactory() { + styleToSupport = new HashMap(); + styleToSupportClass = new HashMap(); + ServiceLoader s = ServiceLoader.load(LanguageSupportRegistration.class); + for(LanguageSupportRegistration l : s) { + addLanguageSupport(l.getLanguage(), l.getLanguageSupportType()); + } + } + + /** + * Adds language support for a language. This is a hook for applications + * using this library to add language support for custom languages. + * + * @param style The language to add support for. This should be one of the + * values defined in {@link SyntaxConstants}. Any previous language support + * for this language is removed. + * @param lsClassName The class name of the LanguageSupport. + */ + public void addLanguageSupport(String style, String lsClassName) { + styleToSupportClass.put(style, lsClassName); + } + + /** + * Returns the singleton instance of this class. + * + * @return The singleton instance. + */ + public static LanguageSupportFactory get() { + return INSTANCE; + } + + /** + * Returns the language support for a programming language. + * + * @param style The language. This should be one of the constants defined in + * {@link SyntaxConstants}. + * @return The language support, or null if none is registered + * for the language specified. + */ + public LanguageSupport getSupportFor(String style) { + + LanguageSupport support = styleToSupport.get(style); + + if (support == null) { + String supportClazz = styleToSupportClass.get(style); + if (supportClazz != null) { + try { + Class clazz = Class.forName(supportClazz); + support = (LanguageSupport) clazz.newInstance(); + } catch (RuntimeException re) { // FindBugs + throw re; + } catch (Exception e) { + e.printStackTrace(); + } + styleToSupport.put(style, support); + // Always remove from classes to load, so we don't try again + styleToSupportClass.remove(style); + } + } + + return support; + + } + + /** + * Installs language support on an RSTA depending on its syntax style. + * + * @param textArea The text area to install language support on. + * @see #uninstallSupport(RSyntaxTextArea) + */ + private void installSupport(RSyntaxTextArea textArea) { + String style = textArea.getSyntaxEditingStyle(); + LanguageSupport support = getSupportFor(style); + if (support != null) { + support.install(textArea); + } + textArea.putClientProperty(LANGUAGE_SUPPORT_PROPERTY, support); + } + + /** + * Listens for RSyntaxTextAreas to change what language they're + * highlighting, so language support can be updated appropriately. + * + * @param e The event. + */ + public void propertyChange(PropertyChangeEvent e) { + + RSyntaxTextArea source = (RSyntaxTextArea) e.getSource(); + String name = e.getPropertyName(); + if (RSyntaxTextArea.SYNTAX_STYLE_PROPERTY.equals(name)) { + uninstallSupport(source); + installSupport(source); + } + + } + + /** + * Registers an RSyntaxTextArea to receive language support. The text area + * will get support for the currently highlighted language, and if it + * changes what language it is highlighting, the support will change as + * appropriate. + * + * @param textArea The text area to register. + */ + public void register(RSyntaxTextArea textArea) { + installSupport(textArea); + textArea.addPropertyChangeListener( + RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); + } + + /** + * Uninstalls the language support on an RSyntaxTextArea, if any. + * + * @param textArea The text area. + * @see #installSupport(RSyntaxTextArea) + */ + private void uninstallSupport(RSyntaxTextArea textArea) { + LanguageSupport support = (LanguageSupport) textArea.getClientProperty( + LANGUAGE_SUPPORT_PROPERTY); + if (support != null) { + support.uninstall(textArea); + } + } + + /** + * Un-registers an RSyntaxTextArea. This removes any language support on it. + * + * @param textArea The text area. + * @see #register(RSyntaxTextArea) + */ + public void unregister(RSyntaxTextArea textArea) { + uninstallSupport(textArea); + textArea.removePropertyChangeListener( + RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java b/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java new file mode 100644 index 00000000..2d128c18 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java @@ -0,0 +1,22 @@ +/* + * 01/12/2017 + * + * Copyright (C) 2017 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac; + +/** + * + * @author matta + */ +public interface LanguageSupportRegistration { + + String getLanguage(); + + String getLanguageSupportType(); +} diff --git a/src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java new file mode 100644 index 00000000..5e2c4ce3 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java @@ -0,0 +1,32 @@ +/* + * 01/12/2017 + * + * Copyright (C) 2017 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.c; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.CTokenRegistration; + +/** + * + * @author matta + */ +public class CLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return CTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return CLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java new file mode 100644 index 00000000..4a59b73d --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java @@ -0,0 +1,32 @@ +/* + * 01/12/2017 + * + * Copyright (C) 2017 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.css; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.CSSTokenRegistration; + +/** + * + * @author matta + */ +public class CssLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return CSSTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return CssLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java b/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java index 3863dae5..3a0faee0 100644 --- a/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java +++ b/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java @@ -33,6 +33,20 @@ import org.fife.ui.rsyntaxtextarea.ErrorStrip; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_C; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_CSS; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_GROOVY; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_HTML; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_JAVA; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_JSP; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_LESS; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_PERL; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_PHP; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL; +import static org.fife.ui.rsyntaxtextarea.SyntaxConstants.SYNTAX_STYLE_XML; +import org.fife.ui.rsyntaxtextarea.TokenMakerFactory; +import org.fife.ui.rsyntaxtextarea.modes.TypeScriptTokenRegistration; import org.fife.ui.rtextarea.RTextScrollPane; @@ -44,259 +58,261 @@ * @version 1.0 */ class DemoRootPane extends JRootPane implements HyperlinkListener, - SyntaxConstants, Actions { - - private JScrollPane treeSP; - private AbstractSourceTree tree; - private RTextScrollPane scrollPane; - private RSyntaxTextArea textArea; - - - public DemoRootPane() { - - LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(SYNTAX_STYLE_JAVA); - JavaLanguageSupport jls = (JavaLanguageSupport)support; - // TODO: This API will change! It will be easier to do per-editor - // changes to the build path. - try { - jls.getJarManager().addCurrentJreClassFileSource(); - //jsls.getJarManager().addClassFileSource(ji); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - - // Dummy tree keeps JViewport's "background" looking right initially - JTree dummy = new JTree((TreeNode)null); - treeSP = new JScrollPane(dummy); - - textArea = createTextArea(); - setText("CExample.txt", SYNTAX_STYLE_C); - scrollPane = new RTextScrollPane(textArea, true); - scrollPane.setIconRowHeaderEnabled(true); - scrollPane.getGutter().setBookmarkingEnabled(true); - - final JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, - treeSP, scrollPane); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - sp.setDividerLocation(0.25); - } - }); - sp.setContinuousLayout(true); -// setContentPane(sp); - - setJMenuBar(createMenuBar()); - - ErrorStrip errorStrip = new ErrorStrip(textArea); + SyntaxConstants, Actions { + + private JScrollPane treeSP; + private AbstractSourceTree tree; + private RTextScrollPane scrollPane; + private RSyntaxTextArea textArea; + + + public DemoRootPane() { + + LanguageSupportFactory lsf = LanguageSupportFactory.get(); + LanguageSupport support = lsf.getSupportFor(SYNTAX_STYLE_JAVA); + JavaLanguageSupport jls = (JavaLanguageSupport)support; + // TODO: This API will change! It will be easier to do per-editor + // changes to the build path. + try { + jls.getJarManager().addCurrentJreClassFileSource(); + //jsls.getJarManager().addClassFileSource(ji); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + + // Dummy tree keeps JViewport's "background" looking right initially + JTree dummy = new JTree((TreeNode)null); + treeSP = new JScrollPane(dummy); + + textArea = createTextArea(); + setText("CExample.txt", SYNTAX_STYLE_C); + scrollPane = new RTextScrollPane(textArea, true); + scrollPane.setIconRowHeaderEnabled(true); + scrollPane.getGutter().setBookmarkingEnabled(true); + + final JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, + treeSP, scrollPane); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + sp.setDividerLocation(0.25); + } + }); + sp.setContinuousLayout(true); +// setContentPane(sp); + + setJMenuBar(createMenuBar()); + + ErrorStrip errorStrip = new ErrorStrip(textArea); //errorStrip.setBackground(java.awt.Color.blue); JPanel cp = new JPanel(new BorderLayout()); cp.add(sp); cp.add(errorStrip, BorderLayout.LINE_END); setContentPane(cp); - } - - - private void addItem(Action a, ButtonGroup bg, JMenu menu) { - JRadioButtonMenuItem item = new JRadioButtonMenuItem(a); - bg.add(item); - menu.add(item); - } - - - private JMenuBar createMenuBar() { - - JMenuBar mb = new JMenuBar(); - - JMenu menu = new JMenu("File"); - menu.add(new JMenuItem(new OpenAction(this))); - menu.addSeparator(); - menu.add(new JMenuItem(new ExitAction())); - mb.add(menu); - - menu = new JMenu("Language"); - ButtonGroup bg = new ButtonGroup(); - addItem(new StyleAction(this, "C", "CExample.txt", SYNTAX_STYLE_C), bg, menu); - addItem(new StyleAction(this, "CSS", "CssExample.txt", SYNTAX_STYLE_CSS), bg, menu); - addItem(new StyleAction(this, "Groovy", "GroovyExample.txt", SYNTAX_STYLE_GROOVY), bg, menu); - addItem(new StyleAction(this, "Java", "JavaExample.txt", SYNTAX_STYLE_JAVA), bg, menu); - addItem(new StyleAction(this, "JavaScript", "JSExample.txt", SYNTAX_STYLE_JAVASCRIPT), bg, menu); - addItem(new StyleAction(this, "JSP", "JspExample.txt", SYNTAX_STYLE_JSP), bg, menu); - addItem(new StyleAction(this, "Less", "LessExample.txt", SYNTAX_STYLE_LESS), bg, menu); - addItem(new StyleAction(this, "Perl", "PerlExample.txt", SYNTAX_STYLE_PERL), bg, menu); - addItem(new StyleAction(this, "HTML", "HtmlExample.txt", SYNTAX_STYLE_HTML), bg, menu); - addItem(new StyleAction(this, "PHP", "PhpExample.txt", SYNTAX_STYLE_PHP), bg, menu); - addItem(new StyleAction(this, "sh", "ShellExample.txt", SYNTAX_STYLE_UNIX_SHELL), bg, menu); - addItem(new StyleAction(this, "TypeScript", "TypeScriptExample.txt", SYNTAX_STYLE_TYPESCRIPT), bg, menu); - addItem(new StyleAction(this, "XML", "XMLExample.txt", SYNTAX_STYLE_XML), bg, menu); - menu.getItem(0).setSelected(true); - mb.add(menu); - - menu = new JMenu("LookAndFeel"); - bg = new ButtonGroup(); - LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); - for (int i=0; i