Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
625aeab398 | ||
|
|
bad6712338 | ||
|
|
b54c7909bd | ||
|
|
4ccc703fcf | ||
|
|
7348820caf | ||
|
|
525985b1f2 | ||
|
|
ab3852d2e4 | ||
|
|
9928073e48 | ||
|
|
3091da64bc | ||
|
|
74dca95101 | ||
|
|
2a6a3b76b7 | ||
|
|
0e4ea95d74 | ||
|
|
7389dbb56f | ||
|
|
d982c71efe | ||
|
|
1b36c684d6 | ||
|
|
a6a83b1fcd | ||
|
|
d6f01bfe9a | ||
|
|
271dd7dcee | ||
|
|
95fbb810e2 | ||
|
|
1aa439311b | ||
|
|
12ddaccaf7 | ||
|
|
09fe7e5941 |
231
.idea/codeStyleSettings.xml
generated
Normal file
231
.idea/codeStyleSettings.xml
generated
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectCodeStyleSettingsManager">
|
||||||
|
<option name="PER_PROJECT_SETTINGS">
|
||||||
|
<value>
|
||||||
|
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
|
||||||
|
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
|
||||||
|
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||||
|
<value />
|
||||||
|
</option>
|
||||||
|
<option name="IMPORT_LAYOUT_TABLE">
|
||||||
|
<value>
|
||||||
|
<package name="android" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="com" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="junit" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="net" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="org" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="java" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="javax" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="" withSubpackages="true" static="false" />
|
||||||
|
<emptyLine />
|
||||||
|
<package name="" withSubpackages="true" static="true" />
|
||||||
|
<emptyLine />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="RIGHT_MARGIN" value="100" />
|
||||||
|
<AndroidXmlCodeStyleSettings>
|
||||||
|
<option name="USE_CUSTOM_SETTINGS" value="true" />
|
||||||
|
</AndroidXmlCodeStyleSettings>
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
|
||||||
|
<option name="RELEASE_STYLE" value="IVAR" />
|
||||||
|
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="h" />
|
||||||
|
<pair source="c" header="h" />
|
||||||
|
</extensions>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
<XML>
|
||||||
|
<option name="XML_KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
|
||||||
|
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||||
|
</XML>
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_NAMESPACE />
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_NAMESPACE />
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>name</NAME>
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>style</NAME>
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:layout_width</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:layout_height</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:layout_.*</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:width</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:height</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
</rules>
|
||||||
|
</arrangement>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="TermuxCodeStyle" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
15
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
15
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="AndroidLintGoogleAppIndexingWarning" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="EmptyStatementBody" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="m_reportEmptyBlocks" value="true" />
|
||||||
|
<option name="commentsAreContent" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
<option name="processCode" value="true" />
|
||||||
|
<option name="processLiterals" value="true" />
|
||||||
|
<option name="processComments" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
7
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
7
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
@@ -11,9 +11,9 @@ android:
|
|||||||
components:
|
components:
|
||||||
- platform-tools
|
- platform-tools
|
||||||
- tools
|
- tools
|
||||||
- build-tools-23.0.1
|
- build-tools-23.0.2
|
||||||
- android-23
|
- android-23
|
||||||
- sys-img-x86-android-23
|
- extra-android-m2repository
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- ./gradlew testDebugUnitTest
|
- ./gradlew testDebugUnitTest
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ apply plugin: 'com.android.application'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.1"
|
buildToolsVersion "23.0.2"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile 'com.android.support:support-annotations:23.1.1'
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
@@ -13,9 +17,9 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.termux"
|
applicationId "com.termux"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 22
|
targetSdkVersion 23
|
||||||
versionCode 20
|
versionCode 21
|
||||||
versionName "0.20"
|
versionName "0.21"
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
android:fullBackupContent="@xml/backupscheme"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:banner="@drawable/banner"
|
android:banner="@drawable/banner"
|
||||||
android:label="@string/application_name"
|
android:label="@string/application_name"
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import android.net.Uri;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -87,7 +89,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
|
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
|
||||||
|
|
||||||
/** The main view of the activity showing the terminal. */
|
/** The main view of the activity showing the terminal. */
|
||||||
TerminalView mTerminalView;
|
@NonNull TerminalView mTerminalView;
|
||||||
|
|
||||||
final FullScreenHelper mFullScreenHelper = new FullScreenHelper(this);
|
final FullScreenHelper mFullScreenHelper = new FullScreenHelper(this);
|
||||||
|
|
||||||
@@ -143,6 +145,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
if (event.getAction() != KeyEvent.ACTION_DOWN) return false;
|
if (event.getAction() != KeyEvent.ACTION_DOWN) return false;
|
||||||
|
|
||||||
final TerminalSession currentSession = getCurrentTermSession();
|
final TerminalSession currentSession = getCurrentTermSession();
|
||||||
|
if (currentSession == null) return false;
|
||||||
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER && !currentSession.isRunning()) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER && !currentSession.isRunning()) {
|
||||||
// Return pressed with finished session - remove it.
|
// Return pressed with finished session - remove it.
|
||||||
@@ -461,7 +464,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalSession getCurrentTermSession() {
|
@Nullable TerminalSession getCurrentTermSession() {
|
||||||
return mTerminalView.getCurrentSession();
|
return mTerminalView.getCurrentSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,12 +583,11 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showUrlSelection() {
|
static LinkedHashSet<CharSequence> extractUrls(String text) {
|
||||||
String text = getCurrentTermSession().getEmulator().getScreen().getTranscriptText();
|
|
||||||
// Pattern for recognizing a URL, based off RFC 3986
|
// Pattern for recognizing a URL, based off RFC 3986
|
||||||
// http://stackoverflow.com/questions/5713558/detect-and-extract-url-from-a-string
|
// http://stackoverflow.com/questions/5713558/detect-and-extract-url-from-a-string
|
||||||
final Pattern urlPattern = Pattern.compile(
|
final Pattern urlPattern = Pattern.compile(
|
||||||
"(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)" + "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*" + "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
|
"(?:^|[\\W])((ht|f)tp(s?)://|www\\.)" + "(([\\w\\-]+\\.)+?([\\w\\-.~]+/?)*" + "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
|
||||||
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
||||||
LinkedHashSet<CharSequence> urlSet = new LinkedHashSet<>();
|
LinkedHashSet<CharSequence> urlSet = new LinkedHashSet<>();
|
||||||
Matcher matcher = urlPattern.matcher(text);
|
Matcher matcher = urlPattern.matcher(text);
|
||||||
@@ -595,7 +597,12 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
|||||||
String url = text.substring(matchStart, matchEnd);
|
String url = text.substring(matchStart, matchEnd);
|
||||||
urlSet.add(url);
|
urlSet.add(url);
|
||||||
}
|
}
|
||||||
|
return urlSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showUrlSelection() {
|
||||||
|
String text = getCurrentTermSession().getEmulator().getScreen().getTranscriptText();
|
||||||
|
LinkedHashSet<CharSequence> urlSet = extractUrls(text);
|
||||||
if (urlSet.isEmpty()) {
|
if (urlSet.isEmpty()) {
|
||||||
new AlertDialog.Builder(this).setMessage(R.string.select_url_no_found).show();
|
new AlertDialog.Builder(this).setMessage(R.string.select_url_no_found).show();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -768,16 +768,10 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
// or pick a magic number from thin air otherwise.
|
// or pick a magic number from thin air otherwise.
|
||||||
// TODO Better communication with tools of this bogus state.
|
// TODO Better communication with tools of this bogus state.
|
||||||
// It will crash on a real device.
|
// It will crash on a real device.
|
||||||
if (widthMode == MeasureSpec.AT_MOST) {
|
if (widthMode == MeasureSpec.UNSPECIFIED) {
|
||||||
widthMode = MeasureSpec.EXACTLY;
|
|
||||||
} else if (widthMode == MeasureSpec.UNSPECIFIED) {
|
|
||||||
widthMode = MeasureSpec.EXACTLY;
|
|
||||||
widthSize = 300;
|
widthSize = 300;
|
||||||
}
|
}
|
||||||
if (heightMode == MeasureSpec.AT_MOST) {
|
if (heightMode == MeasureSpec.UNSPECIFIED) {
|
||||||
heightMode = MeasureSpec.EXACTLY;
|
|
||||||
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
|
|
||||||
heightMode = MeasureSpec.EXACTLY;
|
|
||||||
heightSize = 300;
|
heightSize = 300;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -934,10 +928,7 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
|
|
||||||
private static boolean hasOpaqueBackground(View v) {
|
private static boolean hasOpaqueBackground(View v) {
|
||||||
final Drawable bg = v.getBackground();
|
final Drawable bg = v.getBackground();
|
||||||
if (bg != null) {
|
return bg != null && bg.getOpacity() == PixelFormat.OPAQUE;
|
||||||
return bg.getOpacity() == PixelFormat.OPAQUE;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1114,7 +1105,6 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
mRightDragger.processTouchEvent(ev);
|
mRightDragger.processTouchEvent(ev);
|
||||||
|
|
||||||
final int action = ev.getAction();
|
final int action = ev.getAction();
|
||||||
boolean wantTouchEvents = true;
|
|
||||||
|
|
||||||
switch (action & MotionEvent.ACTION_MASK) {
|
switch (action & MotionEvent.ACTION_MASK) {
|
||||||
case MotionEvent.ACTION_DOWN: {
|
case MotionEvent.ACTION_DOWN: {
|
||||||
@@ -1154,7 +1144,7 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wantTouchEvents;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1317,10 +1307,7 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
*/
|
*/
|
||||||
public boolean isDrawerOpen(int drawerGravity) {
|
public boolean isDrawerOpen(int drawerGravity) {
|
||||||
final View drawerView = findDrawerWithGravity(drawerGravity);
|
final View drawerView = findDrawerWithGravity(drawerGravity);
|
||||||
if (drawerView != null) {
|
return drawerView != null && isDrawerOpen(drawerView);
|
||||||
return isDrawerOpen(drawerView);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1350,10 +1337,7 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
*/
|
*/
|
||||||
public boolean isDrawerVisible(int drawerGravity) {
|
public boolean isDrawerVisible(int drawerGravity) {
|
||||||
final View drawerView = findDrawerWithGravity(drawerGravity);
|
final View drawerView = findDrawerWithGravity(drawerGravity);
|
||||||
if (drawerView != null) {
|
return drawerView != null && isDrawerVisible(drawerView);
|
||||||
return isDrawerVisible(drawerView);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasPeekingDrawer() {
|
private boolean hasPeekingDrawer() {
|
||||||
@@ -1776,10 +1760,7 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
|
public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
|
||||||
if (CAN_HIDE_DESCENDANTS || includeChildForAccessibility(child)) {
|
return (CAN_HIDE_DESCENDANTS || includeChildForAccessibility(child)) && super.onRequestSendAccessibilityEvent(host, child, event);
|
||||||
return super.onRequestSendAccessibilityEvent(host, child, event);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1796,4 +1777,4 @@ public class DrawerLayout extends ViewGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1485,10 +1485,7 @@ public class ViewDragHelper {
|
|||||||
* @return true if the supplied view is under the given point, false otherwise
|
* @return true if the supplied view is under the given point, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isViewUnder(View view, int x, int y) {
|
public boolean isViewUnder(View view, int x, int y) {
|
||||||
if (view == null) {
|
return view != null && x >= view.getLeft() && x < view.getRight() && y >= view.getTop() && y < view.getBottom();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return x >= view.getLeft() && x < view.getRight() && y >= view.getTop() && y < view.getBottom();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1522,4 +1519,4 @@ public class ViewDragHelper {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,17 +36,12 @@ public class TermuxFilePickerActivity extends ListActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.file_picker);
|
setContentView(R.layout.file_picker);
|
||||||
|
|
||||||
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mFileNames);
|
mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mFileNames);
|
||||||
|
|
||||||
enterDirectory(new File(TERMUX_HOME));
|
enterDirectory(new File(TERMUX_HOME));
|
||||||
setListAdapter(mAdapter);
|
setListAdapter(mAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.content.ContentValues;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -18,32 +19,32 @@ public class TermuxFilePickerProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType(Uri uri) {
|
public String getType(@NonNull Uri uri) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Uri insert(Uri uri, ContentValues values) {
|
public Uri insert(@NonNull Uri uri, ContentValues values) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
public int delete(@NonNull Uri uri, String selection, String[] selectionArgs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
|
public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {
|
||||||
File file = new File(uri.getPath());
|
File file = new File(uri.getPath());
|
||||||
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
|
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2156,15 +2156,22 @@ public final class TerminalEmulator {
|
|||||||
|
|
||||||
final boolean autoWrap = isDecsetInternalBitSet(DECSET_BIT_AUTOWRAP);
|
final boolean autoWrap = isDecsetInternalBitSet(DECSET_BIT_AUTOWRAP);
|
||||||
final int displayWidth = WcWidth.width(codePoint);
|
final int displayWidth = WcWidth.width(codePoint);
|
||||||
|
final boolean cursorInLastColumn = mCursorCol == mRightMargin - 1;
|
||||||
|
|
||||||
if (autoWrap && (mCursorCol == mRightMargin - 1 && ((mAboutToAutoWrap && displayWidth == 1) || displayWidth == 2))) {
|
if (autoWrap) {
|
||||||
mScreen.setLineWrap(mCursorRow);
|
if (cursorInLastColumn && ((mAboutToAutoWrap && displayWidth == 1) || displayWidth == 2)) {
|
||||||
mCursorCol = mLeftMargin;
|
mScreen.setLineWrap(mCursorRow);
|
||||||
if (mCursorRow + 1 < mBottomMargin) {
|
mCursorCol = mLeftMargin;
|
||||||
mCursorRow++;
|
if (mCursorRow + 1 < mBottomMargin) {
|
||||||
} else {
|
mCursorRow++;
|
||||||
scrollDownOneLine();
|
} else {
|
||||||
|
scrollDownOneLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (cursorInLastColumn && displayWidth == 2) {
|
||||||
|
// The behaviour when a wide character is output with cursor in the last column when
|
||||||
|
// autowrap is disabled is not obvious - it's ignored here.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mInsertMode && displayWidth > 0) {
|
if (mInsertMode && displayWidth > 0) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import android.view.MotionEvent;
|
|||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
|
|
||||||
/** A combination of {@link GestureDetector} and {@link ScaleGestureDetector}. */
|
/** A combination of {@link GestureDetector} and {@link ScaleGestureDetector}. */
|
||||||
public class GestureAndScaleRecognizer {
|
public final class GestureAndScaleRecognizer {
|
||||||
|
|
||||||
public interface Listener {
|
public interface Listener {
|
||||||
boolean onSingleTapUp(MotionEvent e);
|
boolean onSingleTapUp(MotionEvent e);
|
||||||
@@ -29,6 +29,7 @@ public class GestureAndScaleRecognizer {
|
|||||||
private final GestureDetector mGestureDetector;
|
private final GestureDetector mGestureDetector;
|
||||||
private final ScaleGestureDetector mScaleDetector;
|
private final ScaleGestureDetector mScaleDetector;
|
||||||
final Listener mListener;
|
final Listener mListener;
|
||||||
|
boolean isAfterLongPress;
|
||||||
|
|
||||||
public GestureAndScaleRecognizer(Context context, Listener listener) {
|
public GestureAndScaleRecognizer(Context context, Listener listener) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
@@ -52,6 +53,7 @@ public class GestureAndScaleRecognizer {
|
|||||||
@Override
|
@Override
|
||||||
public void onLongPress(MotionEvent e) {
|
public void onLongPress(MotionEvent e) {
|
||||||
mListener.onLongPress(e);
|
mListener.onLongPress(e);
|
||||||
|
isAfterLongPress = true;
|
||||||
}
|
}
|
||||||
}, null, true /* ignoreMultitouch */);
|
}, null, true /* ignoreMultitouch */);
|
||||||
|
|
||||||
@@ -88,8 +90,17 @@ public class GestureAndScaleRecognizer {
|
|||||||
public void onTouchEvent(MotionEvent event) {
|
public void onTouchEvent(MotionEvent event) {
|
||||||
mGestureDetector.onTouchEvent(event);
|
mGestureDetector.onTouchEvent(event);
|
||||||
mScaleDetector.onTouchEvent(event);
|
mScaleDetector.onTouchEvent(event);
|
||||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
switch (event.getAction()) {
|
||||||
mListener.onUp(event);
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
isAfterLongPress = false;
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if (!isAfterLongPress) {
|
||||||
|
// This behaviour is desired when in e.g. vim with mouse events, where we do not
|
||||||
|
// want to move the cursor when lifting finger after a long press.
|
||||||
|
mListener.onUp(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,4 +108,4 @@ public class GestureAndScaleRecognizer {
|
|||||||
return mScaleDetector.isInProgress();
|
return mScaleDetector.isInProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,13 @@
|
|||||||
|
|
||||||
<ListView android:id="@android:id/list"
|
<ListView android:id="@android:id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawSelectorOnTop="false"/>
|
android:drawSelectorOnTop="false"/>
|
||||||
|
|
||||||
<TextView android:id="@android:id/empty"
|
<TextView android:id="@android:id/empty"
|
||||||
|
android:gravity="center"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="$HOME is empty!"/>
|
android:text="@string/empty_folder"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -56,4 +56,6 @@
|
|||||||
<string name="notification_action_wakelock">Wake</string>
|
<string name="notification_action_wakelock">Wake</string>
|
||||||
<string name="notification_action_wifilock">Wifi</string>
|
<string name="notification_action_wifilock">Wifi</string>
|
||||||
|
|
||||||
|
<string name="empty_folder">Empty folder.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
5
app/src/main/res/xml/backupscheme.xml
Normal file
5
app/src/main/res/xml/backupscheme.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<full-backup-content>
|
||||||
|
<!-- See https://developer.android.com/training/backup/autosyncapi.html -->
|
||||||
|
<include domain="file" path="home/backup" />
|
||||||
|
</full-backup-content>
|
||||||
25
app/src/test/java/com/termux/app/TermuxActivityTest.java
Normal file
25
app/src/test/java/com/termux/app/TermuxActivityTest.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package com.termux.app;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
|
public class TermuxActivityTest extends TestCase {
|
||||||
|
|
||||||
|
private void assertUrlsAre(String text, String... urls) {
|
||||||
|
LinkedHashSet<String> expected = new LinkedHashSet<>();
|
||||||
|
Collections.addAll(expected, urls);
|
||||||
|
assertEquals(expected, TermuxActivity.extractUrls(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExtractUrls() {
|
||||||
|
assertUrlsAre("hello http://example.com world", "http://example.com");
|
||||||
|
|
||||||
|
assertUrlsAre("http://example.com\nhttp://another.com", "http://example.com", "http://another.com");
|
||||||
|
|
||||||
|
assertUrlsAre("hello http://example.com world and http://more.example.com with secure https://more.example.com",
|
||||||
|
"http://example.com", "http://more.example.com", "https://more.example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,21 +17,21 @@ public class ByteQueueTest extends TestCase {
|
|||||||
|
|
||||||
public void testCompleteWrites() throws Exception {
|
public void testCompleteWrites() throws Exception {
|
||||||
ByteQueue q = new ByteQueue(10);
|
ByteQueue q = new ByteQueue(10);
|
||||||
assertEquals(true, q.write(new byte[] { 1, 2, 3 }, 0, 3));
|
assertEquals(true, q.write(new byte[]{1, 2, 3}, 0, 3));
|
||||||
|
|
||||||
byte[] arr = new byte[10];
|
byte[] arr = new byte[10];
|
||||||
assertEquals(3, q.read(arr, true));
|
assertEquals(3, q.read(arr, true));
|
||||||
assertArrayEquals(new byte[] { 1, 2, 3 }, new byte[] { arr[0], arr[1], arr[2] });
|
assertArrayEquals(new byte[]{1, 2, 3}, new byte[]{arr[0], arr[1], arr[2]});
|
||||||
|
|
||||||
assertEquals(true, q.write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10));
|
assertEquals(true, q.write(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 10));
|
||||||
assertEquals(10, q.read(arr, true));
|
assertEquals(10, q.read(arr, true));
|
||||||
assertArrayEquals(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, arr);
|
assertArrayEquals(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testQueueWraparound() throws Exception {
|
public void testQueueWraparound() throws Exception {
|
||||||
ByteQueue q = new ByteQueue(10);
|
ByteQueue q = new ByteQueue(10);
|
||||||
|
|
||||||
byte[] origArray = new byte[] { 1, 2, 3, 4, 5, 6 };
|
byte[] origArray = new byte[]{1, 2, 3, 4, 5, 6};
|
||||||
byte[] readArray = new byte[origArray.length];
|
byte[] readArray = new byte[origArray.length];
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
q.write(origArray, 0, origArray.length);
|
q.write(origArray, 0, origArray.length);
|
||||||
@@ -43,7 +43,7 @@ public class ByteQueueTest extends TestCase {
|
|||||||
public void testWriteNotesClosing() throws Exception {
|
public void testWriteNotesClosing() throws Exception {
|
||||||
ByteQueue q = new ByteQueue(10);
|
ByteQueue q = new ByteQueue(10);
|
||||||
q.close();
|
q.close();
|
||||||
assertEquals(false, q.write(new byte[] { 1, 2, 3 }, 0, 3));
|
assertEquals(false, q.write(new byte[]{1, 2, 3}, 0, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testReadNonBlocking() throws Exception {
|
public void testReadNonBlocking() throws Exception {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ package com.termux.terminal;
|
|||||||
* <pre>
|
* <pre>
|
||||||
* "CSI ? Pm h", DEC Private Mode Set (DECSET)
|
* "CSI ? Pm h", DEC Private Mode Set (DECSET)
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
* <p/>
|
||||||
* and
|
* and
|
||||||
*
|
* <p/>
|
||||||
* <pre>
|
* <pre>
|
||||||
* "CSI ? Pm l", DEC Private Mode Reset (DECRST)
|
* "CSI ? Pm l", DEC Private Mode Reset (DECRST)
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
* <p/>
|
||||||
* controls various aspects of the terminal
|
* controls various aspects of the terminal
|
||||||
*/
|
*/
|
||||||
public class DecSetTest extends TerminalTestCase {
|
public class DecSetTest extends TerminalTestCase {
|
||||||
@@ -59,4 +59,15 @@ public class DecSetTest extends TerminalTestCase {
|
|||||||
assertEquals("Terminal reset() should disable bracketed paste mode", "a", mOutput.getOutputAndClear());
|
assertEquals("Terminal reset() should disable bracketed paste mode", "a", mOutput.getOutputAndClear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DECSET 7, DECAWM, controls wraparound mode. */
|
||||||
|
public void testWrapAroundMode() {
|
||||||
|
// Default with wraparound:
|
||||||
|
withTerminalSized(3, 3).enterString("abcd").assertLinesAre("abc", "d ", " ");
|
||||||
|
// With wraparound disabled:
|
||||||
|
withTerminalSized(3, 3).enterString("\033[?7labcd").assertLinesAre("abd", " ", " ");
|
||||||
|
enterString("efg").assertLinesAre("abg", " ", " ");
|
||||||
|
// Re-enabling wraparound:
|
||||||
|
enterString("\033[?7hhij").assertLinesAre("abh", "ij ", " ");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.termux.terminal;
|
package com.termux.terminal;
|
||||||
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
public class KeyHandlerTest extends TestCase {
|
public class KeyHandlerTest extends TestCase {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.termux.terminal;
|
package com.termux.terminal;
|
||||||
|
|
||||||
|
import android.util.Base64;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import android.util.Base64;
|
|
||||||
|
|
||||||
/** "ESC ]" is the Operating System Command. */
|
/** "ESC ]" is the Operating System Command. */
|
||||||
public class OperatingSystemControlTest extends TerminalTestCase {
|
public class OperatingSystemControlTest extends TerminalTestCase {
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.termux.terminal;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ${CSI}${top};${bottom}r" - set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM).
|
* ${CSI}${top};${bottom}r" - set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM).
|
||||||
*
|
* <p/>
|
||||||
* "DECSTBM moves the cursor to column 1, line 1 of the page" (http://www.vt100.net/docs/vt510-rm/DECSTBM).
|
* "DECSTBM moves the cursor to column 1, line 1 of the page" (http://www.vt100.net/docs/vt510-rm/DECSTBM).
|
||||||
*/
|
*/
|
||||||
public class ScrollRegionTest extends TerminalTestCase {
|
public class ScrollRegionTest extends TerminalTestCase {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.termux.terminal;
|
package com.termux.terminal;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class TerminalRowTest extends TestCase {
|
public class TerminalRowTest extends TestCase {
|
||||||
|
|
||||||
/** The properties of these code points are validated in {@link #testStaticConstants()}. */
|
/** The properties of these code points are validated in {@link #testStaticConstants()}. */
|
||||||
@@ -96,7 +96,7 @@ public class TerminalRowTest extends TestCase {
|
|||||||
assertEquals(80, row.getSpaceUsed());
|
assertEquals(80, row.getSpaceUsed());
|
||||||
assertColumnCharIndicesStartsWith(0, 1, 2, 3);
|
assertColumnCharIndicesStartsWith(0, 1, 2, 3);
|
||||||
|
|
||||||
char[] someChars = new char[] { 'a', 'c', 'e', '4', '5', '6', '7', '8' };
|
char[] someChars = new char[]{'a', 'c', 'e', '4', '5', '6', '7', '8'};
|
||||||
|
|
||||||
char[] rawLine = new char[80];
|
char[] rawLine = new char[80];
|
||||||
Arrays.fill(rawLine, ' ');
|
Arrays.fill(rawLine, ' ');
|
||||||
@@ -373,13 +373,13 @@ public class TerminalRowTest extends TestCase {
|
|||||||
assertEquals(0, WcWidth.width(0x009F));
|
assertEquals(0, WcWidth.width(0x009F));
|
||||||
assertEquals(1, Character.charCount(0x009F));
|
assertEquals(1, Character.charCount(0x009F));
|
||||||
|
|
||||||
int[] points = new int[] { 0xC2541, 'a', '8', 0x73EE, 0x009F, 0x881F, 0x8324, 0xD4C9, 0xFFFD, 'B', 0x009B, 0x61C9, 'Z' };
|
int[] points = new int[]{0xC2541, 'a', '8', 0x73EE, 0x009F, 0x881F, 0x8324, 0xD4C9, 0xFFFD, 'B', 0x009B, 0x61C9, 'Z'};
|
||||||
// int[] expected = new int[] { TerminalEmulator.UNICODE_REPLACEMENT_CHAR, 'a', '8', 0x73EE, 0x009F, 0x881F, 0x8324, 0xD4C9, 0xFFFD,
|
// int[] expected = new int[] { TerminalEmulator.UNICODE_REPLACEMENT_CHAR, 'a', '8', 0x73EE, 0x009F, 0x881F, 0x8324, 0xD4C9, 0xFFFD,
|
||||||
// 'B', 0x009B, 0x61C9, 'Z' };
|
// 'B', 0x009B, 0x61C9, 'Z' };
|
||||||
int currentColumn = 0;
|
int currentColumn = 0;
|
||||||
for (int i = 0; i < points.length; i++) {
|
for (int point : points) {
|
||||||
row.setChar(currentColumn, points[i], 0);
|
row.setChar(currentColumn, point, 0);
|
||||||
currentColumn += WcWidth.width(points[i]);
|
currentColumn += WcWidth.width(point);
|
||||||
}
|
}
|
||||||
// assertLineStartsWith(points);
|
// assertLineStartsWith(points);
|
||||||
// assertEquals(Character.highSurrogate(0xC2541), line.mText[0]);
|
// assertEquals(Character.highSurrogate(0xC2541), line.mText[0]);
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.termux.terminal;
|
package com.termux.terminal;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -9,16 +12,10 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import com.termux.terminal.TerminalEmulator;
|
|
||||||
import com.termux.terminal.TerminalOutput;
|
|
||||||
|
|
||||||
public abstract class TerminalTestCase extends TestCase {
|
public abstract class TerminalTestCase extends TestCase {
|
||||||
|
|
||||||
public static class MockTerminalOutput extends TerminalOutput {
|
public static class MockTerminalOutput extends TerminalOutput {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
public final List<ChangedTitle> titleChanges = new ArrayList<>();
|
public final List<ChangedTitle> titleChanges = new ArrayList<>();
|
||||||
public final List<String> clipboardPuts = new ArrayList<>();
|
public final List<String> clipboardPuts = new ArrayList<>();
|
||||||
public int bellsRung = 0;
|
public int bellsRung = 0;
|
||||||
@@ -57,7 +54,7 @@ public abstract class TerminalTestCase extends TestCase {
|
|||||||
public TerminalEmulator mTerminal;
|
public TerminalEmulator mTerminal;
|
||||||
public MockTerminalOutput mOutput;
|
public MockTerminalOutput mOutput;
|
||||||
|
|
||||||
public static class ChangedTitle {
|
public static final class ChangedTitle {
|
||||||
final String oldTitle;
|
final String oldTitle;
|
||||||
final String newTitle;
|
final String newTitle;
|
||||||
|
|
||||||
@@ -68,6 +65,7 @@ public abstract class TerminalTestCase extends TestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof ChangedTitle)) return false;
|
||||||
ChangedTitle other = (ChangedTitle) o;
|
ChangedTitle other = (ChangedTitle) o;
|
||||||
return Objects.equals(oldTitle, other.oldTitle) && Objects.equals(newTitle, other.newTitle);
|
return Objects.equals(oldTitle, other.oldTitle) && Objects.equals(newTitle, other.newTitle);
|
||||||
}
|
}
|
||||||
@@ -115,8 +113,8 @@ public abstract class TerminalTestCase extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LineWrapper {
|
private static final class LineWrapper {
|
||||||
TerminalRow mLine;
|
final TerminalRow mLine;
|
||||||
|
|
||||||
public LineWrapper(TerminalRow line) {
|
public LineWrapper(TerminalRow line) {
|
||||||
mLine = line;
|
mLine = line;
|
||||||
@@ -129,7 +127,7 @@ public abstract class TerminalTestCase extends TestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
return ((LineWrapper) o).mLine == mLine;
|
return o instanceof LineWrapper && ((LineWrapper) o).mLine == mLine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
public class TextStyleTest extends TestCase {
|
public class TextStyleTest extends TestCase {
|
||||||
|
|
||||||
private static final int[] ALL_EFFECTS = new int[] { 0, TextStyle.CHARACTER_ATTRIBUTE_BOLD, TextStyle.CHARACTER_ATTRIBUTE_ITALIC,
|
private static final int[] ALL_EFFECTS = new int[]{0, TextStyle.CHARACTER_ATTRIBUTE_BOLD, TextStyle.CHARACTER_ATTRIBUTE_ITALIC,
|
||||||
TextStyle.CHARACTER_ATTRIBUTE_UNDERLINE, TextStyle.CHARACTER_ATTRIBUTE_BLINK, TextStyle.CHARACTER_ATTRIBUTE_INVERSE,
|
TextStyle.CHARACTER_ATTRIBUTE_UNDERLINE, TextStyle.CHARACTER_ATTRIBUTE_BLINK, TextStyle.CHARACTER_ATTRIBUTE_INVERSE,
|
||||||
TextStyle.CHARACTER_ATTRIBUTE_INVISIBLE, TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH, TextStyle.CHARACTER_ATTRIBUTE_PROTECTED,
|
TextStyle.CHARACTER_ATTRIBUTE_INVISIBLE, TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH, TextStyle.CHARACTER_ATTRIBUTE_PROTECTED,
|
||||||
TextStyle.CHARACTER_ATTRIBUTE_DIM };
|
TextStyle.CHARACTER_ATTRIBUTE_DIM};
|
||||||
|
|
||||||
public void testEncodingSingle() {
|
public void testEncodingSingle() {
|
||||||
for (int fx : ALL_EFFECTS) {
|
for (int fx : ALL_EFFECTS) {
|
||||||
@@ -34,7 +34,7 @@ public class TextStyleTest extends TestCase {
|
|||||||
public void testEncodingStrikeThrough() {
|
public void testEncodingStrikeThrough() {
|
||||||
int encoded = TextStyle.encode(TextStyle.COLOR_INDEX_FOREGROUND, TextStyle.COLOR_INDEX_BACKGROUND,
|
int encoded = TextStyle.encode(TextStyle.COLOR_INDEX_FOREGROUND, TextStyle.COLOR_INDEX_BACKGROUND,
|
||||||
TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH);
|
TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH);
|
||||||
assertTrue((TextStyle.decodeEffect(encoded) | TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH) != 0);
|
assertTrue((TextStyle.decodeEffect(encoded) & TextStyle.CHARACTER_ATTRIBUTE_STRIKETHROUGH) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEncodingProtected() {
|
public void testEncodingProtected() {
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ public class UnicodeInputTest extends TerminalTestCase {
|
|||||||
// continue with valid successor bytes (see Table 3-7), it must not consume the successor bytes as part of the ill-formed
|
// continue with valid successor bytes (see Table 3-7), it must not consume the successor bytes as part of the ill-formed
|
||||||
// subsequence whenever those successor bytes themselves constitute part of a well-formed UTF-8 code unit subsequence."
|
// subsequence whenever those successor bytes themselves constitute part of a well-formed UTF-8 code unit subsequence."
|
||||||
withTerminalSized(5, 5);
|
withTerminalSized(5, 5);
|
||||||
mTerminal.append(new byte[] { (byte) 0b11101111, (byte) 'a' }, 2);
|
mTerminal.append(new byte[]{(byte) 0b11101111, (byte) 'a'}, 2);
|
||||||
assertLineIs(0, ((char) TerminalEmulator.UNICODE_REPLACEMENT_CHAR) + "a ");
|
assertLineIs(0, ((char) TerminalEmulator.UNICODE_REPLACEMENT_CHAR) + "a ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUnassignedCodePoint() throws UnsupportedEncodingException {
|
public void testUnassignedCodePoint() throws UnsupportedEncodingException {
|
||||||
withTerminalSized(3, 3);
|
withTerminalSized(3, 3);
|
||||||
// UTF-8 for U+C2541, an unassigned code point:
|
// UTF-8 for U+C2541, an unassigned code point:
|
||||||
byte[] b = new byte[] { (byte) 0xf3, (byte) 0x82, (byte) 0x95, (byte) 0x81 };
|
byte[] b = new byte[]{(byte) 0xf3, (byte) 0x82, (byte) 0x95, (byte) 0x81};
|
||||||
mTerminal.append(b, b.length);
|
mTerminal.append(b, b.length);
|
||||||
enterString("Y");
|
enterString("Y");
|
||||||
assertEquals(1, Character.charCount(TerminalEmulator.UNICODE_REPLACEMENT_CHAR));
|
assertEquals(1, Character.charCount(TerminalEmulator.UNICODE_REPLACEMENT_CHAR));
|
||||||
@@ -26,10 +26,10 @@ public class UnicodeInputTest extends TerminalTestCase {
|
|||||||
|
|
||||||
public void testStuff() {
|
public void testStuff() {
|
||||||
withTerminalSized(80, 24);
|
withTerminalSized(80, 24);
|
||||||
byte[] b = new byte[] { (byte) 0xf3, (byte) 0x82, (byte) 0x95, (byte) 0x81, (byte) 0x61, (byte) 0x38, (byte) 0xe7, (byte) 0x8f,
|
byte[] b = new byte[]{(byte) 0xf3, (byte) 0x82, (byte) 0x95, (byte) 0x81, (byte) 0x61, (byte) 0x38, (byte) 0xe7, (byte) 0x8f,
|
||||||
(byte) 0xae, (byte) 0xc2, (byte) 0x9f, (byte) 0xe8, (byte) 0xa0, (byte) 0x9f, (byte) 0xe8, (byte) 0x8c, (byte) 0xa4,
|
(byte) 0xae, (byte) 0xc2, (byte) 0x9f, (byte) 0xe8, (byte) 0xa0, (byte) 0x9f, (byte) 0xe8, (byte) 0x8c, (byte) 0xa4,
|
||||||
(byte) 0xed, (byte) 0x93, (byte) 0x89, (byte) 0xef, (byte) 0xbf, (byte) 0xbd, (byte) 0x42, (byte) 0xc2, (byte) 0x9b,
|
(byte) 0xed, (byte) 0x93, (byte) 0x89, (byte) 0xef, (byte) 0xbf, (byte) 0xbd, (byte) 0x42, (byte) 0xc2, (byte) 0x9b,
|
||||||
(byte) 0xe6, (byte) 0x87, (byte) 0x89, (byte) 0x5a };
|
(byte) 0xe6, (byte) 0x87, (byte) 0x89, (byte) 0x5a};
|
||||||
mTerminal.append(b, b.length);
|
mTerminal.append(b, b.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,8 +80,16 @@ public class UnicodeInputTest extends TerminalTestCase {
|
|||||||
public void testOverlongUtf8Encoding() throws Exception {
|
public void testOverlongUtf8Encoding() throws Exception {
|
||||||
// U+0020 should be encoded as 0x20, 0xc0 0xa0 is an overlong encoding
|
// U+0020 should be encoded as 0x20, 0xc0 0xa0 is an overlong encoding
|
||||||
// so should be replaced with the replacement char U+FFFD.
|
// so should be replaced with the replacement char U+FFFD.
|
||||||
withTerminalSized(5, 5).mTerminal.append(new byte[] { (byte) 0xc0, (byte) 0xa0, 'Y' }, 3);
|
withTerminalSized(5, 5).mTerminal.append(new byte[]{(byte) 0xc0, (byte) 0xa0, 'Y'}, 3);
|
||||||
assertLineIs(0, "\uFFFDY ");
|
assertLineIs(0, "\uFFFDY ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testWideCharacterWithoutWrapping() throws Exception {
|
||||||
|
// With wraparound disabled. The behaviour when a wide character is output with cursor in
|
||||||
|
// the last column when autowrap is disabled is not obvious, but we expect the wide
|
||||||
|
// character to be ignored here.
|
||||||
|
withTerminalSized(3, 3).enterString("\033[?7l").enterString("枝枝枝").assertLinesAre("枝 ", " ", " ");
|
||||||
|
enterString("a枝").assertLinesAre("枝a", " ", " ");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
#Tue Nov 17 21:52:59 CET 2015
|
#Sat Nov 28 23:59:10 CET 2015
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip
|
||||||
|
|||||||
Reference in New Issue
Block a user