Blank Form/Spreadsheet of all Key Combination Hot-Keys for a standard 101-keyboard


Between Keyboard Maestro and the DAW I use, I'm beginning to lose track of what keyboard hot-key combinations that aren't in-use and I actually still have free.

Keyboard Maestro makes that very easy to see, but not my DAW application, unfortunately!

Does anyone know of a blank spreadsheet that has all of the possible key-combinations for a 101-standard-keyboard?

That way I could just fill it in as I go, and see which ones remain free.

I did some searching on the web but have had no luck so far.


That would be a very large spread sheet.

There are four modifiers, so that is 16 possibilities, so even leaving off most of the keys, that is roughly 1300 entries.

Can you really remember that many?

I would suggest you are better off using the Conflict Palette to trim down the numbers and to provide a second level with prompting. You can then press a single first hot key and then a second key from a selection provided to perform your task.

But if you really want a list of all possibilities, it would not be overly hard to generate it based on the set of possible modifiers and the set of possible keys.

Hey thank you!

Wow I didn't realize that it would create that many possibilities, though it is nice to know that there are that many available!

The conflict pallets is terrific.

The problem is not Keyboard Maestro, it's my DAW (Motu DP) that won't let you search commands by key-combo (only by name).

Thanks again!

If you want to paste a column of all 15 combinations of modifier keys into Excel for example, you could use the toy macro below.

(The 16th combination is, of course, the plain key with no modifier held down)


Paste a column of all modifier-key combinations.kmmacros (19.7 KB)

JS Source

(() => {
    'use strict'

    // Rob Trew (c) 2018

    const main = () =>
                subsets(['⌘', '⌥', '⌃', '⇧'])

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


    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (() => {
            const unit = 'string' !== typeof xs[0] ? (
            ) : '';
            return unit.concat.apply(unit, xs);
        })() : [];

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) =>;

    // subsets :: [a] -> [[a]]
    const subsets = xs => {
        const go = ys =>
            0 < ys.length ? (() => {
                const subs = go(ys.slice(1));
                return subs.concat(
           => [ys[0]].concat(zs))
            })() : [
        return go(xs);

    // tail :: [a] -> [a]
    const tail = xs => 0 < xs.length ? xs.slice(1) : [];

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // MAIN ---
    return main()

1 Like


You are so kind to do this!

I'm going to use it right now.

Thanks again!

1 Like

He probably can : -)

( Literacy in Chinese, for example, involves memory of 4000+ characters )

1 Like

Seriously, it helps so much.

Keyboard Maestro (much love!) lets you see conflicts, but not my other DAW software.

Again, THANKS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Good !

In case its of interest to anyone, here is an AppleScript parallel translation.

(Both are clicked together by pasting five standard functions)

Applescript source

-- List of all 15 modifier-key combinations,
-- for pasting as an Excel column, etc

-- Rob Trew (c) 2018

on run
    unlines(tail(map(concat, ¬
        subsets({"⌘", "⌥", "⌃", "⇧"}))))
end run

-- GENERIC FUNCTIONS ----------------------------------------------


-- concat :: [[a]] -> [a]
-- concat :: [String] -> String
on concat(xs)
    set lng to length of xs
    if 0 < lng and string is class of (item 1 of xs) then
        set acc to ""
        set acc to {}
    end if
    repeat with i from 1 to lng
        set acc to acc & item i of xs
    end repeat
end concat

-- Lift 2nd class handler function into 1st class script wrapper 
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    if class of f is script then
            property |λ| : f
        end script
    end if
end mReturn

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- subsets :: [a] -> [[a]]
on subsets(xs)
    script go
        on |λ|(ys)
            if 0 < length of ys then
                set subs to |λ|(rest of ys)
                set y to item 1 of ys
                script ycons
                    on |λ|(zs)
                        {y} & zs
                    end |λ|
                end script
                subs & map(ycons, subs)
            end if
        end |λ|
    end script
    go's |λ|(xs)
end subsets

-- tail :: [a] -> [a]
on tail(xs)
    if xs = {} then
        missing value
        rest of xs
    end if
end tail

-- unlines :: [String] -> String
on unlines(xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set str to xs as text
    set my text item delimiters to dlm
end unlines

PS Applying Lucida Grande as the font for these modifier characters improves legibility.

1 Like

That you i will try that.

I started to set it up in Excel yesterday, and was indeed surprised at how many combinations are available.

I' happy I'll have enough key-combos available for just about everything.

Thanks again!

Just tried Lucida Grande, and it is way more instantly legible.

It's not a font I would have thought of, but now It makes me think about using that font for other uses.