diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index 51ac549486..35aaa4fc70 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -846,6 +846,9 @@ private void reloadActivityStyling() { if (mTermuxTerminalViewClient != null) mTermuxTerminalViewClient.onReload(); + if (mTermuxService != null) + mTermuxService.setTerminalTranscriptRows(); + // To change the activity and drawer theme, activity needs to be recreated. // But this will destroy the activity, and will call the onCreate() again. // We need to investigate if enabling this is wise, since all stored variables and diff --git a/app/src/main/java/com/termux/app/TermuxService.java b/app/src/main/java/com/termux/app/TermuxService.java index 3457b7d8e3..71a4eb81c7 100644 --- a/app/src/main/java/com/termux/app/TermuxService.java +++ b/app/src/main/java/com/termux/app/TermuxService.java @@ -20,6 +20,7 @@ import android.widget.ArrayAdapter; import com.termux.R; +import com.termux.app.settings.properties.TermuxAppSharedProperties; import com.termux.app.terminal.TermuxTerminalSessionClient; import com.termux.app.utils.PluginUtils; import com.termux.shared.termux.TermuxConstants; @@ -106,6 +107,8 @@ class LocalBinder extends Binder { /** If the user has executed the {@link TERMUX_SERVICE#ACTION_STOP_SERVICE} intent. */ boolean mWantsToStop = false; + public Integer mTerminalTranscriptRows; + private static final String LOG_TAG = "TermuxService"; @Override @@ -503,6 +506,7 @@ public synchronized TermuxSession createTermuxSession(ExecutionCommand execution // If the execution command was started for a plugin, only then will the stdout be set // Otherwise if command was manually started by the user like by adding a new terminal session, // then no need to set stdout + executionCommand.terminalTranscriptRows = getTerminalTranscriptRows(); TermuxSession newTermuxSession = TermuxSession.execute(this, executionCommand, getTermuxTerminalSessionClient(), this, sessionName, executionCommand.isPluginExecutionCommand); if (newTermuxSession == null) { Logger.logError(LOG_TAG, "Failed to execute new TermuxSession command for:\n" + executionCommand.getCommandIdAndLabelLogString()); @@ -560,6 +564,19 @@ public void onTermuxSessionExited(final TermuxSession termuxSession) { updateNotification(); } + /** Get the terminal transcript rows to be used for new {@link TermuxSession}. */ + public Integer getTerminalTranscriptRows() { + if (mTerminalTranscriptRows == null) + setTerminalTranscriptRows(); + return mTerminalTranscriptRows; + } + + public void setTerminalTranscriptRows() { + // TermuxService only uses this termux property currently, so no need to load them all into + // an internal values map like TermuxActivity does + mTerminalTranscriptRows = TermuxAppSharedProperties.getTerminalTranscriptRows(this); + } + diff --git a/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java b/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java index 2ad4209532..6c2e03713a 100644 --- a/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java +++ b/app/src/main/java/com/termux/app/settings/properties/TermuxAppSharedProperties.java @@ -5,7 +5,6 @@ import com.termux.app.terminal.io.KeyboardShortcut; import com.termux.app.terminal.io.extrakeys.ExtraKeysInfo; import com.termux.shared.logger.Logger; -import com.termux.shared.settings.properties.SharedPropertiesParser; import com.termux.shared.settings.properties.TermuxPropertyConstants; import com.termux.shared.settings.properties.TermuxSharedProperties; @@ -17,7 +16,7 @@ import javax.annotation.Nonnull; -public class TermuxAppSharedProperties extends TermuxSharedProperties implements SharedPropertiesParser { +public class TermuxAppSharedProperties extends TermuxSharedProperties { private ExtraKeysInfo mExtraKeysInfo; private List mSessionShortcuts = new ArrayList<>(); @@ -96,4 +95,13 @@ public ExtraKeysInfo getExtraKeysInfo() { return mExtraKeysInfo; } + + + /** + * Load the {@link TermuxPropertyConstants#KEY_TERMINAL_TRANSCRIPT_ROWS} value from termux properties file on disk. + */ + public static int getTerminalTranscriptRows(Context context) { + return (int) TermuxSharedProperties.getInternalPropertyValue(context, TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS); + } + } diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java index f5fb10e855..7c04488d97 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java @@ -137,6 +137,11 @@ public final class TerminalEmulator { /** The number of character rows and columns in the terminal screen. */ public int mRows, mColumns; + /** The number of terminal transcript rows that can be scrolled back to. */ + public static final int TERMINAL_TRANSCRIPT_ROWS_MIN = 100; + public static final int TERMINAL_TRANSCRIPT_ROWS_MAX = 50000; + public static final int DEFAULT_TERMINAL_TRANSCRIPT_ROWS = 2000; + /** The normal screen buffer. Stores the characters that appear on the screen of the emulated terminal. */ private final TerminalBuffer mMainBuffer; /** @@ -294,9 +299,9 @@ static int mapDecSetBitToInternalBit(int decsetBit) { } } - public TerminalEmulator(TerminalOutput session, int columns, int rows, int transcriptRows, TerminalSessionClient client) { + public TerminalEmulator(TerminalOutput session, int columns, int rows, Integer transcriptRows, TerminalSessionClient client) { mSession = session; - mScreen = mMainBuffer = new TerminalBuffer(columns, transcriptRows, rows); + mScreen = mMainBuffer = new TerminalBuffer(columns, getTerminalTranscriptRows(transcriptRows), rows); mAltBuffer = new TerminalBuffer(columns, rows, rows); mClient = client; mRows = rows; @@ -317,6 +322,13 @@ public boolean isAlternateBufferActive() { return mScreen == mAltBuffer; } + private int getTerminalTranscriptRows(Integer transcriptRows) { + if (transcriptRows == null || transcriptRows < TERMINAL_TRANSCRIPT_ROWS_MIN || transcriptRows > TERMINAL_TRANSCRIPT_ROWS_MAX) + return DEFAULT_TERMINAL_TRANSCRIPT_ROWS; + else + return transcriptRows; + } + /** * @param mouseButton one of the MOUSE_* constants of this class. */ diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java index 688c8e58e7..3770827987 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java @@ -74,14 +74,17 @@ public final class TerminalSession extends TerminalOutput { private final String mCwd; private final String[] mArgs; private final String[] mEnv; + private final Integer mTranscriptRows; + private static final String LOG_TAG = "TerminalSession"; - public TerminalSession(String shellPath, String cwd, String[] args, String[] env, TerminalSessionClient client) { + public TerminalSession(String shellPath, String cwd, String[] args, String[] env, Integer transcriptRows, TerminalSessionClient client) { this.mShellPath = shellPath; this.mCwd = cwd; this.mArgs = args; this.mEnv = env; + this.mTranscriptRows = transcriptRows; this.mClient = client; } @@ -118,7 +121,7 @@ public String getTitle() { * @param rows The number of rows in the terminal window. */ public void initializeEmulator(int columns, int rows) { - mEmulator = new TerminalEmulator(this, columns, rows, /* transcript= */2000, mClient); + mEmulator = new TerminalEmulator(this, columns, rows, mTranscriptRows, mClient); int[] processId = new int[1]; mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns); diff --git a/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java b/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java index 5ee3948faf..7fb8f96397 100644 --- a/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java +++ b/termux-shared/src/main/java/com/termux/shared/models/ExecutionCommand.java @@ -81,6 +81,10 @@ public int getValue() { public String workingDirectory; + /** The terminal transcript rows for the {@link ExecutionCommand}. */ + public Integer terminalTranscriptRows; + + /** If the {@link ExecutionCommand} is a background or a foreground terminal session command. */ public boolean inBackground; /** If the {@link ExecutionCommand} is meant to start a failsafe terminal session. */ diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java index 78a381cc25..3d1ae2823a 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java @@ -3,6 +3,7 @@ import com.google.common.collect.ImmutableBiMap; import com.termux.shared.termux.TermuxConstants; import com.termux.shared.logger.Logger; +import com.termux.terminal.TerminalEmulator; import com.termux.view.TerminalView; import java.io.File; @@ -11,7 +12,7 @@ import java.util.Set; /* - * Version: v0.10.0 + * Version: v0.11.0 * * Changelog * @@ -49,6 +50,9 @@ * - 0.10.0 (2021-05-15) * - Add `MAP_BACK_KEY_BEHAVIOUR`, `MAP_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR`, `MAP_VOLUME_KEYS_BEHAVIOUR`. * + * - 0.11.0 (2021-06-10) + * - Add `*KEY_TERMINAL_TRANSCRIPT_ROWS*`. + * */ /** @@ -131,6 +135,14 @@ public final class TermuxPropertyConstants { + /** Defines the key for the terminal transcript rows */ + public static final String KEY_TERMINAL_TRANSCRIPT_ROWS = "terminal-transcript-rows"; // Default: "terminal-transcript-rows" + public static final int IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN = TerminalEmulator.TERMINAL_TRANSCRIPT_ROWS_MIN; + public static final int IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX = TerminalEmulator.TERMINAL_TRANSCRIPT_ROWS_MAX; + public static final int DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS = TerminalEmulator.DEFAULT_TERMINAL_TRANSCRIPT_ROWS; + + + /* float */ @@ -259,6 +271,7 @@ public final class TermuxPropertyConstants { /* int */ KEY_BELL_BEHAVIOUR, KEY_TERMINAL_CURSOR_BLINK_RATE, + KEY_TERMINAL_TRANSCRIPT_ROWS, /* float */ KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java index 2532a74eb0..16d0ce9c24 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java @@ -13,7 +13,7 @@ import javax.annotation.Nonnull; -public class TermuxSharedProperties implements SharedPropertiesParser { +public class TermuxSharedProperties { protected final Context mContext; protected final SharedProperties mSharedProperties; @@ -24,7 +24,7 @@ public class TermuxSharedProperties implements SharedPropertiesParser { public TermuxSharedProperties(@Nonnull Context context) { mContext = context; mPropertiesFile = TermuxPropertyConstants.getTermuxPropertiesFile(); - mSharedProperties = new SharedProperties(context, mPropertiesFile, TermuxPropertyConstants.TERMUX_PROPERTIES_LIST, this); + mSharedProperties = new SharedProperties(context, mPropertiesFile, TermuxPropertyConstants.TERMUX_PROPERTIES_LIST, new SharedPropertiesParserClient()); loadTermuxPropertiesFromDisk(); } @@ -146,24 +146,47 @@ public Object getInternalPropertyValue(String key, boolean cached) { // {@link #loadTermuxPropertiesFromDisk()} call // A null value can still be returned by // {@link #getInternalPropertyValueFromValue(Context,String,String)} for some keys - value = getInternalPropertyValueFromValue(mContext, key, null); + value = getInternalTermuxPropertyValueFromValue(mContext, key, null); Logger.logWarn(LOG_TAG, "The value for \"" + key + "\" not found in SharedProperties cache, force returning default value: `" + value + "`"); return value; } } else { // We get the property value directly from file and return its internal value - return getInternalPropertyValueFromValue(mContext, key, mSharedProperties.getProperty(key, false)); + return getInternalTermuxPropertyValueFromValue(mContext, key, mSharedProperties.getProperty(key, false)); } } + + + + /** - * Override the - * {@link SharedPropertiesParser#getInternalPropertyValueFromValue(Context,String,String)} - * interface function. + * Get the internal {@link Object} value for the key passed from the file returned by + * {@link TermuxPropertyConstants#getTermuxPropertiesFile()}. The {@link Properties} object is + * read directly from the file and internal value is returned for the property value against the key. + * + * @param context The context for operations. + * @param key The key for which the internal object is required. + * @return Returns the {@link Object} object. This will be {@code null} if key is not found or + * the object stored against the key is {@code null}. */ - @Override - public Object getInternalPropertyValueFromValue(Context context, String key, String value) { - return getInternalTermuxPropertyValueFromValue(context, key, value); + public static Object getInternalPropertyValue(Context context, String key) { + return SharedProperties.getInternalProperty(context, TermuxPropertyConstants.getTermuxPropertiesFile(), key, new SharedPropertiesParserClient()); + } + + /** + * The class that implements the {@link SharedPropertiesParser} interface. + */ + public static class SharedPropertiesParserClient implements SharedPropertiesParser { + /** + * Override the + * {@link SharedPropertiesParser#getInternalPropertyValueFromValue(Context,String,String)} + * interface function. + */ + @Override + public Object getInternalPropertyValueFromValue(Context context, String key, String value) { + return getInternalTermuxPropertyValueFromValue(context, key, value); + } } /** @@ -194,6 +217,8 @@ public static Object getInternalTermuxPropertyValueFromValue(Context context, St return (int) getBellBehaviourInternalPropertyValueFromValue(value); case TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE: return (int) getTerminalCursorBlinkRateInternalPropertyValueFromValue(value); + case TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS: + return (int) getTerminalTranscriptRowsInternalPropertyValueFromValue(value); /* float */ case TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR: @@ -263,9 +288,9 @@ public static int getBellBehaviourInternalPropertyValueFromValue(String value) { /** * Returns the int for the value if its not null and is between - * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and - * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX}, - * otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}. + * {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and + * {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX}, + * otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}. * * @param value The {@link String} value to convert. * @return Returns the internal value for value. @@ -279,6 +304,24 @@ public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(Str true, true, LOG_TAG); } + /** + * Returns the int for the value if its not null and is between + * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN} and + * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX}, + * otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS}. + * + * @param value The {@link String} value to convert. + * @return Returns the internal value for value. + */ + public static float getTerminalTranscriptRowsInternalPropertyValueFromValue(String value) { + return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS, + DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS), + TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS, + TermuxPropertyConstants.IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN, + TermuxPropertyConstants.IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX, + true, true, LOG_TAG); + } + /** * Returns the int for the value if its not null and is between * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and @@ -435,6 +478,10 @@ public int getTerminalCursorBlinkRate() { return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, true); } + public int getTerminalTranscriptRows() { + return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS, true); + } + public float getTerminalToolbarHeightScaleFactor() { return (float) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, true); } diff --git a/termux-shared/src/main/java/com/termux/shared/shell/TermuxSession.java b/termux-shared/src/main/java/com/termux/shared/shell/TermuxSession.java index 825910b1cb..5bc654ce8b 100644 --- a/termux-shared/src/main/java/com/termux/shared/shell/TermuxSession.java +++ b/termux-shared/src/main/java/com/termux/shared/shell/TermuxSession.java @@ -109,7 +109,7 @@ public static TermuxSession execute(@NonNull final Context context, @NonNull Exe Logger.logDebug(LOG_TAG, executionCommand.toString()); Logger.logDebug(LOG_TAG, "Running \"" + executionCommand.getCommandIdAndLabelLogString() + "\" TermuxSession"); - TerminalSession terminalSession = new TerminalSession(executionCommand.executable, executionCommand.workingDirectory, executionCommand.arguments, environment, terminalSessionClient); + TerminalSession terminalSession = new TerminalSession(executionCommand.executable, executionCommand.workingDirectory, executionCommand.arguments, environment, executionCommand.terminalTranscriptRows, terminalSessionClient); if (sessionName != null) { terminalSession.mSessionName = sessionName;