forked from scala-ide/scala-ide
/
ScalaSourceViewerConfiguration.scala
212 lines (185 loc) · 10.1 KB
/
ScalaSourceViewerConfiguration.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
* Copyright 2005-2010 LAMP/EPFL
*/
// $Id$
package scala.tools.eclipse
import scala.tools.eclipse.formatter.ScalaFormattingStrategy
import scala.tools.eclipse.hyperlink.text.detector.CompositeHyperlinkDetector
import scala.tools.eclipse.hyperlink.text.detector.DeclarationHyperlinkDetector
import scala.tools.eclipse.hyperlink.text.detector.ImplicitHyperlinkDetector
import scala.tools.eclipse.javaelements.ScalaCompilationUnit
import scala.tools.eclipse.lexical.ScalaCodeScanner
import scala.tools.eclipse.lexical.ScalaCommentScanner
import scala.tools.eclipse.lexical.ScalaPartitions
import scala.tools.eclipse.lexical.ScaladocTokenScanner
import scala.tools.eclipse.lexical.SingleTokenScanner
import scala.tools.eclipse.lexical.StringTokenScanner
import scala.tools.eclipse.lexical.XmlCDATAScanner
import scala.tools.eclipse.lexical.XmlCommentScanner
import scala.tools.eclipse.lexical.XmlPIScanner
import scala.tools.eclipse.lexical.XmlTagScanner
import scala.tools.eclipse.properties.syntaxcolouring.{ScalaSyntaxClasses => SSC}
import scala.tools.eclipse.reconciliation.ScalaReconcilingStrategy
import scala.tools.eclipse.ui.BracketAutoEditStrategy
import scala.tools.eclipse.ui.CommentAutoIndentStrategy
import scala.tools.eclipse.ui.JdtPreferenceProvider
import scala.tools.eclipse.ui.LiteralAutoEditStrategy
import scala.tools.eclipse.ui.MultiLineStringAutoEditStrategy
import scala.tools.eclipse.ui.ScalaAutoIndentStrategy
import scala.tools.eclipse.ui.StringAutoEditStrategy
import org.eclipse.core.runtime.NullProgressMonitor
import org.eclipse.jdt.core.ICodeAssist
import org.eclipse.jdt.core.IJavaElement
import org.eclipse.jdt.core.IJavaProject
import org.eclipse.jdt.internal.ui.JavaPlugin
import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput
import org.eclipse.jdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider
import org.eclipse.jdt.internal.ui.text.java.SmartSemicolonAutoEditStrategy
import org.eclipse.jdt.ui.text.IJavaPartitions
import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration
import org.eclipse.jface.preference.IPreferenceStore
import org.eclipse.jface.text.DefaultTextHover
import org.eclipse.jface.text.IAutoEditStrategy
import org.eclipse.jface.text.IDocument
import org.eclipse.jface.text.ITextHover
import org.eclipse.jface.text.formatter.IContentFormatter
import org.eclipse.jface.text.formatter.MultiPassContentFormatter
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector
import org.eclipse.jface.text.hyperlink.URLHyperlinkDetector
import org.eclipse.jface.text.reconciler.IReconciler
import org.eclipse.jface.text.reconciler.MonoReconciler
import org.eclipse.jface.text.rules.DefaultDamagerRepairer
import org.eclipse.jface.text.source.ISourceViewer
import org.eclipse.jface.util.PropertyChangeEvent
import scalariform.ScalaVersions
class ScalaSourceViewerConfiguration(
javaPreferenceStore: IPreferenceStore,
scalaPreferenceStore: IPreferenceStore,
editor: ScalaEditor)
extends JavaSourceViewerConfiguration(
JavaPlugin.getDefault.getJavaTextTools.getColorManager,
javaPreferenceStore,
editor,
IJavaPartitions.JAVA_PARTITIONING) {
private val codeHighlightingScanners = {
import scala.tools.eclipse.properties.syntaxcolouring.{ ScalaSyntaxClasses => SSC }
val scalaCodeScanner = new ScalaCodeScanner(scalaPreferenceStore, ScalaVersions.DEFAULT)
val singleLineCommentScanner = new ScalaCommentScanner(scalaPreferenceStore, javaPreferenceStore, SSC.SINGLE_LINE_COMMENT, SSC.TASK_TAG)
val multiLineCommentScanner = new ScalaCommentScanner(scalaPreferenceStore, javaPreferenceStore, SSC.MULTI_LINE_COMMENT, SSC.TASK_TAG)
val scaladocScanner = new ScaladocTokenScanner(scalaPreferenceStore, javaPreferenceStore, SSC.SCALADOC, SSC.SCALADOC_ANNOTATION, SSC.SCALADOC_MACRO, SSC.TASK_TAG)
val scaladocCodeBlockScanner = new SingleTokenScanner(scalaPreferenceStore, SSC.SCALADOC_CODE_BLOCK)
val stringScanner = new StringTokenScanner(scalaPreferenceStore, SSC.ESCAPE_SEQUENCE, SSC.STRING)
val characterScanner = new StringTokenScanner(scalaPreferenceStore, SSC.ESCAPE_SEQUENCE, SSC.CHARACTER)
val multiLineStringScanner = new SingleTokenScanner(scalaPreferenceStore, SSC.MULTI_LINE_STRING)
val xmlTagScanner = new XmlTagScanner(scalaPreferenceStore)
val xmlCommentScanner = new XmlCommentScanner(scalaPreferenceStore)
val xmlCDATAScanner = new XmlCDATAScanner(scalaPreferenceStore)
val xmlPCDATAScanner = new SingleTokenScanner(scalaPreferenceStore, SSC.DEFAULT)
val xmlPIScanner = new XmlPIScanner(scalaPreferenceStore)
Map(
IDocument.DEFAULT_CONTENT_TYPE -> scalaCodeScanner,
IJavaPartitions.JAVA_DOC -> scaladocScanner,
ScalaPartitions.SCALADOC_CODE_BLOCK -> scaladocCodeBlockScanner,
IJavaPartitions.JAVA_SINGLE_LINE_COMMENT -> singleLineCommentScanner,
IJavaPartitions.JAVA_MULTI_LINE_COMMENT -> multiLineCommentScanner,
IJavaPartitions.JAVA_STRING -> stringScanner,
IJavaPartitions.JAVA_CHARACTER -> characterScanner,
ScalaPartitions.SCALA_MULTI_LINE_STRING -> multiLineStringScanner,
ScalaPartitions.XML_TAG -> xmlTagScanner,
ScalaPartitions.XML_COMMENT -> xmlCommentScanner,
ScalaPartitions.XML_CDATA -> xmlCDATAScanner,
ScalaPartitions.XML_PCDATA -> xmlPCDATAScanner,
ScalaPartitions.XML_PI -> xmlPIScanner
)
}
override def getReconciler(sourceViewer: ISourceViewer): IReconciler =
if (editor ne null) {
val reconciler = new MonoReconciler(new ScalaReconcilingStrategy(editor), /*isIncremental = */ false)
// FG: I don't know any better that to defer this to the MonoReconciler constructor's default value
// reconciler.setDelay(500)
reconciler.install(sourceViewer)
reconciler.setProgressMonitor(new NullProgressMonitor())
reconciler
} else
null // the editor is null for the Syntax coloring previewer pane, (so no reconciliation)
override def getPresentationReconciler(sourceViewer: ISourceViewer): ScalaPresentationReconciler = {
val reconciler = new ScalaPresentationReconciler()
reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer))
for ((partitionType, tokenScanner) <- codeHighlightingScanners) {
val dr = new DefaultDamagerRepairer(tokenScanner)
reconciler.setDamager(dr, partitionType)
reconciler.setRepairer(dr, partitionType)
}
reconciler
}
override def getTextHover(sv: ISourceViewer, contentType: String, stateMask: Int): ITextHover =
getCodeAssist match {
case Some(scu: ScalaCompilationUnit) => new ScalaHover(scu)
case _ => new DefaultTextHover(sv)
}
override def getHyperlinkDetectors(sv: ISourceViewer): Array[IHyperlinkDetector] = {
val strategies = List(DeclarationHyperlinkDetector(), ImplicitHyperlinkDetector())
val detector = new CompositeHyperlinkDetector(strategies)
if (editor != null) detector.setContext(editor)
Array(detector, new URLHyperlinkDetector())
}
def getCodeAssist: Option[ICodeAssist] = Option(editor) map { editor =>
val input = editor.getEditorInput
val provider = editor.getDocumentProvider
(provider, input) match {
case (icudp: ICompilationUnitDocumentProvider, _) => icudp getWorkingCopy input
case (_, icfei: IClassFileEditorInput) => icfei.getClassFile
case _ => null
}
}
def getProject: IJavaProject =
getCodeAssist.map(_.asInstanceOf[IJavaElement].getJavaProject).orNull
/**
* Replica of JavaSourceViewerConfiguration#getAutoEditStrategies that returns
* a ScalaAutoIndentStrategy instead of a JavaAutoIndentStrategy.
*
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAutoEditStrategies(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
*/
override def getAutoEditStrategies(sourceViewer: ISourceViewer, contentType: String): Array[IAutoEditStrategy] = {
def prefProvider = new JdtPreferenceProvider(getProject)
val partitioning = getConfiguredDocumentPartitioning(sourceViewer)
contentType match {
case IJavaPartitions.JAVA_DOC | IJavaPartitions.JAVA_MULTI_LINE_COMMENT | ScalaPartitions.SCALADOC_CODE_BLOCK =>
Array(new CommentAutoIndentStrategy(ScalaPlugin.prefStore, partitioning))
case ScalaPartitions.SCALA_MULTI_LINE_STRING =>
Array(
new SmartSemicolonAutoEditStrategy(partitioning),
new ScalaAutoIndentStrategy(partitioning, getProject, sourceViewer, prefProvider),
new MultiLineStringAutoEditStrategy(partitioning, ScalaPlugin.prefStore))
case IJavaPartitions.JAVA_STRING =>
Array(
new SmartSemicolonAutoEditStrategy(partitioning),
new StringAutoEditStrategy(partitioning, ScalaPlugin.prefStore))
case IJavaPartitions.JAVA_CHARACTER | IDocument.DEFAULT_CONTENT_TYPE =>
Array(
new SmartSemicolonAutoEditStrategy(partitioning),
new ScalaAutoIndentStrategy(partitioning, getProject, sourceViewer, prefProvider),
new BracketAutoEditStrategy(ScalaPlugin.prefStore),
new LiteralAutoEditStrategy(ScalaPlugin.prefStore))
case _ =>
Array(new ScalaAutoIndentStrategy(partitioning, getProject, sourceViewer, prefProvider))
}
}
override def getContentFormatter(sourceViewer: ISourceViewer): IContentFormatter = {
val formatter = new MultiPassContentFormatter(getConfiguredDocumentPartitioning(sourceViewer), IDocument.DEFAULT_CONTENT_TYPE)
formatter.setMasterStrategy(new ScalaFormattingStrategy(editor))
formatter
}
override def handlePropertyChangeEvent(event: PropertyChangeEvent) {
super.handlePropertyChangeEvent(event)
codeHighlightingScanners.values foreach (_ adaptToPreferenceChange event)
}
/**
* Adds Scala related partition types to the list of configured content types,
* in order that they are available for several features of the IDE.
*/
override def getConfiguredContentTypes(sourceViewer: ISourceViewer): Array[String] =
super.getConfiguredContentTypes(sourceViewer) ++
Seq(ScalaPartitions.SCALA_MULTI_LINE_STRING, ScalaPartitions.SCALADOC_CODE_BLOCK)
override def affectsTextPresentation(event: PropertyChangeEvent) = true
}