Skip to content

Commit beec5db

Browse files
committed
REPL completion - Enable levenstien based typo matching
scala> scala.tools.nsc.util.EditDistance.levenshtien<TAB> scala> scala.tools.nsc.util.EditDistance.levenshtein<TAB>
1 parent 9ae4955 commit beec5db

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/repl-frontend/scala/tools/nsc/interpreter/jline/Reader.scala

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,25 @@ object Reader {
103103
}
104104
object customCompletionMatcher extends CompletionMatcherImpl {
105105
override def compile(options: util.Map[LineReader.Option, lang.Boolean], prefix: Boolean, line: CompletingParsedLine, caseInsensitive: Boolean, errors: Int, originalGroupName: String): Unit = {
106-
super.compile(options, prefix, line, caseInsensitive, errors, originalGroupName)
107-
// TODO Use Option.COMPLETION_MATCHER_TYPO(false) in once https://github.com/jline/jline3/pull/646
108-
matchers.remove(matchers.size() - 2)
106+
val errorsReduced = line.wordCursor() match {
107+
case 0 | 1 | 2 | 3 => 0 // disable JLine's levenshtein-distance based typo matcher for short strings
108+
case 4 | 5 => math.max(errors, 1)
109+
case _ => errors
110+
}
111+
super.compile(options, prefix, line, caseInsensitive, errorsReduced, originalGroupName)
112+
113+
// TODO JLINE All of this can/must be removed after the next JLine upgrade
114+
matchers.remove(matchers.size() - 2) // remove ty
115+
val wd = line.word();
116+
val wdi = if (caseInsensitive) wd.toLowerCase() else wd
117+
val typoMatcherWord = if (prefix) wdi.substring(0, line.wordCursor()) else wdi
118+
val fixedTypoMatcher = typoMatcher(
119+
typoMatcherWord,
120+
errorsReduced,
121+
!caseInsensitive, // Fixed in JLine https://github.com/jline/jline3/pull/647, remove the negation when upgrading!
122+
originalGroupName
123+
)
124+
matchers.add(matchers.size - 2, fixedTypoMatcher)
109125
}
110126

111127
override def matches(candidates: JList[Candidate]): JList[Candidate] = {
@@ -323,12 +339,15 @@ class Completion(delegate: shell.Completion) extends shell.Completion with Compl
323339
result.candidates.filter(_.name == parsedLineWord) match {
324340
case Nil =>
325341
case exacts =>
326-
lineReader.getTerminal.writer.println()
327-
for (cc <- exacts)
328-
lineReader.getTerminal.writer.println(cc.declString())
329-
lineReader.callWidget(LineReader.REDRAW_LINE)
330-
lineReader.callWidget(LineReader.REDISPLAY)
331-
lineReader.getTerminal.flush()
342+
val declStrings = exacts.map(_.declString()).filterNot(_ == "")
343+
if (declStrings.nonEmpty) {
344+
lineReader.getTerminal.writer.println()
345+
for (declString <- declStrings)
346+
lineReader.getTerminal.writer.println(declString)
347+
lineReader.callWidget(LineReader.REDRAW_LINE)
348+
lineReader.callWidget(LineReader.REDISPLAY)
349+
lineReader.getTerminal.flush()
350+
}
332351
}
333352
}
334353
}

src/repl/scala/tools/nsc/interpreter/PresentationCompilation.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,11 @@ trait PresentationCompilation { self: IMain =>
192192
isDeprecated = isMemberDeprecated(member),
193193
isUniversal = isMemberUniversal(member),
194194
declString = () => {
195-
val tp = member.prefix memberType sym; sugared.defStringSeenAs(tp)
195+
if (sym.isPackageObjectOrClass) ""
196+
else {
197+
val tp = member.prefix memberType sym;
198+
sugared.defStringSeenAs(tp)
199+
}
196200
})
197201
}
198202
ccs

0 commit comments

Comments
 (0)