A floating window that updates automatically based on text file?

I have some macros that automatically update text files as a logging thing. Every now and then I open the text files, sometimes I use a KM macro that reads the file and displays the message (in the floating window), but what I'd really like is some kind of floating window in which the contents of a text file are displayed and, crucially, automatically updates when the source file updates. If I can style it and position in some way, that would be ideal.

What are my options for something like this?

The approach I've taken to this is to use the console.app provided with macOS.

In my KM macro I'll create/write to a file called, say, mylogfile.log and open it in console.app which then updates in real time as and when my macro writes to the log file.

I think that whatever you name your log file, its extension must be ".log" for this to work as expected.

There may well be other approaches to solving your requirement but I've found this to be both simple and easy to use.

Hope it helps.

2 Likes

That's a clever idea, @tiffle!

I had a quick search of the forum for other ideas.

  • If you don't mind the KM Editor being open, you might be able to use this to view variables supplied when your write to a file macros run.

https://wiki.keyboardmaestro.com/manual/Windows#Value_Inspector_Window

  • This looks promising, and you wouldn't need to use any polling to get the results, as your current macros could update the prompt. I've messaged @avialan to ask if he'd be willing to share the code he used for it.
1 Like

Thanks for saying that. When I was developing my debugging utility for KM I searched high and low for a solution to this (it had to be scriptable using AppleScript/JavaScript) and independent of the KM editor and after exploring many avenues this was the easiest and most reliable approach I found.

1 Like

If you don't care what the window looks like you can just run a terminal window with:

tail -f file.txt

I also found that OBS (Open broadcaster software) has this functionality built in, if you create a text overlay set to read a text file it will automatically updates when the text file does. This is obviously overkill if all you want is a floating window to monitor a text file, but it works really well and if you don't have any video inputs/outputs OBS is fairly lightweight.

3 Likes

Love @tiffle's solution, and I'm also a fan of tail -f.

To add another to the mix -- BBEdit (even the free version) will also update an open document as the file's contents are changed in the background.

3 Likes

Nice and simple - that's perfect for what I need! Bonus - the files I have been updating were saved as .log already, so no messing about there.

1 Like

Ah, I may also try this. I normally use Sublime Text but that did not update unless I switched focus.

I did it with a standalone applescript app, that had an idle loop. At first I was concerned about performance - either wasting cpu resources, or not being responsive enough. Turns out neither was a problem.

when an applescript application provides a function called “idle”, the system will call it, at the interval set by the app

And the app provided a public function to display data - which any other app could call. So I intended for it to be a general purpose floating status window - "InfloaTainment"

So it had real time power output of solar panels, etc...

the floating window was created by KM, which my app could access by applescript calls to KM.

excerpt:

on idle
	displaystats(pushdata) -- go do things with new data we've received
	set pushdata to {}	
	return idletime — set to 0.5 seconds
end idle

############	Public Entry points
on PUBLICaddpushdata(mydata) --	PUBLIC API
	#	anyone can call this, anytime. will launch the program if it wasnt running.
	# with no window to display in. Dangers of public API.

	try --	 can't test variable exists. but trying to use it will throw an error
		set pushdata to pushdata & mydata
	on error errStr
		quit
		return errStr -- why yes, you CAN actually quit, and _then_ return a value. 🤓
	end try
	return "success"
end PUBLICaddpushdata
2 Likes