I used to have a macro(s) that handled stacks and queues of strings for me. But that was before subroutines existed. Now that subroutines exist, which can return variables, it would be even simpler to do.
In fact, one of the parameters my routines accepted was the name of the queue or stack. So it was one macro that handled all queues and stacks by passing the name as one parameter.
A variable that does not exist is obviously empty, and a variable that has a value obviously exists.
So the only interesting case would be a variable that exists but is empty. However setting a variable to empty deletes it (from the engine’s perspective, the editor may still know about the variable in other ways).
Thanks for the tips on further simplifying my already pretty simple macro.
That suggests my basic subroutine can be simplified to simply deleting any literally matching line that currently exists, which does not require that the variable exist or be non-empty, and then prepending the line to the variable, which again does not require that the variable exist or be non-empty.
I could also prevent the list from growing too long without having to filter any line counts or evaluate any conditionals simply by adding a third action that deletes the 21st (or whatever) entry, if there is one.
Is there a way to delete the line and the %Return% delimiter in one step? This action:
leaves an empty line, I think. I suppose that I could add a second action to look for empty lines and delete them, but I'd love to do it all in one step.
That requires initiating a shell. I'm hoping to do it all in one command, deleting the content of the line along with the %Return% delimiter, but haven't come up with it yet.
Right now, this is what I have, all KBM built-in actions, without (I hope) having to initiate a shell:
Just curious, why is that a problem? It will take .002 seconds or so to execute, so it won't slow your macro in any meaningful way. Why the aversion to a shell/desire to do it in one command?
Because it's part of a sequence that happens every time I change Desktop Workspaces and which sometimes can take as long as 2 sec, it seems -- which is long enough that I get where I'm going and start to read, work, find my place, etc. when >>POP<< comes the notification that I'm in the new workspace and all is right with the world. That's annoying. I'm trying to improve it.
If that notification happens in about 1/2 sec, then my experience is simply a flow of: I change Spaces, I get the notice that I am where I want to be, I go on. Calm, reassuring, comfortable.
So I'm looking at what I can shave off. I can see what that 0.5 - 1.0 sec feels like if I leave out all kinds of housekeeping, error conditions, and stuff that makes a difference elsewhere, or predefine things for testing that have to be queried for in reality, which I don't want to do or can't do on a regular basis. So I'm exploring what I can tighten up.
To find out where the time is going, you might try timing some of the routines—my MultiTimer macro does just that, and lets you get subtotals just by inserting calls wherever you need them. You might be surprised to find where the time is going. I know I was when I worked on optimizing my biggest time-consuming macros.
I made the erroneous assumption that the initial Set Variable action would somehow only execute IF there already was an Item #21 in the list. Silly me. When does KBM ever require variables to exist before they can be set?
So what does it do? It adds enough delimiters to the end of the list to create an Item #21 and then it sets that to the supplied text, which in this case is empty.
And the second action deletes approximately half of the added items, changing each pair of Returns to a single Return.
So the number of blank lines that was added was not entirely consistent and the resulting length of the list was not entirely consistent -- and it only happened the first time a shorter list got accessed, then no further changes were made, mostly. A bit difficult to debug until the Ah-Ha!
So truncating the list will require a slightly different approach. Later ...
Just in case you have forgotten, with KM the zero element of any array ([0]) contains the current size of the array, so you can tell beforehand how many items there are. So if
GlobalRecentDeskSpaces[0]\r
Is equal to 21, you know it's safe to "delete" that element. The trouble is, the way you are deleting the last element isn't reducing the size of the array, so to do that you need to trim off the last \r from the variable.
BTW (apropos your remark about variables existing)
GlobalRecentDeskSpaces[21]\r
is not really a variable - it's an array element and it behaves like a variable. What is a variable is this:
YES! I had indeed forgotten. I had been looking at Filtering the variable with a Line Count filter. But the filter will actually go through and count the lines, one by one. The [0] syntax refers to a value that is already automatically there, and therefore will execute marginally faster.
Thank you!
Pardon the sloppy terminology, I was trying to point out my sloppy thinking and the erroneous assumption that lead to a bug that was hard to find.
Yes, it behaves like a variable and KBM will assign a value to the array element, within the existing variable, even if that array element does yet exist. If the array is not long enough, KBM make it long enough in order to be able to assign the value.
In another thread somewhere here, Peter explains that this is expected ... a coming update (maybe the one that just came out?) will limit it to creating 100 elements, if I recall correctly.
Another BUG in the previous pushdown stack subroutine, with a simple fix:
Using the Preferences > Variables window I started seeing a final entry in the list that consisted of one long string of every item, with no delimiters, just 8, 12, 20, or whatever items run together as a single item. WTF? Except for that, it's been doing it's job, in the background, mostly being used to switch to the previous desktop.
I was contemplating creating a log that would have entries every time the variable changed so that I could match up when it happened to the KBM Engine log and have a clue. Then in adding comments to the subroutine, to walk through how it works, I found the answer. It's in the removal of the new item from its previous place in the list.
I realized that if the variable theNewDeskSpaceID was empty (or non existant) then this would do exactly what I was seeing. It would remove every Return from the variable. Then the next time the subroutine was called, new entries would be added to the front, and this would stay at the bottom of the list.
Wrapping it in an If/Else seems to have done the trick.