From d9014872c8e60adf269d4d0c71bf5234b10f2362 Mon Sep 17 00:00:00 2001 From: Akash Yadav Date: Mon, 13 Nov 2023 18:11:36 +0530 Subject: [PATCH] fix(terminal): start session in project's working directory when started from editor sidebar --- .../actions/sidebar/TerminalSidebarAction.kt | 1 + .../androidide/activities/TerminalActivity.kt | 23 ++++++------- .../java/com/termux/app/TermuxActivity.java | 34 ++++++++++++++----- .../termux/shared/termux/TermuxConstants.java | 12 +++++++ 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/itsaky/androidide/actions/sidebar/TerminalSidebarAction.kt b/app/src/main/java/com/itsaky/androidide/actions/sidebar/TerminalSidebarAction.kt index d2b6879e5..d5a623b39 100644 --- a/app/src/main/java/com/itsaky/androidide/actions/sidebar/TerminalSidebarAction.kt +++ b/app/src/main/java/com/itsaky/androidide/actions/sidebar/TerminalSidebarAction.kt @@ -51,6 +51,7 @@ class TerminalSidebarAction(context: Context, override val order: Int) : Abstrac TerminalActivity.KEY_WORKING_DIRECTORY, Objects.requireNonNull(IProjectManager.getInstance().projectDirPath) ) + intent.putExtra(TerminalActivity.KEY_SESSION_NAME, IProjectManager.getInstance().rootProject?.rootProject?.name) context.startActivity(intent) return true } diff --git a/app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt index 476ff804a..89fbfaeeb 100755 --- a/app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt @@ -16,19 +16,24 @@ */ package com.itsaky.androidide.activities +import android.content.ComponentName import android.os.Bundle +import android.os.IBinder import androidx.core.content.ContextCompat import androidx.core.view.WindowCompat import com.itsaky.androidide.utils.Environment import com.itsaky.androidide.utils.ILogger import com.termux.app.TermuxActivity +import com.termux.shared.termux.TermuxConstants import java.io.File class TerminalActivity : TermuxActivity() { companion object { - const val KEY_WORKING_DIRECTORY = "terminal_workingDirectory" + const val KEY_WORKING_DIRECTORY = TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_SESSION_WORKING_DIR + const val KEY_SESSION_NAME = TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_SESSION_NAME + private val LOG = ILogger.newInstance("TerminalActivity") private val SOURCES_LIST_CONTENT = "deb https://packages.androidide.com/apt/termux-main/ stable main".toByteArray() } @@ -46,18 +51,10 @@ class TerminalActivity : TermuxActivity() { super.onCreate(savedInstanceState) } - private val workingDirectory: String - get() { - val extras = intent.extras - if (extras != null && extras.containsKey(KEY_WORKING_DIRECTORY)) { - var directory = extras.getString(KEY_WORKING_DIRECTORY, null) - if (directory.isNullOrBlank()) { - directory = Environment.HOME.absolutePath - } - return directory - } - return Environment.HOME.absolutePath - } + override fun onServiceConnected(componentName: ComponentName?, service: IBinder?) { + writeSourcesList() + super.onServiceConnected(componentName, service) + } private fun writeSourcesList() { try { diff --git a/termux/termux-app/src/main/java/com/termux/app/TermuxActivity.java b/termux/termux-app/src/main/java/com/termux/app/TermuxActivity.java index 221c37b7c..0a458ed37 100644 --- a/termux/termux-app/src/main/java/com/termux/app/TermuxActivity.java +++ b/termux/termux-app/src/main/java/com/termux/app/TermuxActivity.java @@ -64,6 +64,7 @@ import com.termux.shared.termux.extrakeys.ExtraKeysView; import com.termux.shared.termux.interact.TextInputDialogUtils; import com.termux.shared.termux.settings.preferences.TermuxAppSharedPreferences; import com.termux.shared.termux.settings.properties.TermuxAppSharedProperties; +import com.termux.shared.termux.shell.command.runner.terminal.TermuxSession; import com.termux.shared.termux.theme.TermuxThemeUtils; import com.termux.shared.view.KeyboardUtils; import com.termux.shared.view.ViewUtils; @@ -72,6 +73,8 @@ import com.termux.terminal.TerminalSessionClient; import com.termux.view.TerminalView; import com.termux.view.TerminalViewClient; import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; /** * A terminal emulator activity. @@ -374,6 +377,16 @@ public class TermuxActivity extends BaseIDEActivity implements ServiceConnection final Intent intent = getIntent(); setIntent(null); + final String workingDir; + final String sessionName; + if (intent != null && intent.getExtras() != null) { + workingDir = intent.getExtras().getString(TERMUX_ACTIVITY.EXTRA_SESSION_WORKING_DIR, null); + sessionName = intent.getExtras().getString(TERMUX_ACTIVITY.EXTRA_SESSION_NAME, null); + } else { + workingDir = null; + sessionName = null; + } + if (mTermuxService.isTermuxSessionsEmpty()) { if (mIsVisible) { TermuxInstaller.setupBootstrapIfNeeded(TermuxActivity.this, () -> { @@ -383,7 +396,7 @@ public class TermuxActivity extends BaseIDEActivity implements ServiceConnection if (intent != null && intent.getExtras() != null) { launchFailsafe = intent.getExtras().getBoolean(TERMUX_ACTIVITY.EXTRA_FAILSAFE_SESSION, false); } - mTermuxTerminalSessionActivityClient.addNewSession(launchFailsafe, null); + mTermuxTerminalSessionActivityClient.addNewSession(launchFailsafe, null, workingDir); } catch (WindowManager.BadTokenException e) { // Activity finished - ignore. } @@ -393,14 +406,19 @@ public class TermuxActivity extends BaseIDEActivity implements ServiceConnection finishActivityIfNotFinishing(); } } else { - // If termux was started from launcher "New session" shortcut and activity is recreated, - // then the original intent will be re-delivered, resulting in a new session being re-added - // each time. - if (!mIsActivityRecreated && intent != null && Intent.ACTION_RUN.equals(intent.getAction())) { - // Android 7.1 app shortcut from res/xml/shortcuts.xml. - boolean isFailSafe = intent.getBooleanExtra(TERMUX_ACTIVITY.EXTRA_FAILSAFE_SESSION, false); - mTermuxTerminalSessionActivityClient.addNewSession(isFailSafe, null); + final Optional existingSession = workingDir == null ? Optional.empty() : + mTermuxService.getTermuxSessions().stream().filter(session -> Objects.equals( + session.getTerminalSession().getCwd(), workingDir)).findFirst(); + + if (existingSession.isPresent()) { + // requested to open a session with a specific working directory + // a session is already opened with the provided working directory + mTermuxTerminalSessionActivityClient.setCurrentSession(existingSession.get().getTerminalSession()); + } else if (workingDir != null) { + // working directory is provided, but no session has that specific CWD + mTermuxTerminalSessionActivityClient.addNewSession(false, sessionName, workingDir); } else { + // no working directory provided mTermuxTerminalSessionActivityClient.setCurrentSession(mTermuxTerminalSessionActivityClient.getCurrentStoredSessionOrLast()); } } diff --git a/termux/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java b/termux/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java index 4d3dda12b..162997d6a 100644 --- a/termux/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java +++ b/termux/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java @@ -675,6 +675,18 @@ public final class TermuxConstants { */ public static final class TERMUX_ACTIVITY { + /** + * Path to the working directory of the session which should be selected when the + * termux activity connects to the termux service. If no session's CWD is the given + * directory, a new session will be created with the given CWD. + */ + public static final String EXTRA_SESSION_WORKING_DIR = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.session_cwd"; + + /** + * The name for the session. + */ + public static final String EXTRA_SESSION_NAME = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.session_name"; + /** Intent extra for if termux failsafe session needs to be started and is used by {@link TERMUX_ACTIVITY} and {@link TERMUX_SERVICE#ACTION_STOP_SERVICE} */ public static final String EXTRA_FAILSAFE_SESSION = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.failsafe_session"; // Default: "com.termux.app.failsafe_session"