2

I want to check its properties as soon as a Greek word has been inserted into the buffer. As far as I can see, this requires me to check each time the buffer changes, whether, if a Greek word was being typed, the last character was not a word character. How might I do this? That is, how can I run a function every time a new character is inserted into the buffer?

2

Edit: Trying to compile all comments to this answer into one large text. Please upvote the comments instead of the answer.

There are several ways how you can approach this. It depends on the details what exactly you want to do.

Low Level

Most of this was actually the original answer before the helpful comments were added.

You could use post-command-hook and see if a character was pressed. Given that most (all?) 'normal' characters are bound to self-insert-command your function could look something like this:

(defun echo-char ()
  (if (eq this-command 'self-insert-command)
      (message "Inserted %s" (save-excursion
                               (backward-char)
                               (thing-at-point 'char)))))

The call to message is just a demo here. It messes with a lot of other interaction, for example inserting text in the minibuffer. Also, I'm pretty sure that there's a better way to get the character that was inserted.

You can add it to the hook globally like this:

(add-hook 'post-command-hook #'echo-char)

If you used the message example from above, you'd probably want to be able to remove the function again:

(remove-hook 'post-command-hook #'echo-char)

This allows you to add your function interactively from any buffer, for example your *scratch* buffer or your elisp library.

Later in your code, you'll want to use the 4 argument form of add-hook which allows you to add the hook locally in the current buffer. (Thanks to @lawlist for pointing this out.)

(add-hook 'post-command-hook #'echo-char nil t)

This works character-wise and hopefully gives you some pointers for further research.

I call this approach 'low level' because the post-command-hook is run after every command and you could test for whatever command was called, not just self-insert-command.

A Shortcut

If you're only interested in character-wise input, take the shortcut suggested by @lawlist: use post-self-insert-hook. Those functions only get called after a self-inserting character was used. As far as I understand, it should be semantically the same as using post-command-hook and the test for self-insert-command, but it is run only in the relevant cases and could save some CPU cycles.

More Than Just Chars

As @rpluim pointed out, you could also add a function to the after-change-functions. (Don't ask me why this is not called ...-hook).

Then your function would need to take 3 arguments: begin, end and length of inserted text. You could use this approach to look at larger things than just characters. This function would also trigger when someone yanks (pastes) text into a buffer. If this is preferable for you or the first approaches mentioned, depends on what exactly you want to achieve, I guess.

  • 2
    after-change-functions might be better for ths – rpluim Jul 30 '18 at 10:25
  • Good idea. In your after change function you'd be able to deal with whole words being yanked (pasted), too. It depends on what exactly OP wants to do, I guess. – Stefan Kamphausen Jul 30 '18 at 11:01
  • 2
    See also post-self-insert-hook. – lawlist Jul 30 '18 at 13:42
  • 1
    Hooks can also be buffer-local by using the optional argument (add-hook HOOK FUNCTION &optional APPEND LOCAL), which avoids messing with the undesired buffers such as the minibuffer. – lawlist Jul 30 '18 at 13:49
  • after-change-functions isn't called ...-hook because it's an abnormal hook – matteol Jul 31 '18 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.