I'm creating a major mode for editing Algol source files which are written using Unicode characters.
(add-to-list 'auto-mode-alist '("\\.a60\\'" . algol-mode))
I want to have the following behaviour when editing .a60 files:
As an example, when I type the two characters <= in succession, I want
them to be deleted and the Unicode character ≤ inserted instead. But
only when typed in that order - if I typed < then a space. then erased
the space and typed =, I wouldn't want the replacement to happen - I would
expect to see an unaltered <=. And to be clear I want this change to
be made to text I type - not existing text already in the file. The
replacement text is to be inserted in the file as if it had been typed...
it is not just a replacement for display, like the way some language major
modes will underline keywords on the screen but not save the underlined
text in the file.
So <= was one trivial example - but what I actually want is a fully
general-purpose input text filter where I can define pairs of typed text
and replacement text in my language mode for .a60 files in .emacs,
eg something like
(subtitute "&&", "∧")
or
(subtitute "'begin'", "b̲e̲g̲i̲n̲")
I.e. I can define several replacements for things I can type, with unicode text that I can't easily type.
And to reiterate, I don't want to type any escape characters of any sort -
I just want to key in a line of code such as 'if' a <= b 'then' explode;
and have i̲f̲ a ≤ b t̲h̲e̲n̲ explode; entered into my file.
(I will be careful not to create definitions that could infinitely recurse.) I naively tried using global-set-key but as you probably know (although I didn't until I tried it) that only works for strings with certain prefix characters. I want this new mechanism to work with arbitrary text. I don't think abbrev mode or flymake are what I'm looking for - those were the closest similar solutions I could find in other postings here.
At the end of the day... I did try the abbrev solution suggested by Rorshach (and modifed by https://emacs.stackexchange.com/questions/36890/alternative-to-abbrev-mode-that-supports-special-characters-in-abbreviations ) but couldn't make it work 100%. I ended up using the following code:
(add-to-list 'auto-mode-alist '("\\.a60\\'" . a60-mode))
(defun a60-chars () "Convert Algol 60 symbols from ISO to Unicode."
(interactive)
(if (looking-back "<=") (progn (backward-delete-char 2) (insert "≤") )
(if (looking-back ">=") (progn (backward-delete-char 2) (insert "≥") )
;; (if (looking-back "\\\\") (progn (backward-delete-char 1) (insert "¬") )
(if (looking-back "~") (progn (backward-delete-char 1) (insert "¬") )
(if (looking-back "&&") (progn (backward-delete-char 2) (insert "∧") )
(if (looking-back "||") (progn (backward-delete-char 2) (insert "∨") )
(if (looking-back "!=") (progn (backward-delete-char 2) (insert "≠") )
(if (looking-back "==") (progn (backward-delete-char 2) (insert "≡") )
(if (looking-back "*") (progn (backward-delete-char 1) (insert "×") )
;; (if (looking-back "\\^") (progn (backward-delete-char 1) (insert "↑") )
(if (looking-back "<>") (progn (backward-delete-char 2) (insert "≠") )
(if (looking-back "//") (progn (backward-delete-char 2) (insert "÷") )
)))))))))))
;; Only enable when editing .a60 files:
(add-hook 'a60-mode-hook
'(lambda()
(add-hook 'post-self-insert-hook #'a60-chars nil 'local)
)
t
)
I still have some small tweaking to do (to allow replacements for ^ and \) but basically the above does what I need. Thanks for the help.