Last Sunday I woke up earlier. While waiting for sleep to return it occured to me that it would be useful to keep a log of daily tasks from the many activities I’m involved in. Mostly because I’m frequently forced to jump from one activity to the other, which can reduce my productivity every time I have to remember where I left off and it makes it more difficult to keep track of what I have accomplished. There are a number of apps that offer to help with these sort of tasks. The problem is that most offen they are not that efficient and they end up just standing in the way and causing more distraction. I decided to get up and find a simple solution with a simple text file. Each line could be a new dated entry, possibily including the activity name and the task that was accomplished. If the values are coma separated, I can the easily convert the txt file to csv just changing the extension and adding a header.

As there is no need to reinvent the wheel, I went looking around if anyone had already done it. I found Lifehacker has a few suggestions on how to do this on Windows and Mac. Eu use both interchangeabily so the solution should be seamless. In this article I will detail how I have implemented a arguabily better solution on macOS without a need for installing any other applications.

The first step is to write a script that does what I want: (1) Use a keyboard shortcut (2) to call a text box where I can write the info I would like to log, (3) add the date and time, (4) say what activity this task part of. We can do all this without writing a line of code, using Automator, but I found this is not very elegant. I can’t sort the entries the way I want or add comas between the values. The code bellow does all the steps from 2 to 4.

function run() {
  
  var app = Application.currentApplication() 
  app.includeStandardAdditions = true
  
  function prompt(text, defaultAnswer) {
  		var options = { defaultAnswer: defaultAnswer || '' }
  		try {
    		return app.displayDialog(text, options).textReturned
  		} catch (e) {
    		return null
  		}
  }
  var text = prompt("What task have you accomplished?", "")
  var activity = app.chooseFromList(['Activity1', 'Activity2', 'Activity3'], {withPrompt: 'This task is for what activity?'});
  var date = app.currentDate().toString()
  var entry = date + ";" + activity + ";" + text + "\n\n"
  path = Path('/Users/XXXXX/XXXXX/log.txt')
  
  function writeTextToFile(text, path, overwriteExistingContent) {
    	try { 
        	// Open the file for writing
        	var openedFile = app.openForAccess(path, { writePermission: true })
 
        	// Clear the file if content should be overwritten
        	if (overwriteExistingContent) {
            	app.setEof(openedFile, { to: 0 })
        	}
 
        	// Write the new content to the file
        	app.write(text, { to: openedFile, startingAt: app.getEof(openedFile) })
 
        	// Close the file
        	app.closeAccess(openedFile)
 
        	// Return a boolean indicating that writing was successful
        	return true
    	}
    	catch(error) {
 
        	try {
            	// Close the file
            	app.closeAccess(file)
        	}
        	catch(error) {
            	// Report the error is closing failed
            	console.log(`Couldn't close file: ${error}`)
        	}
        	// Return a boolean indicating that writing was successful
        	return false
    	}
  }

  writeTextToFile(entry, path, false)
}

What’s in the code?

function run() {...} This is the function within which we create out litlle app. The next two lines create a variable so we can call our app and include some standard libraries to read and write files. Then we declare the function that will open the text box  function prompt(text, defaultAnswer). This is a generic and modular function which could be saved in a library, such as the other function we declare a few lines down: function writeTextToFile(text, path, overwriteExistingContent).

On the next line we create and assign a value to the variable text by calling the first function. Next, we use a function to create a window with a list of activities we or the user can select. We ask the system what time it is and organize the variables in the following format: Date; Activity; Text. Lastly, we provide the path to the file where the data will be appended path = Path('/Users/XXXX/XXXX/registo.txt') and call the function that does it for us like so: writeTextToFile(entry, path, false).

Final steps

The code above can be pasted to the Script Editor and executed. But this is not what we wanted. To be able to use a keyboard shortcut to execute the script there are a few steps missing:

  1. Open Automator
  2. Create a new Quick Action
  3. Make sure that the process takes “no input”.
  4. Select “Run Javascript” and write your code or use the one I provide below (don’t forget to change the folders to something that makes sense for you).
  5. Save.
  6. Go to System Preferences > Keyboard > Shortcuts. Select Services from the sidebar and find your service. Add a shortcut by double clicking (none).
  7. Go to System Preferences > Security and Privacy. Select Input Monitoring from the sidebar and add Automator to the list of apps that are allowed to monitor your keyboard across all applications.

Done! Now we just press the keyboard short cut and our script gets executed.


Leave a Reply

Your email address will not be published. Required fields are marked *

11 + 12 =


@