Terminal: added ability to execute a command using scripting

Add a B_EXECUTE_PROPERTY to execute a given command.

Also set fAttached to false in _DetachShell() for symmetry.

Done by Andrea Anzani plus some style / refactoring by myself
Change-Id: Ifa26b60b1c1d3598a863adc4fb701155f9edf588
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9154
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
JackBurton79
2025-04-09 11:19:17 +00:00
committed by Adrien Destugues
parent ace1f642d0
commit 197dcc80dc
3 changed files with 65 additions and 20 deletions
+3 -1
View File
@@ -312,8 +312,10 @@ Shell::AttachBuffer(TerminalBuffer *buffer)
void
Shell::DetachBuffer()
{
if (fAttached)
if (fAttached) {
fTermParse->StopThreads();
fAttached = false;
}
}
+58 -18
View File
@@ -18,15 +18,12 @@
#include "TermView.h"
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <algorithm>
#include <new>
#include <vector>
#include <Alert.h>
#include <Application.h>
#include <Beep.h>
@@ -87,7 +84,11 @@ static property_info sPropList[] = {
{B_GET_PROPERTY, 0},
{B_DIRECT_SPECIFIER, 0},
"get tty name."},
{ 0 }
{ "command",
{B_EXECUTE_PROPERTY, 0},
{B_DIRECT_SPECIFIER, 0},
"execute command"},
{ 0 },
};
@@ -245,13 +246,8 @@ TermView::TermView(BMessage* archive)
fRows = ROWS_DEFAULT;
int32 argc = 0;
if (archive->HasInt32("argc"))
archive->FindInt32("argc", &argc);
const char **argv = new const char*[argc];
for (int32 i = 0; i < argc; i++) {
archive->FindString("argv", i, (const char**)&argv[i]);
}
const char** argv = NULL;
_GetArgumentsFromMessage(archive, argv, argc);
// TODO: Retrieve colors, history size, etc. from archive
status_t status = _InitObject(ShellParameters(argc, argv));
@@ -365,12 +361,7 @@ TermView::_InitObject(const ShellParameters& shellParameters)
ShellParameters modifiedShellParameters(shellParameters);
modifiedShellParameters.SetEncoding(fEncoding);
error = fShell->Open(fRows, fColumns, modifiedShellParameters);
if (error < B_OK)
return error;
error = _AttachShell(fShell);
error = _AttachShell(fShell, modifiedShellParameters);
if (error < B_OK)
return error;
@@ -992,12 +983,30 @@ TermView::_InvalidateTextRange(TermPos start, TermPos end)
}
void
TermView::_GetArgumentsFromMessage(const BMessage* message, const char**& argv, int32& argc)
{
type_code type;
if (message->GetInfo("argv", &type, &argc) == B_OK) {
argv = new const char*[argc + 1];
int32 i = 0;
while (message->FindString("argv", i, &argv[i]) == B_OK)
i++;
argv[i] = NULL;
}
}
status_t
TermView::_AttachShell(Shell *shell)
TermView::_AttachShell(Shell *shell, const ShellParameters& shellParameters)
{
if (shell == NULL)
return B_BAD_VALUE;
status_t status = shell->Open(fRows, fColumns, shellParameters);
if (status != B_OK)
return status;
fShell = shell;
return fShell->AttachBuffer(TextBuffer());
@@ -1745,6 +1754,37 @@ TermView::MessageReceived(BMessage *message)
break;
}
case B_EXECUTE_PROPERTY:
{
int32 i;
BMessage specifier;
if (message->GetCurrentSpecifier(&i, &specifier) == B_OK
&& strcmp("command",
specifier.FindString("property", i)) == 0) {
Shell* shell = _DetachShell();
shell->Close();
int32 argc = 0;
const char** argv = NULL;
_GetArgumentsFromMessage(message, argv, argc);
if (message->GetBool("clear", false))
Clear();
ShellParameters shellParameters(argc, argv);
shellParameters.SetEncoding(fEncoding);
_AttachShell(shell, shellParameters);
delete[] argv;
message->SendReply(B_REPLY);
} else {
BView::MessageReceived(message);
}
break;
}
case B_MODIFIERS_CHANGED:
{
_UpdateModifiers();
+4 -1
View File
@@ -197,7 +197,10 @@ private:
status_t _InitObject(
const ShellParameters& shellParameters);
status_t _AttachShell(Shell* shell);
void _GetArgumentsFromMessage(const BMessage* message,
const char**& argv, int32& argc);
status_t _AttachShell(Shell* shell, const ShellParameters& shellParameters);
Shell* _DetachShell();
void _Activate();