Improve: AutoComplete complete partly

This commit is contained in:
zt515 2017-07-23 23:46:20 +08:00
parent c648822c41
commit 3681806910
2 changed files with 43 additions and 12 deletions

View File

@ -38,8 +38,9 @@ open class FileCompletionProvider : ICandidateProvider {
val candidates = mutableListOf<CompletionCandidate>() val candidates = mutableListOf<CompletionCandidate>()
listDirectory(file, filter) listDirectory(file, filter)
.mapTo(candidates, { .mapTo(candidates, {
val candidate = CompletionCandidate(transformToCompletionString(it)) val candidate = CompletionCandidate(it.name)
candidate.description = generateDesc(it) candidate.description = generateDesc(it)
candidate.displayName = generateDisplayName(it)
candidate candidate
}) })
return candidates return candidates
@ -47,7 +48,7 @@ open class FileCompletionProvider : ICandidateProvider {
return null return null
} }
open fun transformToCompletionString(file: File): String { open fun generateDisplayName(file: File): String {
return if (file.isDirectory) "${file.name}/" else file.name return if (file.isDirectory) "${file.name}/" else file.name
} }

View File

@ -1,6 +1,8 @@
package io.neoterm.frontend.client package io.neoterm.frontend.client
import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import io.neoterm.BuildConfig
import io.neoterm.frontend.completion.CompletionManager import io.neoterm.frontend.completion.CompletionManager
import io.neoterm.frontend.completion.listener.OnAutoCompleteListener import io.neoterm.frontend.completion.listener.OnAutoCompleteListener
import io.neoterm.frontend.completion.listener.OnCandidateSelectedListener import io.neoterm.frontend.completion.listener.OnCandidateSelectedListener
@ -16,12 +18,14 @@ import java.util.*
class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteListener, OnCandidateSelectedListener { class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteListener, OnCandidateSelectedListener {
private val inputStack = Stack<Char>() private val inputStack = Stack<Char>()
private var popupWindow: CandidatePopupWindow? = null private var popupWindow: CandidatePopupWindow? = null
private var lastCompletedIndex = 0
override fun onKeyCode(keyCode: Int, keyMod: Int) { override fun onKeyCode(keyCode: Int, keyMod: Int) {
when (keyCode) { when (keyCode) {
KeyEvent.KEYCODE_DEL -> { KeyEvent.KEYCODE_DEL -> {
popChar() popChar()
activateAutoCompletion() fixLastCompletedIndex()
triggerCompletion()
} }
KeyEvent.KEYCODE_ENTER -> { KeyEvent.KEYCODE_ENTER -> {
@ -31,12 +35,17 @@ class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteList
} }
} }
private fun fixLastCompletedIndex() {
val currentText = getCurrentEditingText()
lastCompletedIndex = minOf(lastCompletedIndex, currentText.length - 1)
}
override fun onAutoComplete(newText: String?) { override fun onAutoComplete(newText: String?) {
if (newText == null || newText.isEmpty()) { if (newText == null || newText.isEmpty()) {
return return
} }
pushString(newText) pushString(newText)
activateAutoCompletion() triggerCompletion()
} }
override fun onCleanUp() { override fun onCleanUp() {
@ -58,22 +67,40 @@ class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteList
override fun onCandidateSelected(candidate: CompletionCandidate) { override fun onCandidateSelected(candidate: CompletionCandidate) {
val session = terminalView?.currentSession ?: return val session = terminalView?.currentSession ?: return
val currentText = getCurrentEditingText() val textNeedCompletion = getCurrentEditingText().substring(lastCompletedIndex + 1)
val newText = candidate.completeString val newText = candidate.completeString
var finalString = ""
val startIndex = newText.indexOf(currentText) + currentText.length val finalString: String
val startIndex = newText.indexOf(textNeedCompletion) + textNeedCompletion.length
val endIndex = newText.length val endIndex = newText.length
val cutLength = endIndex - startIndex val cutLength = endIndex - startIndex
if (cutLength > 0) { if (cutLength > 0) {
finalString = newText.substring(startIndex, endIndex) finalString = newText.substring(startIndex, endIndex)
} else {
// The same situation: startIndex < 0
// We are just triggering a completion
// No any other chars are input
// If a candidate selected, complete all.
finalString = newText
} }
if (BuildConfig.DEBUG) {
Log.e("NeoTerm-AC", "currentEditing: $textNeedCompletion, " +
"start: $startIndex, end: $endIndex, " +
"completeString: $newText, finalComplete: $finalString")
}
if (finalString.isNotEmpty()) {
pushString(finalString) pushString(finalString)
session.write(finalString) session.write(finalString)
// Trigger next completion
lastCompletedIndex = inputStack.size
triggerCompletion()
}
} }
private fun activateAutoCompletion() { private fun triggerCompletion() {
val text = getCurrentEditingText() val text = getCurrentEditingText()
if (text.isEmpty()) { if (text.isEmpty()) {
return return
@ -85,6 +112,7 @@ class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteList
// But no candidates are provided // But no candidates are provided
// Give it zero angrily! // Give it zero angrily!
result.markScore(0) result.markScore(0)
onFinishCompletion()
return return
} }
showAutoCompleteCandidates(result) showAutoCompleteCandidates(result)
@ -113,10 +141,11 @@ class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteList
val size = inputStack.size val size = inputStack.size
var start = inputStack.lastIndexOf(' ') var start = inputStack.lastIndexOf(' ')
if (start < 0) { if (start < 0) {
start = 0 // Yes, it is -1, we will do `start + 1` below.
start = -1
} }
(start..(size - 1)) IntRange(start + 1, size - 1)
.map { inputStack[it] } .map { inputStack[it] }
.takeWhile { !(it == 0.toChar() || it == ' ') } .takeWhile { !(it == 0.toChar() || it == ' ') }
.forEach { builder.append(it) } .forEach { builder.append(it) }
@ -125,6 +154,7 @@ class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteList
private fun clearChars() { private fun clearChars() {
inputStack.clear() inputStack.clear()
lastCompletedIndex = 0
} }
private fun popChar() { private fun popChar() {