├── termux-shared ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── raw │ │ │ │ ├── bell.ogg │ │ │ │ └── apt_info_script.sh │ │ │ ├── values │ │ │ │ ├── dimens.xml │ │ │ │ ├── colors.xml │ │ │ │ └── themes.xml │ │ │ ├── drawable │ │ │ │ ├── ic_copy.xml │ │ │ │ ├── ic_share.xml │ │ │ │ └── ic_error_notification.xml │ │ │ ├── layout │ │ │ │ ├── markdown_adapter_node_default.xml │ │ │ │ ├── activity_report.xml │ │ │ │ ├── partial_toolbar.xml │ │ │ │ ├── markdown_adapter_node_code_block.xml │ │ │ │ ├── dialog_show_message.xml │ │ │ │ └── activity_text_io.xml │ │ │ ├── menu │ │ │ │ ├── menu_text_io.xml │ │ │ │ └── menu_report.xml │ │ │ └── values-night │ │ │ │ └── themes.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── termux │ │ │ └── shared │ │ │ ├── file │ │ │ └── filesystem │ │ │ │ ├── FileType.java │ │ │ │ ├── NativeDispatcher.java │ │ │ │ ├── FileKey.java │ │ │ │ └── FilePermission.java │ │ │ ├── settings │ │ │ └── properties │ │ │ │ └── SharedPropertiesParser.java │ │ │ ├── crash │ │ │ └── TermuxCrashUtils.java │ │ │ ├── shell │ │ │ ├── TermuxShellEnvironmentClient.java │ │ │ ├── ShellEnvironmentClient.java │ │ │ └── ShellUtils.java │ │ │ ├── models │ │ │ ├── errors │ │ │ │ ├── ResultSenderErrno.java │ │ │ │ ├── FunctionErrno.java │ │ │ │ └── Errno.java │ │ │ └── ReportInfo.java │ │ │ ├── terminal │ │ │ ├── io │ │ │ │ ├── extrakeys │ │ │ │ │ ├── SpecialButton.java │ │ │ │ │ └── SpecialButtonState.java │ │ │ │ ├── BellHandler.java │ │ │ │ └── TerminalExtraKeys.java │ │ │ ├── TermuxTerminalSessionClientBase.java │ │ │ └── TermuxTerminalViewClientBase.java │ │ │ ├── notification │ │ │ └── TermuxNotificationUtils.java │ │ │ └── interact │ │ │ ├── TextInputDialogUtils.java │ │ │ └── MessageDialogUtils.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── termux │ │ └── shared │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── jitpack.yml ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── 02-feature-request.yml │ └── 01-bug-report.yml └── workflows │ ├── run_tests.yml │ ├── gradle-wrapper-validation.yml │ ├── trigger_library_builds_on_jitpack.yml │ └── attach_debug_apks_to_release.yml ├── app ├── dev_keystore.jks ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── drawable │ │ │ │ ├── banner.png │ │ │ │ ├── current_session.xml │ │ │ │ ├── current_session_black.xml │ │ │ │ ├── session_ripple.xml │ │ │ │ ├── session_ripple_black.xml │ │ │ │ ├── session_background_selected.xml │ │ │ │ ├── session_background_black_selected.xml │ │ │ │ ├── terminal_scroll_shape.xml │ │ │ │ ├── ic_new_session.xml │ │ │ │ ├── ic_service_notification.xml │ │ │ │ ├── ic_foreground.xml │ │ │ │ └── ic_settings.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── layout │ │ │ │ ├── activity_settings.xml │ │ │ │ ├── view_terminal_toolbar_extra_keys.xml │ │ │ │ ├── item_terminal_sessions_list.xml │ │ │ │ ├── view_terminal_toolbar_text_input.xml │ │ │ │ └── preference_markdown_text.xml │ │ │ └── xml │ │ │ │ ├── termux_api_preferences.xml │ │ │ │ ├── termux_float_preferences.xml │ │ │ │ ├── termux_tasker_preferences.xml │ │ │ │ ├── termux_widget_preferences.xml │ │ │ │ ├── termux_api_debugging_preferences.xml │ │ │ │ ├── termux_tasker_debugging_preferences.xml │ │ │ │ ├── termux_widget_debugging_preferences.xml │ │ │ │ ├── termux_terminal_view_preferences.xml │ │ │ │ ├── termux_float_debugging_preferences.xml │ │ │ │ ├── termux_preferences.xml │ │ │ │ ├── termux_terminal_io_preferences.xml │ │ │ │ ├── termux_debugging_preferences.xml │ │ │ │ ├── root_preferences.xml │ │ │ │ └── shortcuts.xml │ │ ├── cpp │ │ │ ├── Android.mk │ │ │ ├── termux-bootstrap.c │ │ │ └── termux-bootstrap-zip.S │ │ └── java │ │ │ └── com │ │ │ └── termux │ │ │ └── app │ │ │ ├── terminal │ │ │ └── io │ │ │ │ ├── KeyboardShortcut.java │ │ │ │ ├── TermuxTerminalExtraKeys.java │ │ │ │ └── FullScreenWorkAround.java │ │ │ ├── models │ │ │ └── UserAction.java │ │ │ ├── TermuxApplication.java │ │ │ ├── fragments │ │ │ └── settings │ │ │ │ ├── TermuxPreferencesFragment.java │ │ │ │ ├── TermuxAPIPreferencesFragment.java │ │ │ │ ├── TermuxFloatPreferencesFragment.java │ │ │ │ ├── TermuxTaskerPreferencesFragment.java │ │ │ │ ├── TermuxWidgetPreferencesFragment.java │ │ │ │ ├── termux │ │ │ │ ├── TerminalViewPreferencesFragment.java │ │ │ │ └── TerminalIOPreferencesFragment.java │ │ │ │ ├── termux_api │ │ │ │ └── DebuggingPreferencesFragment.java │ │ │ │ ├── termux_tasker │ │ │ │ └── DebuggingPreferencesFragment.java │ │ │ │ └── termux_widget │ │ │ │ └── DebuggingPreferencesFragment.java │ │ │ └── activities │ │ │ └── HelpActivity.java │ └── test │ │ └── java │ │ └── com │ │ └── termux │ │ ├── app │ │ └── TermuxActivityTest.java │ │ └── filepicker │ │ └── TermuxFileReceiverActivityTest.java └── proguard-rules.pro ├── art ├── ic_launcher2.png ├── ic_launcher2_round.png ├── generate-feature-graphic.sh ├── copy-to-other-apps.sh ├── generate-tv-banner.sh ├── generate-launcher-images.sh ├── ic_launcher.svg ├── generate-big-icon.sh ├── tv-banner.svg └── feature-graphic.svg ├── settings.gradle ├── terminal-view ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ ├── values │ │ │ └── strings.xml │ │ └── drawable │ │ │ ├── text_select_handle_right_material.xml │ │ │ └── text_select_handle_left_material.xml │ │ └── java │ │ └── com │ │ └── termux │ │ └── view │ │ ├── textselection │ │ └── CursorController.java │ │ └── TerminalViewClient.java ├── proguard-rules.pro └── build.gradle ├── terminal-emulator ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── jni │ │ │ └── Android.mk │ │ └── java │ │ │ └── com │ │ │ └── termux │ │ │ └── terminal │ │ │ ├── TerminalOutput.java │ │ │ ├── TerminalSessionClient.java │ │ │ ├── JNI.java │ │ │ ├── TerminalColors.java │ │ │ └── TextStyle.java │ └── test │ │ └── java │ │ └── com │ │ └── termux │ │ └── terminal │ │ ├── HistoryTest.java │ │ ├── ByteQueueTest.java │ │ ├── DeviceControlStringTest.java │ │ ├── WcWidthTest.java │ │ ├── TextStyleTest.java │ │ ├── ScreenBufferTest.java │ │ ├── DecSetTest.java │ │ └── ControlSequenceIntroducerTest.java ├── proguard-rules.pro └── build.gradle ├── fastlane └── metadata │ └── android │ └── en-US │ ├── short_description.txt │ ├── images │ ├── icon.png │ └── phoneScreenshots │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ └── 4.jpg │ └── full_description.txt ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitattributes ├── .editorconfig ├── LICENSE.md ├── .gitignore ├── gradle.properties └── gradlew.bat /termux-shared/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | env: 2 | JITPACK_NDK_VERSION: "21.1.6352462" 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: termux 2 | custom: https://paypal.me/fornwall 3 | -------------------------------------------------------------------------------- /app/dev_keystore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/dev_keystore.jks -------------------------------------------------------------------------------- /art/ic_launcher2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/art/ic_launcher2.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':termux-shared', ':terminal-emulator', ':terminal-view' 2 | -------------------------------------------------------------------------------- /terminal-view/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /art/ic_launcher2_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/art/ic_launcher2_round.png -------------------------------------------------------------------------------- /terminal-emulator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Terminal emulator app with a large set of command line utilities 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/drawable/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/drawable/banner.png -------------------------------------------------------------------------------- /termux-shared/src/main/res/raw/bell.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/termux-shared/src/main/res/raw/bell.ogg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.bat text eol=crlf 3 | *.gradle text eol=lf 4 | *.mk text eol=lf 5 | *.sh text eol=lf 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hax4us/termux-app/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg -------------------------------------------------------------------------------- /terminal-emulator/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | LOCAL_MODULE:= libtermux 4 | LOCAL_SRC_FILES:= termux.c 5 | include $(BUILD_SHARED_LIBRARY) 6 | -------------------------------------------------------------------------------- /app/src/main/cpp/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | LOCAL_MODULE := libtermux-bootstrap 4 | LOCAL_SRC_FILES := termux-bootstrap-zip.S termux-bootstrap.c 5 | include $(BUILD_SHARED_LIBRARY) 6 | -------------------------------------------------------------------------------- /terminal-view/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Paste 3 | Copy 4 | More… 5 | 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Want ask questions about the project? 4 | url: https://github.com/termux/termux-app/discussions 5 | about: Join GitHub Discussions 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/current_session.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /art/generate-feature-graphic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Generating feature graphics to ~/termux-icons/termux-feature-graphic.png..." 4 | mkdir -p ~/termux-icons/ 5 | rsvg-convert feature-graphic.svg > ~/termux-icons/feature-graphic.png 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/current_session_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /termux-shared/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/session_ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/session_ripple_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/session_background_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/session_background_black_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_api_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/cpp/termux-bootstrap.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern jbyte blob[]; 4 | extern int blob_size; 5 | 6 | JNIEXPORT jbyteArray JNICALL Java_com_termux_app_TermuxInstaller_getZip(JNIEnv *env, __attribute__((__unused__)) jobject This) 7 | { 8 | jbyteArray ret = (*env)->NewByteArray(env, blob_size); 9 | (*env)->SetByteArrayRegion(env, ret, 0, blob_size, blob); 10 | return ret; 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_float_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_tasker_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_widget_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/termux/app/terminal/io/KeyboardShortcut.java: -------------------------------------------------------------------------------- 1 | package com.termux.app.terminal.io; 2 | 3 | public class KeyboardShortcut { 4 | 5 | public final int codePoint; 6 | public final int shortcutAction; 7 | 8 | public KeyboardShortcut(int codePoint, int shortcutAction) { 9 | this.codePoint = codePoint; 10 | this.shortcutAction = shortcutAction; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /termux-shared/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | -dontobfuscate 9 | #-renamesourcefileattribute SourceFile 10 | #-keepattributes SourceFile,LineNumberTable 11 | -------------------------------------------------------------------------------- /art/copy-to-other-apps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e -u 3 | 4 | for APP in api boot styling tasker widget; do 5 | APPDIR=../../termux-$APP 6 | for file in ic_foreground ic_launcher; do 7 | cp ../app/src/main/res/drawable/$file.xml \ 8 | $APPDIR/app/src/main/res/drawable/$file.xml 9 | done 10 | 11 | cp ../app/src/main/res/drawable-anydpi-v26/ic_launcher.xml \ 12 | $APPDIR/app/src/main/res/drawable-anydpi-v26/$file.xml 13 | done 14 | -------------------------------------------------------------------------------- /.github/workflows/run_tests.yml: -------------------------------------------------------------------------------- 1 | name: Unit tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - android-10 8 | pull_request: 9 | branches: 10 | - master 11 | - android-10 12 | 13 | jobs: 14 | testing: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Clone repository 18 | uses: actions/checkout@v2 19 | - name: Execute tests 20 | run: | 21 | ./gradlew test 22 | -------------------------------------------------------------------------------- /art/generate-tv-banner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Generating feature graphics to ~/termux-icons/termux-feature-graphic.png..." 4 | mkdir -p ~/termux-icons/ 5 | 6 | # The Android TV banner on google play (1280x720) has same aspect ratio 7 | # as the banner in the app (320x180). 8 | rsvg-convert -w 1280 -h 720 tv-banner.svg > ~/termux-icons/tv-banner.png 9 | rsvg-convert -w 320 -h 180 tv-banner.svg > ../app/src/main/res/drawable/banner.png 10 | -------------------------------------------------------------------------------- /.github/workflows/gradle-wrapper-validation.yml: -------------------------------------------------------------------------------- 1 | name: "Validate Gradle Wrapper" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - android-10 8 | pull_request: 9 | branches: 10 | - master 11 | - android-10 12 | 13 | jobs: 14 | validation: 15 | name: "Validation" 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | - uses: gradle/wrapper-validation-action@v1 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_terminal_toolbar_extra_keys.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8dip 8 | 16dip 9 | 4dip 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_terminal_sessions_list.xml: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/drawable/ic_copy.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/cpp/termux-bootstrap-zip.S: -------------------------------------------------------------------------------- 1 | .global blob 2 | .global blob_size 3 | .section .rodata 4 | blob: 5 | #if defined __i686__ 6 | .incbin "bootstrap-i686.zip" 7 | #elif defined __x86_64__ 8 | .incbin "bootstrap-x86_64.zip" 9 | #elif defined __aarch64__ 10 | .incbin "bootstrap-aarch64.zip" 11 | #elif defined __arm__ 12 | .incbin "bootstrap-arm.zip" 13 | #else 14 | # error Unsupported arch 15 | #endif 16 | 1: 17 | blob_size: 18 | .int 1b - blob 19 | -------------------------------------------------------------------------------- /art/generate-launcher-images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for DENSITY in mdpi hdpi xhdpi xxhdpi xxxhdpi; do 4 | case $DENSITY in 5 | mdpi) SIZE=48;; 6 | hdpi) SIZE=72;; 7 | xhdpi) SIZE=96;; 8 | xxhdpi) SIZE=144;; 9 | xxxhdpi) SIZE=192;; 10 | esac 11 | 12 | FOLDER=../app/src/main/res/mipmap-$DENSITY 13 | mkdir -p $FOLDER 14 | 15 | for FILE in ic_launcher ic_launcher_round; do 16 | PNG=$FOLDER/$FILE.png 17 | rsvg-convert -w $SIZE -h $SIZE $FILE.svg > $PNG 18 | zopflipng -y $PNG $PNG 19 | done 20 | done 21 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_api_debugging_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_tasker_debugging_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_widget_debugging_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Copying and distribution of this file, with or without modification, 2 | # are permitted in any medium without royalty provided this notice is 3 | # preserved. This file is offered as-is, without any warranty. 4 | 5 | # EditorConfig 6 | # http://EditorConfig.org 7 | 8 | # top-most EditorConfig file 9 | root = true 10 | 11 | [*] 12 | end_of_line = lf 13 | insert_final_newline = true 14 | charset = utf-8 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.y{a,}ml] 19 | indent_size = 2 20 | indent_style = space 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/termux/app/models/UserAction.java: -------------------------------------------------------------------------------- 1 | package com.termux.app.models; 2 | 3 | public enum UserAction { 4 | 5 | ABOUT("about"), 6 | CRASH_REPORT("crash report"), 7 | PLUGIN_EXECUTION_COMMAND("plugin execution command"), 8 | REPORT_ISSUE_FROM_TRANSCRIPT("report issue from transcript"); 9 | 10 | private final String name; 11 | 12 | UserAction(final String name) { 13 | this.name = name; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The `termux/termux-app` repository is released under [GPLv3 only](https://www.gnu.org/licenses/gpl-3.0.html) license. 2 | 3 | ### Exceptions 4 | 5 | - [Terminal Emulator for Android](https://github.com/jackpal/Android-Terminal-Emulator) code is used which is released under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). Check [`terminal-view`](terminal-view) and [`terminal-emulator`](terminal-emulator) libraries. 6 | - Check [`termux-shared/LICENSE.md`](termux-shared/LICENSE.md) for `termux-shared` library related exceptions. 7 | -------------------------------------------------------------------------------- /terminal-view/src/main/res/drawable/text_select_handle_right_material.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/terminal_scroll_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /terminal-view/src/main/res/drawable/text_select_handle_left_material.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /art/ic_launcher.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /art/generate-big-icon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e -u 3 | 4 | echo "Generating ~/termux-icons/ic_launcher.png..." 5 | mkdir -p ~/termux-icons/ 6 | 7 | vector2svg ../app/src/main/res/drawable/ic_launcher.xml ~/termux-icons/ic_launcher.svg 8 | 9 | sed -i "" 's/viewBox="0 0 108 108"/viewBox="18 18 72 72"/' ~/termux-icons/ic_launcher.svg 10 | 11 | SIZE=512 12 | rsvg-convert \ 13 | -w $SIZE \ 14 | -h $SIZE \ 15 | -o ~/termux-icons/ic_launcher_$SIZE.png \ 16 | ~/termux-icons/ic_launcher.svg 17 | 18 | rsvg-convert \ 19 | -b black \ 20 | -w $SIZE \ 21 | -h $SIZE \ 22 | -o ~/termux-icons/ic_launcher_square_$SIZE.png \ 23 | ~/termux-icons/ic_launcher.svg 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02-feature-request.yml: -------------------------------------------------------------------------------- 1 | name: "Feature request" 2 | description: "Suggest a new feature for Termux application" 3 | title: "[Feature]: " 4 | labels: ["feature request"] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Feature description 9 | description: Describe the feature and why you want it. 10 | validations: 11 | required: true 12 | - type: textarea 13 | attributes: 14 | label: Additional information 15 | description: | 16 | Does another app/terminal emulator have this feature? 17 | Provide links to more background information. 18 | validations: 19 | required: true 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # From https://gist.github.com/iainconnor/8605514 2 | # with the addition of the /captures below. 3 | /captures 4 | 5 | # Built application files 6 | build/ 7 | release/ 8 | *.apk 9 | *.so 10 | .externalNativeBuild 11 | .cxx 12 | *.zip 13 | 14 | # Crashlytics configuations 15 | com_crashlytics_export_strings.xml 16 | 17 | # Local configuration file (sdk path, etc) 18 | local.properties 19 | 20 | # Gradle generated files 21 | .gradle/ 22 | 23 | # Signing files 24 | .signing/ 25 | 26 | # Intellij 27 | .idea/ 28 | *.iml 29 | 30 | # OS-specific files 31 | .DS_Store 32 | .DS_Store? 33 | ._* 34 | .Spotlight-V100 35 | .Trashes 36 | .swp 37 | ehthumbs.db 38 | Thumbs.db 39 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_terminal_view_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #1F000000 4 | #0F000000 5 | 6 | #FF000000 7 | #FFFFFFFF 8 | 9 | #FF0000 10 | #C4001D 11 | 12 | #EEEEEE 13 | #424242 14 | #212121 15 | 16 | #DC143C 17 | #FC143C 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_new_session.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/layout/markdown_adapter_node_default.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_terminal_toolbar_text_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/menu/menu_text_io.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 14 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | -dontobfuscate 11 | #-renamesourcefileattribute SourceFile 12 | #-keepattributes SourceFile,LineNumberTable 13 | 14 | # Temp fix for androidx.window:window:1.0.0-alpha09 imported by termux-shared 15 | # https://issuetracker.google.com/issues/189001730 16 | # https://android-review.googlesource.com/c/platform/frameworks/support/+/1757630 17 | -keep class androidx.window.** { *; } 18 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/menu/menu_report.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 15 | 16 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_service_notification.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | 12 | 14 | 15 | 18 | 19 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /art/tv-banner.svg: -------------------------------------------------------------------------------- 1 | 2 | 10 | 13 | 14 | 15 | 16 | 20 | Termux ▌ 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/layout/activity_report.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_float_debugging_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_foreground.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 18 | 19 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /termux-shared/src/androidTest/java/com/termux/shared/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.termux.shared.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/file/filesystem/FileType.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.file.filesystem; 2 | 3 | /** The {@link Enum} that defines file types. */ 4 | public enum FileType { 5 | 6 | NO_EXIST("no exist", 0), // 0000000 7 | REGULAR("regular", 1), // 0000001 8 | DIRECTORY("directory", 2), // 0000010 9 | SYMLINK("symlink", 4), // 0000100 10 | CHARACTER("character", 8), // 0001000 11 | FIFO("fifo", 16), // 0010000 12 | BLOCK("block", 32), // 0100000 13 | UNKNOWN("unknown", 64); // 1000000 14 | 15 | private final String name; 16 | private final int value; 17 | 18 | FileType(final String name, final int value) { 19 | this.name = name; 20 | this.value = value; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public int getValue() { 28 | return value; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/preference_markdown_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 11 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## Project-wide Gradle settings. 2 | # 3 | # For more details on how to configure your build environment visit 4 | # http://www.gradle.org/docs/current/userguide/build_environment.html 5 | # 6 | # Specifies the JVM arguments used for the daemon process. 7 | # The setting is particularly useful for tweaking memory settings. 8 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 10 | # 11 | # When configured, Gradle will run in incubating parallel mode. 12 | # This option should only be used with decoupled projects. More details, visit 13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 14 | # org.gradle.parallel=true 15 | org.gradle.jvmargs=-Xmx2048M 16 | android.useAndroidX=true 17 | 18 | minSdkVersion=24 19 | targetSdkVersion=28 20 | ndkVersion=22.1.7171670 21 | compileSdkVersion=30 22 | 23 | markwonVersion=4.6.2 24 | 25 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_terminal_io_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/layout/partial_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/settings/properties/SharedPropertiesParser.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.settings.properties; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.HashMap; 6 | 7 | /** 8 | * An interface that must be defined by the caller of the {@link SharedProperties} class. 9 | */ 10 | public interface SharedPropertiesParser { 11 | 12 | /** 13 | * A function that should return the internal {@link Object} to be stored for a key/value pair 14 | * read from properties file in the {@link HashMap <>} in-memory cache. 15 | * 16 | * @param context The context for operations. 17 | * @param key The key for which the internal object is required. 18 | * @param value The literal value for the property found is the properties file. 19 | * @return Returns the {@link Object} object to store in the {@link HashMap <>} in-memory cache. 20 | */ 21 | Object getInternalPropertyValueFromValue(Context context, String key, String value); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /terminal-view/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/fornwall/lib/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /terminal-emulator/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/fornwall/lib/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/termux/app/TermuxApplication.java: -------------------------------------------------------------------------------- 1 | package com.termux.app; 2 | 3 | import android.app.Application; 4 | 5 | import com.termux.shared.crash.TermuxCrashUtils; 6 | import com.termux.shared.settings.preferences.TermuxAppSharedPreferences; 7 | import com.termux.shared.logger.Logger; 8 | 9 | 10 | public class TermuxApplication extends Application { 11 | public void onCreate() { 12 | super.onCreate(); 13 | 14 | // Set crash handler for the app 15 | TermuxCrashUtils.setCrashHandler(this); 16 | 17 | // Set log level for the app 18 | setLogLevel(); 19 | } 20 | 21 | private void setLogLevel() { 22 | // Load the log level from shared preferences and set it to the {@link Logger.CURRENT_LOG_LEVEL} 23 | TermuxAppSharedPreferences preferences = TermuxAppSharedPreferences.build(getApplicationContext()); 24 | if (preferences == null) return; 25 | preferences.setLogLevel(null, preferences.getLogLevel()); 26 | Logger.logDebug("Starting Application"); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /art/feature-graphic.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 15 | 16 | 17 | 18 | 22 | 27 | $ Termux █ 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/crash/TermuxCrashUtils.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.crash; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.termux.shared.termux.TermuxConstants; 8 | import com.termux.shared.termux.TermuxUtils; 9 | 10 | public class TermuxCrashUtils implements CrashHandler.CrashHandlerClient { 11 | 12 | /** 13 | * Set default uncaught crash handler of current thread to {@link CrashHandler} for Termux app 14 | * and its plugin to log crashes at {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}. 15 | */ 16 | public static void setCrashHandler(@NonNull final Context context) { 17 | CrashHandler.setCrashHandler(context, new TermuxCrashUtils()); 18 | } 19 | 20 | @NonNull 21 | @Override 22 | public String getCrashLogFilePath(Context context) { 23 | return TermuxConstants.TERMUX_CRASH_LOG_FILE_PATH; 24 | } 25 | 26 | @Override 27 | public String getAppInfoMarkdownString(Context context) { 28 | return TermuxUtils.getAppInfoMarkdownString(context, true); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/shell/TermuxShellEnvironmentClient.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.shell; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | public class TermuxShellEnvironmentClient implements ShellEnvironmentClient { 8 | 9 | @NonNull 10 | @Override 11 | public String getDefaultWorkingDirectoryPath() { 12 | return TermuxShellUtils.getDefaultWorkingDirectoryPath(); 13 | } 14 | 15 | @NonNull 16 | @Override 17 | public String getDefaultBinPath() { 18 | return TermuxShellUtils.getDefaultBinPath(); 19 | } 20 | 21 | @NonNull 22 | @Override 23 | public String[] buildEnvironment(Context currentPackageContext, boolean isFailSafe, String workingDirectory) { 24 | return TermuxShellUtils.buildEnvironment(currentPackageContext, isFailSafe, workingDirectory); 25 | } 26 | 27 | @NonNull 28 | @Override 29 | public String[] setupProcessArgs(@NonNull String fileToExecute, String[] arguments) { 30 | return TermuxShellUtils.setupProcessArgs(fileToExecute, arguments); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/layout/markdown_adapter_node_code_block.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/models/errors/ResultSenderErrno.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.models.errors; 2 | 3 | /** The {@link Class} that defines ResultSender error messages and codes. */ 4 | public class ResultSenderErrno extends Errno { 5 | 6 | public static final String TYPE = "ResultSender Error"; 7 | 8 | 9 | /* Errors for null or empty parameters (100-150) */ 10 | public static final Errno ERROR_RESULT_FILE_BASENAME_NULL_OR_INVALID = new Errno(TYPE, 100, "The result file basename \"%1$s\" is null, empty or contains forward slashes \"/\"."); 11 | public static final Errno ERROR_RESULT_FILES_SUFFIX_INVALID = new Errno(TYPE, 101, "The result files suffix \"%1$s\" contains forward slashes \"/\"."); 12 | public static final Errno ERROR_FORMAT_RESULT_ERROR_FAILED_WITH_EXCEPTION = new Errno(TYPE, 102, "Formatting result error failed.\nException: %1$s"); 13 | public static final Errno ERROR_FORMAT_RESULT_OUTPUT_FAILED_WITH_EXCEPTION = new Errno(TYPE, 103, "Formatting result output failed.\nException: %1$s"); 14 | 15 | 16 | ResultSenderErrno(final String type, final int code, final String message) { 17 | super(type, code, message); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/models/errors/FunctionErrno.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.models.errors; 2 | 3 | /** The {@link Class} that defines function error messages and codes. */ 4 | public class FunctionErrno extends Errno { 5 | 6 | public static final String TYPE = "Function Error"; 7 | 8 | 9 | /* Errors for null or empty parameters (100-150) */ 10 | public static final Errno ERRNO_NULL_OR_EMPTY_PARAMETER = new Errno(TYPE, 100, "The %1$s parameter passed to \"%2$s\" is null or empty."); 11 | public static final Errno ERRNO_NULL_OR_EMPTY_PARAMETERS = new Errno(TYPE, 101, "The %1$s parameters passed to \"%2$s\" are null or empty."); 12 | public static final Errno ERRNO_UNSET_PARAMETER = new Errno(TYPE, 102, "The %1$s parameter passed to \"%2$s\" must be set."); 13 | public static final Errno ERRNO_UNSET_PARAMETERS = new Errno(TYPE, 103, "The %1$s parameters passed to \"%2$s\" must be set."); 14 | public static final Errno ERRNO_INVALID_PARAMETER = new Errno(TYPE, 104, "The %1$s parameter passed to \"%2$s\" is invalid.\"%3$s\""); 15 | 16 | 17 | FunctionErrno(final String type, final int code, final String message) { 18 | super(type, code, message); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/trigger_library_builds_on_jitpack.yml: -------------------------------------------------------------------------------- 1 | name: Trigger Termux Library Builds on Jitpack 2 | 3 | on: 4 | release: 5 | types: 6 | - published 7 | 8 | jobs: 9 | trigger-termux-library-builds: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Set vars 13 | run: echo "TERMUX_LIB_VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV # Do not include "v" prefix 14 | - name: Echo release 15 | run: echo "Triggering termux library builds on jitpack for '$TERMUX_LIB_VERSION' release after waiting for 3 mins" 16 | - name: Trigger termux library builds on jitpack 17 | run: | 18 | sleep 180 # It will take some time for the new tag to be detected by Jitpack 19 | curl --max-time 600 --no-progress-meter "https://jitpack.io/com/termux/termux-app/terminal-emulator/$TERMUX_LIB_VERSION/terminal-emulator-$TERMUX_LIB_VERSION.pom" 20 | curl --max-time 600 --no-progress-meter "https://jitpack.io/com/termux/termux-app/terminal-view/$TERMUX_LIB_VERSION/terminal-view-$TERMUX_LIB_VERSION.pom" 21 | curl --max-time 600 --no-progress-meter "https://jitpack.io/com/termux/termux-app/termux-shared/$TERMUX_LIB_VERSION/termux-shared-$TERMUX_LIB_VERSION.pom" 22 | -------------------------------------------------------------------------------- /app/src/test/java/com/termux/app/TermuxActivityTest.java: -------------------------------------------------------------------------------- 1 | package com.termux.app; 2 | 3 | import com.termux.shared.data.UrlUtils; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | import java.util.Collections; 9 | import java.util.LinkedHashSet; 10 | 11 | public class TermuxActivityTest { 12 | 13 | private void assertUrlsAre(String text, String... urls) { 14 | LinkedHashSet expected = new LinkedHashSet<>(); 15 | Collections.addAll(expected, urls); 16 | Assert.assertEquals(expected, UrlUtils.extractUrls(text)); 17 | } 18 | 19 | @Test 20 | public void testExtractUrls() { 21 | assertUrlsAre("hello http://example.com world", "http://example.com"); 22 | 23 | assertUrlsAre("http://example.com\nhttp://another.com", "http://example.com", "http://another.com"); 24 | 25 | assertUrlsAre("hello http://example.com world and http://more.example.com with secure https://more.example.com", 26 | "http://example.com", "http://more.example.com", "https://more.example.com"); 27 | 28 | assertUrlsAre("hello https://example.com/#bar https://example.com/foo#bar", 29 | "https://example.com/#bar", "https://example.com/foo#bar"); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | Termux is a terminal emulator application enhanced with a large set of command line utilities ported to Android OS. The main goal is to bring a Linux command line experience to users of mobile devices with no rooting or other special setup required. 2 | 3 | * Enjoy the Bash and Zsh shells. 4 | * Edit files with nano and vim. 5 | * Access servers over SSH. 6 | * Compile C/C++ code with clang. 7 | * Use the Python console as a pocket calculator. 8 | * Check out projects with Git and Subversion. 9 | * Run text-based games with frotz. 10 | 11 | At first start a small base system is being configured. The GNU Bash, Coreutils, Findutils and other core utilities are available out-of-box. Additionally, we provide more than 1000 other packages installable by using the 'pkg' utility which currently is a frontend for the 'apt' package manager. All provided software has been patched and compiled with Android NDK to provide max compatibility with Android OS. 12 | 13 | To learn more about application usage tips and tricks, long-press anywhere on the terminal and select the Help menu option to access Termux Wiki. This resource is also accessible directly in a web browser: https://wiki.termux.com/wiki/Main_Page. 14 | -------------------------------------------------------------------------------- /terminal-emulator/src/test/java/com/termux/terminal/HistoryTest.java: -------------------------------------------------------------------------------- 1 | package com.termux.terminal; 2 | 3 | 4 | public class HistoryTest extends TerminalTestCase { 5 | 6 | public void testHistory() { 7 | final int rows = 3; 8 | final int cols = 3; 9 | withTerminalSized(cols, rows).enterString("111222333444555666777888999"); 10 | assertCursorAt(2, 2); 11 | assertLinesAre("777", "888", "999"); 12 | assertHistoryStartsWith("666", "555"); 13 | 14 | mTerminal.resize(cols, 2); 15 | assertHistoryStartsWith("777", "666", "555"); 16 | 17 | mTerminal.resize(cols, 3); 18 | assertHistoryStartsWith("666", "555"); 19 | } 20 | 21 | public void testHistoryWithScrollRegion() { 22 | // "CSI P_s ; P_s r" - set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM). 23 | withTerminalSized(3, 4).enterString("111222333444"); 24 | assertLinesAre("111", "222", "333", "444"); 25 | enterString("\033[2;3r"); 26 | // NOTE: "DECSTBM moves the cursor to column 1, line 1 of the page." 27 | assertCursorAt(0, 0); 28 | enterString("\nCDEFGH").assertLinesAre("111", "CDE", "FGH", "444"); 29 | enterString("IJK").assertLinesAre("111", "FGH", "IJK", "444").assertHistoryStartsWith("CDE"); 30 | enterString("LMN").assertLinesAre("111", "IJK", "LMN", "444").assertHistoryStartsWith("FGH", "CDE"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/test/java/com/termux/filepicker/TermuxFileReceiverActivityTest.java: -------------------------------------------------------------------------------- 1 | package com.termux.filepicker; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.robolectric.RobolectricTestRunner; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @RunWith(RobolectricTestRunner.class) 12 | public class TermuxFileReceiverActivityTest { 13 | 14 | @Test 15 | public void testIsSharedTextAnUrl() { 16 | List validUrls = new ArrayList<>(); 17 | validUrls.add("http://example.com"); 18 | validUrls.add("https://example.com"); 19 | validUrls.add("https://example.com/path/parameter=foo"); 20 | validUrls.add("magnet:?xt=urn:btih:d540fc48eb12f2833163eed6421d449dd8f1ce1f&dn=Ubuntu+desktop+19.04+%2864bit%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80"); 21 | for (String url : validUrls) { 22 | Assert.assertTrue(TermuxFileReceiverActivity.isSharedTextAnUrl(url)); 23 | } 24 | 25 | List invalidUrls = new ArrayList<>(); 26 | invalidUrls.add("a test with example.com"); 27 | for (String url : invalidUrls) { 28 | Assert.assertFalse(TermuxFileReceiverActivity.isSharedTextAnUrl(url)); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/drawable/ic_error_notification.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | 12 | 14 | 15 | 18 | 19 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /terminal-emulator/src/main/java/com/termux/terminal/TerminalOutput.java: -------------------------------------------------------------------------------- 1 | package com.termux.terminal; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | 5 | /** A client which receives callbacks from events triggered by feeding input to a {@link TerminalEmulator}. */ 6 | public abstract class TerminalOutput { 7 | 8 | /** Write a string using the UTF-8 encoding to the terminal client. */ 9 | public final void write(String data) { 10 | if (data == null) return; 11 | byte[] bytes = data.getBytes(StandardCharsets.UTF_8); 12 | write(bytes, 0, bytes.length); 13 | } 14 | 15 | /** Write bytes to the terminal client. */ 16 | public abstract void write(byte[] data, int offset, int count); 17 | 18 | /** Notify the terminal client that the terminal title has changed. */ 19 | public abstract void titleChanged(String oldTitle, String newTitle); 20 | 21 | /** Notify the terminal client that text should be copied to clipboard. */ 22 | public abstract void onCopyTextToClipboard(String text); 23 | 24 | /** Notify the terminal client that text should be pasted from clipboard. */ 25 | public abstract void onPasteTextFromClipboard(); 26 | 27 | /** Notify the terminal client that a bell character (ASCII 7, bell, BEL, \a, ^G)) has been received. */ 28 | public abstract void onBell(); 29 | 30 | public abstract void onColorsChanged(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /terminal-emulator/src/main/java/com/termux/terminal/TerminalSessionClient.java: -------------------------------------------------------------------------------- 1 | package com.termux.terminal; 2 | 3 | /** 4 | * The interface for communication between {@link TerminalSession} and its client. It is used to 5 | * send callbacks to the client when {@link TerminalSession} changes or for sending other 6 | * back data to the client like logs. 7 | */ 8 | public interface TerminalSessionClient { 9 | 10 | void onTextChanged(TerminalSession changedSession); 11 | 12 | void onTitleChanged(TerminalSession changedSession); 13 | 14 | void onSessionFinished(TerminalSession finishedSession); 15 | 16 | void onCopyTextToClipboard(TerminalSession session, String text); 17 | 18 | void onPasteTextFromClipboard(TerminalSession session); 19 | 20 | void onBell(TerminalSession session); 21 | 22 | void onColorsChanged(TerminalSession session); 23 | 24 | void onTerminalCursorStateChange(boolean state); 25 | 26 | 27 | 28 | Integer getTerminalCursorStyle(); 29 | 30 | 31 | 32 | void logError(String tag, String message); 33 | 34 | void logWarn(String tag, String message); 35 | 36 | void logInfo(String tag, String message); 37 | 38 | void logDebug(String tag, String message); 39 | 40 | void logVerbose(String tag, String message); 41 | 42 | void logStackTraceWithMessage(String tag, String message, Exception e); 43 | 44 | void logStackTrace(String tag, Exception e); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /termux-shared/src/main/res/raw/apt_info_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | subscribed_repositories() { 4 | local main_sources 5 | main_sources=$(grep -P '^\s*deb\s' "@TERMUX_PREFIX@/etc/apt/sources.list") 6 | 7 | if [ -n "$main_sources" ]; then 8 | echo "#### sources.list" 9 | echo "\`$main_sources\`" 10 | fi 11 | 12 | local filename repo_package supl_sources 13 | while read -r filename; do 14 | repo_package=$(dpkg -S "$filename" 2>/dev/null | cut -d : -f 1) 15 | supl_sources=$(grep -P '^\s*deb\s' "$filename") 16 | 17 | if [ -n "$supl_sources" ]; then 18 | if [ -n "$repo_package" ]; then 19 | echo "#### $repo_package (sources.list.d/$(basename "$filename"))" 20 | else 21 | echo "#### sources.list.d/$(basename "$filename")" 22 | fi 23 | echo "\`$supl_sources\` " 24 | fi 25 | done < <(find "@TERMUX_PREFIX@/etc/apt/sources.list.d" -maxdepth 1 ! -type d) 26 | } 27 | 28 | updatable_packages() { 29 | local updatable 30 | 31 | if [ "$(id -u)" = "0" ]; then 32 | echo "Running as root. Cannot check updatable packages." 33 | else 34 | apt update >/dev/null 2>&1 35 | updatable=$(apt list --upgradable 2>/dev/null | tail -n +2) 36 | 37 | if [ -z "$updatable" ];then 38 | echo "All packages up to date" 39 | else 40 | echo $'```\n'"$updatable"$'\n```\n' 41 | fi 42 | fi 43 | } 44 | 45 | output=" 46 | ### Subscribed Repositories 47 | 48 | $(subscribed_repositories) 49 | ## 50 | 51 | 52 | ### Updatable Packages 53 | 54 | $(updatable_packages) 55 | ## 56 | 57 | " 58 | 59 | echo "$output" 60 | -------------------------------------------------------------------------------- /app/src/main/res/xml/termux_debugging_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 12 | 13 | 18 | 19 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /terminal-view/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'maven-publish' 3 | 4 | android { 5 | compileSdkVersion project.properties.compileSdkVersion.toInteger() 6 | 7 | dependencies { 8 | implementation "androidx.annotation:annotation:1.3.0" 9 | api project(":terminal-emulator") 10 | } 11 | 12 | defaultConfig { 13 | minSdkVersion project.properties.minSdkVersion.toInteger() 14 | targetSdkVersion project.properties.targetSdkVersion.toInteger() 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_1_8 27 | targetCompatibility JavaVersion.VERSION_1_8 28 | } 29 | } 30 | 31 | dependencies { 32 | testImplementation 'junit:junit:4.13.2' 33 | } 34 | 35 | task sourceJar(type: Jar) { 36 | from android.sourceSets.main.java.srcDirs 37 | classifier "sources" 38 | } 39 | 40 | afterEvaluate { 41 | publishing { 42 | publications { 43 | // Creates a Maven publication called "release". 44 | release(MavenPublication) { 45 | from components.release 46 | groupId = 'com.termux' 47 | artifactId = 'terminal-view' 48 | version = '0.118.0' 49 | artifact(sourceJar) 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/shell/ShellEnvironmentClient.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.shell; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | public interface ShellEnvironmentClient { 8 | 9 | /** 10 | * Get the default working directory path for the environment in case the path that was passed 11 | * was {@code null} or empty. 12 | * 13 | * @return Should return the default working directory path. 14 | */ 15 | @NonNull 16 | String getDefaultWorkingDirectoryPath(); 17 | 18 | /** 19 | * Get the default "/bin" path, likely $PREFIX/bin. 20 | * 21 | * @return Should return the "/bin" path. 22 | */ 23 | @NonNull 24 | String getDefaultBinPath(); 25 | 26 | /** 27 | * Build the shell environment to be used for commands. 28 | * 29 | * @param currentPackageContext The {@link Context} for the current package. 30 | * @param isFailSafe If running a failsafe session. 31 | * @param workingDirectory The working directory for the environment. 32 | * @return Should return the build environment. 33 | */ 34 | @NonNull 35 | String[] buildEnvironment(Context currentPackageContext, boolean isFailSafe, String workingDirectory); 36 | 37 | /** 38 | * Setup process arguments for the file to execute, like interpreter, etc. 39 | * 40 | * @param fileToExecute The file to execute. 41 | * @param arguments The arguments to pass to the executable. 42 | * @return Should return the final process arguments. 43 | */ 44 | @NonNull 45 | String[] setupProcessArgs(@NonNull String fileToExecute, String[] arguments); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/termux/app/fragments/settings/TermuxPreferencesFragment.java: -------------------------------------------------------------------------------- 1 | package com.termux.app.fragments.settings; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.Keep; 7 | import androidx.preference.PreferenceDataStore; 8 | import androidx.preference.PreferenceFragmentCompat; 9 | import androidx.preference.PreferenceManager; 10 | 11 | import com.termux.R; 12 | import com.termux.shared.settings.preferences.TermuxAppSharedPreferences; 13 | 14 | @Keep 15 | public class TermuxPreferencesFragment extends PreferenceFragmentCompat { 16 | 17 | @Override 18 | public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 19 | Context context = getContext(); 20 | if (context == null) return; 21 | 22 | PreferenceManager preferenceManager = getPreferenceManager(); 23 | preferenceManager.setPreferenceDataStore(TermuxPreferencesDataStore.getInstance(context)); 24 | 25 | setPreferencesFromResource(R.xml.termux_preferences, rootKey); 26 | } 27 | 28 | } 29 | 30 | class TermuxPreferencesDataStore extends PreferenceDataStore { 31 | 32 | private final Context mContext; 33 | private final TermuxAppSharedPreferences mPreferences; 34 | 35 | private static TermuxPreferencesDataStore mInstance; 36 | 37 | private TermuxPreferencesDataStore(Context context) { 38 | mContext = context; 39 | mPreferences = TermuxAppSharedPreferences.build(context, true); 40 | } 41 | 42 | public static synchronized TermuxPreferencesDataStore getInstance(Context context) { 43 | if (mInstance == null) { 44 | mInstance = new TermuxPreferencesDataStore(context); 45 | } 46 | return mInstance; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /terminal-view/src/main/java/com/termux/view/textselection/CursorController.java: -------------------------------------------------------------------------------- 1 | package com.termux.view.textselection; 2 | 3 | import android.view.MotionEvent; 4 | import android.view.ViewTreeObserver; 5 | 6 | import com.termux.view.TerminalView; 7 | 8 | /** 9 | * A CursorController instance can be used to control cursors in the text. 10 | * It is not used outside of {@link TerminalView}. 11 | */ 12 | public interface CursorController extends ViewTreeObserver.OnTouchModeChangeListener { 13 | /** 14 | * Show the cursors on screen. Will be drawn by {@link #render()} by a call during onDraw. 15 | * See also {@link #hide()}. 16 | */ 17 | void show(MotionEvent event); 18 | 19 | /** 20 | * Hide the cursors from screen. 21 | * See also {@link #show(MotionEvent event)}. 22 | */ 23 | boolean hide(); 24 | 25 | /** 26 | * Render the cursors. 27 | */ 28 | void render(); 29 | 30 | /** 31 | * Update the cursor positions. 32 | */ 33 | void updatePosition(TextSelectionHandleView handle, int x, int y); 34 | 35 | /** 36 | * This method is called by {@link #onTouchEvent(MotionEvent)} and gives the cursors 37 | * a chance to become active and/or visible. 38 | * 39 | * @param event The touch event 40 | */ 41 | boolean onTouchEvent(MotionEvent event); 42 | 43 | /** 44 | * Called when the view is detached from window. Perform house keeping task, such as 45 | * stopping Runnable thread that would otherwise keep a reference on the context, thus 46 | * preventing the activity to be recycled. 47 | */ 48 | void onDetached(); 49 | 50 | /** 51 | * @return true if the cursors are currently active. 52 | */ 53 | boolean isActive(); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/SpecialButton.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.terminal.io.extrakeys; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.util.HashMap; 6 | 7 | /** The {@link Class} that implements special buttons for {@link ExtraKeysView}. */ 8 | public class SpecialButton { 9 | 10 | private static final HashMap map = new HashMap<>(); 11 | 12 | public static final SpecialButton CTRL = new SpecialButton("CTRL"); 13 | public static final SpecialButton ALT = new SpecialButton("ALT"); 14 | public static final SpecialButton SHIFT = new SpecialButton("SHIFT"); 15 | public static final SpecialButton FN = new SpecialButton("FN"); 16 | 17 | /** The special button key. */ 18 | private final String key; 19 | 20 | /** 21 | * Initialize a {@link SpecialButton}. 22 | * 23 | * @param key The unique key name for the special button. The key is registered in {@link #map} 24 | * with which the {@link SpecialButton} can be retrieved via a call to 25 | * {@link #valueOf(String)}. 26 | */ 27 | public SpecialButton(@NonNull final String key) { 28 | this.key = key; 29 | map.put(key, this); 30 | } 31 | 32 | /** Get {@link #key} for this {@link SpecialButton}. */ 33 | public String getKey() { 34 | return key; 35 | } 36 | 37 | /** 38 | * Get the {@link SpecialButton} for {@code key}. 39 | * 40 | * @param key The unique key name for the special button. 41 | */ 42 | public static SpecialButton valueOf(String key) { 43 | return map.get(key); 44 | } 45 | 46 | @NonNull 47 | @Override 48 | public String toString() { 49 | return key; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /termux-shared/src/main/java/com/termux/shared/terminal/io/extrakeys/SpecialButtonState.java: -------------------------------------------------------------------------------- 1 | package com.termux.shared.terminal.io.extrakeys; 2 | 3 | import android.widget.Button; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** The {@link Class} that maintains a state of a {@link SpecialButton} */ 9 | public class SpecialButtonState { 10 | 11 | /** If special button has been created for the {@link ExtraKeysView}. */ 12 | boolean isCreated = false; 13 | /** If special button is active. */ 14 | boolean isActive = false; 15 | /** If special button is locked due to long hold on it and should not be deactivated if its 16 | * state is read. */ 17 | boolean isLocked = false; 18 | 19 | List