Issue with %FinderSelections% counting as 1 when nothing is selected

image

Nothing is selected in Finder, but it still shows 1 in the first action.
This wouldn't be an issue, because it could be counting the folder itself (it would still be weird taking into account that the token is referred to "selections" and nothing is in fact selected, but I could work with that).
The issue is that when I then use %FinderSelection% in the third action, I get no path when I display Local__selectedItem in a window, for example. It's empty.

So on one hand it's assuming something is selected, but then it doesn't allow me to save the path of the "selected" item.

Am I missing something here? Or is this a bug?

If you run your series of Actions you will get a path if an item in the Finder is selected.

But if no item is selected then there is no path to display.

But the issue I see here is that KM is assuming something is selected, at the very top.
But then at the bottom, it no longer assumes that something is selected.

So the first action should also show 0, not 1 like it is now.
I have nothing selected in Finder, so why is it showing 1?

As I said, it would be ok if it was using the current folder as something that's "selected" even though that's not accurate, because being "inside" a folder is not the same as being "selected". But, yes, I could work with that mindset.

But then if that's the mindset, the third action should also assume that something is selected.

Hope it makes sense?

The Line Count Filter Action returns 1 when the text is empty. This isn't intuitive to me, but if my memory is correct, @peternlewis has intentionally implemented it that way.

In cases like this, I use this calculation:

LINES(%Variable%local_List%)*(CHARACTERS(%Variable%local_List%)>0)

Keyboard Maestro Export

He's an example macro you can use to see the difference.

Download: Line Count Test.kmmacros (3.3 KB)

Macro-Image


Macro-Notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.

System Information
  • macOS 26.0.1 (25A362)
  • Keyboard Maestro v11.0.4

FWIW, it seems correct to me :slight_smile:

"" is the identity element of string values under concatenation.
Like all other such identity elements, it's still a value of the given type – not the absence of a value.

Monoid (Value Type) Combining Operation (<>) Identity Element (id)
Numbers Addition (+) 0
Numbers Multiplication (*) 1
Strings Concatenation "" (the empty string)
Lists Concatenation [ ] (the empty list)
Booleans Conjunction (AND) TRUE
Booleans Disjunction (OR) FALSE

Where a string with a single \n delimiter, such as "alpha\nbeta" is said to have a line count of 2,
any string with zero delimiters must have a line count of (2 - 1) → 1

String line count
"alpha\nbeta" 2
"alpha" 1
"" 1

( or so it seems to me :slight_smile: )


To put it another way:

  • the character count of "" is 0
  • the line count, however, is the line-delimiter count plus one.
1 Like

@ComplexPoint, I think you've stated that you're not a professional programmer, but I contend that your brain is wired like one. Mine is like an engineer.

Thanks for sharing the information in your post, but I don't think the above statement is correct. Otherwise, wouldn't the Filter action return 2 for the first variable and 3 for the second?

Keyboard Maestro Export

Keyboard Maestro Export

Both return 2.

You said in your post that you had nothing selected in the Finder.

So, whatever the logic of the line count is in the %FinderSelections% Token (whether it returns a figure of 1, 0 or whatever) you still have nothing selected so the Token %FinderSelection% does not contain a path. It would contain a path if you had a single item selected in the Finder.

The implementation does seem to right-trim trailling white space,
but we can see that blank lines (empty "") are counted, both leading empty lines, and empty lines between printing lines.

(i.e. they are not treated as the absence of a line, and string consisting of "" is still a string, rather than a separate species signifying null or nothing)

(9 lines below)

Leading and intermediate blanks counted- string RTRIMMED ?.kmmacros (3.3 KB)

1 Like

Yes, it doesn't seem intuitive to me either.

I believe I kinda understand @ComplexPoint point of view. An empty line, is still a line. It's just empty. Still, if nothing is selected, it shouldn't even output anything, similar ot not even having the action at all. At least, that's how I think. It's almost like someone asking me: how many oranges do you have?
Me: I have none.
The person: ok, so just by mentioning "orange", that means you have one.
(just by adding a filter to count lines, here's an free, bonus line, to make you as confused as possible)

Thank you for sharing this.
I will save this as a favorite action. Appreciate it!
Do you mind clarifying the thought process behind it?

Yes, that's the obvious logic. I wasn't expecting it to show anything if I have no items selected. But if the first action doesn't seem very logical, then the second shouldn't either. Otherwise, there's a conflict. So, yes, the issue here is with the first action, not the second, of course.

I think the issues here are:

  1. Unfortunately sometimes Keyboard Maestro focus too much on aspects that only people in certain fields fully understand instead of taking into consideration that the average user is not a developer. Sure, if we have actions with AppleScript, Shell, etc, that is already expected to be something that the average user doesn't understand. That's ok. But I think that from a UX point of view, KM fails multiple times in separating things.
  2. When you ask someone: "You were supposed to start writing your book today. How many lines have you written?" and the person says "None", you are not assuming the line count is 1. None = 0. So we go back to the previous point: mixing plain English with "developer" language, when not necessary or doesn't bring any benefit, is not a good decision.

I don't expect this to change, because I've been proven time and time again, that this kind of feedback is received with "probably not going to implement that", so this is just me ranting :wink:

I appreciate your feedback anyway :muscle:

Defining empty is never easy.

Perhaps a test for a string with zero characters is better defined than one for a string with “zero lines” ?

1 Like

This topic came up a few years ago, and Peter chimed in. I think he said something about his method matching the way macOS commands work.

You're welcome, @alltiagocom.

I'm might not be understanding what you are asking, but maybe this will help...

(CHARACTERS(%Variable%local_List%)>0) = 0 if local_List is empty; otherwise 1.

That result is multiplied by LINES(%Variable%local_List%) which works like the Line Count Filter Action.

Hope that helps!

2 Likes

or this also works: (same number of characters, I had been hoping it would be less)

CHARACTERS(%Variable%local_List%)>0?LINES(%Variable%local_List%):0 
2 Likes

Yes! For some, your syntax might be easier to follow. Thanks for sharing, @Airy!

2 Likes

Count of lines in the empty text is 1, as designed.

"" ➤ 1
"xxx" ➤ 1
"xxx\n" ➤ 1
"xxx\nxxx" ➤ 2
"xxx\nxxx\n" ➤ 2

A different choice could be made, but this is how it is defined and working as intended.

So yes, you are missing something, that is that with no selections, FinderSelections token will return the empty string and the line count of that will be 1.

Correct (assuming you know what you consider intuitive is). Line Count of empty text is 1.

You are talking about two entirely different concepts.

And empty line is still a line, which is part of the reasoning as to why the line count of empty text is 1.

If nothing is selected, then the FinderSelections returns empty text.

The error is in putting the two together. Line Count of FinderSelections is not the number of selected items.

I do not believe this is an accurate assessment of thinking. More accurate would be:

Unfortunately sometimes things have multiple possible interpretations and sometimes the one Keyboard Maestro chose is not the any specific person might personally choose.

As can be seen above, some people think it should be 1 some 0. A choice was made (by me) and that choice is 1. If you think I am alone on this, I suggest opening a new BBEdit editor window and check out the character / word / line count at the bottom:

image

(that said, BBEdit makes a different choice for "xxx\n" as being 2. These are choices. Not everyone is going to make the same choice. It's not about developer-centric, it's about what was chosen at the time and the reasoning that was used.

How about this then "You started writing your book today, got all set up and were about to put pen to paper and then stopped and had a beer - how many pages did you get out?". It's 1, not 0.

It's not going to change because this decision is a choice, and to change it to a different choice could potentially break people’s existing macros which rarely makes sense. If I'm going to change an existing behaviour it has to be demonstrably wrong.

3 Likes

I had to do some research, because I never used CHARACTERS before or even that type of calculation/condition.
So if anyone in the future has the same question:

CHARACTERS(%Variable%local_list%) outputs the number of characters.

Adding >0 like CHARACTERS(%Variable%local_list%)>0 makes it a condition that only outputs either 1 as true or 0 as false.

>0 checks if the variable local_list contains at least one character. In the case of no selected Finder items that would be false (0).

Then LINES(%Variable%local_List%) = number of lines in the variable. In this case it will always be at least 1, never 0.

So, the whole calculation
LINES(%Variable%local_List%)*(CHARACTERS(%Variable%local_List%)>0) translates to 1 (number of lines) * 0 (number of characters), which will be 0.

Thank you for your workaround.

1 Like

This clearly illustrates why this "logic" doesn't make sense:

image

Everything empty = 1 line
Empty line after something is there, doesn't count as a line (?)

We should either count ALL empty lines as lines, or none.

But at least they are consistent with their logic:

image

image

The fundamental issue here is that you are assuming that a "choice" is never wrong, it's just a choice. You either assume that the last empty line is also a line and it's counted, or you don't count an empty string as a line. Yes, it's a choice, but a choice built on inconsistency and that's bad UX, whether you agree with it or not.

This analogy makes no sense. My page is like my KM variable. It has nothing to do with the content of the page/variable. So the moment I have a variable (page), it's 1 variable (page), it has nothing to do with lines, which is the content of the variable (page). The content of that variable (page) is not the variable (page) itself.

Empty book page = No lines written (0)
Empty variable = No lines written (0)

How many pages do you have, empty or not? 1
Ok, on that page, how many lines have you written? 0

How many variables do you have, empty or not? 1
Ok, on that variable, how many lines do you have with content (written)? 0

Again, as I previously said, I can accept that an empty string = 1 line and work with that. I can "kinda" see the "logic" behind it, even though from a UX point of view for the average user, that makes no sense. Other than developers, no one reads "empty book page" as having at least 1 line of content. And even then, maybe not all developers find this logical?

What then breaks this whole thing apart is the fact that KM is not consistent. Empty line = 1, but 2 lines followed by an empty line, counts as 2, not 3. This is where your "choice" is logically wrong, even if you find ways to justify it. I can make all the choices I want in life, find justifications for them, and call them "choices". That doesn't make them good/right choices.

Start of rant...
Unfortunately, from what I've been seeing on the forum, 99.9% of the feedback from users gets a reply from you that is something along the lines of "this is how KM works, because I wanted it to work like this" or "it's most likely not going to be implemented", even when it's clear that what the users expect and need, is something that is beneficial to most users, such as this issue we are debating here (either count all empty lines, or count none). At one point, I stopped seeing any value in sharing my suggestions or feature requests. I don't expect that all requests (mine or note) get implemented, obviously, but I honestly don't recall ever seeing a request having a reply from you that reads something like "that's a great new feature. I will implement that". You mostly agree when it's a serious bug, because it makes sense to fix those.

Important note: I said that I don't recall ever seeing one that you do. Obviously I don't read all topics. I'm just saying that from the ones I did read, none got that type of reply where you agree with them and actually sound interested in implementing it.

This doesn't change the fact that I still find the value in KM and I will always find ways to achieve what I need, even if my macros end up with 50 actions instead of just 2. I just find it very frustrating trying to make you see that things evolve and that maybe, just maybe, your choices are wrong. Nothing needs to break in order to implement changes. It doesn't have to be a "let's remove this and add that". It can be "let's also add this to complement that". But it all starts with you being open enough to accept that others also have an opinion, sometimes better than your choices, otherwise, what's the point in sharing request features? I was expecting a forum to also be a discourse for people to help you improve your product by accepting new, good, innovative ideas?

End of rant...

When you need:

  • either a value drawn from some well-defined set (numbers, strings, etc)
  • or a special {nothing found, no number, no string, no selection, no lines } kind of empty value

then you need a kind of meta-type with two possible types of value {Nothing, Something} where the Something can be drawn from some other type of value.

This is such a common and fundamental need that it's:

  1. Well-studied mathematically (see under monads), and
  2. well-supported by modern progamming languages (see option types in Swift, and types like Maybe, and Either in the ML family of languages).

But for casual end-user scripting and macros, it seems sensible, and is certainly well-established (see the ancient unix shells) to settle on everything is a a string.

Strings (the underlying Keyboard Maestro variable datatype) are:

  • familiar and easy to grasp, but
  • not equipped, by their structure, to represent the meta-choice between something and nothing. (An empty string has a character count, and is still a string)

(If your data-type was a list of strings, then you could have an empty list – not a string in sight – but a list of strings is not a string, and its not the data type that Keyboard Maestro uses)

As there's no unique or formally derivable way of representing "zero lines" in a string-type value, you just need some consistent convention.

Keyboard Maestro's line-count convention of:

  • right trimming white space
  • adding one to the number of remaining line-delimiters

seems both consistent and workable.

( not sure that changing it now would solve much, but it would almost certainly break things)

1 Like