How can I access the "selected_text" variable from Shell script?

Sorry I really forgot to implement this. I'll add it to the next alpha, you'll then just be able to query the selected_text variable.

For now, you can still do it, here is an example using the "Execute Real JavaScript" action, which speaks the selected text using the "say" command line utility:


(async () => {

// 256 is the identifier of the "save selected text to variable" action
let actionDefinition = {
  "BTTPredefinedActionType" : 256
};

// save the selected text
 await callBTT('trigger_action', {json: JSON.stringify(actionDefinition), wait_for_reply: true});

let selectedText = await callBTT('get_string_variable', {'variable_name': 'selected_text'});

let shellScript = `say ${selectedText}`;

let shellScriptWrapper = {
    script: shellScript, // mandatory
    launchPath: '/bin/bash', //optional - default is /bin/bash
    parameters: '-c', // optional - default is -c. If you use multiple parameters please separate them by ;; e.g. -c;;date
    environmentVariables: 'PATH=/usr/bin' //optional e.g. VAR1=/test/;VAR2=/test2/;
};

let result = await runShellScript(shellScriptWrapper);

returnToBTT(`{BTTMenuItemText: "${x}" }`);
})()


A wait, there is an easier way. Use the "Transform & Copy Selection With JavaScript" action like this:

async (clipboardContentString) => {
  let shellScript = `say ${clipboardContentString}`;

let shellScriptWrapper = {
    script: shellScript, // mandatory
    launchPath: '/bin/bash', //optional - default is /bin/bash
    parameters: '-c', // optional - default is -c. If you use multiple parameters please separate them by ;; e.g. -c;;date
    environmentVariables: 'PATH=/usr/bin' //optional e.g. VAR1=/test/;VAR2=/test2/;
};

let result = await runShellScript(shellScriptWrapper);  
 return "done";
}

(although this version will replace your clipboard content)

Giving it a go now! I mostly used BTT for my TouchBar, and after upgrading to a Mac without one (boo I loved my TouchBar — mostly due to BTT) I wasn't sure it was going to be worth it to buy a lifetime license when my yearly ran out.

I did buy that lifetime license though, since you're one of the most active and responsive developers of any app I've ever used and I figured it would end up well worth it. With these floating menus it's made my license worth every penny!

In just five minutes I've been able to use them to fill at least part of the hole left by TotalSpaces dying (lovely little floating grid to navigate directly to any space) and added several little workflow tweaks that I'm certain will pay dividends! Amazing new addition. I will try your suggestions! Replacing the clipboard is no big issue for now, but I'll definitely look forward to being able to query the selected_text variable when you have time to add it (though no rush given the perfectly viable alternatives you've suggested).

Edit: Somehow managed to write all that without actually saying THANKS!

That's great!
I also think the floating menus have great potential. Just need to work a lot on the documentation :slight_smile:

Thanks, I am also looking forward to using selected text in shell script, the use case for me is that I want to pipe the output of shellscript to vscode.
With javascript I am not sure How do i do that.

the variable is now available - also from javascript you can easily run shell scripts like described here: Using Java Script (not JXA) · GitBook

Wow, Do you have an example of that variable ?
I am currently doing the same using Popclip app but that is not extensible, if I can get this to run via BTT, then I can add this to floating menu

random_file="/Users/abc/throwaway/$(openssl rand -hex 8).json"; python3 /Users/abc/python_files/display/GammaCurl.py "$POPCLIP_TEXT" > "$random_file"; code "$random_file"; sleep 1; rm "$random_file"

I think this should work when using the "run real javascript" action. You might need to provide environment variables if the python script depends on some.

(async ()=> {

let selectedText = await callBTT('get_string_variable', {variable_name:'selected_text'})


// put the shell script into a string (single backticks are great for multiline strings)
let shellScript = `random_file="/Users/abc/throwaway/$(/usr/bin/openssl rand -hex 8).json"; /usr/bin/python3 /Users/abc/python_files/display/GammaCurl.py "${selectedText}" > "$random_file"; code "$random_file"; sleep 1; rm "$random_file"`;


let shellScriptWrapper = {
    script: shellScript, 
    environmentVariables: 'PATH=/usr/bin/' //optional e.g. PATH=/test/;VAR2=/test2/;
};

let result = await runShellScript(shellScriptWrapper);
returnToBTT(result)


})();











Thanks for getting back. I tried 2 things and both of them failed to fullfill my usecase

  1. Tried your method which you posted above , The problem is that selected text is getting cut off in between when I try to select the complete JSON request that I am trying to curl. I verified that by just using the below and piping it to vscode to check the selected text
echo "${selectedText}"
  1. Tried to directly use the ${selected_text} variable using the Execute shell script Action, the variable does not seem to work and is not selecting any text.

maybe there is a misunderstanding, this variable does not select text - it contains the currently selected text

Thats my understanding too, so using mouse I select the complete json request which I have in an editor and execute this BTT script.

This can only work if you use the run real javascript action and get the variable value first

let selectedText = await callBTT('get_string_variable', {variable_name:'selected_text'})

Here is a fully working script, which uses the say command to speak the selected text:

(async ()=> {

let selectedText = await callBTT('get_string_variable', {variable_name:'selected_text'})


// put the shell script into a string (single backticks are great for multiline strings)
let shellScript = `say ${selectedText}`;


let shellScriptWrapper = {
    script: shellScript
 
};


let result = await runShellScript(shellScriptWrapper);
returnToBTT(result)


})();











Yes, Sorry if I was not clear earlier. I Used the whole script that you pasted and instead of running my python script, just to check if the selected text is properly being selected or not, i used echo
Here is the script that I run and saw that selected text is getting cut off and it is not selecting the complete text that is meant to be selected, is there some cap on selection?

(async ()=> {

let selectedText = await callBTT('get_string_variable', {variable_name:'selected_text'})


// put the shell script into a string (single backticks are great for multiline strings)
let shellScript = `random_file="/Users/abc/throwaway/$(openssl rand -hex 8).json"; echo "${selectedText}" > "$random_file"; code "$random_file"; sleep 1; rm "$random_file"`;


let shellScriptWrapper = {
    script: shellScript, 
    environmentVariables: 'PATH=MY PATH (Cant share)' //optional e.g. PATH=/test/;VAR2=/test2/;
};

let result = await runShellScript(shellScriptWrapper);
returnToBTT(result)


})();

There shouldn't be, does the slected text contain quotes? If so they would need to be escaped first, maybe something like this would work:

(async ()=> {

let selectedText = await callBTT('get_string_variable', {variable_name:'selected_text'})
let escapedSelectedText = JSON.stringify(selectedText).slice(1, -1);


// put the shell script into a string (single backticks are great for multiline strings)
let shellScript = `random_file="/Users/abc/throwaway/$(openssl rand -hex 8).json"; echo "${escapedSelectedText}" > "$random_file"; code "$random_file"; sleep 1; rm "$random_file"`;


let shellScriptWrapper = {
    script: shellScript, 
    environmentVariables: 'PATH=MY PATH (Cant share)' //optional e.g. PATH=/test/;VAR2=/test2/;
};

let result = await runShellScript(shellScriptWrapper);
returnToBTT(result)


})();

It does contain quotes, Its a proper JSON request that I will be making to a service. I am not sure if I can share the request or the text , but let me try to anonymize it and share

Ah, then with the initial version it would cut off at the first quote because it would insert the whole selected text with the quote in the command (and the command itself expects a quote to end the "echo"

Did not get what you meant.
Its still not working, I suspect it has something to do with string itself, but I am not able to figure it out
Here is the request I am trying to select

The Problem is there is a user agent string in the request and that is causing some problems. I can take it from here. Thanks for your help :slight_smile:

"Dalvik/2.1.0 (Linux; U; Android 7.1.2; AFTMM Build/NS6287)"

This string is causing problems

Weird, I don't see anything that would need further escaping in this :-/