Insert a Variable Length List

Is there a way of getting Keyboard Maestro to insert a variable length list?

I want Keyboard Maestro to ask me how long the list should be.

If a length of 5, then this should be list that Keyboard Maestro types out:

If a length of 10, then this should be list that Keyboard Maestro types out:

And so on..

Yes, of course there are many ways to do something like this, but the way I would choose is this:

OOPS, I forgot the period at the end. Let me fix that. Give me a minute.

If you change the "seq" line to the following it will add the period:

seq $KMVAR_Limit | sed 's/$/./'

However now I see you may want some spaces at the beginning. How many spaces do you want? What app are you inserting your text into? This may not be the best solution to your problem, if you tell us what app you are using.

If you change the seq command as follows, it will give you exactly what you showed in your example:

seq -f %2g $KMVAR_Limit | sed 's/$/./'

Bear in mind that once you reach the number 100, the alignment won't be perfect, because you didn't say you wanted more than a single space justification. If you clarify your needs, I can probably fix it.

Following @Sleepy's lead, but assuming you don't want leading spaces if all the numbers are less than 10, you can use this for your shell script:

seq -w -s '. \n' $KMVAR_Limit | sed 's/^0/ /'

This sed will replace only one leading zero. If you expect to use this with lists longer than 99, a bit more coding will be needed.

1 Like

Yes. There's a solution for every problem, but we don't know exactly what the problem is here.

For left-padded ordinal sequences of arbitrary length, you should be able to use some variant of this pattern in an Execute JavasScript for Automation action:

Numbering.kmmacros (3.9 KB)

Expand disclosure triangle to view JS Source
(() => {
    "use strict";

    const main = () => {
        const
            kme = Application("Keyboard Maestro Engine"),
            highest = kme.getvariable("highestIndex"),
            maxWidth = highest.length,
            n = parseInt(highest, 10);

        const
            ordinalList = enumFromTo(1)(n).map(x => {
                const
                    padded = `${x}`
                    .padStart(maxWidth, " ");

                return `${padded}.`;
            })
            .join("\n");


        return (
            kme.setvariable("ordinalList", {
                to: ordinalList
            }),
            ordinalList
        );
    };

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

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    return main();
})();

Perl to the rescue.

seq -w -s '. \n' 20 | perl -ne 's!(?:\G|^)0! !g; print;'

This will handle lists less than 10 and greater than 99.

The \G assertion is not well known but is quite useful.