├── Xorg
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ │ ├── raw
│ │ │ │ ├── gba.raw
│ │ │ │ ├── keen.raw
│ │ │ │ ├── n64.raw
│ │ │ │ ├── psx.raw
│ │ │ │ ├── snes.raw
│ │ │ │ ├── sun.raw
│ │ │ │ ├── retro.raw
│ │ │ │ ├── dualshock.raw
│ │ │ │ ├── simpletheme.raw
│ │ │ │ └── ultimatedroid.raw
│ │ │ ├── drawable
│ │ │ │ ├── b1.png
│ │ │ │ ├── b2.png
│ │ │ │ ├── b3.png
│ │ │ │ ├── b4.png
│ │ │ │ ├── b5.png
│ │ │ │ ├── b6.png
│ │ │ │ ├── dpad.png
│ │ │ │ ├── sun_b1.png
│ │ │ │ ├── sun_b2.png
│ │ │ │ ├── sun_b3.png
│ │ │ │ ├── sun_b4.png
│ │ │ │ ├── sun_b5.png
│ │ │ │ ├── sun_b6.png
│ │ │ │ ├── calibrate.png
│ │ │ │ ├── keyboard.png
│ │ │ │ ├── rectangle.png
│ │ │ │ ├── sun_dpad.png
│ │ │ │ ├── sun_keyboard.png
│ │ │ │ ├── publisherlogo.png
│ │ │ │ ├── tv_border_left.jpg
│ │ │ │ └── tv_border_top.jpg
│ │ │ ├── values
│ │ │ │ ├── dimen.xml
│ │ │ │ └── ids.xml
│ │ │ └── xml
│ │ │ │ └── amiga.xml
│ │ └── java
│ │ │ └── io
│ │ │ └── neoterm
│ │ │ ├── NeoXorgSettings.java
│ │ │ ├── NeoAudioThread.java
│ │ │ ├── NeoRenderer.java
│ │ │ ├── NeoAccelerometerReader.java
│ │ │ ├── NeoGLView.java
│ │ │ ├── NeoTextInput.java
│ │ │ └── xorg
│ │ │ └── NeoXorgViewClient.java
│ └── test
│ │ └── java
│ │ └── io
│ │ └── neoterm
│ │ └── ExampleUnitTest.java
└── build.gradle
├── app
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── raw
│ │ │ └── bell.ogg
│ │ ├── drawable
│ │ │ ├── banner.png
│ │ │ ├── plat_logo.png
│ │ │ ├── ic_tab_icon.png
│ │ │ ├── text_select_handle_left_material.xml
│ │ │ ├── text_select_handle_right_material.xml
│ │ │ ├── ic_person.xml
│ │ │ ├── ic_description.xml
│ │ │ ├── ic_info.xml
│ │ │ ├── ic_new_session.xml
│ │ │ ├── ic_donate.xml
│ │ │ ├── ic_terminal_running.xml
│ │ │ ├── ic_github.xml
│ │ │ └── ic_neoterm.xml
│ │ ├── drawable-hdpi
│ │ │ ├── ic_done.png
│ │ │ ├── ic_search.png
│ │ │ ├── ic_apps_white_36dp.png
│ │ │ ├── ic_info_white_36dp.png
│ │ │ ├── ic_ui_white_36dp.png
│ │ │ ├── ic_guide_white_36dp.png
│ │ │ ├── ic_install_white_36.png
│ │ │ ├── ic_add_box_white_24dp.png
│ │ │ ├── ic_general_white_36dp.png
│ │ │ ├── ic_backup_restore_white_36dp.png
│ │ │ └── ic_customization_white_36dp.png
│ │ ├── mipmap-hdpi
│ │ │ ├── about_logo.png
│ │ │ └── ic_danger.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_danger.png
│ │ │ └── about_logo.png
│ │ ├── drawable-mdpi
│ │ │ ├── ic_search.png
│ │ │ └── ic_add_box_white_24dp.png
│ │ ├── drawable-xhdpi
│ │ │ ├── ic_search.png
│ │ │ └── ic_add_box_white_24dp.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── about_logo.png
│ │ │ └── ic_danger.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_danger.png
│ │ │ ├── about_logo.png
│ │ │ └── ic_launcher_neoterm_round.png
│ │ ├── drawable-xxhdpi
│ │ │ ├── ic_search.png
│ │ │ ├── ic_add_box_white_24dp.png
│ │ │ ├── text_select_handle_left_mtrl_alpha.png
│ │ │ └── text_select_handle_right_mtrl_alpha.png
│ │ ├── drawable-xxxhdpi
│ │ │ └── ic_add_box_white_24dp.png
│ │ ├── values
│ │ │ ├── shortcut_configs.xml
│ │ │ ├── colors.xml
│ │ │ ├── attrs.xml
│ │ │ ├── dimens.xml
│ │ │ ├── preference_keys.xml
│ │ │ └── styles.xml
│ │ ├── xml
│ │ │ ├── backup_config.xml
│ │ │ ├── app_shortcuts.xml
│ │ │ ├── settings_ui.xml
│ │ │ ├── settings_main.xml
│ │ │ └── setting_general.xml
│ │ ├── menu
│ │ │ ├── menu_color_editor.xml
│ │ │ ├── menu_pm.xml
│ │ │ └── menu_main.xml
│ │ └── layout
│ │ │ ├── ui_xorg.xml
│ │ │ ├── ui_term_embedded.xml
│ │ │ ├── popup_auto_complete.xml
│ │ │ ├── ui_term_dialog.xml
│ │ │ ├── layout_pm_package_list.xml
│ │ │ ├── ui_pm_single_tab.xml
│ │ │ ├── dialog_edit_text.xml
│ │ │ ├── ui_term.xml
│ │ │ ├── item_complete_candidate.xml
│ │ │ ├── item_package.xml
│ │ │ ├── ui_main.xml
│ │ │ ├── dialog_edit_two_text.xml
│ │ │ ├── ui_pm.xml
│ │ │ ├── ui_user_script_list.xml
│ │ │ ├── ui_command_shortcut.xml
│ │ │ ├── item_color.xml
│ │ │ └── ui_crash.xml
│ │ ├── assets
│ │ ├── eks_font.ttf
│ │ ├── fonts
│ │ │ ├── UbuntuMono.ttf
│ │ │ └── SourceCodePro.ttf
│ │ ├── colors
│ │ │ ├── Default.nl
│ │ │ ├── Material.nl
│ │ │ ├── SolarizedLight.nl
│ │ │ ├── SolarizedDark.nl
│ │ │ └── Dracula.nl
│ │ ├── scripts
│ │ │ ├── open-in-vim
│ │ │ └── extract-archive
│ │ └── eks
│ │ │ ├── default.nl
│ │ │ └── vim.nl
│ │ ├── jniLibs
│ │ └── arm64-v8a
│ │ │ └── libnexec.so
│ │ └── java
│ │ └── io
│ │ └── neoterm
│ │ ├── framework
│ │ ├── reflection
│ │ │ ├── NullPointer.java
│ │ │ └── ReflectionException.java
│ │ └── database
│ │ │ ├── annotation
│ │ │ ├── Ignore.java
│ │ │ ├── NotNull.java
│ │ │ ├── ID.java
│ │ │ └── Table.java
│ │ │ ├── OnDatabaseUpgradedListener.java
│ │ │ ├── DatabaseDataType.java
│ │ │ └── bean
│ │ │ └── TableInfo.java
│ │ ├── backend
│ │ ├── EmulatorDebug.java
│ │ ├── TerminalOutput.java
│ │ └── JNI.java
│ │ ├── setup
│ │ ├── SourceConnection.java
│ │ └── setup.kt
│ │ ├── component
│ │ ├── codegen
│ │ │ ├── interfaces.kt
│ │ │ ├── comp.kt
│ │ │ └── generators.kt
│ │ ├── completion
│ │ │ ├── listeners.kt
│ │ │ ├── data.kt
│ │ │ ├── comp.kt
│ │ │ └── providers.kt
│ │ ├── pm
│ │ │ ├── Source.java
│ │ │ └── data.kt
│ │ ├── font
│ │ │ └── data.kt
│ │ ├── userscript
│ │ │ └── comp.kt
│ │ ├── config
│ │ │ └── defaults.kt
│ │ ├── data.kt
│ │ ├── profile
│ │ │ ├── comp.kt
│ │ │ └── data.kt
│ │ └── extrakey
│ │ │ └── comp.kt
│ │ ├── frontend
│ │ ├── session
│ │ │ ├── terminal
│ │ │ │ ├── events.kt
│ │ │ │ ├── data.kt
│ │ │ │ └── term-basic.kt
│ │ │ └── view
│ │ │ │ ├── extrakey
│ │ │ │ └── CombinedSequence.kt
│ │ │ │ └── TerminalViewClient.java
│ │ └── completion
│ │ │ └── MaxHeightView.kt
│ │ ├── ui
│ │ ├── settings
│ │ │ ├── SettingActivity.kt
│ │ │ ├── UISettingsActivity.kt
│ │ │ └── GeneralSettingsActivity.kt
│ │ ├── term
│ │ │ └── SessionRemover.kt
│ │ ├── other
│ │ │ └── CrashActivity.kt
│ │ ├── customize
│ │ │ └── BaseCustomizeActivity.kt
│ │ └── pm
│ │ │ └── model.kt
│ │ ├── utils
│ │ ├── CrashHandler.kt
│ │ ├── StringDistance.java
│ │ ├── NeoPermission.kt
│ │ └── Terminals.kt
│ │ └── App.kt
├── CMakeLists.txt
└── build.gradle
├── NeoLang
├── .gitignore
├── example
│ ├── profile.nl
│ ├── color-scheme.nl
│ └── extra-key.nl
├── build.gradle
└── src
│ └── main
│ └── java
│ └── io
│ └── neolang
│ ├── runtime
│ ├── context.kt
│ └── types.kt
│ └── frontend
│ └── tokens.kt
├── chrome-tabs
├── .gitignore
├── gradle.properties
├── src
│ └── main
│ │ ├── res
│ │ ├── drawable-mdpi
│ │ │ ├── ic_close_tab_18dp.png
│ │ │ ├── phone_tab_border.9.png
│ │ │ ├── phone_tab_background.9.png
│ │ │ └── tab_switcher_drawable_background.png
│ │ ├── drawable-hdpi
│ │ │ ├── phone_close_tab_icon.png
│ │ │ ├── phone_tab_border.9.png
│ │ │ ├── phone_tab_background.9.png
│ │ │ └── tab_switcher_drawable_background.png
│ │ ├── drawable-xhdpi
│ │ │ ├── ic_close_tab_18dp.png
│ │ │ ├── phone_tab_border.9.png
│ │ │ ├── phone_tab_background.9.png
│ │ │ └── tab_switcher_drawable_background.png
│ │ ├── drawable-xxhdpi
│ │ │ ├── ic_close_tab_18dp.png
│ │ │ ├── phone_tab_border.9.png
│ │ │ ├── phone_tab_background.9.png
│ │ │ └── tab_switcher_drawable_background.png
│ │ ├── drawable-xxxhdpi
│ │ │ ├── ic_close_tab_18dp.png
│ │ │ ├── phone_tab_border.9.png
│ │ │ ├── phone_tab_background.9.png
│ │ │ └── tab_switcher_drawable_background.png
│ │ ├── values
│ │ │ ├── ids.xml
│ │ │ ├── colors.xml
│ │ │ ├── styles.xml
│ │ │ ├── attrs.xml
│ │ │ ├── dimens.xml
│ │ │ └── integers.xml
│ │ ├── layout
│ │ │ ├── tab_switcher_menu_item.xml
│ │ │ ├── phone_toolbar.xml
│ │ │ └── phone_tab.xml
│ │ ├── values-v21
│ │ │ └── styles.xml
│ │ └── layout-land
│ │ │ └── phone_tab.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── de
│ │ └── mrapp
│ │ └── android
│ │ └── tabswitcher
│ │ ├── Layout.java
│ │ ├── layout
│ │ ├── AbstractTabViewHolder.java
│ │ ├── phone
│ │ │ └── PhoneTabViewHolder.java
│ │ └── TabSwitcherLayout.java
│ │ ├── model
│ │ ├── State.java
│ │ └── Restorable.java
│ │ ├── TabCloseListener.java
│ │ ├── TabPreviewListener.java
│ │ └── LayoutPolicy.java
└── build.gradle
├── NeoTermBridge
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ │ └── values
│ │ │ │ └── strings.xml
│ │ ├── aidl
│ │ │ └── io
│ │ │ │ └── neoterm
│ │ │ │ └── bridge
│ │ │ │ └── ISessionConnection.aidl
│ │ └── java
│ │ │ └── io
│ │ │ └── neoterm
│ │ │ └── bridge
│ │ │ ├── SessionId.java
│ │ │ └── Bridge.java
│ └── test
│ │ └── java
│ │ └── io
│ │ └── neoterm
│ │ └── bridge
│ │ └── ExampleUnitTest.java
└── build.gradle
├── artwork
├── neoterm.psd
├── old
│ ├── neoterm.psd
│ ├── icon-512.png
│ └── icon-512-old.png
├── NeoTerm_round.psd
└── NeoTerm_round_border.psd
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── CONTRIBUTING.md
├── .github
└── workflows
│ └── gradle-check.yml
├── .gitignore
├── gradle.properties
├── README.md
└── gradlew.bat
/Xorg/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/NeoLang/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/chrome-tabs/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/NeoTermBridge/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/Xorg/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/NeoTermBridge/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/artwork/neoterm.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/artwork/neoterm.psd
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':chrome-tabs', ':NeoLang', ':Xorg', ':NeoTermBridge'
2 |
--------------------------------------------------------------------------------
/artwork/old/neoterm.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/artwork/old/neoterm.psd
--------------------------------------------------------------------------------
/NeoLang/example/profile.nl:
--------------------------------------------------------------------------------
1 | profile-shell: {
2 | name: "Simple Profile"
3 | bell: true
4 | }
5 |
--------------------------------------------------------------------------------
/artwork/NeoTerm_round.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/artwork/NeoTerm_round.psd
--------------------------------------------------------------------------------
/artwork/old/icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/artwork/old/icon-512.png
--------------------------------------------------------------------------------
/artwork/old/icon-512-old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/artwork/old/icon-512-old.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/gba.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/gba.raw
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/keen.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/keen.raw
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/n64.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/n64.raw
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/psx.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/psx.raw
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/snes.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/snes.raw
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/sun.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/sun.raw
--------------------------------------------------------------------------------
/app/src/main/res/raw/bell.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/raw/bell.ogg
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/b1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/b1.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/b2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/b2.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/b3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/b3.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/b4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/b4.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/b5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/b5.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/b6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/b6.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/retro.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/retro.raw
--------------------------------------------------------------------------------
/app/src/main/assets/eks_font.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/assets/eks_font.ttf
--------------------------------------------------------------------------------
/artwork/NeoTerm_round_border.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/artwork/NeoTerm_round_border.psd
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/dpad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/dpad.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/dualshock.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/dualshock.raw
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_b1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_b1.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_b2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_b2.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_b3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_b3.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_b4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_b4.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_b5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_b5.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_b6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_b6.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/simpletheme.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/simpletheme.raw
--------------------------------------------------------------------------------
/app/src/main/res/drawable/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable/banner.png
--------------------------------------------------------------------------------
/chrome-tabs/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_NAME=ChromeLikeTabSwitcher
2 | POM_ARTIFACT_ID=chrome-like-tab-switcher
3 | POM_PACKAGING=aar
--------------------------------------------------------------------------------
/NeoTermBridge/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | NeoTermBridge
3 |
4 |
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/calibrate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/calibrate.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/keyboard.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/rectangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/rectangle.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_dpad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_dpad.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/raw/ultimatedroid.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/raw/ultimatedroid.raw
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/UbuntuMono.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/assets/fonts/UbuntuMono.ttf
--------------------------------------------------------------------------------
/app/src/main/res/drawable/plat_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable/plat_logo.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/sun_keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/sun_keyboard.png
--------------------------------------------------------------------------------
/app/src/main/assets/fonts/SourceCodePro.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/assets/fonts/SourceCodePro.ttf
--------------------------------------------------------------------------------
/app/src/main/jniLibs/arm64-v8a/libnexec.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/jniLibs/arm64-v8a/libnexec.so
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_done.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_tab_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable/ic_tab_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-hdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_danger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-hdpi/ic_danger.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_danger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xhdpi/ic_danger.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/publisherlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/publisherlogo.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/tv_border_left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/tv_border_left.jpg
--------------------------------------------------------------------------------
/Xorg/src/main/res/drawable/tv_border_top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/Xorg/src/main/res/drawable/tv_border_top.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-mdpi/ic_search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xhdpi/ic_search.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xhdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xxhdpi/about_logo.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_danger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xxhdpi/ic_danger.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_danger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_danger.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xxhdpi/ic_search.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/about_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xxxhdpi/about_logo.png
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | # How to
4 |
5 | NeoTerm is a free software, so any contributions and any contribution types are welcomed!
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_apps_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_apps_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_info_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_info_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_ui_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_ui_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_guide_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_guide_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_install_white_36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_install_white_36.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_add_box_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_add_box_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_general_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_general_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_add_box_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-mdpi/ic_add_box_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_add_box_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xhdpi/ic_add_box_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_add_box_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xxhdpi/ic_add_box_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_add_box_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xxxhdpi/ic_add_box_white_24dp.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-mdpi/ic_close_tab_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-mdpi/ic_close_tab_18dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_backup_restore_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_backup_restore_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_customization_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-hdpi/ic_customization_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_neoterm_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_neoterm_round.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-hdpi/phone_close_tab_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-hdpi/phone_close_tab_icon.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-hdpi/phone_tab_border.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-hdpi/phone_tab_border.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-mdpi/phone_tab_border.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-mdpi/phone_tab_border.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xhdpi/ic_close_tab_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xhdpi/ic_close_tab_18dp.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xhdpi/phone_tab_border.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xhdpi/phone_tab_border.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxhdpi/ic_close_tab_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxhdpi/ic_close_tab_18dp.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxhdpi/phone_tab_border.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxhdpi/phone_tab_border.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxxhdpi/ic_close_tab_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxxhdpi/ic_close_tab_18dp.png
--------------------------------------------------------------------------------
/Xorg/src/main/res/values/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 | 0dp
3 | 0dp
4 |
5 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-hdpi/phone_tab_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-hdpi/phone_tab_background.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-mdpi/phone_tab_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-mdpi/phone_tab_background.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxxhdpi/phone_tab_border.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxxhdpi/phone_tab_border.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xhdpi/phone_tab_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xhdpi/phone_tab_background.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxhdpi/phone_tab_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxhdpi/phone_tab_background.9.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxxhdpi/phone_tab_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxxhdpi/phone_tab_background.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/app/src/main/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-hdpi/tab_switcher_drawable_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-hdpi/tab_switcher_drawable_background.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-mdpi/tab_switcher_drawable_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-mdpi/tab_switcher_drawable_background.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xhdpi/tab_switcher_drawable_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xhdpi/tab_switcher_drawable_background.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxhdpi/tab_switcher_drawable_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxhdpi/tab_switcher_drawable_background.png
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/drawable-xxxhdpi/tab_switcher_drawable_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NeoTerrm/NeoTerm/HEAD/chrome-tabs/src/main/res/drawable-xxxhdpi/tab_switcher_drawable_background.png
--------------------------------------------------------------------------------
/app/src/main/res/values/shortcut_configs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | id_create_new_session
4 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/reflection/NullPointer.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.reflection;
2 |
3 | /**
4 | * class representing null pointer.
5 | *
6 | * @author kiva
7 | */
8 | public class NullPointer {
9 | }
--------------------------------------------------------------------------------
/NeoTermBridge/src/main/aidl/io/neoterm/bridge/ISessionConnection.aidl:
--------------------------------------------------------------------------------
1 | // ISessionConnection.aidl
2 | package io.neoterm.bridge;
3 |
4 | // Declare any non-default types here with import statements
5 |
6 | interface ISessionConnection {
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/assets/colors/Default.nl:
--------------------------------------------------------------------------------
1 | color-scheme: {
2 | name: "Default"
3 | version: 1.1
4 |
5 | colors: {
6 | foreground: #ffffff
7 | cursor: #a9aaa9
8 | background: #14181c
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Xorg/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/NeoLang/example/color-scheme.nl:
--------------------------------------------------------------------------------
1 | color-scheme: {
2 | name: "NeoTerm Default Color Scheme"
3 | version: 1.1
4 |
5 | colors: {
6 | background: #777721
7 | foreground: #111233
8 | color1: #color1
9 | color2: #color2
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/text_select_handle_left_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/text_select_handle_right_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 20 22:03:06 EEST 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
7 |
--------------------------------------------------------------------------------
/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | add_library(neoterm
4 | SHARED
5 | src/main/cpp/neoterm.cpp)
6 |
7 | target_link_libraries(neoterm)
8 |
9 | #add_library(nexec
10 | # SHARED
11 | # src/main/cpp/exec.c)
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/assets/scripts/open-in-vim:
--------------------------------------------------------------------------------
1 | #!/data/data/io.neoterm/files/usr/bin/bash
2 |
3 | set -e
4 |
5 | VIM="$(which vim)"
6 |
7 | if [[ "$VIM"x == ""x ]]; then
8 | echo "Vim is not installed, now installing..."
9 | apt update && apt install -y vim
10 | fi
11 |
12 | $VIM "$@"
13 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/reflection/ReflectionException.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.reflection;
2 |
3 | /**
4 | * @author kiva
5 | */
6 | public class ReflectionException extends RuntimeException {
7 | ReflectionException(Throwable cause) {
8 | super(cause);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/NeoXorgSettings.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | import io.neoterm.xorg.NeoXorgViewClient;
4 |
5 | /**
6 | * @author kiva
7 | */
8 |
9 | public class NeoXorgSettings {
10 | public static void init(NeoXorgViewClient client) {
11 | Settings.Load(client);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/backend/EmulatorDebug.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.backend;
2 |
3 | import android.util.Log;
4 |
5 | public final class EmulatorDebug {
6 |
7 | /**
8 | * The tag to use with {@link Log}.
9 | */
10 | public static final String LOG_TAG = "NeoTerm-Emulator";
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/NeoAudioThread.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | import io.neoterm.xorg.NeoXorgViewClient;
4 |
5 | /**
6 | * @author kiva
7 | */
8 |
9 | public class NeoAudioThread extends AudioThread {
10 | public NeoAudioThread(NeoXorgViewClient client) {
11 | super(client);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/setup/SourceConnection.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.setup;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * @author kiva
8 | */
9 | public interface SourceConnection {
10 | InputStream getInputStream() throws IOException;
11 | int getSize();
12 | void close();
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_color_editor.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/NeoLang/example/extra-key.nl:
--------------------------------------------------------------------------------
1 | extra-key: {
2 | version: 10
3 | with-default: true
4 |
5 | program: [ "vim", "vi" ]
6 |
7 | key: [
8 | {
9 | display: "Ctrl"
10 | code: ""
11 | with-enter: true
12 | },
13 | {
14 | display: "Esc"
15 | code: ""
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/codegen/interfaces.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.codegen
2 |
3 | abstract class CodeGenerator(parameter: CodeGenParameter) {
4 | abstract fun getGeneratorName(): String
5 | abstract fun generateCode(codeGenObject: CodeGenObject): String
6 | }
7 |
8 | interface CodeGenObject {
9 | fun getCodeGenerator(parameter: CodeGenParameter): CodeGenerator
10 | }
11 |
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/NeoRenderer.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | /**
4 | * @author kiva
5 | */
6 |
7 | public class NeoRenderer {
8 | public static void callNativeTextInputFinished() {
9 | DemoRenderer.nativeTextInputFinished();
10 | }
11 |
12 | public static void callNativeTextInput(int ascii, int unicode) {
13 | DemoRenderer.nativeTextInput(ascii, unicode);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.github/workflows/gradle-check.yml:
--------------------------------------------------------------------------------
1 | name: Gralde check
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Clone repository
16 | uses: actions/checkout@v2
17 | - name: Build
18 | run: |
19 | ./gradlew :app:assembleDebug
20 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/frontend/session/terminal/events.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.frontend.session.terminal
2 |
3 | import io.neoterm.ui.term.TermTab
4 |
5 | class CreateNewSessionEvent
6 | class SwitchIndexedSessionEvent(val index: Int)
7 | class SwitchSessionEvent(val toNext: Boolean)
8 | class TabCloseEvent(val termTab: TermTab)
9 | class TitleChangedEvent(val title: String)
10 | class ToggleFullScreenEvent
11 | class ToggleImeEvent
12 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/annotation/Ignore.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author kiva
10 | */
11 | @Retention(RetentionPolicy.RUNTIME)
12 | @Target({ElementType.FIELD})
13 | public @interface Ignore {
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/annotation/NotNull.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author kiva
10 | */
11 | @Target(ElementType.FIELD)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface NotNull {
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_person.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/OnDatabaseUpgradedListener.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database;
2 |
3 | import android.database.sqlite.SQLiteDatabase;
4 |
5 | /**
6 | * @author kiva
7 | */
8 | public interface OnDatabaseUpgradedListener {
9 | /**
10 | * @param db 数据库
11 | * @param oldVersion 旧版本
12 | * @param newVersion 新版本
13 | */
14 | void onDatabaseUpgraded(SQLiteDatabase db, int oldVersion, int newVersion);
15 | }
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/NeoAccelerometerReader.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * @author kiva
7 | */
8 |
9 | public class NeoAccelerometerReader extends AccelerometerReader {
10 | public NeoAccelerometerReader(Context context) {
11 | super(context);
12 | }
13 |
14 | public static void setGyroInvertedOrientation(boolean invertedOrientation) {
15 | gyro.invertedOrientation = invertedOrientation;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_description.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_xorg.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Xorg/src/test/java/io/neoterm/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/NeoTermBridge/src/test/java/io/neoterm/bridge/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.bridge;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/completion/listeners.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.completion
2 |
3 | interface MarkScoreListener {
4 | fun onMarkScore(score: Int)
5 | }
6 |
7 | interface OnAutoCompleteListener {
8 | fun onCompletionRequired(newText: String?)
9 | fun onKeyCode(keyCode: Int, keyMod: Int)
10 | fun onCleanUp()
11 | fun onFinishCompletion(): Boolean
12 | }
13 |
14 | interface OnCandidateSelectedListener {
15 | fun onCandidateSelected(candidate: CompletionCandidate)
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/assets/eks/default.nl:
--------------------------------------------------------------------------------
1 | extra-key: {
2 | version: 20
3 | program: [ default ]
4 |
5 | key: [
6 | {
7 | code: "-"
8 | },
9 | {
10 | code: "/"
11 | },
12 | {
13 | code: "\"
14 | },
15 | {
16 | code: "|"
17 | },
18 | {
19 | code: "$"
20 | },
21 | {
22 | code: "<"
23 | },
24 | {
25 | code: ">"
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/completion/data.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.completion
2 |
3 | class CompletionCandidate(val completeString: String) {
4 | var displayName: String = completeString
5 | var description: String? = null
6 | }
7 |
8 | class CompletionResult(val candidates: List, var scoreMarker: MarkScoreListener) {
9 | fun markScore(score: Int) {
10 | scoreMarker.onMarkScore(score)
11 | }
12 |
13 | fun hasResult(): Boolean {
14 | return candidates.isNotEmpty()
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/NeoGLView.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | import io.neoterm.xorg.NeoXorgViewClient;
4 |
5 | /**
6 | * @author kiva
7 | */
8 |
9 | public class NeoGLView extends DemoGLSurfaceView {
10 | public NeoGLView(NeoXorgViewClient client) {
11 | super(client);
12 | }
13 |
14 | public void callNativeScreenKeyboardShown(int shown) {
15 | nativeScreenKeyboardShown(shown);
16 | }
17 |
18 | public void callNativeScreenVisibleRect(int x, int y, int w, int h) {
19 | nativeScreenVisibleRect(x, y, w, h);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/codegen/comp.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.codegen
2 |
3 | import io.neoterm.component.NeoComponent
4 |
5 |
6 | class CodeGenComponent : NeoComponent {
7 | override fun onServiceInit() {
8 | }
9 |
10 | override fun onServiceDestroy() {
11 | }
12 |
13 | override fun onServiceObtained() {
14 | }
15 |
16 | fun newGenerator(codeObject: CodeGenObject): CodeGenerator {
17 | val parameter = CodeGenParameter()
18 | return codeObject.getCodeGenerator(parameter)
19 | }
20 | }
21 |
22 | class CodeGenParameter
23 |
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/NeoTextInput.java:
--------------------------------------------------------------------------------
1 | package io.neoterm;
2 |
3 | import io.neoterm.xorg.R;
4 |
5 | /**
6 | * @author kiva
7 | */
8 |
9 | public class NeoTextInput {
10 | public static int TextInputKeyboardList[][] =
11 | {
12 | {0, R.xml.qwerty, R.xml.c64, R.xml.amiga, R.xml.atari800},
13 | {0, R.xml.qwerty_shift, R.xml.c64, R.xml.amiga_shift, R.xml.atari800},
14 | {0, R.xml.qwerty_alt, R.xml.c64, R.xml.amiga_alt, R.xml.atari800},
15 | {0, R.xml.qwerty_alt_shift, R.xml.c64, R.xml.amiga_alt_shift, R.xml.atari800}
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/annotation/ID.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author kiva
10 | */
11 | @Target(ElementType.FIELD)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface ID {
14 | /**
15 | * 只对Integer类型的ID字段有效
16 | *
17 | * @return 是否为自增长
18 | */
19 | boolean autoIncrement() default false;
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #607D8B
4 | #455A64
5 | #42a5f5
6 | #ff14181c
7 | #fefefe
8 | #ced7db
9 |
10 | #7f000000
11 | #efefef
12 | #363636
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/app_shortcuts.xml:
--------------------------------------------------------------------------------
1 |
3 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/annotation/Table.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author kiva
10 | */
11 | @Target(ElementType.TYPE)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Table {
14 | /**
15 | * @return 表名
16 | */
17 | String name() default "";
18 |
19 | /**
20 | * @return 在表创建后需要回调的方法
21 | */
22 | String afterTableCreate() default "";
23 | }
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 | .cxx/
15 |
16 | # Local configuration file (sdk path, etc)
17 | local.properties
18 |
19 | # Eclipse project files
20 | .classpath
21 | .project
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Intellij project files
27 | *.iml
28 | *.ipr
29 | *.iws
30 | .idea/
31 | .gradle
32 | /local.properties
33 | /.idea/workspace.xml
34 | /.idea/libraries
35 | .DS_Store
36 | /build
37 | /captures
38 | .externalNativeBuild
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/assets/eks/vim.nl:
--------------------------------------------------------------------------------
1 | extra-key: {
2 | version: 20
3 | with-default: true
4 | program: [ vim, vi, nvim ]
5 |
6 | key: [
7 | {
8 | code: " dd"
9 | display: "dd"
10 | with-enter: true
11 | },
12 | {
13 | code: " :x"
14 | display: ":x"
15 | with-enter: true
16 | },
17 | {
18 | code: " :w"
19 | display: ":w"
20 | with-enter: true
21 | },
22 | {
23 | code: " :q"
24 | display: ":q"
25 | with-enter: true
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/pm/Source.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.pm;
2 |
3 | import io.neoterm.framework.database.annotation.ID;
4 | import io.neoterm.framework.database.annotation.Table;
5 |
6 | /**
7 | * @author kiva
8 | */
9 | @Table
10 | public class Source {
11 | @ID(autoIncrement = true)
12 | private int id;
13 |
14 | public String url;
15 |
16 | public String repo;
17 |
18 | public boolean enabled;
19 |
20 | public Source() {
21 | // for Database
22 | }
23 |
24 | public Source(String url, String repo, boolean enabled) {
25 | this.url = url;
26 | this.repo = repo;
27 | this.enabled = enabled;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/DatabaseDataType.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database;
2 |
3 | /**
4 | * @author kiva
5 | */
6 | public enum DatabaseDataType {
7 | /**
8 | * int类型
9 | */
10 | INTEGER,
11 | /**
12 | * String类型
13 | */
14 | TEXT,
15 | /**
16 | * float类型
17 | */
18 | FLOAT,
19 | /**
20 | * long类型
21 | */
22 | BIGINT,
23 | /**
24 | * double类型
25 | */
26 | DOUBLE;
27 |
28 | boolean nullable = true;
29 |
30 | /**
31 | * 数据类型是否允许为null
32 | */
33 | public DatabaseDataType nullable(boolean nullable) {
34 | this.nullable = nullable;
35 | return this;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_new_session.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_term_embedded.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/NeoLang/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'java-library'
2 | apply plugin: 'kotlin'
3 |
4 | dependencies {
5 | implementation fileTree(dir: 'libs', include: ['*.jar'])
6 | compile rootProject.ext.deps["kotlin-stdlib"]
7 | }
8 |
9 | buildscript {
10 | repositories {
11 | mavenCentral()
12 | }
13 | dependencies {
14 | classpath rootProject.ext.deps["kotlin-gradle-plugin"]
15 | }
16 | }
17 | repositories {
18 | mavenCentral()
19 | }
20 | compileKotlin {
21 | kotlinOptions {
22 | jvmTarget = "1.8"
23 | }
24 | }
25 | compileTestKotlin {
26 | kotlinOptions {
27 | jvmTarget = "1.8"
28 | }
29 | }
30 | dependencies {
31 | testImplementation rootProject.ext.deps["junit"]
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/assets/colors/Material.nl:
--------------------------------------------------------------------------------
1 | color-scheme: {
2 | name: "Material"
3 | version: 1.1
4 |
5 | colors: {
6 | background: #263238
7 | foreground: #eceff1
8 |
9 | color0: #263238
10 | color8: #37474f
11 |
12 | color1: #ff9800
13 | color9: #ffa74d
14 |
15 | color2: #8bc34a
16 | color10: #9ccc65
17 |
18 | color3: #ffc107
19 | color11: #ffa000
20 |
21 | color4: #03a9f4
22 | color12: #81d4fa
23 |
24 | color5: #e91e63
25 | color13: #ad1457
26 |
27 | color6: #009688
28 | color14: #26a69a
29 |
30 | color7: #cfd8dc
31 | color15: #eceff1
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/assets/colors/SolarizedLight.nl:
--------------------------------------------------------------------------------
1 | color-scheme: {
2 | name: "Solarized Light"
3 | version: 1.1
4 |
5 | colors: {
6 | background: #fdf6e3
7 | foreground: #657b83
8 | cursor: #586e75
9 |
10 | color0: #073642
11 | color1: #dc322f
12 | color2: #859900
13 | color3: #b58900
14 | color4: #268bd2
15 | color5: #d33682
16 | color6: #2aa198
17 | color7: #eee8d5
18 | color8: #002b36
19 | color9: #cb4b16
20 | color10: #586e75
21 | color11: #657b83
22 | color12: #839496
23 | color13: #6c71c4
24 | color14: #93a1a1
25 | color15: #fdf6e3
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_donate.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/assets/colors/SolarizedDark.nl:
--------------------------------------------------------------------------------
1 | color-scheme: {
2 | name: "Solarized Dark"
3 | version: 1.1
4 |
5 | colors: {
6 | background: #002b36
7 | foreground: #839496
8 | cursor: #93a1a1
9 |
10 | color0: #073642
11 | color1: #dc322f
12 | color2: #859900
13 | color3: #b58900
14 | color4: #268bd2
15 | color5: #d33682
16 | color6: #2aa198
17 | color7: #eee8d5
18 | color9: #cb4b16
19 | color8: #002b36
20 | color10: #586e75
21 | color11: #657b83
22 | color12: #839496
23 | color13: #6c71c4
24 | color14: #93a1a1
25 | color15: #fdf6e3
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/assets/colors/Dracula.nl:
--------------------------------------------------------------------------------
1 | color-scheme: {
2 | name: "Dracula"
3 | version: 1.1
4 |
5 | colors: {
6 | foreground: #f8f8f2
7 | cursor: #f8f8f2
8 | background: #282a36
9 |
10 | color0: #000000
11 | color8: #4d4d4d
12 |
13 | color1: #ff5555
14 | color9: #ff6e67
15 |
16 | color2: #50fa7b
17 | color10: #5af78e
18 |
19 | color3: #f1fa8c
20 | color11: #f4f99d
21 |
22 | color4: #caa9fa
23 | color12: #caa9fa
24 |
25 | color5: #ff79c6
26 | color13: #ff92d0
27 |
28 | color6: #8be9fd
29 | color14: #9aedfe
30 |
31 | color7: #bfbfbf
32 | color15: #e6e6e6
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/popup_auto_complete.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_term_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/chrome-tabs/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION
5 |
6 | defaultConfig {
7 | minSdkVersion rootProject.ext.android.MIN_SDK_VERSION
8 | targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION
9 | versionCode 1
10 | versionName "1.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled true
15 | }
16 | }
17 | }
18 |
19 | dependencies {
20 | api 'com.github.michael-rapp:android-util:1.15.0'
21 | implementation rootProject.ext.deps["annotations"]
22 | testImplementation rootProject.ext.deps["junit"]
23 |
24 | implementation 'androidx.appcompat:appcompat:1.2.0'
25 | implementation 'androidx.appcompat:appcompat-resources:1.2.0'
26 | }
27 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/frontend/session/view/extrakey/CombinedSequence.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.frontend.session.view.extrakey
2 |
3 | /**
4 | *
5 | * C
6 | * :q
7 | *
8 | * @author kiva
9 | */
10 | class CombinedSequence private constructor() {
11 | val keys = mutableListOf()
12 |
13 | companion object {
14 | fun solveString(keyString: String): CombinedSequence {
15 | val seq = CombinedSequence()
16 | keyString.split(' ').forEach {
17 | val key = if (it.startsWith('<') && it.endsWith('>')) {
18 | // is a sequence
19 | it.substring(1, it.length - 1)
20 | } else {
21 | // is a normal string
22 | it
23 | }
24 | seq.keys.add(key)
25 | }
26 | return seq
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | android.enableJetifier=true
10 | android.useAndroidX=true
11 | org.gradle.jvmargs=-Xmx1536m
12 | # When configured, Gradle will run in incubating parallel mode.
13 | # This option should only be used with decoupled projects. More details, visit
14 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
15 | # org.gradle.parallel=true
16 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/settings/SettingActivity.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.settings
2 |
3 | import android.os.Bundle
4 | import android.view.MenuItem
5 | import io.neoterm.R
6 |
7 | /**
8 | * @author Lody
9 | */
10 | class SettingActivity : BasePreferenceActivity() {
11 |
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | supportActionBar?.title = getString(R.string.settings)
15 | supportActionBar?.setDisplayHomeAsUpEnabled(true)
16 | addPreferencesFromResource(R.xml.settings_main)
17 | }
18 |
19 | override fun onBuildHeaders(target: MutableList?) {
20 | }
21 |
22 | override fun onOptionsItemSelected(item: MenuItem?): Boolean {
23 | when (item?.itemId) {
24 | android.R.id.home ->
25 | finish()
26 | }
27 | return super.onOptionsItemSelected(item)
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/settings/UISettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.settings
2 |
3 | import android.os.Bundle
4 | import android.view.MenuItem
5 | import io.neoterm.R
6 |
7 | /**
8 | * @author kiva
9 | */
10 | class UISettingsActivity : BasePreferenceActivity() {
11 |
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | supportActionBar?.title = getString(R.string.ui_settings)
15 | supportActionBar?.setDisplayHomeAsUpEnabled(true)
16 | addPreferencesFromResource(R.xml.settings_ui)
17 | }
18 |
19 | override fun onBuildHeaders(target: MutableList?) {
20 | }
21 |
22 | override fun onOptionsItemSelected(item: MenuItem?): Boolean {
23 | when (item?.itemId) {
24 | android.R.id.home ->
25 | finish()
26 | }
27 | return super.onOptionsItemSelected(item)
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/utils/CrashHandler.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.utils
2 |
3 | import android.content.Intent
4 | import io.neoterm.App
5 | import io.neoterm.ui.other.CrashActivity
6 |
7 | /**
8 | * @author kiva
9 | */
10 | object CrashHandler : Thread.UncaughtExceptionHandler {
11 | private lateinit var defaultHandler: Thread.UncaughtExceptionHandler
12 |
13 | fun init() {
14 | defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
15 | Thread.setDefaultUncaughtExceptionHandler(this)
16 | }
17 |
18 | override fun uncaughtException(t: Thread?, e: Throwable?) {
19 | e?.printStackTrace()
20 |
21 | val intent = Intent(App.get(), CrashActivity::class.java)
22 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
23 | intent.putExtra("exception", e)
24 | App.get().startActivity(intent)
25 | defaultHandler.uncaughtException(t, e)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_pm_package_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_pm_single_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_edit_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/framework/database/bean/TableInfo.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.framework.database.bean;
2 |
3 |
4 | import io.neoterm.framework.database.DatabaseDataType;
5 |
6 | import java.lang.reflect.Field;
7 | import java.lang.reflect.Method;
8 | import java.util.Map;
9 |
10 | /**
11 | * @author kiva
12 | */
13 | public class TableInfo {
14 |
15 | /**
16 | * 是否包含ID
17 | */
18 | public boolean containID;
19 | /**
20 | * 主键字段
21 | */
22 | public Field primaryField;
23 |
24 | /**
25 | * 表名
26 | */
27 | public String tableName;
28 |
29 | /**
30 | * 字段表
31 | */
32 | public Map fieldToDataTypeMap;
33 |
34 | /**
35 | * 创建table的语句
36 | */
37 | public String createTableStatement;
38 |
39 | /**
40 | * 是否已经创建
41 | */
42 | public boolean isCreate = false;
43 |
44 | public Method afterTableCreateMethod;
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 | #ff14181c
19 | #fff2f2f2
20 | #a8000000
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_terminal_running.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/layout/tab_switcher_menu_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/NeoTermBridge/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | def libraryVersionCode = 1
4 | def libraryVersionName = "1.0"
5 |
6 | android {
7 | compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION
8 |
9 | defaultConfig {
10 | minSdkVersion rootProject.ext.android.MIN_SDK_VERSION
11 | targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION
12 | versionCode libraryVersionCode
13 | versionName libraryVersionName
14 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | }
21 | }
22 | }
23 |
24 | dependencies {
25 | implementation fileTree(dir: 'libs', include: ['*.jar'])
26 | implementation 'androidx.appcompat:appcompat:1.2.0'
27 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
28 | exclude group: 'com.android.support', module: 'support-annotations'
29 | })
30 | testImplementation rootProject.ext.deps["junit"]
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NeoTerm
2 | =======
3 | [](https://travis-ci.org/NeoTerm/NeoTerm)
4 | 
5 | 
6 |
7 | A modern-designed android terminal emulator for the 21st century.
8 |
9 | ### Our Pledge
10 |
11 | Originally, NeoTerm was designed as the front end of Termux to provide some functions that Termux didn't have, but we
12 | found it very convenient. In continuous development, we discovered our goal: to be the best terminal for Android.
13 |
14 | ### Help & Documentation
15 |
16 | View on [GitBook](https://neoterm.gitbooks.io/neoterm-wiki/content)
17 |
18 | View on [GitHub](https://github.com/NeoTerm/NeoTerm-Wiki)
19 |
20 | ### Download
21 |
22 | [GitHub Release Page](https://github.com/NeoTerm/NeoTerm/releases)
23 |
24 | [lzzySoft's F-Droid repo](https://apt.izzysoft.de/fdroid/index/apk/io.neoterm) (thanks to @lzzySoft)
25 |
--------------------------------------------------------------------------------
/Xorg/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION
5 |
6 | defaultConfig {
7 | minSdkVersion rootProject.ext.android.MIN_SDK_VERSION
8 | targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
12 | }
13 |
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | }
18 | }
19 |
20 | sourceSets {
21 | main {
22 | jniLibs.srcDirs = ['src/main/jniLibs']
23 | }
24 | }
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 |
30 | implementation rootProject.ext.deps["appcompat-v7"]
31 | testImplementation rootProject.ext.deps["junit"]
32 |
33 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
34 | exclude group: 'com.android.support', module: 'support-annotations'
35 | })
36 | }
37 |
--------------------------------------------------------------------------------
/Xorg/src/main/java/io/neoterm/xorg/NeoXorgViewClient.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.xorg;
2 |
3 | import android.content.Context;
4 | import android.view.Window;
5 | import android.view.WindowManager;
6 | import io.neoterm.NeoGLView;
7 |
8 | /**
9 | * @author kiva
10 | */
11 |
12 | public interface NeoXorgViewClient {
13 | Context getContext();
14 |
15 | boolean isKeyboardWithoutTextInputShown();
16 |
17 | void showScreenKeyboardWithoutTextInputField(int flags);
18 |
19 | void setScreenKeyboardHintMessage(String hideMessage);
20 |
21 | boolean isScreenKeyboardShown();
22 |
23 | void showScreenKeyboard(String message);
24 |
25 | void hideScreenKeyboard();
26 |
27 | void runOnUiThread(Runnable runnable);
28 |
29 | void updateScreenOrientation();
30 |
31 | void initScreenOrientation();
32 |
33 | boolean isRunningOnOUYA();
34 |
35 | NeoGLView getGLView();
36 |
37 | Window getWindow();
38 |
39 | WindowManager getWindowManager();
40 |
41 | void setSystemMousePointerVisible(int visible);
42 |
43 | boolean isPaused();
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/pm/data.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.pm
2 |
3 | enum class Architecture {
4 | ALL, ARM, AARCH64, X86, X86_64;
5 |
6 | companion object {
7 | fun parse(arch: String): Architecture {
8 | return when (arch) {
9 | "arm" -> ARM
10 | "aarch64" -> AARCH64
11 | "x86" -> X86
12 | "x86_64" -> X86_64
13 | else -> ALL
14 | }
15 | }
16 | }
17 | }
18 |
19 | class NeoPackageInfo {
20 | var packageName: String? = null
21 | var isEssential: Boolean = false
22 | var version: String? = null
23 | var architecture: Architecture = Architecture.ALL
24 | var maintainer: String? = null
25 | var installedSizeInBytes: Long = 0L
26 | var fileName: String? = null
27 | var dependenciesString: String? = null
28 | var dependencies: Array? = null
29 | var sizeInBytes: Long = 0L
30 | var md5: String? = null
31 | var sha1: String? = null
32 | var sha256: String? = null
33 | var homePage: String? = null
34 | var description: String? = null
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_pm.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/font/data.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.font
2 |
3 | import android.graphics.Typeface
4 | import io.neoterm.frontend.session.view.TerminalView
5 | import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
6 | import java.io.File
7 |
8 | class NeoFont {
9 | private var fontFile: File? = null
10 | private var typeface: Typeface? = null
11 |
12 | constructor(fontFile: File) {
13 | this.fontFile = fontFile
14 | }
15 |
16 | constructor(typeface: Typeface) {
17 | this.typeface = typeface
18 | }
19 |
20 | internal fun applyFont(terminalView: TerminalView?, extraKeysView: ExtraKeysView?) {
21 | val typeface = getTypeFace()
22 | terminalView?.setTypeface(typeface)
23 | extraKeysView?.setTypeface(typeface)
24 | }
25 |
26 | private fun getTypeFace(): Typeface? {
27 | if (typeface == null && fontFile == null) {
28 | return null
29 | }
30 |
31 | if (typeface == null) {
32 | typeface = Typeface.createFromFile(fontFile)
33 | }
34 | return typeface
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_github.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_term.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
15 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 180dp
3 | 16dp
4 | 16dp
5 | 8dp
6 | 32dp
7 | 32dp
8 | 32dp
9 | 32dp
10 | 72dp
11 | 36dp
12 | 256dp
13 | 48dp
14 | 36dp
15 | 36dp
16 | 24dp
17 | 4dp
18 | 48dp
19 | 48dp
20 |
21 | 16dp
22 | 4dp
23 |
24 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/utils/StringDistance.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.utils;
2 |
3 | /**
4 | * @author kiva
5 | */
6 |
7 | public class StringDistance {
8 | public static int distance(String source, String target) {
9 | char[] sources = source.toCharArray();
10 | char[] targets = target.toCharArray();
11 | int sourceLen = sources.length;
12 | int targetLen = targets.length;
13 |
14 | int[][] d = new int[sourceLen + 1][targetLen + 1];
15 | for (int i = 0; i <= sourceLen; i++) {
16 | d[i][0] = i;
17 | }
18 | for (int i = 0; i <= targetLen; i++) {
19 | d[0][i] = i;
20 | }
21 |
22 | for (int i = 1; i <= sourceLen; i++) {
23 | for (int j = 1; j <= targetLen; j++) {
24 | if (sources[i - 1] == targets[j - 1]) {
25 | d[i][j] = d[i - 1][j - 1];
26 | } else {
27 | int insert = d[i][j - 1] + 1;
28 | int delete = d[i - 1][j] + 1;
29 | int replace = d[i - 1][j - 1] + 1;
30 | d[i][j] = Math.min(Math.min(insert, delete), Math.min(delete, replace));
31 | }
32 | }
33 | }
34 | return d[sourceLen][targetLen];
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
25 |
26 |
--------------------------------------------------------------------------------
/NeoLang/src/main/java/io/neolang/runtime/context.kt:
--------------------------------------------------------------------------------
1 | package io.neolang.runtime
2 |
3 | /**
4 | * @author kiva
5 | */
6 | class NeoLangContext(val contextName: String) {
7 | companion object {
8 | private val emptyContext = NeoLangContext("")
9 | }
10 |
11 | private val attributes = mutableMapOf()
12 | val children = mutableListOf()
13 | var parent: NeoLangContext? = null
14 |
15 | fun defineAttribute(attributeName: String, attributeValue: NeoLangValue): NeoLangContext {
16 | attributes[attributeName] = attributeValue
17 | return this
18 | }
19 |
20 | fun getAttribute(attributeName: String): NeoLangValue {
21 | return attributes[attributeName] ?: parent?.getAttribute(attributeName) ?: NeoLangValue.UNDEFINED
22 | }
23 |
24 | fun getChild(contextName: String): NeoLangContext {
25 | var found: NeoLangContext? = null
26 | children.forEach {
27 | if (it.contextName == contextName) {
28 | found = it
29 | }
30 | }
31 | return found ?: emptyContext
32 | }
33 |
34 | fun getAttributes(): Map {
35 | return attributes
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.term
2 |
3 | import io.neoterm.backend.TerminalSession
4 | import io.neoterm.component.session.XSession
5 | import io.neoterm.services.NeoTermService
6 |
7 | /**
8 | * @author kiva
9 | */
10 | object SessionRemover {
11 | fun removeSession(termService: NeoTermService?, tab: TermTab) {
12 | tab.termData.termSession?.finishIfRunning()
13 | removeFinishedSession(termService, tab.termData.termSession)
14 | tab.cleanup()
15 | }
16 |
17 | fun removeXSession(termService: NeoTermService?, tab: XSessionTab?) {
18 | removeFinishedSession(termService, tab?.session)
19 | }
20 |
21 | private fun removeFinishedSession(termService: NeoTermService?, finishedSession: TerminalSession?) {
22 | if (termService == null || finishedSession == null) {
23 | return
24 | }
25 |
26 | termService.removeTermSession(finishedSession)
27 | }
28 |
29 | private fun removeFinishedSession(termService: NeoTermService?, finishedSession: XSession?) {
30 | if (termService == null || finishedSession == null) {
31 | return
32 | }
33 |
34 | termService.removeXSession(finishedSession)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/layout/phone_toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/backend/TerminalOutput.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.backend;
2 |
3 | import java.nio.charset.StandardCharsets;
4 |
5 | /**
6 | * A client which receives callbacks from events triggered by feeding input to a {@link TerminalEmulator}.
7 | */
8 | public abstract class TerminalOutput {
9 |
10 | /**
11 | * Write a string using the UTF-8 encoding to the terminal client.
12 | */
13 | public final void write(String data) {
14 | byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
15 | write(bytes, 0, bytes.length);
16 | }
17 |
18 | /**
19 | * Write bytes to the terminal client.
20 | */
21 | public abstract void write(byte[] data, int offset, int count);
22 |
23 | /**
24 | * Notify the terminal client that the terminal title has changed.
25 | */
26 | public abstract void titleChanged(String oldTitle, String newTitle);
27 |
28 | /**
29 | * Notify the terminal client that the terminal title has changed.
30 | */
31 | public abstract void clipboardText(String text);
32 |
33 | /**
34 | * Notify the terminal client that a bell character (ASCII 7, bell, BEL, \a, ^G)) has been received.
35 | */
36 | public abstract void onBell();
37 |
38 | public abstract void onColorsChanged();
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_complete_candidate.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
22 |
23 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_package.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
20 |
21 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/frontend/session/view/TerminalViewClient.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.frontend.session.view;
2 |
3 | import android.view.KeyEvent;
4 | import android.view.MotionEvent;
5 | import android.view.ScaleGestureDetector;
6 | import io.neoterm.backend.TerminalSession;
7 |
8 | /**
9 | * Input and scale listener which may be set on a {@link TerminalView} through
10 | * {@link TerminalView#setTerminalViewClient(TerminalViewClient)}.
11 | *
12 | */
13 | public interface TerminalViewClient {
14 | /**
15 | * Callback function on scale events according to {@link ScaleGestureDetector#getScaleFactor()}.
16 | */
17 | float onScale(float scale);
18 |
19 | /**
20 | * On a single tap on the terminal if terminal mouse reporting not enabled.
21 | */
22 | void onSingleTapUp(MotionEvent e);
23 |
24 | boolean shouldBackButtonBeMappedToEscape();
25 |
26 | void copyModeChanged(boolean copyMode);
27 |
28 | boolean onKeyDown(int keyCode, KeyEvent e, TerminalSession session);
29 |
30 | boolean onKeyUp(int keyCode, KeyEvent e);
31 |
32 | boolean readControlKey();
33 |
34 | boolean readAltKey();
35 |
36 | boolean onCodePoint(int codePoint, boolean ctrlDown, TerminalSession session);
37 |
38 | boolean onLongPress(MotionEvent event);
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/Layout.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher;
15 |
16 | /**
17 | * Contains all possible layouts of a {@link TabSwitcher}.
18 | *
19 | * @author Michael Rapp
20 | * @since 0.1.0
21 | */
22 | public enum Layout {
23 |
24 | /**
25 | * The layout, which is used on smartphones and phablet devices, when in portrait mode.
26 | */
27 | PHONE_PORTRAIT,
28 |
29 | /**
30 | * The layout, which is used on smartphones and phablet devices, when in landscape mode.
31 | */
32 | PHONE_LANDSCAPE,
33 |
34 | /**
35 | * The layout, which is used on tablets.
36 | */
37 | TABLET
38 |
39 | }
--------------------------------------------------------------------------------
/NeoTermBridge/src/main/java/io/neoterm/bridge/SessionId.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.bridge;
2 |
3 | import java.util.Objects;
4 |
5 | /**
6 | * @author kiva
7 | */
8 | public class SessionId {
9 | /**
10 | * Created a new session.
11 | */
12 | public static final SessionId NEW_SESSION = SessionId.of("new");
13 |
14 | /**
15 | * Presents current session in NeoTerm.
16 | */
17 | public static final SessionId CURRENT_SESSION = SessionId.of("current");
18 |
19 | private final String sessionId;
20 |
21 | SessionId(String sessionId) {
22 | this.sessionId = sessionId;
23 | }
24 |
25 | public String getSessionId() {
26 | return sessionId;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "TerminalSession { id = " + sessionId + " }";
32 | }
33 |
34 | @Override
35 | public boolean equals(Object o) {
36 | if (this == o) return true;
37 | if (o == null || getClass() != o.getClass()) return false;
38 | SessionId sessionId1 = (SessionId) o;
39 | return Objects.equals(sessionId, sessionId1.sessionId);
40 | }
41 |
42 | @Override
43 | public int hashCode() {
44 | return Objects.hash(sessionId);
45 | }
46 |
47 | public static SessionId of(String sessionId) {
48 | return new SessionId(sessionId);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/settings_ui.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_edit_two_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
28 |
29 |
35 |
36 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/layout/AbstractTabViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher.layout;
15 |
16 | import android.widget.ImageButton;
17 | import android.widget.TextView;
18 | import de.mrapp.android.tabswitcher.TabSwitcher;
19 |
20 | /**
21 | * An abstract base class for all view holders, which allow to store references to the views, a tab
22 | * of a {@link TabSwitcher} consists of.
23 | *
24 | * @author Michael Rapp
25 | * @since 0.1.0
26 | */
27 | public abstract class AbstractTabViewHolder {
28 |
29 | /**
30 | * The text view, which is used to display the title of a tab.
31 | */
32 | public TextView titleTextView;
33 |
34 | /**
35 | * The close button of a tab.
36 | */
37 | public ImageButton closeButton;
38 |
39 | }
--------------------------------------------------------------------------------
/app/src/main/assets/scripts/extract-archive:
--------------------------------------------------------------------------------
1 | #!/data/data/io.neoterm/files/usr/bin/bash
2 |
3 | function file_suffix() {
4 | echo "${1##*.}"
5 | }
6 |
7 | function detect_program() {
8 | case "$1" in
9 | *.tar.* | *.tar ) echo "tar xvf %s" ;;
10 | *.7z ) echo "7za x %s" ;;
11 | *.rar ) echo "unrar x %s" ;;
12 | *.zip ) echo "unzip %s" ;;
13 | * ) echo "" ;;
14 | esac
15 | }
16 |
17 | function do_extract() {
18 | local file="$1"
19 | local dir="$(dirname $file)"
20 |
21 | if [[ ! -f "$file" ]]; then
22 | echo "$file: no such file or directory"
23 | return 1
24 | fi
25 |
26 | local program="$(detect_program $file)"
27 |
28 | if [[ "$program" == "" ]]; then
29 | echo "Unsupported format: $(file_suffix $file)"
30 | return 1
31 | fi
32 |
33 | local command="$(printf "$program" "$file")"
34 |
35 | if [[ ! -w "$dir" || ! -r "$file" ]]; then
36 | command="sudo $command"
37 | fi
38 |
39 | cd "$dir" || {
40 | echo "Failed to cd: $dir"
41 | return 1
42 | }
43 |
44 | eval "$command"
45 | }
46 |
47 | if [[ "$#" == 0 ]]; then
48 | echo "You must specific at least a file to extract."
49 | exit 1
50 | fi
51 |
52 | clear
53 | while [[ "$#" != 0 ]]; do
54 | file="$1"; shift
55 | echo "[Extracting] $(basename $file)"
56 | do_extract "$file"
57 | done
58 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/userscript/comp.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.userscript
2 |
3 | import android.content.Context
4 | import android.system.Os
5 | import io.neoterm.App
6 | import io.neoterm.component.NeoComponent
7 | import io.neoterm.component.config.NeoTermPath
8 | import io.neoterm.utils.NLog
9 | import io.neoterm.utils.extractAssetsDir
10 | import java.io.File
11 |
12 | class UserScript(val scriptFile: File)
13 |
14 | class UserScriptComponent : NeoComponent {
15 | var userScripts = listOf()
16 | private val scriptDir = File(NeoTermPath.USER_SCRIPT_PATH)
17 |
18 | override fun onServiceInit() = checkForFiles()
19 |
20 | override fun onServiceDestroy() {
21 | }
22 |
23 | override fun onServiceObtained() = checkForFiles()
24 |
25 | private fun extractDefaultScript(context: Context) = kotlin.runCatching {
26 | context.extractAssetsDir("scripts", NeoTermPath.USER_SCRIPT_PATH)
27 | scriptDir.listFiles().forEach {
28 | Os.chmod(it.absolutePath, 448 /*Dec of 0700*/)
29 | }
30 | }.onFailure {
31 | NLog.e("UserScript", "Failed to extract default user scripts: ${it.localizedMessage}")
32 | }
33 |
34 | private fun checkForFiles() {
35 | extractDefaultScript(App.get())
36 | reloadScripts()
37 | }
38 |
39 | private fun reloadScripts() {
40 | userScripts = scriptDir.listFiles()
41 | .takeWhile { it.canExecute() }
42 | .map { UserScript(it) }
43 | .toList()
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_pm.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
22 |
23 |
28 |
29 |
30 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/model/State.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher.model;
15 |
16 | /**
17 | * Contains all possible states of a tab, while the switcher is shown.
18 | *
19 | * @author Michael Rapp
20 | * @since 0.1.0
21 | */
22 | public enum State {
23 |
24 | /**
25 | * When the tab is part of the stack, which is located at the start of the switcher.
26 | */
27 | STACKED_START,
28 |
29 | /**
30 | * When the tab is displayed atop of the stack, which is located at the start of the switcher.
31 | */
32 | STACKED_START_ATOP,
33 |
34 | /**
35 | * When the tab is floating and freely movable.
36 | */
37 | FLOATING,
38 |
39 | /**
40 | * When the tab is part of the stack, which is located at the end of the switcher.
41 | */
42 | STACKED_END,
43 |
44 | /**
45 | * When the tab is currently not visible, i.e. if no view is inflated to visualize it.
46 | */
47 | HIDDEN
48 |
49 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_user_script_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
19 |
20 |
24 |
25 |
26 |
27 |
33 |
34 |
38 |
39 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/frontend/completion/MaxHeightView.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.frontend.completion
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import android.widget.LinearLayout
7 |
8 | class MaxHeightView : LinearLayout {
9 | var maxHeight = -1
10 |
11 | constructor(context: Context) : super(context)
12 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
13 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
14 |
15 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
16 | var finalHeightMeasureSpec = heightMeasureSpec
17 |
18 | if (maxHeight > 0) {
19 | val heightMode = View.MeasureSpec.getMode(heightMeasureSpec)
20 | var heightSize = View.MeasureSpec.getSize(heightMeasureSpec)
21 |
22 | if (heightMode == View.MeasureSpec.EXACTLY) {
23 | heightSize = if (heightSize <= maxHeight)
24 | heightSize
25 | else
26 | maxHeight
27 | }
28 |
29 | if (heightMode == View.MeasureSpec.UNSPECIFIED) {
30 | heightSize = if (heightSize <= maxHeight)
31 | heightSize
32 | else
33 | maxHeight
34 | }
35 | if (heightMode == View.MeasureSpec.AT_MOST) {
36 | heightSize = if (heightSize <= maxHeight)
37 | heightSize
38 | else
39 | maxHeight
40 | }
41 | finalHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
42 | heightSize,
43 | heightMode
44 | )
45 | }
46 |
47 | super.onMeasure(widthMeasureSpec, finalHeightMeasureSpec)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/TabCloseListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | /**
19 | * Defines the interface, a class, which should be notified, when a tab is about to be closed by
20 | * clicking its close button, must implement.
21 | *
22 | * @author Michael Rapp
23 | * @since 0.1.0
24 | */
25 | public interface TabCloseListener {
26 |
27 | /**
28 | * The method, which is invoked, when a tab is about to be closed by clicking its close button.
29 | *
30 | * @param tabSwitcher The tab switcher, the tab belongs to, as an instance of the class {@link
31 | * TabSwitcher}. The tab switcher may not be null
32 | * @param tab The tab, which is about to be closed, as an instance of the class {@link Tab}. The
33 | * tab may not be null
34 | * @return True, if the tab should be closed, false otherwise
35 | */
36 | boolean onCloseTab(@NonNull TabSwitcher tabSwitcher, @NonNull Tab tab);
37 |
38 | }
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/model/Restorable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher.model;
15 |
16 | import android.os.Bundle;
17 | import androidx.annotation.NonNull;
18 | import androidx.annotation.Nullable;
19 |
20 | /**
21 | * Defines the interface, a class, whose state should be stored and restored, must implement.
22 | *
23 | * @author Michael Rapp
24 | * @since 0.1.0
25 | */
26 | public interface Restorable {
27 |
28 | /**
29 | * Saves the current state.
30 | *
31 | * @param outState The bundle, which should be used to store the saved state, as an instance of the
32 | * class {@link Bundle}. The bundle may not be null
33 | */
34 | void saveInstanceState(@NonNull Bundle outState);
35 |
36 | /**
37 | * Restores a previously saved state.
38 | *
39 | * @param savedInstanceState The saved state as an instance of the class {@link Bundle} or null, if no saved state
40 | * is available
41 | */
42 | void restoreInstanceState(@Nullable Bundle savedInstanceState);
43 |
44 | }
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 | 16dp
19 | 4dp
20 | 48dp
21 | 12dp
22 | 8dp
23 | 128dp
24 | 4dp
25 | 48dp
26 | 1280dp
27 | 2048dp
28 | 8dp
29 | 24dp
30 | 32dp
31 | 10sp
32 | 7sp
33 | - 0.5
34 | - 0
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/utils/NeoPermission.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.utils
2 |
3 | import android.Manifest
4 | import android.content.ActivityNotFoundException
5 | import android.content.DialogInterface
6 | import android.content.pm.PackageManager
7 | import androidx.appcompat.app.AlertDialog
8 | import androidx.appcompat.app.AppCompatActivity
9 | import androidx.core.app.ActivityCompat
10 | import androidx.core.content.ContextCompat
11 |
12 | /**
13 | * @author kiva
14 | */
15 | object NeoPermission {
16 | const val REQUEST_APP_PERMISSION = 10086
17 |
18 | fun initAppPermission(context: AppCompatActivity, requestCode: Int) {
19 | if (ContextCompat.checkSelfPermission(
20 | context,
21 | Manifest.permission.READ_EXTERNAL_STORAGE
22 | )
23 | != PackageManager.PERMISSION_GRANTED
24 | ) {
25 |
26 | if (ActivityCompat.shouldShowRequestPermissionRationale(
27 | context,
28 | Manifest.permission.READ_EXTERNAL_STORAGE
29 | )
30 | ) {
31 | AlertDialog.Builder(context).setMessage("需要存储权限来访问存储设备上的文件")
32 | .setPositiveButton(android.R.string.ok, { _: DialogInterface, _: Int ->
33 | doRequestPermission(context, requestCode)
34 | })
35 | .show()
36 |
37 | } else {
38 | doRequestPermission(context, requestCode)
39 | }
40 | }
41 | }
42 |
43 | private fun doRequestPermission(context: AppCompatActivity, requestCode: Int) {
44 | try {
45 | ActivityCompat.requestPermissions(
46 | context,
47 | arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
48 | requestCode
49 | )
50 | } catch (ignore: ActivityNotFoundException) {
51 | // for MIUI, we ignore it.
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/settings_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
11 |
12 |
13 |
17 |
20 |
21 |
22 |
26 |
29 |
30 |
31 |
35 |
38 |
39 |
40 |
43 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/TabPreviewListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher;
15 |
16 | import androidx.annotation.NonNull;
17 |
18 | /**
19 | * Defines the interface, a class, which should be notified, when the preview of a tab is about to
20 | * be loaded, must implement.
21 | *
22 | * @author Michael Rapp
23 | * @since 0.1.0
24 | */
25 | public interface TabPreviewListener {
26 |
27 | /**
28 | * The method, which is invoked, when the preview of a tab is about to be loaded.
29 | *
30 | * @param tabSwitcher The tab switcher, which contains the tab, whose preview is about to be loaded, as an
31 | * instance of the class {@link TabSwitcher}. The tab switcher may not be null
32 | * @param tab The tab, whose preview is about to be loaded, as an instance of the class {@link
33 | * Tab}. The tab may not be null
34 | * @return True, if loading the preview should be proceeded, false otherwise. When returning
35 | * false, the method gets invoked repeatedly until true is returned.
36 | */
37 | boolean onLoadTabPreview(@NonNull TabSwitcher tabSwitcher, @NonNull Tab tab);
38 |
39 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/preference_keys.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | neoterm_general_bell
4 | neoterm_general_vibrate
5 | neoterm_general_backspace_map_to_esc
6 | neoterm_general_shell
7 | neoterm_general_initial_command
8 | neoterm_general_auto_completion
9 | neoterm_general_volume_as_control
10 | neoterm_general_use_execve_wrapper
11 | neoterm_general_enable_word_based_ime
12 |
13 | neoterm_ui_fullscreen
14 | neoterm_ui_hide_toolbar
15 | neoterm_ui_next_tab_anim
16 | neoterm_ui_eks_weight_explicit
17 | neoterm_ui_eks_enabled
18 |
19 | neoterm_package_source
20 |
21 | neoterm_ui_font
22 | neoterm_ui_color_scheme
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_command_shortcut.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
23 |
24 |
25 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
46 |
47 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 | 3
19 | 2
20 | 3
21 | @android:integer/config_shortAnimTime
22 | @android:integer/config_shortAnimTime
23 | @android:integer/config_mediumAnimTime
24 | @android:integer/config_shortAnimTime
25 | @android:integer/config_longAnimTime
26 | @android:integer/config_shortAnimTime
27 | @android:integer/config_mediumAnimTime
28 | @android:integer/config_shortAnimTime
29 | @android:integer/config_shortAnimTime
30 | @android:integer/config_shortAnimTime
31 | 1200
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/config/defaults.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.config
2 |
3 | import android.annotation.SuppressLint
4 |
5 | object DefaultValues {
6 | const val fontSize = 30
7 |
8 | const val enableBell = false
9 | const val enableVibrate = false
10 | const val enableExecveWrapper = true
11 | const val enableAutoCompletion = false
12 | const val enableFullScreen = false
13 | const val enableAutoHideToolbar = false
14 | const val enableSwitchNextTab = false
15 | const val enableExtraKeys = true
16 | const val enableExplicitExtraKeysWeight = false
17 | const val enableBackButtonBeMappedToEscape = false
18 | const val enableSpecialVolumeKeys = false
19 | const val enableWordBasedIme = false
20 |
21 | const val loginShell = "bash"
22 | const val initialCommand = ""
23 | const val defaultFont = "SourceCodePro"
24 | }
25 |
26 | object NeoTermPath {
27 | @SuppressLint("SdCardPath")
28 | const val ROOT_PATH = "/data/data/io.neoterm/files"
29 | const val USR_PATH = "$ROOT_PATH/usr"
30 | const val HOME_PATH = "$ROOT_PATH/home"
31 | const val APT_BIN_PATH = "$USR_PATH/bin/apt"
32 | const val LIB_PATH = "$USR_PATH/lib"
33 |
34 | const val CUSTOM_PATH = "$HOME_PATH/.neoterm"
35 | const val NEOTERM_LOGIN_SHELL_PATH = "$CUSTOM_PATH/shell"
36 | const val EKS_PATH = "$CUSTOM_PATH/eks"
37 | const val EKS_DEFAULT_FILE = "$EKS_PATH/default.nl"
38 | const val FONT_PATH = "$CUSTOM_PATH/font"
39 | const val COLORS_PATH = "$CUSTOM_PATH/color"
40 | const val USER_SCRIPT_PATH = "$CUSTOM_PATH/script"
41 | const val PROFILE_PATH = "$CUSTOM_PATH/profile"
42 |
43 | const val SOURCE_FILE = "$USR_PATH/etc/apt/sources.list"
44 | const val PACKAGE_LIST_DIR = "$USR_PATH/var/lib/apt/lists"
45 |
46 | private const val SOURCE = "https://raw.githubusercontent.com/NeoTerm/NeoTerm-repo/main"
47 |
48 | val DEFAULT_MAIN_PACKAGE_SOURCE: String
49 |
50 | init {
51 | DEFAULT_MAIN_PACKAGE_SOURCE = SOURCE
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/layout/phone/PhoneTabViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher.layout.phone;
15 |
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.widget.ImageView;
19 | import de.mrapp.android.tabswitcher.TabSwitcher;
20 | import de.mrapp.android.tabswitcher.layout.AbstractTabViewHolder;
21 |
22 | /**
23 | * A view holder, which allows to store references to the views, a tab of a {@link TabSwitcher}
24 | * consists of, when using the smartphone layout.
25 | *
26 | * @author Michael Rapp
27 | * @since 0.1.0
28 | */
29 | public class PhoneTabViewHolder extends AbstractTabViewHolder {
30 |
31 | /**
32 | * The view group, which contains the title and close button of a tab.
33 | */
34 | public ViewGroup titleContainer;
35 |
36 | /**
37 | * The view group, which contains the child view of a tab.
38 | */
39 | public ViewGroup childContainer;
40 |
41 | /**
42 | * The child view, which contains the tab's content.
43 | */
44 | public View child;
45 |
46 | /**
47 | * The image view, which is used to display the preview of a tab.
48 | */
49 | public ImageView previewImageView;
50 |
51 | /**
52 | * The view, which is used to display a border around the preview of a tab.
53 | */
54 | public View borderView;
55 |
56 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
27 |
28 |
36 |
37 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/backend/JNI.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.backend;
2 |
3 | /**
4 | * Native methods for creating and managing pseudoterminal subprocesses. C code is in jni/termux.c.
5 | */
6 | final class JNI {
7 |
8 | static {
9 | System.loadLibrary("neoterm");
10 | }
11 |
12 | /**
13 | * Create a subprocess. Differs from {@link ProcessBuilder} in that a pseudoterminal is used to communicate with the
14 | * subprocess.
15 | *
16 | * Callers are responsible for calling {@link #close(int)} on the returned file descriptor.
17 | *
18 | * @param cmd The command to execute
19 | * @param cwd The current working directory for the executed command
20 | * @param args An array of arguments to the command
21 | * @param envVars An array of strings of the form "VAR=value" to be added to the environment of the process
22 | * @param processId A one-element array to which the process ID of the started process will be written.
23 | * @return the file descriptor resulting from opening /dev/ptmx master device. The sub process will have opened the
24 | * slave device counterpart (/dev/pts/$N) and have it as stdint, stdout and stderr.
25 | */
26 | public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId, int rows, int columns);
27 |
28 | /**
29 | * Set the window size for a given pty, which allows connected programs to learn how large their screen is.
30 | */
31 | public static native void setPtyWindowSize(int fd, int rows, int cols);
32 |
33 | /**
34 | * Causes the calling thread to wait for the process associated with the receiver to finish executing.
35 | *
36 | * @return if >= 0, the exit status of the process. If < 0, the signal causing the process to stop negated.
37 | */
38 | public static native int waitFor(int processId);
39 |
40 | /**
41 | * Close a file descriptor through the close(2) system call.
42 | */
43 | public static native void close(int fileDescriptor);
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/NeoLang/src/main/java/io/neolang/frontend/tokens.kt:
--------------------------------------------------------------------------------
1 | package io.neolang.frontend
2 |
3 | import io.neolang.runtime.NeoLangValue
4 |
5 | /**
6 | * @author kiva
7 | */
8 | class NeoLangEOFToken : NeoLangToken(NeoLangTokenType.EOF, NeoLangTokenValue.EOF)
9 |
10 | /**
11 | * @author kiva
12 | */
13 |
14 | open class NeoLangToken(val tokenType: NeoLangTokenType, val tokenValue: NeoLangTokenValue) {
15 | var lineNumber = 0
16 |
17 | override fun toString(): String {
18 | return "Token { tokenType: $tokenType, tokenValue: $tokenValue };"
19 | }
20 | }
21 |
22 | /**
23 | * @author kiva
24 | */
25 |
26 | enum class NeoLangTokenType {
27 | NUMBER,
28 | ID,
29 | STRING,
30 | BRACKET_START,
31 | BRACKET_END,
32 | ARRAY_START,
33 | ARRAY_END,
34 | COLON,
35 | COMMA,
36 | EOL,
37 | EOF,
38 | }
39 |
40 | /**
41 | * @author kiva
42 | */
43 | class NeoLangTokenValue(val value: NeoLangValue) {
44 |
45 | override fun toString(): String {
46 | return value.asString()
47 | }
48 |
49 | companion object {
50 | val COLON = NeoLangTokenValue(NeoLangValue(":"))
51 | val COMMA = NeoLangTokenValue(NeoLangValue(","))
52 | val QUOTE = NeoLangTokenValue(NeoLangValue("\""))
53 | val EOF = NeoLangTokenValue(NeoLangValue(""))
54 |
55 | val BRACKET_START = NeoLangTokenValue(NeoLangValue("{"))
56 | val BRACKET_END = NeoLangTokenValue(NeoLangValue("}"))
57 | val ARRAY_START = NeoLangTokenValue(NeoLangValue("["))
58 | val ARRAY_END = NeoLangTokenValue(NeoLangValue("]"))
59 |
60 | fun wrap(tokenText: String): NeoLangTokenValue {
61 | return when (tokenText) {
62 | COLON.value.asString() -> COLON
63 | COMMA.value.asString() -> COMMA
64 | QUOTE.value.asString() -> QUOTE
65 | BRACKET_START.value.asString() -> BRACKET_START
66 | BRACKET_END.value.asString() -> BRACKET_END
67 | ARRAY_START.value.asString() -> ARRAY_START
68 | ARRAY_END.value.asString() -> ARRAY_END
69 | else -> NeoLangTokenValue(NeoLangValue(tokenText))
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/completion/comp.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.completion
2 |
3 | import io.neoterm.component.NeoComponent
4 |
5 | class CompletionComponent : NeoComponent {
6 | override fun onServiceInit() {
7 | CompletionManager.registerProvider(FileCompletionProvider())
8 | CompletionManager.registerProvider(ProgramCompletionProvider())
9 | }
10 |
11 | override fun onServiceDestroy() {
12 | }
13 |
14 | override fun onServiceObtained() {
15 | }
16 | }
17 |
18 | object CompletionManager {
19 | private val candidateProviders = mutableMapOf()
20 |
21 | fun registerProvider(provider: ICandidateProvider) {
22 | this.candidateProviders[provider.providerName] = provider
23 | }
24 |
25 | fun unregisterProvider(providerName: String) {
26 | this.candidateProviders.remove(providerName)
27 | }
28 |
29 | fun unregisterProvider(provider: ICandidateProvider) {
30 | unregisterProvider(provider.providerName)
31 | }
32 |
33 | fun getProvider(providerName: String): ICandidateProvider? {
34 | return candidateProviders[providerName]
35 | }
36 |
37 | fun tryCompleteFor(text: String): CompletionResult {
38 | val detector = detectProviders(text)
39 | val provider = detector.detectBest()
40 |
41 | val candidates = provider?.provideCandidates(text) ?: listOf()
42 | return CompletionResult(candidates, detector)
43 | }
44 |
45 | private fun detectProviders(text: String): ProviderDetector {
46 | return ProviderDetector(candidateProviders.values
47 | .takeWhile { it.canComplete(text) })
48 | }
49 | }
50 |
51 | class ProviderDetector(val providers: List) : MarkScoreListener {
52 | private var detectedProvider: ICandidateProvider? = null
53 |
54 | override fun onMarkScore(score: Int) {
55 | // TODO: Save provider score
56 | }
57 |
58 | fun detectBest(): ICandidateProvider? {
59 | // TODO: detect best
60 | detectedProvider = if (providers.isEmpty())
61 | null
62 | else
63 | providers[0]
64 |
65 | return detectedProvider
66 | }
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/data.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component
2 |
3 | import io.neolang.frontend.ConfigVisitor
4 | import io.neoterm.component.config.ConfigureComponent
5 | import io.neoterm.utils.NLog
6 | import java.io.File
7 | import java.io.FileFilter
8 |
9 | interface ConfigFileBasedObject {
10 | @Throws(RuntimeException::class)
11 | fun onConfigLoaded(configVisitor: ConfigVisitor)
12 | }
13 |
14 | abstract class ConfigFileBasedComponent(protected val baseDir: String) : NeoComponent {
15 | companion object {
16 | private val TAG = ConfigFileBasedComponent::class.java.simpleName
17 |
18 | val NEOLANG_FILTER = FileFilter {
19 | it.extension == "nl"
20 | }
21 | }
22 |
23 | open val checkComponentFileWhenObtained = false
24 |
25 | override fun onServiceInit() {
26 | val baseDirFile = File(this.baseDir)
27 | if (!baseDirFile.exists()) {
28 | if (!baseDirFile.mkdirs()) {
29 | throw RuntimeException("Cannot create component config directory: ${baseDirFile.absolutePath}")
30 | }
31 | }
32 | onCheckComponentFiles()
33 | }
34 |
35 | override fun onServiceDestroy() {
36 | }
37 |
38 | override fun onServiceObtained() {
39 | if (checkComponentFileWhenObtained) {
40 | onCheckComponentFiles()
41 | }
42 | }
43 |
44 | fun loadConfigure(file: File): T? {
45 | return try {
46 | val loaderService = ComponentManager.getComponent()
47 | val configure = loaderService.newLoader(file).loadConfigure()
48 | ?: throw RuntimeException("Parse configuration failed.")
49 |
50 | val configVisitor = configure.getVisitor()
51 | val componentObject = onCreateComponentObject(configVisitor)
52 | componentObject.onConfigLoaded(configVisitor)
53 | componentObject
54 | } catch (e: RuntimeException) {
55 | NLog.e(TAG, "Failed to load config: ${file.absolutePath}: ${e.localizedMessage}")
56 | null
57 | }
58 | }
59 |
60 | abstract fun onCheckComponentFiles()
61 |
62 | abstract fun onCreateComponentObject(configVisitor: ConfigVisitor): T
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/profile/comp.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.profile
2 |
3 | import io.neolang.frontend.ConfigVisitor
4 | import io.neoterm.component.ConfigFileBasedComponent
5 | import io.neoterm.component.config.NeoTermPath
6 | import io.neoterm.utils.NLog
7 | import java.io.File
8 |
9 | class ProfileComponent : ConfigFileBasedComponent(NeoTermPath.PROFILE_PATH) {
10 | override val checkComponentFileWhenObtained
11 | get() = true
12 |
13 | private val profileRegistry = mutableMapOf>()
14 | private val profileList = mutableMapOf>()
15 |
16 | override fun onCheckComponentFiles() = reloadProfiles()
17 |
18 | override fun onCreateComponentObject(configVisitor: ConfigVisitor): NeoProfile {
19 | val rootContext = configVisitor.getRootContext()
20 |
21 | val profileClass = rootContext.children
22 | .mapNotNull {
23 | profileRegistry[it.contextName]
24 | }
25 | .singleOrNull()
26 |
27 | if (profileClass != null) {
28 | NLog.e("ProfileComponent", "Loaded profile: " + profileClass.name)
29 | return profileClass.newInstance()
30 | }
31 |
32 | throw IllegalArgumentException("No proper profile registry found")
33 | }
34 |
35 | fun getProfiles(metaName: String): List = profileList[metaName] ?: listOf()
36 |
37 | fun reloadProfiles() {
38 | profileList.clear()
39 | File(baseDir)
40 | .listFiles(NEOLANG_FILTER)
41 | .mapNotNull {
42 | this.loadConfigure(it)
43 | }
44 | .forEach {
45 | val list = profileList[it.profileMetaName]
46 | if (list != null) {
47 | list.add(it)
48 | } else {
49 | val newList = mutableListOf(it)
50 | profileList.put(it.profileMetaName, newList)
51 | }
52 | }
53 | }
54 |
55 | fun registerProfile(metaName: String, prototype: Class) {
56 | profileRegistry[metaName] = prototype
57 | reloadProfiles()
58 | }
59 |
60 | fun unregisterProfile(metaName: String) {
61 | profileRegistry.remove(metaName)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/completion/providers.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.completion
2 |
3 | import java.io.File
4 |
5 | interface ICandidateProvider {
6 | val providerName: String
7 | fun provideCandidates(text: String): List
8 | fun canComplete(text: String): Boolean
9 | }
10 |
11 | open class FileCompletionProvider : ICandidateProvider {
12 | override val providerName: String
13 | get() = "NeoTermProvider.FileCompletionProvider"
14 |
15 | override fun provideCandidates(text: String): List {
16 | var file = File(text)
17 | var filter: ((File) -> Boolean)? = null
18 |
19 | if (!file.isDirectory) {
20 | val partName = file.name
21 | file = file.parentFile
22 | filter = { pathname -> pathname.name.startsWith(partName) }
23 | }
24 |
25 | return generateCandidateList(file, filter)
26 | }
27 |
28 | override fun canComplete(text: String): Boolean {
29 | return text.startsWith(File.separatorChar) || text.startsWith("\\./")
30 | }
31 |
32 | private fun listDirectory(path: File, filter: ((File) -> Boolean)?): Array {
33 | return if (filter != null) path.listFiles(filter) else path.listFiles()
34 | }
35 |
36 | private fun generateCandidateList(file: File, filter: ((File) -> Boolean)?) =
37 | if (file.canRead()) listDirectory(file, filter).map {
38 | val candidate = CompletionCandidate(it.name)
39 | candidate.description = generateDesc(it)
40 | candidate.displayName = generateDisplayName(it)
41 | candidate
42 | }.toList()
43 | else listOf()
44 |
45 | open fun generateDisplayName(file: File): String {
46 | return if (file.isDirectory) "${file.name}/" else file.name
47 | }
48 |
49 | open fun generateDesc(file: File): String? {
50 | return null
51 | }
52 | }
53 |
54 | class ProgramCompletionProvider : FileCompletionProvider() {
55 | override val providerName: String
56 | get() = "NeoTermProvider.ProgramCompletionProvider"
57 |
58 |
59 | override fun generateDesc(file: File): String? {
60 | return if (file.canExecute()) "" else super.generateDesc(file)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
17 |
18 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
32 |
43 |
44 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/other/CrashActivity.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.other
2 |
3 | import android.os.Build
4 | import android.os.Bundle
5 | import android.widget.TextView
6 | import androidx.appcompat.app.AppCompatActivity
7 | import io.neoterm.R
8 | import java.io.ByteArrayOutputStream
9 | import java.io.PrintStream
10 |
11 | /**
12 | * @author kiva
13 | */
14 | class CrashActivity : AppCompatActivity() {
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.ui_crash)
18 | setSupportActionBar(findViewById(R.id.crash_toolbar))
19 |
20 | (findViewById(R.id.crash_model)).text = getString(R.string.crash_model, collectModelInfo())
21 | (findViewById(R.id.crash_app_version)).text = getString(R.string.crash_app, collectAppInfo())
22 | (findViewById(R.id.crash_details)).text = collectExceptionInfo()
23 | }
24 |
25 | private fun collectExceptionInfo(): String {
26 | val extra = intent.getSerializableExtra("exception")
27 | if (extra != null && extra is Throwable) {
28 | val byteArrayOutput = ByteArrayOutputStream()
29 | val printStream = PrintStream(byteArrayOutput)
30 | (extra.cause ?: extra).printStackTrace(printStream)
31 | return byteArrayOutput.use {
32 | byteArrayOutput.toString("utf-8")
33 | }
34 | }
35 | return "are.you.kidding.me.NoExceptionFoundException: This is a bug, please contact developers!"
36 | }
37 |
38 | private fun collectAppInfo(): String {
39 | val pm = packageManager
40 | val info = pm.getPackageInfo(packageName, 0)
41 | return "${info.versionName} (${info.versionCode})"
42 | }
43 |
44 | private fun collectModelInfo(): String {
45 | return "${Build.MODEL} (Android ${Build.VERSION.RELEASE} ${determineArchName()})"
46 | }
47 |
48 | private fun determineArchName(): String {
49 | for (androidArch in Build.SUPPORTED_ABIS) {
50 | when (androidArch) {
51 | "arm64-v8a" -> return "aarch64"
52 | "armeabi-v7a" -> return "arm"
53 | "x86_64" -> return "x86_64"
54 | "x86" -> return "i686"
55 | }
56 | }
57 | return "Unknown Arch"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.settings
2 |
3 | import android.os.Bundle
4 | import android.view.MenuItem
5 | import androidx.appcompat.app.AlertDialog
6 | import io.neoterm.R
7 | import io.neoterm.component.config.NeoPreference
8 | import io.neoterm.utils.runApt
9 |
10 | /**
11 | * @author kiva
12 | */
13 | class GeneralSettingsActivity : BasePreferenceActivity() {
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | supportActionBar?.title = getString(R.string.general_settings)
18 | supportActionBar?.setDisplayHomeAsUpEnabled(true)
19 | addPreferencesFromResource(R.xml.setting_general)
20 |
21 | val currentShell = NeoPreference.getLoginShellName()
22 | findPreference(getString(R.string.key_general_shell)).setOnPreferenceChangeListener { _, value ->
23 | val shellName = value.toString()
24 | val newShell = NeoPreference.findLoginProgram(shellName)
25 | if (newShell == null) {
26 | requestInstallShell(shellName, currentShell)
27 | } else {
28 | postChangeShell(shellName)
29 | }
30 | return@setOnPreferenceChangeListener true
31 | }
32 | }
33 |
34 | private fun postChangeShell(shellName: String) = NeoPreference.setLoginShellName(shellName)
35 |
36 | private fun requestInstallShell(shellName: String, currentShell: String) {
37 | AlertDialog.Builder(this)
38 | .setTitle(getString(R.string.shell_not_found, shellName))
39 | .setMessage(R.string.shell_not_found_message)
40 | .setPositiveButton(R.string.install) { _, _ ->
41 | runApt("install", "-y", shellName) {
42 | it.onSuccess { postChangeShell(shellName) }
43 | }
44 | }
45 | .setNegativeButton(android.R.string.no, null)
46 | .setOnDismissListener { postChangeShell(currentShell) }
47 | .show()
48 | }
49 |
50 | override fun onBuildHeaders(target: MutableList?) {
51 | }
52 |
53 | override fun onOptionsItemSelected(item: MenuItem?): Boolean {
54 | when (item?.itemId) {
55 | android.R.id.home -> finish()
56 | }
57 | return super.onOptionsItemSelected(item)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/extrakey/comp.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.extrakey
2 |
3 | import android.content.Context
4 | import io.neolang.frontend.ConfigVisitor
5 | import io.neoterm.App
6 | import io.neoterm.component.ConfigFileBasedComponent
7 | import io.neoterm.component.config.NeoTermPath
8 | import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
9 | import io.neoterm.utils.NLog
10 | import io.neoterm.utils.extractAssetsDir
11 | import java.io.File
12 |
13 | class ExtraKeyComponent : ConfigFileBasedComponent(NeoTermPath.EKS_PATH) {
14 | override val checkComponentFileWhenObtained
15 | get() = true
16 |
17 | private val extraKeys: MutableMap = mutableMapOf()
18 |
19 | override fun onCheckComponentFiles() {
20 | val defaultFile = File(NeoTermPath.EKS_DEFAULT_FILE)
21 | if (!defaultFile.exists()) {
22 | extractDefaultConfig(App.get())
23 | }
24 | reloadExtraKeyConfig()
25 | }
26 |
27 | override fun onCreateComponentObject(configVisitor: ConfigVisitor): NeoExtraKey {
28 | return NeoExtraKey()
29 | }
30 |
31 | fun showShortcutKeys(program: String, extraKeysView: ExtraKeysView?) {
32 | if (extraKeysView == null) {
33 | return
34 | }
35 |
36 | val extraKey = extraKeys[program]
37 | if (extraKey != null) {
38 | extraKey.applyExtraKeys(extraKeysView)
39 | return
40 | }
41 |
42 | extraKeysView.loadDefaultUserKeys()
43 | }
44 |
45 | private fun registerShortcutKeys(extraKey: NeoExtraKey) =
46 | extraKey.programNames.forEach {
47 | extraKeys[it] = extraKey
48 | }
49 |
50 | private fun extractDefaultConfig(context: Context) {
51 | try {
52 | context.extractAssetsDir("eks", baseDir)
53 | } catch (e: Exception) {
54 | NLog.e("ExtraKey", "Failed to extract configure: ${e.localizedMessage}")
55 | }
56 | }
57 |
58 | private fun reloadExtraKeyConfig() {
59 | extraKeys.clear()
60 | File(baseDir)
61 | .listFiles(NEOLANG_FILTER)
62 | .filter { it.absolutePath != NeoTermPath.EKS_DEFAULT_FILE }
63 | .mapNotNull { this.loadConfigure(it) }
64 | .forEach {
65 | registerShortcutKeys(it)
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_neoterm.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
10 |
15 |
39 |
43 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.customize
2 |
3 | import android.annotation.SuppressLint
4 | import android.view.MenuItem
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.appcompat.widget.Toolbar
7 | import io.neoterm.R
8 | import io.neoterm.backend.TerminalSession
9 | import io.neoterm.component.config.NeoTermPath
10 | import io.neoterm.component.session.ShellParameter
11 | import io.neoterm.frontend.session.terminal.BasicSessionCallback
12 | import io.neoterm.frontend.session.terminal.BasicViewClient
13 | import io.neoterm.frontend.session.view.TerminalView
14 | import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
15 | import io.neoterm.utils.Terminals
16 |
17 | /**
18 | * @author kiva
19 | */
20 | @SuppressLint("Registered")
21 | open class BaseCustomizeActivity : AppCompatActivity() {
22 | lateinit var terminalView: TerminalView
23 | lateinit var viewClient: BasicViewClient
24 | lateinit var sessionCallback: BasicSessionCallback
25 | lateinit var session: TerminalSession
26 | lateinit var extraKeysView: ExtraKeysView
27 |
28 | fun initCustomizationComponent(layoutId: Int) {
29 | setContentView(layoutId)
30 |
31 | val toolbar = findViewById(R.id.custom_toolbar)
32 | setSupportActionBar(toolbar)
33 | supportActionBar?.setDisplayHomeAsUpEnabled(true)
34 |
35 | terminalView = findViewById(R.id.terminal_view)
36 | extraKeysView = findViewById(R.id.custom_extra_keys)
37 | viewClient = BasicViewClient(terminalView)
38 | sessionCallback = BasicSessionCallback(terminalView)
39 | Terminals.setupTerminalView(terminalView, viewClient)
40 | Terminals.setupExtraKeysView(extraKeysView)
41 |
42 | val script = resources.getStringArray(R.array.custom_preview_script_colors)
43 | val parameter = ShellParameter()
44 | .executablePath("${NeoTermPath.USR_PATH}/bin/echo")
45 | .arguments(arrayOf("echo", "-e", *script))
46 | .callback(sessionCallback)
47 | .systemShell(false)
48 |
49 | session = Terminals.createSession(this, parameter)
50 | terminalView.attachSession(session)
51 | }
52 |
53 | override fun onOptionsItemSelected(item: MenuItem?): Boolean {
54 | when (item?.itemId) {
55 | android.R.id.home -> finish()
56 | }
57 | return super.onOptionsItemSelected(item)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/frontend/session/terminal/data.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.frontend.session.terminal
2 |
3 | import io.neoterm.backend.TerminalSession
4 | import io.neoterm.component.completion.OnAutoCompleteListener
5 | import io.neoterm.component.session.ShellProfile
6 | import io.neoterm.component.session.ShellTermSession
7 | import io.neoterm.frontend.session.view.TerminalView
8 | import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
9 |
10 | class TermSessionData {
11 | var termSession: TerminalSession? = null
12 | var sessionCallback: TermSessionCallback? = null
13 | var viewClient: TermViewClient? = null
14 | var onAutoCompleteListener: OnAutoCompleteListener? = null
15 |
16 | var termUI: TermUiPresenter? = null
17 | var termView: TerminalView? = null
18 | var extraKeysView: ExtraKeysView? = null
19 |
20 | var profile: ShellProfile? = null
21 |
22 | fun cleanup() {
23 | onAutoCompleteListener?.onCleanUp()
24 | onAutoCompleteListener = null
25 |
26 | sessionCallback?.termSessionData = null
27 | viewClient?.termSessionData = null
28 |
29 | termUI = null
30 | termView = null
31 | extraKeysView = null
32 | termSession = null
33 |
34 | profile = null
35 | }
36 |
37 | fun initializeSessionWith(
38 | session: TerminalSession,
39 | sessionCallback: TermSessionCallback?,
40 | viewClient: TermViewClient?
41 | ) {
42 | this.termSession = session
43 | this.sessionCallback = sessionCallback
44 | this.viewClient = viewClient
45 | this.sessionCallback?.termSessionData = this
46 | this.viewClient?.termSessionData = this
47 |
48 | if (session is ShellTermSession) {
49 | profile = session.shellProfile
50 | }
51 | }
52 |
53 | fun initializeViewWith(termUI: TermUiPresenter?, termView: TerminalView?, eks: ExtraKeysView?) {
54 | this.termUI = termUI
55 | this.termView = termView
56 | this.extraKeysView = eks
57 | }
58 | }
59 |
60 | interface TermUiPresenter {
61 | fun requireClose()
62 | fun requireToggleFullScreen()
63 | fun requirePaste()
64 | fun requireUpdateTitle(title: String?)
65 | fun requireOnSessionFinished()
66 | fun requireHideIme()
67 | fun requireFinishAutoCompletion(): Boolean
68 | fun requireCreateNew()
69 | fun requireSwitchToPrevious()
70 | fun requireSwitchToNext()
71 | fun requireSwitchTo(index: Int)
72 | }
73 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion rootProject.ext.android.COMPILE_SDK_VERSION
6 |
7 | defaultConfig {
8 | applicationId "io.neoterm"
9 | minSdkVersion rootProject.ext.android.MIN_SDK_VERSION
10 | targetSdkVersion rootProject.ext.android.TARGET_SDK_VERSION
11 | versionCode 38
12 | versionName "2.0.5"
13 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
14 | resConfigs "zh-rCN", "zh-rTW"
15 | externalNativeBuild {
16 | cmake {
17 | cppFlags "-std=c++11"
18 | abiFilters 'arm64-v8a'
19 | }
20 | }
21 | sourceSets {
22 | main {
23 | jniLibs.srcDirs = ['src/main/jniLibs']
24 | }
25 | }
26 | }
27 | buildTypes {
28 | release {
29 | minifyEnabled true
30 | zipAlignEnabled true
31 | shrinkResources true
32 | }
33 | }
34 | externalNativeBuild {
35 | cmake {
36 | path "CMakeLists.txt"
37 | }
38 | }
39 | lintOptions {
40 | abortOnError false
41 | checkReleaseBuilds false
42 | }
43 | compileOptions {
44 | targetCompatibility 1.8
45 | sourceCompatibility 1.8
46 | }
47 | kotlinOptions {
48 | freeCompilerArgs = ["-Xallow-result-return-type"]
49 | }
50 | }
51 |
52 | dependencies {
53 | implementation fileTree(include: ['*.jar'], dir: 'libs')
54 | testImplementation rootProject.ext.deps["junit"]
55 | androidTestImplementation project(path: ':NeoLang')
56 |
57 | implementation rootProject.ext.deps["kotlin-stdlib"]
58 |
59 | implementation 'org.greenrobot:eventbus:3.0.0'
60 | implementation 'com.github.wrdlbrnft:modular-adapter:0.2.0.6'
61 | implementation 'com.github.wrdlbrnft:sorted-list-adapter:0.2.0.19'
62 | implementation 'com.simplecityapps:recyclerview-fastscroll:1.0.16'
63 | implementation 'de.psdev.licensesdialog:licensesdialog:1.8.3'
64 | implementation 'com.github.GrenderG:Color-O-Matic:1.1.5'
65 | implementation 'androidx.annotation:annotation:1.2.0'
66 | implementation 'androidx.cardview:cardview:1.0.0'
67 | implementation 'androidx.appcompat:appcompat:1.2.0'
68 | implementation 'androidx.appcompat:appcompat-resources:1.2.0'
69 |
70 | implementation project(':chrome-tabs')
71 | implementation project(':NeoLang')
72 | implementation project(':NeoTermBridge')
73 | implementation project(':Xorg')
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/App.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm
2 |
3 | import android.annotation.SuppressLint
4 | import android.app.Application
5 | import android.content.Context
6 | import android.content.Intent
7 | import android.net.Uri
8 | import android.view.Gravity
9 | import android.widget.Toast
10 | import androidx.appcompat.app.AlertDialog
11 | import io.neoterm.component.NeoInitializer
12 | import io.neoterm.component.config.NeoPreference
13 | import io.neoterm.ui.other.BonusActivity
14 | import io.neoterm.utils.CrashHandler
15 |
16 | /**
17 | * @author kiva
18 | */
19 | class App : Application() {
20 | override fun onCreate() {
21 | super.onCreate()
22 | app = this
23 | NeoPreference.init(this)
24 | CrashHandler.init()
25 | NeoInitializer.init(this)
26 | }
27 |
28 | fun errorDialog(context: Context, message: Int, dismissCallback: (() -> Unit)?) {
29 | errorDialog(context, getString(message), dismissCallback)
30 | }
31 |
32 | fun errorDialog(context: Context, message: String, dismissCallback: (() -> Unit)?) {
33 | AlertDialog.Builder(context)
34 | .setTitle(R.string.error)
35 | .setMessage(message)
36 | .setNegativeButton(android.R.string.no, null)
37 | .setPositiveButton(R.string.show_help) { _, _ ->
38 | openHelpLink()
39 | }
40 | .setOnDismissListener {
41 | dismissCallback?.invoke()
42 | }
43 | .show()
44 | }
45 |
46 | fun openHelpLink() {
47 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://neoterm.gitbooks.io/neoterm-wiki/content/"))
48 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
49 | startActivity(intent)
50 | }
51 |
52 | fun easterEgg(context: Context, message: String) {
53 | val happyCount = NeoPreference.loadInt(NeoPreference.KEY_HAPPY_EGG, 0) + 1
54 | NeoPreference.store(NeoPreference.KEY_HAPPY_EGG, happyCount)
55 |
56 | val trigger = NeoPreference.VALUE_HAPPY_EGG_TRIGGER
57 |
58 | if (happyCount == trigger / 2) {
59 | @SuppressLint("ShowToast")
60 | val toast = Toast.makeText(this, message, Toast.LENGTH_LONG)
61 | toast.setGravity(Gravity.CENTER, 0, 0)
62 | toast.show()
63 | } else if (happyCount > trigger) {
64 | NeoPreference.store(NeoPreference.KEY_HAPPY_EGG, 0)
65 | context.startActivity(Intent(context, BonusActivity::class.java))
66 | }
67 | }
68 |
69 | companion object {
70 | private var app: App? = null
71 |
72 | fun get(): App {
73 | return app!!
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/setting_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
15 |
16 |
21 |
22 |
27 |
28 |
33 |
34 |
39 |
40 |
45 |
46 |
51 |
52 |
57 |
58 |
--------------------------------------------------------------------------------
/NeoTermBridge/src/main/java/io/neoterm/bridge/Bridge.java:
--------------------------------------------------------------------------------
1 | package io.neoterm.bridge;
2 |
3 | import android.content.ComponentName;
4 | import android.content.Intent;
5 |
6 | import java.util.Objects;
7 |
8 | /**
9 | * @author kiva
10 | */
11 | public class Bridge {
12 | public static final String ACTION_EXECUTE = "neoterm.action.remote.execute";
13 | public static final String ACTION_SILENT_RUN = "neoterm.action.remote.silent-run";
14 | public static final String EXTRA_COMMAND = "neoterm.extra.remote.execute.command";
15 | public static final String EXTRA_SESSION_ID = "neoterm.extra.remote.execute.session";
16 | public static final String EXTRA_FOREGROUND = "neoterm.extra.remote.execute.foreground";
17 | private static final String NEOTERM_PACKAGE = "io.neoterm";
18 | private static final String NEOTERM_REMOTE_INTERFACE = "io.neoterm.ui.term.NeoTermRemoteInterface";
19 | private static final ComponentName NEOTERM_COMPONENT = new ComponentName(NEOTERM_PACKAGE, NEOTERM_REMOTE_INTERFACE);
20 |
21 | private Bridge() throws IllegalAccessException {
22 | throw new IllegalAccessException();
23 | }
24 |
25 | public static Intent createExecuteIntent(SessionId sessionId,
26 | String command,
27 | boolean foreground) {
28 | Objects.requireNonNull(command, "command");
29 | Objects.requireNonNull(sessionId, "session id");
30 |
31 | Intent intent = new Intent(ACTION_EXECUTE);
32 | intent.setComponent(NEOTERM_COMPONENT);
33 | intent.putExtra(EXTRA_COMMAND, command);
34 | intent.putExtra(EXTRA_SESSION_ID, sessionId.getSessionId());
35 | intent.putExtra(EXTRA_FOREGROUND, foreground);
36 | return intent;
37 | }
38 |
39 | public static Intent createExecuteIntent(SessionId sessionId, String command) {
40 | return createExecuteIntent(sessionId, command, true);
41 | }
42 |
43 | public static Intent createExecuteIntent(String command) {
44 | return createExecuteIntent(SessionId.NEW_SESSION, command);
45 | }
46 |
47 | public static Intent createExecuteIntent(String command, boolean foreground) {
48 | return createExecuteIntent(SessionId.NEW_SESSION, command, foreground);
49 | }
50 |
51 | public static SessionId parseResult(Intent data) {
52 | Objects.requireNonNull(data, "data");
53 |
54 | if (data.hasExtra(EXTRA_SESSION_ID)) {
55 | String handle = data.getStringExtra(EXTRA_SESSION_ID);
56 | return SessionId.of(handle);
57 | }
58 | return null;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/ui_crash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
22 |
23 |
29 |
30 |
36 |
37 |
45 |
46 |
49 |
50 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/utils/Terminals.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.utils
2 |
3 | import android.content.Context
4 | import androidx.appcompat.app.AppCompatActivity
5 | import io.neoterm.backend.TerminalSession
6 | import io.neoterm.component.ComponentManager
7 | import io.neoterm.component.config.NeoPreference
8 | import io.neoterm.component.font.FontComponent
9 | import io.neoterm.component.session.SessionComponent
10 | import io.neoterm.component.session.ShellParameter
11 | import io.neoterm.component.session.XParameter
12 | import io.neoterm.component.session.XSession
13 | import io.neoterm.frontend.session.view.TerminalView
14 | import io.neoterm.frontend.session.view.TerminalViewClient
15 | import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
16 |
17 | /**
18 | * @author kiva
19 | */
20 | object Terminals {
21 | fun setupTerminalView(terminalView: TerminalView?, terminalViewClient: TerminalViewClient? = null) {
22 | terminalView?.textSize = NeoPreference.getFontSize();
23 |
24 | val fontComponent = ComponentManager.getComponent()
25 | fontComponent.applyFont(terminalView, null, fontComponent.getCurrentFont())
26 |
27 | if (terminalViewClient != null) {
28 | terminalView?.setTerminalViewClient(terminalViewClient)
29 | }
30 | }
31 |
32 | fun setupExtraKeysView(extraKeysView: ExtraKeysView?) {
33 | val fontComponent = ComponentManager.getComponent()
34 | val font = fontComponent.getCurrentFont()
35 | fontComponent.applyFont(null, extraKeysView, font)
36 | }
37 |
38 | fun createSession(context: Context, parameter: ShellParameter): TerminalSession {
39 | val sessionComponent = ComponentManager.getComponent()
40 | return sessionComponent.createSession(context, parameter)
41 | }
42 |
43 | fun createSession(activity: AppCompatActivity, parameter: XParameter): XSession {
44 | val sessionComponent = ComponentManager.getComponent()
45 | return sessionComponent.createSession(activity, parameter)
46 | }
47 |
48 | fun escapeString(s: String?): String {
49 | if (s == null) {
50 | return ""
51 | }
52 |
53 | val builder = StringBuilder()
54 | val specialChars = "\"\\$`!"
55 | builder.append('"')
56 | val length = s.length
57 | for (i in 0 until length) {
58 | val c = s[i]
59 | if (specialChars.indexOf(c) >= 0) {
60 | builder.append('\\')
61 | }
62 | builder.append(c)
63 | }
64 | builder.append('"')
65 | return builder.toString()
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/LayoutPolicy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher;
15 |
16 | /**
17 | * Contains all possible layout policies of a {@link TabSwitcher}.
18 | *
19 | * @author Michael Rapp
20 | * @since 0.1.0
21 | */
22 | public enum LayoutPolicy {
23 |
24 | /**
25 | * If the layout should automatically adapted, depending on whether the device is a smartphone
26 | * or tablet.
27 | */
28 | AUTO(0),
29 |
30 | /**
31 | * If the smartphone layout should be used, regardless of the device.
32 | */
33 | PHONE(1),
34 |
35 | /**
36 | * If the tablet layout should be used, regardless of the device.
37 | */
38 | TABLET(2);
39 |
40 | /**
41 | * The value of the layout policy.
42 | */
43 | private int value;
44 |
45 | /**
46 | * Creates a new layout policy.
47 | *
48 | * @param value The value of the layout policy as an {@link Integer} value
49 | */
50 | LayoutPolicy(final int value) {
51 | this.value = value;
52 | }
53 |
54 | /**
55 | * Returns the value of the layout policy.
56 | *
57 | * @return The value of the layout policy as an {@link Integer} value
58 | */
59 | public final int getValue() {
60 | return value;
61 | }
62 |
63 | /**
64 | * Returns the layout policy, which corresponds to a specific value.
65 | *
66 | * @param value The value of the layout policy, which should be returned, as an {@link Integer}
67 | * value
68 | * @return The layout policy, which corresponds to the given value, as a value of the enum
69 | * {@link LayoutPolicy}
70 | */
71 | public static LayoutPolicy fromValue(final int value) {
72 | for (LayoutPolicy layoutPolicy : values()) {
73 | if (layoutPolicy.getValue() == value) {
74 | return layoutPolicy;
75 | }
76 | }
77 |
78 | throw new IllegalArgumentException("Invalid enum value: " + value);
79 | }
80 |
81 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/profile/data.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.profile
2 |
3 | import io.neolang.frontend.ConfigVisitor
4 | import io.neoterm.component.ComponentManager
5 | import io.neoterm.component.ConfigFileBasedObject
6 | import io.neoterm.component.codegen.CodeGenObject
7 | import io.neoterm.component.codegen.CodeGenParameter
8 | import io.neoterm.component.codegen.CodeGenerator
9 | import io.neoterm.component.codegen.NeoProfileGenerator
10 | import io.neoterm.component.config.ConfigureComponent
11 | import io.neoterm.component.config.NeoConfigureFile
12 | import io.neoterm.utils.NLog
13 | import org.jetbrains.annotations.TestOnly
14 | import java.io.File
15 |
16 | abstract class NeoProfile : CodeGenObject, ConfigFileBasedObject {
17 | companion object {
18 | private const val PROFILE_NAME = "name"
19 | }
20 |
21 | abstract val profileMetaName: String
22 | private val profileMetaPath
23 | get() = arrayOf(profileMetaName)
24 |
25 | var profileName = "Unknown Profile"
26 |
27 | override fun onConfigLoaded(configVisitor: ConfigVisitor) {
28 | profileName = configVisitor.getProfileString(PROFILE_NAME, profileName)
29 | }
30 |
31 | override fun getCodeGenerator(parameter: CodeGenParameter): CodeGenerator {
32 | return NeoProfileGenerator(parameter)
33 | }
34 |
35 | @TestOnly
36 | fun testLoadConfigure(file: File): Boolean {
37 | val loaderService = ComponentManager.getComponent()
38 |
39 | val configure: NeoConfigureFile?
40 | try {
41 | configure = loaderService.newLoader(file).loadConfigure()
42 | if (configure == null) {
43 | throw RuntimeException("Parse configuration failed.")
44 | }
45 | } catch (e: Exception) {
46 | NLog.e("Profile", "Failed to load profile: ${file.absolutePath}: ${e.localizedMessage}")
47 | return false
48 | }
49 |
50 | val visitor = configure.getVisitor()
51 | onConfigLoaded(visitor)
52 | return true
53 | }
54 |
55 | protected fun ConfigVisitor.getProfileString(key: String, fallback: String): String {
56 | return getProfileString(key) ?: fallback
57 | }
58 |
59 | protected fun ConfigVisitor.getProfileBoolean(key: String, fallback: Boolean): Boolean {
60 | return getProfileBoolean(key) ?: fallback
61 | }
62 |
63 | protected fun ConfigVisitor.getProfileString(key: String): String? {
64 | return this.getStringValue(profileMetaPath, key)
65 | }
66 |
67 | protected fun ConfigVisitor.getProfileBoolean(key: String): Boolean? {
68 | return this.getBooleanValue(profileMetaPath, key)
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/component/codegen/generators.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.component.codegen
2 |
3 | import io.neoterm.component.ComponentManager
4 | import io.neoterm.component.colorscheme.NeoColorScheme
5 | import io.neoterm.component.config.ConfigureComponent
6 |
7 | class NeoColorGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter) {
8 | override fun getGeneratorName(): String {
9 | return "NeoColorScheme-Generator"
10 | }
11 |
12 | override fun generateCode(codeGenObject: CodeGenObject): String {
13 | if (codeGenObject !is NeoColorScheme) {
14 | throw RuntimeException("Invalid object type, expected NeoColorScheme, got ${codeGenObject.javaClass.simpleName}")
15 | }
16 |
17 | return buildString {
18 | start(this)
19 | generateMetaData(this, codeGenObject)
20 | generateColors(this, codeGenObject)
21 | end(this)
22 | }
23 | }
24 |
25 | private fun start(builder: StringBuilder) {
26 | builder.append("${NeoColorScheme.CONTEXT_META_NAME}: {\n")
27 | }
28 |
29 | private fun end(builder: StringBuilder) {
30 | builder.append("}\n")
31 | }
32 |
33 | private fun generateMetaData(builder: StringBuilder, colorScheme: NeoColorScheme) {
34 | val component = ComponentManager.getComponent()
35 |
36 | builder.append(" ${NeoColorScheme.COLOR_META_NAME}: \"${colorScheme.colorName}\"\n")
37 | builder.append(
38 | " ${NeoColorScheme.COLOR_META_VERSION}: ${
39 | colorScheme.colorVersion
40 | ?: component.getLoaderVersion()
41 | }\n",
42 | )
43 | builder.append("\n")
44 | }
45 |
46 | private fun generateColors(builder: StringBuilder, colorScheme: NeoColorScheme) {
47 | builder.append(" ${NeoColorScheme.CONTEXT_COLOR_NAME}: {\n")
48 |
49 | builder.append(" ${NeoColorScheme.COLOR_DEF_BACKGROUND}: ${colorScheme.backgroundColor}\n")
50 | builder.append(" ${NeoColorScheme.COLOR_DEF_FOREGROUND}: ${colorScheme.foregroundColor}\n")
51 | builder.append(" ${NeoColorScheme.COLOR_DEF_CURSOR}: ${colorScheme.cursorColor}\n")
52 | colorScheme.color.entries.forEach {
53 | builder.append(" ${NeoColorScheme.COLOR_PREFIX}${it.key}: ${it.value}\n")
54 | }
55 |
56 | builder.append(" }\n")
57 | }
58 | }
59 |
60 | class NeoProfileGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter) {
61 | override fun getGeneratorName(): String {
62 | return "NeoProfile-Generator"
63 | }
64 |
65 | override fun generateCode(codeGenObject: CodeGenObject): String {
66 | return ""
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/setup/setup.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.setup
2 |
3 | import android.app.ProgressDialog
4 | import android.content.Context
5 | import android.os.Build
6 | import androidx.appcompat.app.AlertDialog
7 | import androidx.appcompat.app.AppCompatActivity
8 | import io.neoterm.App
9 | import io.neoterm.R
10 | import io.neoterm.component.config.NeoTermPath
11 | import java.io.File
12 | import java.util.*
13 |
14 | /**
15 | * @author kiva
16 | */
17 | interface ResultListener {
18 | fun onResult(error: Exception?)
19 | }
20 |
21 | /**
22 | * @author kiva
23 | */
24 | object SetupHelper {
25 | fun needSetup(): Boolean {
26 | val PREFIX_FILE = File(NeoTermPath.USR_PATH)
27 | return !PREFIX_FILE.isDirectory
28 | }
29 |
30 | fun setup(
31 | activity: AppCompatActivity, connection: SourceConnection,
32 | resultListener: ResultListener
33 | ) {
34 | if (!needSetup()) {
35 | resultListener.onResult(null)
36 | return
37 | }
38 |
39 | val prefixFile = File(NeoTermPath.USR_PATH)
40 |
41 | val progress = makeProgressDialog(activity)
42 | progress.max = 100
43 | progress.show()
44 |
45 | SetupThread(activity, connection, prefixFile, resultListener, progress).start()
46 | }
47 |
48 | private fun makeProgressDialog(context: Context): ProgressDialog {
49 | return makeProgressDialog(context, context.getString(R.string.installer_message))
50 | }
51 |
52 | fun makeProgressDialog(context: Context, message: String): ProgressDialog {
53 | val dialog = ProgressDialog(context)
54 | dialog.setMessage(message)
55 | dialog.isIndeterminate = false
56 | dialog.setCancelable(false)
57 | dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
58 | return dialog
59 | }
60 |
61 | fun makeErrorDialog(context: Context, messageId: Int): AlertDialog {
62 | return makeErrorDialog(context, context.getString(messageId))
63 | }
64 |
65 | fun makeErrorDialog(context: Context, message: String): AlertDialog {
66 | return AlertDialog.Builder(context)
67 | .setTitle(R.string.error)
68 | .setMessage(message)
69 | .setPositiveButton(android.R.string.yes, null)
70 | .setNeutralButton(R.string.show_help) { _, _ -> App.get().openHelpLink() }
71 | .create()
72 | }
73 |
74 | fun determineArchName(): String {
75 | for (androidArch in Build.SUPPORTED_ABIS) {
76 | when (androidArch) {
77 | "arm64-v8a" -> return "aarch64"
78 | "armeabi-v7a" -> return "arm"
79 | "x86_64" -> return "x86_64"
80 | }
81 | }
82 | throw RuntimeException(
83 | "Unable to determine arch from Build.SUPPORTED_ABIS = "
84 | + Arrays.toString(Build.SUPPORTED_ABIS)
85 | )
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/layout/phone_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
22 |
23 |
28 |
29 |
38 |
39 |
47 |
48 |
49 |
50 |
55 |
56 |
63 |
64 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/chrome-tabs/src/main/java/de/mrapp/android/tabswitcher/layout/TabSwitcherLayout.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 - 2017 Michael Rapp
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package de.mrapp.android.tabswitcher.layout;
15 |
16 | import android.view.Menu;
17 | import android.view.ViewGroup;
18 | import androidx.annotation.Nullable;
19 | import androidx.appcompat.widget.Toolbar;
20 | import de.mrapp.android.tabswitcher.TabSwitcher;
21 |
22 | /**
23 | * Defines the interface, a layout, which implements the functionality of a {@link TabSwitcher},
24 | * must implement.
25 | *
26 | * @author Michael Rapp
27 | * @since 0.1.0
28 | */
29 | public interface TabSwitcherLayout {
30 |
31 | /**
32 | * Returns, whether an animation is currently running, or not.
33 | *
34 | * @return True, if an animation is currently running, false otherwise
35 | */
36 | boolean isAnimationRunning();
37 |
38 | /**
39 | * Returns the view group, which contains the tab switcher's tabs.
40 | *
41 | * @return The view group, which contains the tab switcher's tabs, as an instance of the class
42 | * {@link ViewGroup} or null, if the view has not been laid out yet
43 | */
44 | @Nullable
45 | ViewGroup getTabContainer();
46 |
47 | /**
48 | * Returns the toolbars, which are shown, when the tab switcher is shown. When using the
49 | * smartphone layout, only one toolbar is shown. When using the tablet layout, a primary and
50 | * secondary toolbar is shown. In such case, the first index of the returned array corresponds
51 | * to the primary toolbar.
52 | *
53 | * @return An array, which contains the toolbars, which are shown, when the tab switcher is
54 | * shown, as an array of the type Toolbar or null, if the view has not been laid out yet
55 | */
56 | @Nullable
57 | Toolbar[] getToolbars();
58 |
59 | /**
60 | * Returns the menu of the toolbar, which is shown, when the tab switcher is shown. When using
61 | * the tablet layout, the menu corresponds to the secondary toolbar.
62 | *
63 | * @return The menu of the toolbar as an instance of the type {@link Menu} or null, if the view
64 | * has not been laid out yet
65 | */
66 | @Nullable
67 | Menu getToolbarMenu();
68 |
69 | }
--------------------------------------------------------------------------------
/chrome-tabs/src/main/res/layout-land/phone_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
22 |
23 |
28 |
29 |
37 |
38 |
47 |
48 |
49 |
50 |
55 |
56 |
63 |
64 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/Xorg/src/main/res/xml/amiga.xml:
--------------------------------------------------------------------------------
1 |
2 |
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 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/ui/pm/model.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.ui.pm
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter
9 | import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
10 | import io.neoterm.R
11 | import io.neoterm.component.pm.NeoPackageInfo
12 | import io.neoterm.utils.formatSizeInKB
13 |
14 | class PackageAdapter(
15 | context: Context,
16 | comparator: Comparator,
17 | private val listener: PackageAdapter.Listener
18 | ) : SortedListAdapter(context, PackageModel::class.java, comparator),
19 | FastScrollRecyclerView.SectionedAdapter {
20 |
21 | override fun getSectionName(position: Int): String {
22 | return getItem(position).packageInfo.packageName?.substring(0, 1) ?: "#"
23 | }
24 |
25 | interface Listener {
26 | fun onModelClicked(model: PackageModel)
27 | }
28 |
29 | override fun onCreateViewHolder(
30 | inflater: LayoutInflater,
31 | parent: ViewGroup,
32 | viewType: Int
33 | ): ViewHolder {
34 | val rootView = inflater.inflate(R.layout.item_package, parent, false)
35 | return PackageViewHolder(rootView, listener)
36 | }
37 | }
38 |
39 | class PackageViewHolder(private val rootView: View, private val listener: PackageAdapter.Listener) :
40 | SortedListAdapter.ViewHolder(rootView) {
41 | private val packageNameView: TextView = rootView.findViewById(R.id.package_item_name)
42 | private val packageDescView: TextView = rootView.findViewById(R.id.package_item_desc)
43 |
44 | override fun performBind(item: PackageModel) {
45 | rootView.setOnClickListener { listener.onModelClicked(item) }
46 | packageNameView.text = item.packageInfo.packageName
47 | packageDescView.text = item.packageInfo.description
48 | }
49 | }
50 |
51 | /**
52 | * @author kiva
53 | */
54 |
55 | class PackageModel(val packageInfo: NeoPackageInfo) : SortedListAdapter.ViewModel {
56 | override fun isSameModelAs(t: T): Boolean {
57 | if (t is PackageModel) {
58 | return t.packageInfo.packageName == packageInfo.packageName
59 | }
60 | return false
61 | }
62 |
63 | override fun isContentTheSameAs(t: T): Boolean {
64 | return isSameModelAs(t)
65 | }
66 |
67 | fun getPackageDetails(context: Context): String {
68 | return context.getString(
69 | R.string.package_details,
70 | packageInfo.packageName, packageInfo.version,
71 | packageInfo.dependenciesString,
72 | packageInfo.installedSizeInBytes.formatSizeInKB(),
73 | packageInfo.description, packageInfo.homePage
74 | )
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT executablePath
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT executablePath
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/io/neoterm/frontend/session/terminal/term-basic.kt:
--------------------------------------------------------------------------------
1 | package io.neoterm.frontend.session.terminal
2 |
3 | import android.content.Context
4 | import android.view.KeyEvent
5 | import android.view.MotionEvent
6 | import android.view.inputmethod.InputMethodManager
7 | import io.neoterm.backend.TerminalSession
8 | import io.neoterm.component.config.NeoPreference
9 | import io.neoterm.frontend.session.view.TerminalView
10 | import io.neoterm.frontend.session.view.TerminalViewClient
11 |
12 | open class BasicSessionCallback(var terminalView: TerminalView) : TerminalSession.SessionChangedCallback {
13 | override fun onTextChanged(changedSession: TerminalSession?) {
14 | if (changedSession != null) {
15 | terminalView.onScreenUpdated()
16 | }
17 | }
18 |
19 | override fun onTitleChanged(changedSession: TerminalSession?) {
20 | }
21 |
22 | override fun onSessionFinished(finishedSession: TerminalSession?) {
23 | }
24 |
25 | override fun onClipboardText(session: TerminalSession?, text: String?) {
26 | }
27 |
28 | override fun onBell(session: TerminalSession?) {
29 | }
30 |
31 | override fun onColorsChanged(session: TerminalSession?) {
32 | if (session != null) {
33 | terminalView.onScreenUpdated()
34 | }
35 | }
36 | }
37 |
38 | class BasicViewClient(val terminalView: TerminalView) : TerminalViewClient {
39 | override fun onScale(scale: Float): Float {
40 | if (scale < 0.9f || scale > 1.1f) {
41 | val increase = scale > 1f
42 | val changedSize = (if (increase) 1 else -1) * 2
43 | val fontSize = NeoPreference.validateFontSize(terminalView.textSize + changedSize)
44 | terminalView.textSize = fontSize
45 | return 1.0f
46 | }
47 | return scale
48 | }
49 |
50 | override fun onSingleTapUp(e: MotionEvent?) {
51 | if (terminalView.isFocusable && terminalView.isFocusableInTouchMode) {
52 | (terminalView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
53 | .showSoftInput(terminalView, InputMethodManager.SHOW_IMPLICIT)
54 | }
55 | }
56 |
57 | override fun shouldBackButtonBeMappedToEscape(): Boolean {
58 | return false
59 | }
60 |
61 | override fun copyModeChanged(copyMode: Boolean) {
62 | }
63 |
64 | override fun onKeyDown(keyCode: Int, e: KeyEvent?, session: TerminalSession?): Boolean {
65 | return false
66 | }
67 |
68 | override fun onKeyUp(keyCode: Int, e: KeyEvent?): Boolean {
69 | return false
70 | }
71 |
72 | override fun readControlKey(): Boolean {
73 | return false
74 | }
75 |
76 | override fun readAltKey(): Boolean {
77 | return false
78 | }
79 |
80 | override fun onCodePoint(codePoint: Int, ctrlDown: Boolean, session: TerminalSession?): Boolean {
81 | return false
82 | }
83 |
84 | override fun onLongPress(event: MotionEvent?): Boolean {
85 | return false
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/NeoLang/src/main/java/io/neolang/runtime/types.kt:
--------------------------------------------------------------------------------
1 | package io.neolang.runtime
2 |
3 | /**
4 | * @author kiva
5 | */
6 | class NeoLangArray private constructor(
7 | val elements: List,
8 | override val size: Int = elements.size
9 | ) : Collection {
10 | companion object {
11 | internal class PrimaryElement(val primaryValue: NeoLangValue) : NeoLangArrayElement() {
12 | override fun eval(): NeoLangValue {
13 | return primaryValue
14 | }
15 | }
16 |
17 | internal class BlockElement(val blockContext: NeoLangContext) : NeoLangArrayElement() {
18 | override fun eval(key: String): NeoLangValue {
19 | return blockContext.getAttribute(key)
20 | }
21 |
22 | override fun isBlock(): Boolean {
23 | return true
24 | }
25 | }
26 |
27 | fun createFromContext(context: NeoLangContext): NeoLangArray {
28 | val elements = mutableListOf()
29 | context.getAttributes().entries.forEach {
30 | val index = it.key.toInt()
31 | elements.add(index, PrimaryElement(it.value))
32 | }
33 | context.children.forEach {
34 | val index = it.contextName.toInt()
35 | elements.add(index, BlockElement(it))
36 | }
37 | return NeoLangArray(elements)
38 | }
39 | }
40 |
41 | operator fun get(index: Int): NeoLangArrayElement {
42 | return elements[index]
43 | }
44 |
45 | override fun contains(element: NeoLangArrayElement): Boolean {
46 | return elements.contains(element)
47 | }
48 |
49 | override fun containsAll(elements: Collection): Boolean {
50 | return this.elements.containsAll(elements)
51 | }
52 |
53 | override fun isEmpty(): Boolean {
54 | return size == 0
55 | }
56 |
57 | override fun iterator(): Iterator {
58 | return elements.iterator()
59 | }
60 | }
61 |
62 | /**
63 | * @author kiva
64 | */
65 | open class NeoLangArrayElement {
66 | open fun eval(): NeoLangValue {
67 | return NeoLangValue.UNDEFINED
68 | }
69 |
70 | open fun eval(key: String): NeoLangValue {
71 | return NeoLangValue.UNDEFINED
72 | }
73 |
74 | open fun isBlock(): Boolean {
75 | return false
76 | }
77 | }
78 |
79 | /**
80 | * @author kiva
81 | */
82 | class NeoLangValue(private val rawValue: Any) {
83 | fun asString(): String {
84 | return rawValue.toString()
85 | }
86 |
87 | fun asNumber(): Double {
88 | if (rawValue is Array<*>) {
89 | return 0.0
90 | }
91 |
92 | try {
93 | return rawValue.toString().toDouble()
94 | } catch (e: Throwable) {
95 | return 0.0
96 | }
97 | }
98 |
99 | fun isValid(): Boolean {
100 | return this != UNDEFINED
101 | }
102 |
103 | companion object {
104 | val UNDEFINED = NeoLangValue("")
105 | }
106 | }
107 |
--------------------------------------------------------------------------------