Refactoring: only SyntaxHighlighterFactory should be used to create highlighters.

- SyntaxHighlighter.PROVIDER moved to SyntaxHighlighterFactory.
- POVIDER.create() encapsulated into SyntaxHighlighterFactory.getSyntaxHighligher(FileType, Project, VirtualFile()
This commit is contained in:
Oleg Sukhodolsky
2012-10-01 15:32:43 +04:00
parent 07a6739f65
commit 00585b1911
11 changed files with 466 additions and 457 deletions
@@ -17,6 +17,7 @@ package org.intellij.lang.regexp;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
@@ -69,7 +70,7 @@ public class RegExpColorsPage implements ColorSettingsPage {
@NotNull
public SyntaxHighlighter getHighlighter() {
final SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(RegExpFileType.INSTANCE, null, null);
final SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(RegExpFileType.INSTANCE, null, null);
assert highlighter != null;
return highlighter;
}
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.template;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -40,6 +41,6 @@ public abstract class FileTypeBasedContextType extends TemplateContextType {
@Override
public SyntaxHighlighter createHighlighter() {
return SyntaxHighlighter.PROVIDER.create(myFileType, null, null);
return SyntaxHighlighterFactory.getSyntaxHighlighter(myFileType, null, null);
}
}
@@ -1,443 +1,443 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.fileTemplates.impl;
import com.intellij.codeInsight.template.impl.TemplateColors;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.lexer.CompositeLexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SeparatorFactory;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
/*
* @author: MYakovlev
* Date: Jul 26, 2002
* Time: 12:46:00 PM
*/
public class FileTemplateConfigurable implements Configurable, Configurable.NoScroll {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable");
@NonNls private static final String EMPTY_HTML = "<html></html>";
@NonNls private static final String CONTENT_TYPE_PLAIN = "text/plain";
private JPanel myMainPanel;
private FileTemplate myTemplate;
private PsiFile myFile;
private Editor myTemplateEditor;
private JTextField myNameField;
private JTextField myExtensionField;
private JCheckBox myAdjustBox;
private JPanel myTopPanel;
private JEditorPane myDescriptionComponent;
private boolean myModified = false;
private URL myDefaultDescriptionUrl;
private final Project myProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
private final ArrayList<ChangeListener> myChangeListeners = new ArrayList<ChangeListener>();
private Splitter mySplitter;
public FileTemplate getTemplate() {
return myTemplate;
}
public void setTemplate(FileTemplate template, URL defaultDescription) {
myDefaultDescriptionUrl = defaultDescription;
myTemplate = template;
if (myMainPanel != null) {
reset();
myNameField.selectAll();
myExtensionField.selectAll();
}
}
public void setShowInternalMessage(String message) {
if (message == null) {
myTopPanel.removeAll();
myTopPanel.add(new JLabel(IdeBundle.message("label.name")),
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(0, 0, 0, 2), 0, 0));
myTopPanel.add(myNameField,
new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 2), 0, 0));
myTopPanel.add(new JLabel(IdeBundle.message("label.extension")),
new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(0, 2, 0, 2), 0, 0));
myTopPanel.add(myExtensionField,
new GridBagConstraints(3, 0, 1, 1, .3, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0));
myExtensionField.setColumns(7);
}
else {
myTopPanel.removeAll();
myTopPanel.add(new JLabel(message),
new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
myTopPanel.add(Box.createVerticalStrut(myNameField.getPreferredSize().height),
new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
myMainPanel.revalidate();
myTopPanel.repaint();
}
public void setShowAdjustCheckBox(boolean show) {
myAdjustBox.setEnabled(show);
}
public String getDisplayName() {
return IdeBundle.message("title.file.templates");
}
public String getHelpTopic() {
return null;
}
public JComponent createComponent() {
myMainPanel = new JPanel(new GridBagLayout());
myNameField = new JTextField();
myExtensionField = new JTextField();
mySplitter = new Splitter(true, 0.66f);
myTemplateEditor = createEditor();
myDescriptionComponent = new JEditorPane(UIUtil.HTML_MIME, EMPTY_HTML);
myDescriptionComponent.setEditable(false);
myAdjustBox = new JCheckBox(IdeBundle.message("checkbox.reformat.according.to.style"));
myTopPanel = new JPanel(new GridBagLayout());
JPanel secondPanel = new JPanel(new GridBagLayout());
secondPanel.add(SeparatorFactory.createSeparator(IdeBundle.message("label.description"), null),
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 2, 0), 0, 0));
secondPanel.add(ScrollPaneFactory.createScrollPane(myDescriptionComponent),
new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(2, 0, 0, 0), 0, 0));
myMainPanel.add(myTopPanel,
new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0));
myMainPanel.add(myAdjustBox,
new GridBagConstraints(0, 1, 4, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));
myMainPanel.add(mySplitter,
new GridBagConstraints(0, 2, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(2, 0, 0, 0), 0, 0));
mySplitter.setSecondComponent(secondPanel);
setShowInternalMessage(null);
myNameField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
onNameChanged();
}
});
myExtensionField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
onNameChanged();
}
});
myMainPanel.setPreferredSize(new Dimension(400, 300));
return myMainPanel;
}
private Editor createEditor() {
EditorFactory editorFactory = EditorFactory.getInstance();
Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile);
Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject);
EditorSettings editorSettings = editor.getSettings();
editorSettings.setVirtualSpace(false);
editorSettings.setLineMarkerAreaShown(false);
editorSettings.setIndentGuidesShown(false);
editorSettings.setLineNumbersShown(false);
editorSettings.setFoldingOutlineShown(false);
editorSettings.setAdditionalColumnsCount(3);
editorSettings.setAdditionalLinesCount(3);
EditorColorsScheme scheme = editor.getColorsScheme();
scheme.setColor(EditorColors.CARET_ROW_COLOR, null);
editor.getDocument().addDocumentListener(new DocumentAdapter() {
public void documentChanged(DocumentEvent e) {
onTextChanged();
}
});
((EditorEx)editor).setHighlighter(createHighlighter());
mySplitter.setFirstComponent(editor.getComponent());
return editor;
}
private void onTextChanged() {
myModified = true;
}
public String getNameValue() {
return myNameField.getText();
}
public String getExtensionValue() {
return myExtensionField.getText();
}
private void onNameChanged() {
ChangeEvent event = new ChangeEvent(this);
for (ChangeListener changeListener : myChangeListeners) {
changeListener.stateChanged(event);
}
}
public void addChangeListener(ChangeListener listener) {
if (!myChangeListeners.contains(listener)) {
myChangeListeners.add(listener);
}
}
public void removeChangeListener(ChangeListener listener) {
myChangeListeners.remove(listener);
}
public boolean isModified() {
if (myModified) {
return true;
}
String name = (myTemplate == null) ? "" : myTemplate.getName();
String extension = (myTemplate == null) ? "" : myTemplate.getExtension();
if (!Comparing.equal(name, myNameField.getText())) {
return true;
}
if (!Comparing.equal(extension, myExtensionField.getText())) {
return true;
}
if (myTemplate != null) {
if (myTemplate.isReformatCode() != myAdjustBox.isSelected()) {
return true;
}
}
return false;
}
public void apply() throws ConfigurationException {
if (myTemplate != null) {
myTemplate.setText(myTemplateEditor.getDocument().getText());
String name = myNameField.getText();
String extension = myExtensionField.getText();
int lastDotIndex = extension.lastIndexOf(".");
if (lastDotIndex >= 0) {
name += extension.substring(0, lastDotIndex + 1);
extension = extension.substring(lastDotIndex + 1);
}
if (name.length() == 0 || !isValidFilename(name + "." + extension)) {
throw new ConfigurationException(IdeBundle.message("error.invalid.template.file.name.or.extension"));
}
myTemplate.setName(name);
myTemplate.setExtension(extension);
myTemplate.setReformatCode(myAdjustBox.isSelected());
}
myModified = false;
}
// TODO: needs to be generalized someday for other profiles
private static boolean isValidFilename(final String filename) {
if ( filename.contains("/") || filename.contains("\\") || filename.contains(":") ) {
return false;
}
final File tempFile = new File (FileUtil.getTempDirectory() + File.separator + filename);
return FileUtil.ensureCanCreateFile(tempFile);
}
public void reset() {
final String text = (myTemplate == null) ? "" : myTemplate.getText();
String name = (myTemplate == null) ? "" : myTemplate.getName();
String extension = (myTemplate == null) ? "" : myTemplate.getExtension();
String description = (myTemplate == null) ? "" : myTemplate.getDescription();
if ((description.length() == 0) && (myDefaultDescriptionUrl != null)) {
try {
description = UrlUtil.loadText(myDefaultDescriptionUrl);
}
catch (IOException e) {
LOG.error(e);
}
}
EditorFactory.getInstance().releaseEditor(myTemplateEditor);
myFile = createFile(text, name);
myTemplateEditor = createEditor();
boolean adjust = (myTemplate != null) && myTemplate.isReformatCode();
myNameField.setText(name);
myExtensionField.setText(extension);
myAdjustBox.setSelected(adjust);
String desc = description.length() > 0 ? description : EMPTY_HTML;
// [myakovlev] do not delete these stupid lines! Or you get Exception!
myDescriptionComponent.setContentType(CONTENT_TYPE_PLAIN);
myDescriptionComponent.setEditable(true);
myDescriptionComponent.setText(desc);
myDescriptionComponent.setContentType(UIUtil.HTML_MIME);
myDescriptionComponent.setText(desc);
myDescriptionComponent.setCaretPosition(0);
myDescriptionComponent.setEditable(false);
myNameField.setEditable((myTemplate != null) && (!myTemplate.isDefault()));
myExtensionField.setEditable((myTemplate != null) && (!myTemplate.isDefault()));
myModified = false;
}
@Nullable
private PsiFile createFile(final String text, final String name) {
if (myTemplate == null || myProject == null) return null;
final FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension("ft");
if (fileType == FileTypes.UNKNOWN) return null;
final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name + ".txt.ft", fileType, text, 0, true);
file.getViewProvider().putUserData(FileTemplateManager.DEFAULT_TEMPLATE_PROPERTIES, FileTemplateManager.getInstance().getDefaultProperties(myProject));
return file;
}
public void disposeUIResources() {
myMainPanel = null;
if (myTemplateEditor != null) {
EditorFactory.getInstance().releaseEditor(myTemplateEditor);
myTemplateEditor = null;
}
myFile = null;
}
private EditorHighlighter createHighlighter() {
if (myTemplate != null && myProject != null) {
return EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, new LightVirtualFile("aaa." + myTemplate.getExtension() + ".ft"));
}
else {
FileType fileType = null;
if (myTemplate != null) {
fileType = FileTypeManager.getInstance().getFileTypeByExtension(myTemplate.getExtension());
}
if (fileType == null) {
fileType = FileTypes.PLAIN_TEXT;
}
SyntaxHighlighter originalHighlighter = SyntaxHighlighter.PROVIDER.create(fileType, null, null);
if (originalHighlighter == null) originalHighlighter = new PlainSyntaxHighlighter();
return new LexerEditorHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme());
}
}
private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(FileTemplateTokenType.TEXT);
private static class TemplateHighlighter extends SyntaxHighlighterBase {
private final Lexer myLexer;
private final SyntaxHighlighter myOriginalHighlighter;
public TemplateHighlighter(SyntaxHighlighter original) {
myOriginalHighlighter = original;
Lexer originalLexer = original.getHighlightingLexer();
Lexer templateLexer = new FlexAdapter(new FileTemplateTextLexer());
templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE);
myLexer = new CompositeLexer(originalLexer, templateLexer) {
protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) {
if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) {
return type2;
}
else {
return type1;
}
}
};
}
@NotNull
public Lexer getHighlightingLexer() {
return myLexer;
}
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
if (tokenType == FileTemplateTokenType.MACRO) {
return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
}
else if (tokenType == FileTemplateTokenType.DIRECTIVE) {
return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
}
return myOriginalHighlighter.getTokenHighlights(tokenType);
}
}
public void focusToNameField() {
myNameField.selectAll();
myNameField.requestFocus();
}
public void focusToExtensionField() {
myExtensionField.selectAll();
myExtensionField.requestFocus();
}
}
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.fileTemplates.impl;
import com.intellij.codeInsight.template.impl.TemplateColors;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.lexer.CompositeLexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SeparatorFactory;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
/*
* @author: MYakovlev
* Date: Jul 26, 2002
* Time: 12:46:00 PM
*/
public class FileTemplateConfigurable implements Configurable, Configurable.NoScroll {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable");
@NonNls private static final String EMPTY_HTML = "<html></html>";
@NonNls private static final String CONTENT_TYPE_PLAIN = "text/plain";
private JPanel myMainPanel;
private FileTemplate myTemplate;
private PsiFile myFile;
private Editor myTemplateEditor;
private JTextField myNameField;
private JTextField myExtensionField;
private JCheckBox myAdjustBox;
private JPanel myTopPanel;
private JEditorPane myDescriptionComponent;
private boolean myModified = false;
private URL myDefaultDescriptionUrl;
private final Project myProject = PlatformDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
private final ArrayList<ChangeListener> myChangeListeners = new ArrayList<ChangeListener>();
private Splitter mySplitter;
public FileTemplate getTemplate() {
return myTemplate;
}
public void setTemplate(FileTemplate template, URL defaultDescription) {
myDefaultDescriptionUrl = defaultDescription;
myTemplate = template;
if (myMainPanel != null) {
reset();
myNameField.selectAll();
myExtensionField.selectAll();
}
}
public void setShowInternalMessage(String message) {
if (message == null) {
myTopPanel.removeAll();
myTopPanel.add(new JLabel(IdeBundle.message("label.name")),
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(0, 0, 0, 2), 0, 0));
myTopPanel.add(myNameField,
new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 2), 0, 0));
myTopPanel.add(new JLabel(IdeBundle.message("label.extension")),
new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets(0, 2, 0, 2), 0, 0));
myTopPanel.add(myExtensionField,
new GridBagConstraints(3, 0, 1, 1, .3, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 2, 0, 0), 0, 0));
myExtensionField.setColumns(7);
}
else {
myTopPanel.removeAll();
myTopPanel.add(new JLabel(message),
new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
myTopPanel.add(Box.createVerticalStrut(myNameField.getPreferredSize().height),
new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
myMainPanel.revalidate();
myTopPanel.repaint();
}
public void setShowAdjustCheckBox(boolean show) {
myAdjustBox.setEnabled(show);
}
public String getDisplayName() {
return IdeBundle.message("title.file.templates");
}
public String getHelpTopic() {
return null;
}
public JComponent createComponent() {
myMainPanel = new JPanel(new GridBagLayout());
myNameField = new JTextField();
myExtensionField = new JTextField();
mySplitter = new Splitter(true, 0.66f);
myTemplateEditor = createEditor();
myDescriptionComponent = new JEditorPane(UIUtil.HTML_MIME, EMPTY_HTML);
myDescriptionComponent.setEditable(false);
myAdjustBox = new JCheckBox(IdeBundle.message("checkbox.reformat.according.to.style"));
myTopPanel = new JPanel(new GridBagLayout());
JPanel secondPanel = new JPanel(new GridBagLayout());
secondPanel.add(SeparatorFactory.createSeparator(IdeBundle.message("label.description"), null),
new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 2, 0), 0, 0));
secondPanel.add(ScrollPaneFactory.createScrollPane(myDescriptionComponent),
new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(2, 0, 0, 0), 0, 0));
myMainPanel.add(myTopPanel,
new GridBagConstraints(0, 0, 4, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 2, 0), 0, 0));
myMainPanel.add(myAdjustBox,
new GridBagConstraints(0, 1, 4, 1, 0.0, 0.0, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));
myMainPanel.add(mySplitter,
new GridBagConstraints(0, 2, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(2, 0, 0, 0), 0, 0));
mySplitter.setSecondComponent(secondPanel);
setShowInternalMessage(null);
myNameField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
onNameChanged();
}
});
myExtensionField.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
onNameChanged();
}
});
myMainPanel.setPreferredSize(new Dimension(400, 300));
return myMainPanel;
}
private Editor createEditor() {
EditorFactory editorFactory = EditorFactory.getInstance();
Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile);
Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject);
EditorSettings editorSettings = editor.getSettings();
editorSettings.setVirtualSpace(false);
editorSettings.setLineMarkerAreaShown(false);
editorSettings.setIndentGuidesShown(false);
editorSettings.setLineNumbersShown(false);
editorSettings.setFoldingOutlineShown(false);
editorSettings.setAdditionalColumnsCount(3);
editorSettings.setAdditionalLinesCount(3);
EditorColorsScheme scheme = editor.getColorsScheme();
scheme.setColor(EditorColors.CARET_ROW_COLOR, null);
editor.getDocument().addDocumentListener(new DocumentAdapter() {
public void documentChanged(DocumentEvent e) {
onTextChanged();
}
});
((EditorEx)editor).setHighlighter(createHighlighter());
mySplitter.setFirstComponent(editor.getComponent());
return editor;
}
private void onTextChanged() {
myModified = true;
}
public String getNameValue() {
return myNameField.getText();
}
public String getExtensionValue() {
return myExtensionField.getText();
}
private void onNameChanged() {
ChangeEvent event = new ChangeEvent(this);
for (ChangeListener changeListener : myChangeListeners) {
changeListener.stateChanged(event);
}
}
public void addChangeListener(ChangeListener listener) {
if (!myChangeListeners.contains(listener)) {
myChangeListeners.add(listener);
}
}
public void removeChangeListener(ChangeListener listener) {
myChangeListeners.remove(listener);
}
public boolean isModified() {
if (myModified) {
return true;
}
String name = (myTemplate == null) ? "" : myTemplate.getName();
String extension = (myTemplate == null) ? "" : myTemplate.getExtension();
if (!Comparing.equal(name, myNameField.getText())) {
return true;
}
if (!Comparing.equal(extension, myExtensionField.getText())) {
return true;
}
if (myTemplate != null) {
if (myTemplate.isReformatCode() != myAdjustBox.isSelected()) {
return true;
}
}
return false;
}
public void apply() throws ConfigurationException {
if (myTemplate != null) {
myTemplate.setText(myTemplateEditor.getDocument().getText());
String name = myNameField.getText();
String extension = myExtensionField.getText();
int lastDotIndex = extension.lastIndexOf(".");
if (lastDotIndex >= 0) {
name += extension.substring(0, lastDotIndex + 1);
extension = extension.substring(lastDotIndex + 1);
}
if (name.length() == 0 || !isValidFilename(name + "." + extension)) {
throw new ConfigurationException(IdeBundle.message("error.invalid.template.file.name.or.extension"));
}
myTemplate.setName(name);
myTemplate.setExtension(extension);
myTemplate.setReformatCode(myAdjustBox.isSelected());
}
myModified = false;
}
// TODO: needs to be generalized someday for other profiles
private static boolean isValidFilename(final String filename) {
if ( filename.contains("/") || filename.contains("\\") || filename.contains(":") ) {
return false;
}
final File tempFile = new File (FileUtil.getTempDirectory() + File.separator + filename);
return FileUtil.ensureCanCreateFile(tempFile);
}
public void reset() {
final String text = (myTemplate == null) ? "" : myTemplate.getText();
String name = (myTemplate == null) ? "" : myTemplate.getName();
String extension = (myTemplate == null) ? "" : myTemplate.getExtension();
String description = (myTemplate == null) ? "" : myTemplate.getDescription();
if ((description.length() == 0) && (myDefaultDescriptionUrl != null)) {
try {
description = UrlUtil.loadText(myDefaultDescriptionUrl);
}
catch (IOException e) {
LOG.error(e);
}
}
EditorFactory.getInstance().releaseEditor(myTemplateEditor);
myFile = createFile(text, name);
myTemplateEditor = createEditor();
boolean adjust = (myTemplate != null) && myTemplate.isReformatCode();
myNameField.setText(name);
myExtensionField.setText(extension);
myAdjustBox.setSelected(adjust);
String desc = description.length() > 0 ? description : EMPTY_HTML;
// [myakovlev] do not delete these stupid lines! Or you get Exception!
myDescriptionComponent.setContentType(CONTENT_TYPE_PLAIN);
myDescriptionComponent.setEditable(true);
myDescriptionComponent.setText(desc);
myDescriptionComponent.setContentType(UIUtil.HTML_MIME);
myDescriptionComponent.setText(desc);
myDescriptionComponent.setCaretPosition(0);
myDescriptionComponent.setEditable(false);
myNameField.setEditable((myTemplate != null) && (!myTemplate.isDefault()));
myExtensionField.setEditable((myTemplate != null) && (!myTemplate.isDefault()));
myModified = false;
}
@Nullable
private PsiFile createFile(final String text, final String name) {
if (myTemplate == null || myProject == null) return null;
final FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension("ft");
if (fileType == FileTypes.UNKNOWN) return null;
final PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText(name + ".txt.ft", fileType, text, 0, true);
file.getViewProvider().putUserData(FileTemplateManager.DEFAULT_TEMPLATE_PROPERTIES, FileTemplateManager.getInstance().getDefaultProperties(myProject));
return file;
}
public void disposeUIResources() {
myMainPanel = null;
if (myTemplateEditor != null) {
EditorFactory.getInstance().releaseEditor(myTemplateEditor);
myTemplateEditor = null;
}
myFile = null;
}
private EditorHighlighter createHighlighter() {
if (myTemplate != null && myProject != null) {
return EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, new LightVirtualFile("aaa." + myTemplate.getExtension() + ".ft"));
}
else {
FileType fileType = null;
if (myTemplate != null) {
fileType = FileTypeManager.getInstance().getFileTypeByExtension(myTemplate.getExtension());
}
if (fileType == null) {
fileType = FileTypes.PLAIN_TEXT;
}
SyntaxHighlighter originalHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, null, null);
if (originalHighlighter == null) originalHighlighter = new PlainSyntaxHighlighter();
return new LexerEditorHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme());
}
}
private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(FileTemplateTokenType.TEXT);
private static class TemplateHighlighter extends SyntaxHighlighterBase {
private final Lexer myLexer;
private final SyntaxHighlighter myOriginalHighlighter;
public TemplateHighlighter(SyntaxHighlighter original) {
myOriginalHighlighter = original;
Lexer originalLexer = original.getHighlightingLexer();
Lexer templateLexer = new FlexAdapter(new FileTemplateTextLexer());
templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE);
myLexer = new CompositeLexer(originalLexer, templateLexer) {
protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) {
if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) {
return type2;
}
else {
return type1;
}
}
};
}
@NotNull
public Lexer getHighlightingLexer() {
return myLexer;
}
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
if (tokenType == FileTemplateTokenType.MACRO) {
return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
}
else if (tokenType == FileTemplateTokenType.DIRECTIVE) {
return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
}
return myOriginalHighlighter.getTokenHighlights(tokenType);
}
}
public void focusToNameField() {
myNameField.selectAll();
myNameField.requestFocus();
}
public void focusToExtensionField() {
myExtensionField.selectAll();
myExtensionField.requestFocus();
}
}
@@ -112,7 +112,7 @@ public class IndexPatternSearcher implements QueryExecutor<IndexPatternOccurrenc
if (file instanceof PsiPlainTextFile) {
FileType fType = file.getFileType();
if (fType instanceof CustomSyntaxTableFileType) {
Lexer lexer = SyntaxHighlighter.PROVIDER.create(fType, file.getProject(), file.getVirtualFile()).getHighlightingLexer();
Lexer lexer = SyntaxHighlighterFactory.getSyntaxHighlighter(fType, file.getProject(), file.getVirtualFile()).getHighlightingLexer();
findComments(lexer, chars, range, COMMENT_TOKENS, commentStarts, commentEnds, null);
}
else {
@@ -46,7 +46,8 @@ public class FileTypeEditorHighlighterProviders extends FileTypeExtension<Editor
@NotNull FileType fileType,
@Nullable VirtualFile virtualFile,
@NotNull EditorColorsScheme colors) {
return EditorHighlighterFactory.getInstance().createEditorHighlighter(SyntaxHighlighter.PROVIDER.create(fileType, project, virtualFile), colors);
return EditorHighlighterFactory.getInstance().createEditorHighlighter(
SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, virtualFile), colors);
}
};
return Collections.singletonList(defaultProvider);
@@ -27,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
* @see com.intellij.openapi.fileTypes.SyntaxHighlighterFactory#getSyntaxHighlighter(com.intellij.lang.Language, com.intellij.openapi.project.Project, com.intellij.openapi.vfs.VirtualFile)
*/
public interface SyntaxHighlighter {
SyntaxHighlighterProvider PROVIDER = new FileTypeExtensionFactory<SyntaxHighlighterProvider>(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get();
/**
* Returns the lexer used for highlighting the file. The lexer is invoked incrementally when the file is changed, so it must be
* capable of saving/restoring state and resuming lexing from the middle of the file.
@@ -23,14 +23,20 @@ import com.intellij.lang.Language;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class SyntaxHighlighterFactory {
public static SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory();
public static final SyntaxHighlighterLanguageFactory LANGUAGE_FACTORY = new SyntaxHighlighterLanguageFactory();
private static final SyntaxHighlighterProvider PROVIDER = new FileTypeExtensionFactory<SyntaxHighlighterProvider>(SyntaxHighlighterProvider.class, "com.intellij.syntaxHighlighter").get();
public static SyntaxHighlighter getSyntaxHighlighter(Language lang, Project project, VirtualFile virtualFile) {
return LANGUAGE_FACTORY.forLanguage(lang).getSyntaxHighlighter(project, virtualFile);
}
@Nullable
public static SyntaxHighlighter getSyntaxHighlighter(final FileType fileType, final @Nullable Project project, final @Nullable VirtualFile virtualFile) {
return PROVIDER.create(fileType, project, virtualFile);
}
/**
* Override this method to provide syntax highlighting (coloring) capabilities for your language implementation.
@@ -47,7 +47,7 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
return FileTypeEditorHighlighterProviders.INSTANCE.forFileType(fileType).getEditorHighlighter(project, fileType, null, settings);
}
SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(fileType, project, null);
SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, null);
return createEditorHighlighter(highlighter, settings);
}
@@ -90,7 +90,7 @@ public class EditorHighlighterFactoryImpl extends EditorHighlighterFactory {
}
}
if (highlighter == null) {
highlighter = SyntaxHighlighter.PROVIDER.create(fileType, project, vFile);
highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, vFile);
}
return createEditorHighlighter(highlighter, settings);
}
@@ -28,6 +28,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
@@ -109,7 +110,7 @@ public class ChunkExtractor {
myDocument = PsiDocumentManager.getInstance(project).getDocument(file);
LOG.assertTrue(myDocument != null);
final FileType fileType = file.getFileType();
final SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(fileType, project, file.getVirtualFile());
final SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile());
myHighlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter;
myLexer = myHighlighter.getHighlightingLexer();
myLexer.start(myDocument.getCharsSequence());
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.highlighter.*;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Getter;
@@ -324,7 +325,7 @@ public class PreparedFragmentedContent {
private void setHighlighters(final Document oldDocument, final Document document,
List<BeforeAfter<TextRange>> ranges) {
EditorHighlighterFactory editorHighlighterFactory = EditorHighlighterFactory.getInstance();
final SyntaxHighlighter syntaxHighlighter = SyntaxHighlighter.PROVIDER.create(myFileType, myProject, null);
final SyntaxHighlighter syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(myFileType, myProject, null);
final EditorHighlighter highlighter =
editorHighlighterFactory.createEditorHighlighter(syntaxHighlighter, EditorColorsManager.getInstance().getGlobalScheme());
@@ -18,7 +18,7 @@ package com.intellij.lexer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlTokenType;
import org.jetbrains.annotations.Nullable;
@@ -104,13 +104,13 @@ public class HtmlHighlightingLexer extends BaseHtmlLexer {
Lexer newLexer = null;
if (hasSeenStyle()) {
if (styleLexer==null) {
styleLexer = (ourStyleFileType!=null)? SyntaxHighlighter.PROVIDER.create(ourStyleFileType, null, null).getHighlightingLexer():null;
styleLexer = (ourStyleFileType!=null)? SyntaxHighlighterFactory.getSyntaxHighlighter(ourStyleFileType, null, null).getHighlightingLexer():null;
}
newLexer = styleLexer;
} else if (hasSeenScript()) {
if (scriptLexer==null) {
scriptLexer = (ourScriptFileType!=null)? SyntaxHighlighter.PROVIDER.create(ourScriptFileType, null, null).getHighlightingLexer():null;
scriptLexer = (ourScriptFileType!=null)? SyntaxHighlighterFactory.getSyntaxHighlighter(ourScriptFileType, null, null).getHighlightingLexer():null;
}
newLexer = scriptLexer;
} else newLexer = createELLexer(newLexer);