Permanent Display of Variable

Is there a way to permanently display the contents of a variable? All i see in notifications are error like warnings or prompts. I like to have a display somewhere on my screen that shows a variable and if the variable changes reflect that change too. I could close and reopen the window but i find that distracting.

Woud it be possible to use a pallete for this? that means that i have to name a macro after the content of a variable...

I haven't done this myself, but others have found ways to do this. Read through this discussion Übersicht - display widgets on your desktop to see how.

1 Like

That sure looks interesting. Will investigate, thanks @tiffle !

1 Like

For unoccluded display on the menu bar (rather than on the Desktop) you could also try things like [TextBar - Mac App](http://richsomerfield.com/apps/textbar/)

(I use this during 25min 'pomodoro' sprints, with a countdown value appended, to keep the goal in view)

Screenshot 2020-10-26 at 13.00.35

Sample TextBar script – reads 2 KM values
osascript -l JavaScript <<JXA_END 2>/dev/null
(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
// -------------------- MAIN ---------------------
        const
            kme = Application('Keyboard Maestro Engine'),
            minsLeft = Math.round(
                (
                    new Date(
                        kme.getvariable('sprintEnd')
                    ) - (new Date())
                ) / (60000)
            ),
            strSteps = kme.getvariable('focalBanner');
        return strSteps ? (
            '<html><font style=color:#FFA361; font-family:"Menlo">' + (
                strSteps + ' (' + str(minsLeft) + 'm)</font></html>'
            )
        ) : '⚫';
    };

    // ---------------------- GENERIC ----------------------

    // str :: a -> String
    const str = x =>
        Array.isArray(x) && x.every(
            v => ('string' === typeof v) && (1 === v.length)
        ) ? (
            x.join('')
        ) : x.toString();

    // MAIN ---
    return main();
})();
JXA_END

If, like me, you have a lot of stuff on the menu bar already Textbar might be one extra too far! (And I already use Bartender.)

Also, am I right in thinking that instead of KM needing to push information to Textbar, you have to tell Textbar how frequently it should update its display of information? So potentially there’s a lag between something updating in KM and it being displayed by Textbar.

That's right. TextBar pulls. At whatever frequency you specify.

(For my 25min countdown purpose, I think it's doing that about every 10 seconds).

====> :+1:

Thanks Complex•
But i am lost in how to implement a JavaScript in KM and how to push that to TextBar.
Lost of reading to do i am afraid.
Would you mind posting a simple KM macro with a simple script?

Perhaps not permanent in the strict sense but more like sticky, you can open the Keyboard Maestro editor's Preferences, click on Variables and see all your variables and their values.

The Search field lets you filter the list down to a precious few, if desired.

No need. You just set the variable in KM in any way that you like.

  • KM doesn't doesn't have to push to TextBar
  • TextBar runs a shell script every few seconds (you decide how often, in its Preferences), and the shell script reads one or more KM variables.
  • The shell script is pasted into a field in TextBar preferences.

This is a sample shell script, which can be pasted straight into the TextBar script field:

(In the shell, its uses the osascript command to run a JS snippet which reads one or more KM variables):

osascript -l JavaScript <<JXA_END 2>/dev/null
(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
// -------------------- MAIN ---------------------
        const
            kme = Application('Keyboard Maestro Engine'),
            minsLeft = Math.round(
                (
                    new Date(
                        kme.getvariable('sprintEnd')
                    ) - (new Date())
                ) / (60000)
            ),
            strSteps = kme.getvariable('focalBanner');
        return strSteps ? (
            '<html><font style=color:#FFA361; font-family:"Menlo">' + (
                strSteps + ' (' + str(minsLeft) + 'm)</font></html>'
            )
        ) : '⚫';
    };

    // ---------------------- GENERIC ----------------------

    // str :: a -> String
    const str = x =>
        Array.isArray(x) && x.every(
            v => ('string' === typeof v) && (1 === v.length)
        ) ? (
            x.join('')
        ) : x.toString();

    // MAIN ---
    return main();
})();
JXA_END

For example, assuming that the shell script above has been pasted in the script field of the TextBar Preferences dialog:

Textbar variables for a 25min sprint.kmmacros (20.2 KB)

Yes. You can use the Value Inspector Window.

1 Like

yes, but that is in the KM editor.... that's not what i meant.

The Value Inspector can float in all windows if you just want to be able to see the value, but if your aim is to display the value (like a stock ticker or something), then that is probably not what you want.

You can do it with a periodically updating Custom HTML Prompt action (or updating it when you change the value of the variable, since you presumably know when that happens).

2 Likes

@peternlewis
How do i update the custom HTML prompt? Or, do you mean, closing it and opening an new (updated) one? Or, can i update the prompt itself?

You can do this using JavaScript:
See Reload JavaScript function on a timer

In this function you need to:

  1. Get the KM Variable
  2. Update the HTML on the page that uses that Variable.

After a long pause...Thanks Michael. And Peter.
But i am still stuck. Sorry, i think i miss something basic.
I have a KM script.
I can display a variable in the HTML prompt.
Now the script comes in a loop For Each... etc and now i want to update my HTML prompt within this loop so the progress (which is reflected by a variable) of my For Each loop will be shown in the HTML prompt.So, i want to involve an action within the loop that updates my HTML prompt.
How does that action look like?