Finding a partial match in $Name

I’m overwhelmed with shortcuts (DEVONthink has too many, and so do some others) so I am trying to document them. I have each shortcut as a separate note, with $Name in the format:

⌃⌥⌘L Lock 1Password

I would like to find conflicts (and perhaps flag or colour the notes as a warning), which means matching the shortcut element (⌃⌥⌘L) of $Name but not the menu item it corresponds to, which will differ according to program.

I would think this might be done by creating an agent that queries the first part of $Name, but I’m not sure how this might be done (regex?).

Any ideas very welcome.

Cheers,
Martin.

Note that ^ is a long-standing regex term for ‘start of string’. I think you want:

\⌃⌥⌘L

That works for me here on v8.7.1.

If you’ve not discovered it already, see my page here.

These apps can also be useful in figuring out shortcuts and clases: CheatSheet (free), ShortcutDetective (free), KeyCue (€€)

Thanks Mark. That will get me started.

I have both KeyCue and CheatSheet, but I want my own documentation. They both tell you what shortcuts are operational in the frontmost program, but I want to know how the same shortcut is used in a number of programs. I envisage an agent that might tell me all the programs that use ⌃⌥⌘[somecharacter] or something of the sort. I will have a play.

I’ve folowed the same path (witness the reference to 1Password). There isn’t an app that works quite in the way you describe but ShortcutDetective is probably as close as it gats for an ordinary user (as opposed to a coder/app creator). IIRC, kudos goes to Howard Oakley (check out his blog) for suggesting the app.

Thanks Mark. Yes, I have come to appreciate Howard Oakley’s insights and knowledge. He doesn’t follow the same well-worn groove (almost a trench by now) of other observers of Mac affairs.

On the original subject, is it possible to construct a query in Tinderbox that would look for $Name where the format is [duplicated element]&“some other text”? I know that isDuplicateName exists, but I’ve no understanding of how it works or if I can use it to find shortcut conflicts in the way I’ve described. Maybe this is rather a unique use-case, but it would be interesting to know if you can pull out Notes where part of the name is a duplicate, not the whole of the name being duplicated.

Cheers.

How do you divine the ‘duplicated element’ value. One route (not tested fully) would be to make an additional (user) string attribute $MyString2 and set $MyString and $MyString2 as KA in your agent. $MyString would hold the ‘duplicated element’ and $MyString2 the ‘some other text’. Then the query could be:

$Name==($MyString(agent) & $MyString2(agent))

The extra parentheses are to tell Tinderbox to concatenate the two strings at the right before matching it to $Name of the tested item.

Of course, if either/both of those strings are stored somewhere a more automated method is possible. If nothing else, the above gives a starting test rig.

OK, so I’m thinking that it makes more sense to extract the “shortcut” element from $Name and put that into a user attribute called $MyShortCut, and the rest of the $Name into one called $MyMenuItem, then I can test to see if there is more than one instance of $MyShortCut in the database. Though come to think of it I’m not sure how one would find a duplicate of a user attribute.

As you may surmise, I’m still trying to understand:

It may take me a while to work that out!

In case it wasn’t clear, this is all about finding shortcut conflicts. I would like to zap the buggers. But I can’t do that until I am sure what they are! And I would like to document what I have done to them, just in case I need to return them to what they were. Or I need to reinstall software, which has a habit of undoing lots of work. And I have found the problem with that is that I forget what I did, or how I arrived at things. Better documentation is not just a problem for you!!

So, my adventures with regex continue. According to a little program called Expressions, this:

^(.{1,3}\s.)

Should find the element ⌥⇧⌘ L in ⌥⇧⌘ L Link to x (in $Name).

If I construct a query:

descendedFrom("Content")&$Name.icontains("^(.{1,3}\s.)")

I get about a quarter of the hits I should. If I eliminate \s I go from about 110 hits to 400.

I have also tried descendedFrom("Content")&$Name.icontains("^.{1,3}\s.") but that does not change the result.

Looking at the text in BBEdit suggests that there is indeed a space and not something else in the problem position.

Any ideas?

Before testing lots of things it isn’t (regex are very precise), could you post a small TBX test file so we can work against a common reference. I couldn’t recreate your result but without a common reference this can be hard to resolve.

Incidentally, I assume that here:

$Name.icontains("^(.{1,3}\s.)")

…the inner parentheses are because you want to create a back-reference? If you are trying to match literal parentheses, these must be escaped, e.g. \( and \). the above match means “from the start if the string, open a back reference, match any character between 1 and 3 times (inclusively) , match a single whitespace character, match any character once, close the back-reference”.

I note we are using symbol characters in match which might be a factor but again in cases like this we need to ensure we’re all testing exactly the same thing and not we each assume is meant by the text examples above.

Although I can’t find it documented, I’ve a vague recollection that when using back-references the pattern must match the whole string. IOW:

$Name.icontains("^(.{1,3}\s.).*")

…which extends the the above logic by (after closing the back-reference) match zero or more characters (i.e. to the end of the string).

There’s no requirement for the pattern to match the whole string, though this improves performance in longer texts because, in the example above, we could look at the $Name

ESTHER: Now it came to pass in the days of Ahaseurus, (this is Ahaseurus which reigned from India even unto Ethiopia, over an hundred and seven and twenty provinces:) that in those days…

and reject it immediately because it does not have whitespace \s where the pattern expects it. But if we did not have the initial ^, we’'d have to scan through the whole Megillah.

Thanks for looking at this. I’m a little puzzled.

Test_regex.tbx (99.7 KB)

I also took a couple of screenshots.

Removing the white space makes a difference to the result that I didn’t expect.

Cheers!
M.

To extract N different accelerator keys, a space and a letter or number, I used this:

^[^\s]{1,4}\s\w

…otherwise the ‘⌘ L’ item is detected but not for the right reasons. This works in Expressions and in BBEdit grep. No idea why it’s not working the same in Tinderbox.

Thank you! Remarkable sleuthing. I would never have arrived at that.

Onwards! :wink:

Hmm! Unfortunately, it doesn’t seem to work here.

Not to worry. This is probably something to be done in another app, like Nisus, then put in a spreadsheet. I’ll look at some options. But thanks for trying.

I think it’s a Unicode/symbol related thing. Using the same query as your last example I added some tests without symbols and they work as expected:

This doesn’t therefore look like a simple user input error, or the new examples should fail. I think it probably needs looking at under the hood by support. I’ve sent an email.

Small correction - not that is makes things work:

^[⌃⇧⌥⌘]{1,4}\s\w

The first character is the caret (Shift+6) and is the regex start of string character. The second instance is a different, symbol character Unicode #2303, the “UP ARROWHEAD”.

I’d not try to fix this for now until we have a steer as to how Tinderbox’s regex engine is handling these unicode symbol characters.

Many thanks. I usually assume I must have done something wrong – which is usually true – so it would be a novelty for it not to be my fault :slight_smile:

Cheers!

If it under the hood, a fix might take a bit, so I’ve just tested a fix that seems to work. First, put square brackets around your shortcut. So ⌥⌘ N Menu text becomes [⌥⌘ N] Menu text, etc. Now use the query:

descendedFrom("Content")&$Name.icontains("^\[.+\]")

This gets round the undiagnosed problem of matching symbol characters (higher order Unicode codes). Instead, we match: from string start, a single left [, one of more of any character, until a single right ].

Thus from “[⌥⌘ N] Menu text”, the agent matches “[⌥⌘ N]” If you want, you could put the closing ] before the first space but the letter is also part of the shortcut. So if we use:

descendedFrom("Content")&$Name.icontains("^\[(.+)\]")

We get a back-reference $1 which is the contents of the matched square brackets. Thus from “[⌥⌘ N] Menu text”, the agent matches “[⌥⌘ N]” and the back-reference is “⌥⌘ N`”.

In this example, the agent sets $Text to the back-reference: Test_regex.tbx (99.5 KB)

Slightly different from the starting question, but methinks close enough. There’s so often a different path to or close solution for a problem.

Thank you again for the continued efforts to find a solution! I think I will be playing with a copy of the file in BBEdit or Nisus, as I don’t fancy changing four hundred instances of modifier keys plus character by hand. (That number illustrates to me why shortcuts have become a problem rather than a solution - that is only about three programs I’ve documented thus far.) I’ve already been considering how I might split up the data before putting it into Tinderbox, which might be another way of achieving what I was trying to do (documenting shortcut conflicts, among other things).