As Amit said in his answer, the onEdit() trigger will work for this, and you'll need to get values from the Edit event object. A complete solution for this use case would be something like:
function onEdit(e) {
// Prevent errors if no object is passed.
if (!e) return;
// Get the active sheet.
e.source.getActiveSheet()
// Set the cell you want to update with the date.
.getRange('M2')
// Update the date.
.setValue(new Date());
// Get the active sheet.
e.source.getActiveSheet()
// Set the cell you want to update with the user.
.getRange('M3')
// Update the user (only email is available, and only if security settings allow).
.setValue(e.user.getEmail() );
}
Then you just need to call the function from any random cell like so: =onEdit()
, and then any cell you edit will update the cells you set to in your script.
Warning: The onEdit() trigger will screw up your undo/redo history. Each time it fires when you edit a cell, the action from the trigger gets added to the undo history, which means two things: 1. To undo the last thing you did, you have to undo twice in quick succession (once for onEdit(), once for your edit). 2. Since onEdit() also fires each time you undo something, it effectively gets rid of your redo history by immediately overwriting it.