What is the Sort Order for Macro Names? It's not ASCII

What is the Sort Order for Macro Names? It's not ASCII.

Here is the ASCII sort order:
image

I understand that KBM uses a "number aware" sort order, as explained in Palette Macro Prefixes and Sort Order?, but I am not trying to sort a Palette, I am trying to sequence my macros as they are listed in a Macro Group. And that post from a year ago does not mention where non-numeric, non-alphabetic characters are sorted.

As the table shows, there are some characters after "z" in the ASCII sort, which I used back when I would look at the contents of a directory using "ls -d". But as far as I can tell, in a "alphabetically" sorted list of KBM Macros in a Macro Group, the macro at the bottom of the list will be "zz...", not "~~...".

Is there a list somewhere? I have not been able to find such a thing in the Wiki or the Forum.

If you are actively trying to order your macro, use the Sorting Characters.

You can control the sorting order of macros by adding two characters and a closing parenthesis (eg “01)My Macro”). The prefix will be removed before displaying in the macro palette, but will be used to control the order of the macros shown.

The sort order is localizedStandardCompare.

i.e. as in the Finder

localizedStandardCompare: | Apple Developer Documentation

Probably worth bearing in mind that ASCII hasn't been a default (even for the small proportion of the world's devices that happen to be located in the US) for quite some time now, and UTF-8 (big, polyglot, open to expansion) serves a slightly different purpose.

Particular lexical sort orders are defined for the conventions, diacritics, and cases (if any) etc etc of each locale.

Thanks. That's what I'm already doing. I'm trying to force specific items to always be at the top or bottom of a subgroup identified by the Sorting Characters. The idea is break up a long list of macros in a group into chunks.

image

I can use "Space" to always be at the top of a set. But my real question is, other than trial and error, is there any way to determine if there is any character in the local sort order that comes after "z"?

And yet, it seems to be the only actual LIST that I've been able to find.

I understand that it will vary by locale, but how do I find an ordered list for my locale, other than building it by hand (or programmatically) to find out what it is?

Not quite sure that I have entirely understood yet – inside a Keyboard Maestro Macro group, you can, of course, change the sort order by clicking one of the sort triangles above the macro names and hotkey names columns respectively.

The ordering you speak of is for somewhere else ?

I don't have a sense of how you plan to use the character sort list, or of exactly what problem you are addressing there.


In the meanwhile, for:

  • the set of characters you show in that ASCII list, and
  • the locale 'en'

you should be able to generate a character sequence from an Execute JavaScript for Automation action by writing something like:

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

    // locale :: String
    const locale = "en";

    // A subset of characters in a locale-specific sort order.

    // main :: IO ()
    const main = () =>
        enumFromTo(
            ord(" ")
        )(
            ord("~")
        )
        .map(chr)
        .sort(
            (a, b) => a.localeCompare(
                b, locale, {sensitivity: "base"}
            )
        )
        .join("\n");


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

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


    // chr :: Int -> Char
    const chr = x =>
    // The character at unix code-point x.
        String.fromCodePoint(x);


    // ord :: Char -> Int
    const ord = c =>
    // Unicode ordinal value of the character.
        c.codePointAt(0);

    return main();
})();

obtaining, for example:

_
-
,
;
:
!
?
.
'
"
(
)
[
]
{
}
@
*
/
\
&
#
%
`
^
+
<
=
>
|
~
$
0
1
2
3
4
5
6
7
8
9
A
a
B
b
C
c
D
d
E
e
F
f
G
g
H
h
I
i
J
j
K
k
L
l
M
m
N
n
O
o
P
p
Q
q
R
r
S
s
T
t
U
u
V
v
W
w
X
x
Y
y
Z
z

Not really, no. It depends on your locale.

If you want to leave room for later additions, I suggest you do something like

BB, BE, BJ, BM, … XB, XE, XJ, XM.

Then you have gaps and all of A and Z unused.

If you actually want such characters, there are many code blocks in unicode positions beyond the unaccented Roman characters.

Try, Greek, Hebrew, CJK, for example.

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

    // locale :: String
    const locale = "en";

    //  EN SORT ORDER INCLUDING NON-EN CHARACTERS

    // main :: IO ()
    const main = () =>
        "XxYyZzאבג甲乙丁ΑαΒβΓγ"
        .split("")
        .sort(
            (a, b) => a.localeCompare(
                b, locale, {sensitivity: "base"}
            )
        )
        .join("\n");


    return main();
})();

yielding:

X
x
Y
y
Z
z
Α
α
Β
β
Γ
γ
א
ב
ג
丁
乙
甲

Thanks for the detailed and helpful answer, @ComplexPoint,

I'm aware of that choice, but it doesn't help. As far as I can tell, those triangles only offer the binary choice of Sort by Name and Sort by Hotkey, it doesn't even allow you to reverse the order.

I am trying to sort the list of macros and subroutines in a KBM macro group into subgroups and to separate the subgroups by markers/delimiters in a way that I find readable and organized according to how I'm developing the bits and pieces and how I think of the flow and priority of the macros/subroutines.

It's just about readability and meaning.

Meanwhile, thank you for the list.

It makes it clear that for "normal" characters, "z" is indeed the last in the list.

That is an example, for me, of doing it "building it by hand (or programmatically) to find out what it is", and seems like it would have been hours for me to generate, which is why I was asking for an existing list. I hope it was something that you were able to knock out as simply and directly as I am able to write these paragraphs. Thanks again.

Thanks @peternlewis, for your example:

That makes it clear what it is that I need to do and also makes it clear that I was making the whole thing harder on myself by trying to also add meaning to the Sort Characters. I think that was part of what was tripping me up.

And @ComplexPoint, thanks for the suggestion

That does solve my initial problem. In fact, since the Hebrew character א is used in mathematics for Infinity, especially comparing infinities, I might use that as my Ultimate End character.

Solved. Thanks.

2 Likes

( and you could also use ,
if the RTL behaviour of א proved challenging)

1 Like

Foo. "" sorts before "1".

1 Like

Omega ?

ω

( Ω )

Thanks for that comment about RTL. I think that only applies if it is inserted as literally a Hebrew Language character. When I had just that character in my clipboard, copied from your post above, my clipboard manager showed that particular line in RTL order, with the character at the left and the item number at the right.

image

However, when I insert the Alef Symbol from the Emoji and Symbols viewer, in the Math Symbols group, there is no RTL problem.

And most interesting, WRT the OP, is that every other one of the Math Symbols that I have tried (∞∐≡⊔⊥⊲⊻⨠⩡⫤⟩⟫⊒ etc.), plus the various arrows, bullets, parentheses, etc., all sort before "1" -- except the Alef Symbol, which sorts after "z". It appears to be the only symbol accessible from the Emoji and Symbols tool that sorts that way. And being a Math Symbol, it has no RTL issue.

(Of course, real Greek and CJK symbols also sort after "z", but they aren't as accessible while I'm typing.)

So my new naming pattern, using the Sorting Characters is:

  • A ) or A_) Initial Delimiter to start the A sub-group.
  • A-) or A:) Title of A sub-group.
  • A!) A?) A=) Additional Description of A sub-group, if needed.
  • A$) A0) Initialization macros in A sub-group, if needed.
  • A1) ... A9), AA), Aa), ... AZ), Az). Up to 61 items in the A sub-group.
  • Aℵ) Final Delimiter to end the A sub-group, if needed (using Emoji and Symbols > Math Symbols > Alef Symbol)

That's a lot of detail, most of which I will probably hardly ever use. But it does give me a way to apply a kind of outline form to a long list of macros within a group. Which was the original point.

Who knows, I'll probably have a different idea the fourth or fifth time I use it. And it will all change if KBM gets real sub-groups for macros, as has been requested.

Honestly, this question does not really make sense to ask.

The list is sorted in a localized case insensitive manner, and so the ordering of characters is entirely at the whim of the system, and could change if you change your locale.

I expect there are not any locales that rearrange the ASCII letters A…Z, but there are certainly other characters that could fit within that range (eg é), or could be outside that range, depending on the locale sorting order.

Of course it could change if I change my locale, but I'm unlikely to suddenly switch from my native English to working on my Mac in French, German, or a non-Latin-alphabet language. That's why I asked:

[Emphasis added]

This is not something I am developing for public, international consumption, it's as personal as my own daily to-do list. Now that I know it's basically a system locale issue, my question might have been better stated as asking whether or not, perhaps in the locale definition somewhere in a system plist file, there was perhaps a list that defined the sort order for the current locale.

The answer seems to be, as far as I understand the issue at this point:

No, for English locale settings, there is nothing in the standard keyboard character set that comes after "z", although you could theoretically force something by defining your own custom locale sort order. For the broad range of non-English keyboard characters, symbols, emojis, etc, that can be used in macro names, most non-English language characters sort after "z" and most special symbols sort before "0", but this is inconsistent, so trial and error will be required. The same will be true for other locales.

And by the way,

This is first time I have seen anyone shot down for asking a question on this forum. I'm sorry that my question irks you. @ComplexPoint and I seemed to be having a little fun with it and I learned a bit about locale settings. Isn't that the point?

You are misunderstanding my comment. I am not suggesting not asking the question — how else would someone learn without asking. I am simply pointing out that there is no one answer to the question without specifying the locale (and even then its likely subject to change).

If you want an answer with a specific locale, fair enough. I'd still recommend sticking to ASCII A-Z (or 0-9) sort characters if you want explicit control over the sort order.

2 Likes