mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 10:45:23 +08:00
@@ -12,7 +12,7 @@ android:
|
||||
components:
|
||||
- platform-tools
|
||||
- tools
|
||||
- build-tools-25.0.2
|
||||
- build-tools-26.0.0
|
||||
- android-25
|
||||
- extra-android-m2repository
|
||||
|
||||
|
@@ -7,6 +7,7 @@ Termux app
|
||||
|
||||
* [Termux on Google Play Store](https://play.google.com/store/apps/details?id=com.termux)
|
||||
* [Termux on F-Droid](https://f-droid.org/repository/browse/?fdid=com.termux)
|
||||
* [Termux Wiki](https://wiki.termux.com/wiki/)
|
||||
* [Termux Help](http://termux.com/help/)
|
||||
* [Termux Google+ community](http://termux.com/community/)
|
||||
|
||||
|
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.2"
|
||||
buildToolsVersion "26.0.0"
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:support-annotations:25.3.1'
|
||||
@@ -14,8 +14,8 @@ android {
|
||||
applicationId "com.termux"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 48
|
||||
versionName "0.48"
|
||||
versionCode 53
|
||||
versionName "0.53"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
@@ -13,7 +13,7 @@
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
<application
|
||||
android:extractNativeLibs="false"
|
||||
android:extractNativeLibs="true"
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backupscheme"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@@ -76,6 +76,18 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity-alias
|
||||
android:name=".HomeActivity"
|
||||
android:targetActivity="com.termux.app.TermuxActivity">
|
||||
|
||||
<!-- Launch activity automatically on boot on Android Things devices -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.IOT_LAUNCHER"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<provider
|
||||
android:name=".filepicker.TermuxDocumentsProvider"
|
||||
android:authorities="com.termux.documents"
|
||||
@@ -99,6 +111,7 @@
|
||||
android:grantUriPermissions="true"
|
||||
android:name="com.termux.app.TermuxOpenReceiver$ContentProvider" />
|
||||
|
||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@@ -116,8 +116,9 @@ public final class BackgroundJob {
|
||||
final String langEnv = "LANG=en_US.UTF-8";
|
||||
final String pathEnv = "PATH=" + TermuxService.PREFIX_PATH + "/bin:" + TermuxService.PREFIX_PATH + "/bin/applets";
|
||||
final String pwdEnv = "PWD=" + cwd;
|
||||
final String tmpdirEnv = "TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp";
|
||||
|
||||
return new String[]{termEnv, homeEnv, prefixEnv, ps1Env, ldEnv, langEnv, pathEnv, pwdEnv, androidRootEnv, androidDataEnv, externalStorageEnv};
|
||||
return new String[]{termEnv, homeEnv, prefixEnv, ps1Env, ldEnv, langEnv, pathEnv, pwdEnv, androidRootEnv, androidDataEnv, externalStorageEnv, tmpdirEnv};
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -397,7 +397,6 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
@Override
|
||||
public void onClipboardText(TerminalSession session, String text) {
|
||||
if (!mIsVisible) return;
|
||||
showToast("Clipboard:\n\"" + text + "\"", false);
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
clipboard.setPrimaryClip(new ClipData(null, new String[]{"text/plain"}, new ClipData.Item(text)));
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.1'
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Mon Mar 06 01:34:12 CET 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
|
||||
|
6
gradlew
vendored
6
gradlew
vendored
@@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
@@ -155,7 +155,7 @@ if $cygwin ; then
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save ( ) {
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
|
@@ -13,12 +13,12 @@ ext {
|
||||
libraryDescription = 'The terminal emulator used in Termux'
|
||||
siteUrl = 'https://github.com/termux/termux'
|
||||
gitUrl = 'https://github.com/termux/termux.git'
|
||||
libraryVersion = '0.49'
|
||||
libraryVersion = '0.50'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.2"
|
||||
buildToolsVersion "26.0.0"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
|
@@ -1,3 +1,2 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.termux.terminal">
|
||||
<manifest package="com.termux.terminal">
|
||||
</manifest>
|
||||
|
@@ -223,6 +223,7 @@ public final class TerminalEmulator {
|
||||
|
||||
private byte mUtf8ToFollow, mUtf8Index;
|
||||
private final byte[] mUtf8InputBuffer = new byte[4];
|
||||
private int mLastEmittedCodePoint = -1;
|
||||
|
||||
public final TerminalColors mColors = new TerminalColors();
|
||||
|
||||
@@ -419,10 +420,11 @@ public final class TerminalEmulator {
|
||||
mUtf8Index = mUtf8ToFollow = 0;
|
||||
|
||||
if (codePoint >= 0x80 && codePoint <= 0x9F) {
|
||||
// Sequence decoded to a C1 control character which is the same as escape followed by
|
||||
// ((code & 0x7F) + 0x40).
|
||||
processCodePoint(/* escape (hexadecimal=0x1B, octal=033): */27);
|
||||
processCodePoint((codePoint & 0x7F) + 0x40);
|
||||
// Sequence decoded to a C1 control character which we ignore. They are
|
||||
// not used nowadays and increases the risk of messing up the terminal state
|
||||
// on binary input. XTerm does not allow them in utf-8:
|
||||
// "It is not possible to use a C1 control obtained from decoding the
|
||||
// UTF-8 text" - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
||||
} else {
|
||||
switch (Character.getType(codePoint)) {
|
||||
case Character.UNASSIGNED:
|
||||
@@ -632,6 +634,7 @@ public final class TerminalEmulator {
|
||||
int bottom = Math.min(getArg(2, mRows, true) + 1, effectiveBottomMargin - 1) + effectiveTopMargin;
|
||||
int right = Math.min(getArg(3, mColumns, true) + 1, effectiveRightMargin - 1) + effectiveLeftMargin;
|
||||
if (mArgIndex >= 4) {
|
||||
if (mArgIndex >= mArgs.length) mArgIndex = mArgs.length - 1;
|
||||
for (int i = 4; i <= mArgIndex; i++) {
|
||||
int bits = 0;
|
||||
boolean setOrClear = true; // True if setting, false if clearing.
|
||||
@@ -965,6 +968,7 @@ public final class TerminalEmulator {
|
||||
break;
|
||||
case 'h':
|
||||
case 'l':
|
||||
if (mArgIndex >= mArgs.length) mArgIndex = mArgs.length - 1;
|
||||
for (int i = 0; i <= mArgIndex; i++)
|
||||
doDecSetOrReset(b == 'h', mArgs[i]);
|
||||
break;
|
||||
@@ -981,6 +985,7 @@ public final class TerminalEmulator {
|
||||
break;
|
||||
case 'r':
|
||||
case 's':
|
||||
if (mArgIndex >= mArgs.length) mArgIndex = mArgs.length - 1;
|
||||
for (int i = 0; i <= mArgIndex; i++) {
|
||||
int externalBit = mArgs[i];
|
||||
int internalBit = mapDecSetBitToInternalBit(externalBit);
|
||||
@@ -1307,6 +1312,8 @@ public final class TerminalEmulator {
|
||||
state.mSavedCursorRow = mCursorRow;
|
||||
state.mSavedCursorCol = mCursorCol;
|
||||
state.mSavedEffect = mEffect;
|
||||
state.mSavedForeColor = mForeColor;
|
||||
state.mSavedBackColor = mBackColor;
|
||||
state.mSavedDecFlags = mCurrentDecSetFlags;
|
||||
state.mUseLineDrawingG0 = mUseLineDrawingG0;
|
||||
state.mUseLineDrawingG1 = mUseLineDrawingG1;
|
||||
@@ -1318,6 +1325,8 @@ public final class TerminalEmulator {
|
||||
SavedScreenState state = (mScreen == mMainBuffer) ? mSavedStateMain : mSavedStateAlt;
|
||||
setCursorRowCol(state.mSavedCursorRow, state.mSavedCursorCol);
|
||||
mEffect = state.mSavedEffect;
|
||||
mForeColor = state.mSavedForeColor;
|
||||
mBackColor = state.mSavedBackColor;
|
||||
int mask = (DECSET_BIT_AUTOWRAP | DECSET_BIT_ORIGIN_MODE);
|
||||
mCurrentDecSetFlags = (mCurrentDecSetFlags & ~mask) | (state.mSavedDecFlags & mask);
|
||||
mUseLineDrawingG0 = state.mUseLineDrawingG0;
|
||||
@@ -1501,6 +1510,11 @@ public final class TerminalEmulator {
|
||||
case '`': // Horizontal position absolute (HPA - http://www.vt100.net/docs/vt510-rm/HPA).
|
||||
setCursorColRespectingOriginMode(getArg0(1) - 1);
|
||||
break;
|
||||
case 'b': // Repeat the preceding graphic character Ps times (REP).
|
||||
if (mLastEmittedCodePoint == -1) break;
|
||||
final int numRepeat = getArg0(1);
|
||||
for (int i = 0; i < numRepeat; i++) emitCodePoint(mLastEmittedCodePoint);
|
||||
break;
|
||||
case 'c': // Primary Device Attributes (http://www.vt100.net/docs/vt510-rm/DA1) if argument is missing or zero.
|
||||
// The important part that may still be used by some (tmux stores this value but does not currently use it)
|
||||
// is the first response parameter identifying the terminal service class, where we send 64 for "vt420".
|
||||
@@ -1566,6 +1580,7 @@ public final class TerminalEmulator {
|
||||
// Also require that top + 2 <= bottom.
|
||||
mTopMargin = Math.max(0, Math.min(getArg0(1) - 1, mRows - 2));
|
||||
mBottomMargin = Math.max(mTopMargin + 2, Math.min(getArg1(mRows), mRows));
|
||||
|
||||
// DECSTBM moves the cursor to column 1, line 1 of the page respecting origin mode.
|
||||
setCursorPosition(0, 0);
|
||||
}
|
||||
@@ -1639,6 +1654,7 @@ public final class TerminalEmulator {
|
||||
|
||||
/** Select Graphic Rendition (SGR) - see http://en.wikipedia.org/wiki/ANSI_escape_code#graphics. */
|
||||
private void selectGraphicRendition() {
|
||||
if (mArgIndex >= mArgs.length) mArgIndex = mArgs.length - 1;
|
||||
for (int i = 0; i <= mArgIndex; i++) {
|
||||
int code = mArgs[i];
|
||||
if (code < 0) {
|
||||
@@ -2049,6 +2065,7 @@ public final class TerminalEmulator {
|
||||
buf.append(", escapeState=");
|
||||
buf.append(mEscapeState);
|
||||
boolean firstArg = true;
|
||||
if (mArgIndex >= mArgs.length) mArgIndex = mArgs.length - 1;
|
||||
for (int i = 0; i <= mArgIndex; i++) {
|
||||
int value = mArgs[i];
|
||||
if (value >= 0) {
|
||||
@@ -2081,6 +2098,7 @@ public final class TerminalEmulator {
|
||||
* @param codePoint The code point of the character to display
|
||||
*/
|
||||
private void emitCodePoint(int codePoint) {
|
||||
mLastEmittedCodePoint = codePoint;
|
||||
if (mUseLineDrawingUsesG0 ? mUseLineDrawingG0 : mUseLineDrawingG1) {
|
||||
// http://www.vt100.net/docs/vt102-ug/table5-15.html.
|
||||
switch (codePoint) {
|
||||
@@ -2263,8 +2281,8 @@ public final class TerminalEmulator {
|
||||
mBottomMargin = mRows;
|
||||
mRightMargin = mColumns;
|
||||
mAboutToAutoWrap = false;
|
||||
mForeColor = TextStyle.COLOR_INDEX_FOREGROUND;
|
||||
mBackColor = TextStyle.COLOR_INDEX_BACKGROUND;
|
||||
mForeColor = mSavedStateMain.mSavedForeColor = mSavedStateAlt.mSavedForeColor = TextStyle.COLOR_INDEX_FOREGROUND;
|
||||
mBackColor = mSavedStateMain.mSavedBackColor = mSavedStateAlt.mSavedBackColor = TextStyle.COLOR_INDEX_BACKGROUND;
|
||||
setDefaultTabStops();
|
||||
|
||||
mUseLineDrawingG0 = mUseLineDrawingG1 = false;
|
||||
@@ -2318,7 +2336,7 @@ public final class TerminalEmulator {
|
||||
static final class SavedScreenState {
|
||||
/** Saved state of the cursor position, Used to implement the save/restore cursor position escape sequences. */
|
||||
int mSavedCursorRow, mSavedCursorCol;
|
||||
int mSavedEffect;
|
||||
int mSavedEffect, mSavedForeColor, mSavedBackColor;
|
||||
int mSavedDecFlags;
|
||||
boolean mUseLineDrawingG0, mUseLineDrawingG1, mUseLineDrawingUsesG0 = true;
|
||||
}
|
||||
|
@@ -29,4 +29,21 @@ public class ControlSequenceIntroducerTest extends TerminalTestCase {
|
||||
withTerminalSized(13, 2).enterString("abcdefghijkl\b\b\b\b\b\033[20X").assertLinesAre("abcdefg ", " ");
|
||||
}
|
||||
|
||||
/** CSI Pm m Set SGR parameter(s) from semicolon-separated list Pm. */
|
||||
public void testCsiSGRParameters() {
|
||||
// Set more parameters (19) than supported (16). Additional parameters should be silently consumed.
|
||||
withTerminalSized(3, 2).enterString("\033[0;38;2;255;255;255;48;2;0;0;0;1;2;3;4;5;7;8;9mabc").assertLinesAre("abc", " ");
|
||||
}
|
||||
|
||||
/** CSI Ps b Repeat the preceding graphic character Ps times (REP). */
|
||||
public void testRepeat() {
|
||||
withTerminalSized(3, 2).enterString("a\033[b").assertLinesAre("aa ", " ");
|
||||
withTerminalSized(3, 2).enterString("a\033[2b").assertLinesAre("aaa", " ");
|
||||
// When no char has been output we ignore REP:
|
||||
withTerminalSized(3, 2).enterString("\033[b").assertLinesAre(" ", " ");
|
||||
// This shows that REP outputs the last emitted code point and not the one relative to the
|
||||
// current cursor position:
|
||||
withTerminalSized(5, 2).enterString("abcde\033[2G\033[2b\n").assertLinesAre("aeede", " ");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -227,4 +227,44 @@ public class CursorAndScreenTest extends TerminalTestCase {
|
||||
withTerminalSized(3, 3).enterString("\b\b\b\bhi").assertLinesAre("hi ", " ", " ");
|
||||
}
|
||||
|
||||
public void testCursorSaveRestoreLocation() {
|
||||
// DEC save/restore
|
||||
withTerminalSized(4, 2).enterString("t\0337est\r\nme\0338ry ").assertLinesAre("try ", "me ");
|
||||
// ANSI.SYS save/restore
|
||||
withTerminalSized(4, 2).enterString("t\033[sest\r\nme\033[ury ").assertLinesAre("try ", "me ");
|
||||
// Alternate screen enter/exit
|
||||
withTerminalSized(4, 2).enterString("t\033[?1049h\033[Hest\r\nme").assertLinesAre("est ", "me ").enterString("\033[?1049lry").assertLinesAre("try ", " ");
|
||||
}
|
||||
|
||||
public void testCursorSaveRestoreTextStyle() {
|
||||
long s;
|
||||
|
||||
// DEC save/restore
|
||||
withTerminalSized(4, 2).enterString("\033[31;42;4m..\0337\033[36;47;24m\0338..");
|
||||
s = getStyleAt(0, 3);
|
||||
Assert.assertEquals(1, TextStyle.decodeForeColor(s));
|
||||
Assert.assertEquals(2, TextStyle.decodeBackColor(s));
|
||||
Assert.assertEquals(TextStyle.CHARACTER_ATTRIBUTE_UNDERLINE, TextStyle.decodeEffect(s));
|
||||
|
||||
// ANSI.SYS save/restore
|
||||
withTerminalSized(4, 2).enterString("\033[31;42;4m..\033[s\033[36;47;24m\033[u..");
|
||||
s = getStyleAt(0, 3);
|
||||
Assert.assertEquals(1, TextStyle.decodeForeColor(s));
|
||||
Assert.assertEquals(2, TextStyle.decodeBackColor(s));
|
||||
Assert.assertEquals(TextStyle.CHARACTER_ATTRIBUTE_UNDERLINE, TextStyle.decodeEffect(s));
|
||||
|
||||
// Alternate screen enter/exit
|
||||
withTerminalSized(4, 2);
|
||||
enterString("\033[31;42;4m..\033[?1049h\033[H\033[36;47;24m.");
|
||||
s = getStyleAt(0, 0);
|
||||
Assert.assertEquals(6, TextStyle.decodeForeColor(s));
|
||||
Assert.assertEquals(7, TextStyle.decodeBackColor(s));
|
||||
Assert.assertEquals(0, TextStyle.decodeEffect(s));
|
||||
enterString("\033[?1049l..");
|
||||
s = getStyleAt(0, 3);
|
||||
Assert.assertEquals(1, TextStyle.decodeForeColor(s));
|
||||
Assert.assertEquals(2, TextStyle.decodeBackColor(s));
|
||||
Assert.assertEquals(TextStyle.CHARACTER_ATTRIBUTE_UNDERLINE, TextStyle.decodeEffect(s));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ ext {
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.2"
|
||||
buildToolsVersion "26.0.0"
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:support-annotations:25.3.1'
|
||||
|
@@ -1,3 +1,2 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.termux.view">
|
||||
<manifest package="com.termux.view">
|
||||
</manifest>
|
||||
|
@@ -834,6 +834,10 @@ public final class TerminalView extends View {
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
if (!mIsSelectingText) {
|
||||
// Fix issue where the dialog is pressed while being dismissed.
|
||||
return true;
|
||||
}
|
||||
switch (item.getItemId()) {
|
||||
case 1:
|
||||
String selectedText = mEmulator.getSelectedText(mSelX1, mSelY1, mSelX2, mSelY2).trim();
|
||||
|
Reference in New Issue
Block a user