Feature: Program Suggestions
This commit is contained in:
@ -0,0 +1,10 @@
|
||||
package io.neoterm.customize.shortcut
|
||||
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
interface ShortcutKey {
|
||||
fun applyShortcutKeys(extraKeysView: ExtraKeysView)
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package io.neoterm.customize.shortcut
|
||||
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
object ShortcutKeysManager {
|
||||
val shortcutKeys: MutableMap<String, ShortcutKey> = mutableMapOf()
|
||||
|
||||
fun showShortcutKeys(program: String, extraKeysView: ExtraKeysView?) {
|
||||
if (extraKeysView == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.shortcutKeys.containsKey(program)) {
|
||||
val shortcutKey = shortcutKeys[program]
|
||||
shortcutKey?.applyShortcutKeys(extraKeysView)
|
||||
return
|
||||
}
|
||||
|
||||
extraKeysView.resetExternalButtons()
|
||||
}
|
||||
|
||||
fun registerShortcutKeys(program: String, shortcutKey: ShortcutKey?) {
|
||||
if (shortcutKey == null) {
|
||||
if (this.shortcutKeys.containsKey(program)) {
|
||||
this.shortcutKeys.remove(program)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.shortcutKeys[program] = shortcutKey
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package io.neoterm.customize.shortcut.builtin
|
||||
|
||||
import io.neoterm.customize.shortcut.ShortcutKey
|
||||
import io.neoterm.customize.shortcut.ShortcutKeysManager
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
object BuiltinShortcutKeys {
|
||||
val vim = object : ShortcutKey {
|
||||
override fun applyShortcutKeys(extraKeysView: ExtraKeysView) {
|
||||
extraKeysView.addExternalButton(ExtraKeysView.SLASH) // Search
|
||||
extraKeysView.addExternalButton(ExtraKeysView.TextButton(":w", true)) // Save
|
||||
extraKeysView.addExternalButton(ExtraKeysView.TextButton("dd", true)) // Delete
|
||||
extraKeysView.addExternalButton(ExtraKeysView.TextButton(":q", true)) // Quit
|
||||
}
|
||||
}
|
||||
|
||||
val moreAndLess = object : ShortcutKey {
|
||||
override fun applyShortcutKeys(extraKeysView: ExtraKeysView) {
|
||||
extraKeysView.addExternalButton(ExtraKeysView.TextButton("R", true)) // Rest
|
||||
extraKeysView.addExternalButton(ExtraKeysView.TextButton("Q", true)) // Quit
|
||||
}
|
||||
}
|
||||
|
||||
fun registerAll() {
|
||||
ShortcutKeysManager.registerShortcutKeys("vim", vim)
|
||||
ShortcutKeysManager.registerShortcutKeys("more", moreAndLess)
|
||||
ShortcutKeysManager.registerShortcutKeys("less", moreAndLess)
|
||||
}
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package io.neoterm.ui
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.ComponentName
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.*
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
@ -16,11 +13,13 @@ import android.support.v7.widget.Toolbar
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.ImageButton
|
||||
import de.mrapp.android.tabswitcher.*
|
||||
import de.mrapp.android.tabswitcher.view.TabSwitcherButton
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.customize.shortcut.builtin.BuiltinShortcutKeys
|
||||
import io.neoterm.installer.BaseFileInstaller
|
||||
import io.neoterm.preference.NeoPermission
|
||||
import io.neoterm.preference.NeoTermPreference
|
||||
@ -83,6 +82,8 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
|
||||
NeoPermission.initAppPermission(this, NeoPermission.REQUEST_APP_PERMISSION)
|
||||
NeoTermPreference.init(this)
|
||||
BuiltinShortcutKeys.registerAll()
|
||||
|
||||
if (NeoTermPreference.loadBoolean(R.string.key_ui_fullscreen, false)) {
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
@ -285,6 +286,11 @@ class NeoTermActivity : AppCompatActivity(), ServiceConnection {
|
||||
startActivity(Intent(this, SettingActivity::class.java))
|
||||
true
|
||||
}
|
||||
R.id.menu_item_toggle_ime -> {
|
||||
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0)
|
||||
true
|
||||
}
|
||||
R.id.menu_item_new_session -> {
|
||||
if (!tabSwitcher.isSwitcherShown) {
|
||||
tabSwitcher.showSwitcher()
|
||||
|
@ -2,6 +2,7 @@ package io.neoterm.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.KeyEvent;
|
||||
@ -40,13 +41,23 @@ public final class ExtraKeysView extends GridLayout {
|
||||
}
|
||||
|
||||
public static class TextButton extends ExtraButton {
|
||||
boolean withEnter = false;
|
||||
|
||||
public TextButton(String text) {
|
||||
buttonText = text;
|
||||
this(text, false);
|
||||
}
|
||||
|
||||
public TextButton(String text, boolean withEnter) {
|
||||
this.buttonText = text;
|
||||
this.withEnter = withEnter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
ExtraKeysView.sendKey(view, buttonText);
|
||||
if (withEnter) {
|
||||
ExtraKeysView.sendKey(view, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,10 +107,15 @@ public final class ExtraKeysView extends GridLayout {
|
||||
|
||||
public ExtraKeysView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
externalButtons = new ArrayList<>(3);
|
||||
extraButtons = new ArrayList<>();
|
||||
resetExternalButtons();
|
||||
reload();
|
||||
try {
|
||||
externalButtons = new ArrayList<>(3);
|
||||
extraButtons = new ArrayList<>();
|
||||
resetExternalButtons();
|
||||
updateButtons();
|
||||
} catch (Throwable e) {
|
||||
Log.e("NeoTerm", e.toString());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendKey(View view, String keyName) {
|
||||
@ -167,6 +183,7 @@ public final class ExtraKeysView extends GridLayout {
|
||||
|
||||
public void resetExternalButtons() {
|
||||
clearExternalButton();
|
||||
externalButtons.add(ALT);
|
||||
externalButtons.add(HORIZONTAL);
|
||||
externalButtons.add(SLASH);
|
||||
externalButtons.add(PIPE);
|
||||
@ -175,7 +192,6 @@ public final class ExtraKeysView extends GridLayout {
|
||||
void loadDefaultButtons(List<ExtraButton> buttons) {
|
||||
buttons.add(ESC);
|
||||
buttons.add(CTRL);
|
||||
buttons.add(ALT);
|
||||
buttons.add(TAB);
|
||||
}
|
||||
|
||||
@ -183,8 +199,7 @@ public final class ExtraKeysView extends GridLayout {
|
||||
buttons.addAll(externalButtons);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
ALT.toggleButton = CTRL.toggleButton = null;
|
||||
public void updateButtons() {
|
||||
removeAllViews();
|
||||
|
||||
extraButtons.clear();
|
||||
@ -208,6 +223,7 @@ public final class ExtraKeysView extends GridLayout {
|
||||
|
||||
button.setText(extraButton.buttonText);
|
||||
button.setTextColor(TEXT_COLOR);
|
||||
button.setAllCaps(false);
|
||||
|
||||
final Button finalButton = button;
|
||||
button.setOnClickListener(new OnClickListener() {
|
||||
|
@ -16,7 +16,6 @@ import io.neoterm.view.TerminalView
|
||||
*/
|
||||
class TermSessionChangedCallback : TerminalSession.SessionChangedCallback {
|
||||
var termView: TerminalView? = null
|
||||
var extraKeysView: ExtraKeysView? = null
|
||||
var termTab: TermTab? = null
|
||||
|
||||
var bellId: Int = 0
|
||||
|
@ -3,8 +3,10 @@ package io.neoterm.view.tab
|
||||
import android.graphics.Color
|
||||
import android.support.v7.widget.Toolbar
|
||||
import de.mrapp.android.tabswitcher.Tab
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.customize.color.NeoTermColorScheme
|
||||
import io.neoterm.preference.NeoTermPreference
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
@ -29,7 +31,6 @@ class TermTab(title: CharSequence) : Tab(title) {
|
||||
viewClient?.extraKeysView = null
|
||||
sessionCallback?.termView = null
|
||||
sessionCallback?.termTab = null
|
||||
sessionCallback?.extraKeysView = null
|
||||
closeTabProvider = null
|
||||
toolbar = null
|
||||
termSession = null
|
||||
@ -38,6 +39,9 @@ class TermTab(title: CharSequence) : Tab(title) {
|
||||
fun updateTitle(title: String) {
|
||||
this.title = title
|
||||
toolbar?.title = title
|
||||
if (NeoTermPreference.loadBoolean(R.string.key_ui_suggestions, true)) {
|
||||
viewClient?.updateSuggestions(title)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSessionFinished() {
|
||||
|
@ -68,13 +68,16 @@ class TermTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
|
||||
// 复用前一次的 TermSession
|
||||
termTab.sessionCallback?.termView = view
|
||||
termTab.sessionCallback?.termTab = termTab
|
||||
termTab.sessionCallback?.extraKeysView = extraKeysView
|
||||
|
||||
// 复用上一次的 TermViewClient
|
||||
termTab.viewClient?.termTab = termTab
|
||||
termTab.viewClient?.termView = view
|
||||
termTab.viewClient?.extraKeysView = extraKeysView
|
||||
|
||||
if (termTab.termSession != null) {
|
||||
termTab.viewClient?.updateSuggestions(termTab.termSession?.title, true)
|
||||
}
|
||||
|
||||
view.setOnKeyListener(termTab.viewClient)
|
||||
view.attachSession(termTab.termSession)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import android.view.MotionEvent
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
import io.neoterm.customize.shortcut.ShortcutKeysManager
|
||||
import io.neoterm.preference.NeoTermPreference
|
||||
import io.neoterm.view.ExtraKeysView
|
||||
import io.neoterm.view.TerminalView
|
||||
@ -18,6 +19,7 @@ import io.neoterm.view.TerminalViewClient
|
||||
class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
private var mVirtualControlKeyDown: Boolean = false
|
||||
private var mVirtualFnKeyDown: Boolean = false
|
||||
private var lastTitle: String = ""
|
||||
|
||||
var sessionFinished: Boolean = false
|
||||
|
||||
@ -102,4 +104,17 @@ class TermViewClient(val context: Context) : TerminalViewClient {
|
||||
return false
|
||||
}
|
||||
|
||||
fun updateSuggestions(title: String?, force: Boolean = false) {
|
||||
if (extraKeysView == null || title == null || title.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (lastTitle != title || force) {
|
||||
extraKeysView?.clearExternalButton()
|
||||
ShortcutKeysManager.showShortcutKeys(title, extraKeysView)
|
||||
extraKeysView?.updateButtons()
|
||||
lastTitle = title
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user