You’re in complicated territory.
A terminal emulator listens for key events from the operating system, and translates them into characters. It then sends those characters to the running application (which in this case is Emacs, but the terminal doesn’t know or care what application it is).
There are used to be a lot of different terminals in the world, and most of them were incompatible with each other. Exactly how they translated key events into characters was one of the incompatible things about them. In the modern era of terminal emulators, we mostly emulate the VT100, plus sometimes features from later terminals such as the VT220 or VT420. You don’t say what terminal emulator you are using, but in practice most of them just default to doing whatever xterm does. You can read in excrutiating detail exactly what xterm does, but I will try to summarize.
By default, xterm pretends that your Alt key is a Meta key, and then does what the VT100 did, which is to translate any key press with a Meta modifier into an escape character followed by the modified key. Thus
M-a becomes 0x1b 0x41,
M-b becomes 0x1b 0x42, and so on. It follows then that
M-[ must be 0x1b 0x5b. So far this is not complicated.
So what happens for the function keys? There is no character that corresponds to the F5 key directly, so it has to be translated into some sequence of bytes. Here is the relevant table from that document I linked to:
Key Escape Sequence
F1 | SS3 P
F2 | SS3 Q
F3 | SS3 R
F4 | SS3 S
F5 | CSI 1 5 ~
F6 | CSI 1 7 ~
F7 | CSI 1 8 ~
F8 | CSI 1 9 ~
F9 | CSI 2 0 ~
F10 | CSI 2 1 ~
F11 | CSI 2 3 ~
F12 | CSI 2 4 ~
SS3 and CSI are of course defined way earlier in the document:
Single Shift Select of G3 Character Set (SS3 is 0x8f), VT220.
This affects next character only.
Control Sequence Introducer (CSI is 0x9b).
So anywhere the document says that it sends SS3, it is really going to send an escape followed by an “O”, or 0x1b 0x4f. And any time it says that it will send CSI, it will actually send an escape followed by an “[”, or 0x1b 0x5b.
You may now begin to see the problem.
Every time you hit
<f5>, your terminal sends the bytes 0x1b 0x5b 0x31 0x35 0x7E. The first two bytes trigger your key binding, moving the cursor backwards by a paragraph. The the next three bytes all invoke
self-insert-command and type their corresponding character, inserting a
15~ into the buffer.
In fact, Emacs already had something bound to
M-[. When Emacs starts up inside of a terminal it puts a key map there that handles all of the interesting escape sequences that it might receive, so that your arrow keys and function keys and whatnot will work.