From c0fc52461e845baa3c55d9b6f9e67c451a9ffa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Wed, 14 Feb 2018 19:27:22 +0100 Subject: [PATCH] Bind markdown-insert-list-item to M-RET rather than M- MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This follows what e.g. org-mode and tex-mode do: lisp/org/org.el: (org-defkey org-mode-map (kbd "M-RET") #'org-meta-return) lisp/textmodes/tex-mode.el: (define-key map "\M-\r" 'latex-insert-item) Long story short (but hopefully accurate): - refers to the physical "⏎" function key; - terminals do not tell applications that a function key was pressed, rather they send a character sequence; - so on terminals, M- cannot work; - RET ≡ \r is not an actual key, but rather the control character emitted by pressing Control-M in a terminal; - on graphical displays, Emacs automatically translates into RET if there is no binding for . Using M-RET rather than M- allows the following things: 1. the binding works on terminals[^1]; 2. C-M-m now also works as an alternative (… which was my initial motivation to investigate this). Sources and gory details: - (emacs) Keymaps > Most modern keyboards have function keys as well as character > keys. Function keys send input events just as character keys > do, and keymaps can have bindings for them. > > … > > On text terminals, typing a function key actually sends the > computer a sequence of characters; the precise details of the > sequence depends on the function key and on the terminal type. - (emacs) Named ASCII Chars > Emacs can distinguish these two kinds of input if the keyboard > does. It treats the special keys as function keys named ‘tab’, > ‘return’, ‘backspace’, ‘linefeed’, ‘escape’, and ‘delete’. > These function keys translate automatically into the > corresponding ASCII characters _if_ they have no bindings of > their own. > > If you do not want to distinguish between (for example) > and ‘C-i’, make just one binding, for the ASCII character > (octal code 011). If you do want to distinguish, make one > binding for this ASCII character, and another for the function > key ‘tab’. > > With an ordinary ASCII terminal, there is no way to distinguish > between and ‘C-i’ (and likewise for other such pairs), > because the terminal sends the same character in both cases. - Xah Lee: - - - - a *scratch* buffer: (kbd "RET") ; "^M" (kbd "\r") ; "^M" (kbd "C-m") ; "^M" (kbd "") ; [return] - on X: C-h c ⏎ ; RET (translated from ) runs the command newline - on a TTY: C-h c ⏎ ; RET runs the command newline [^1]: Provided the terminals send the correct character sequences. This is not always straightforward. Here are the results of pressing Alt-⏎ on three different terminals: - on a TTY: M-RET - on Terminator: C-M-j - on XTerm: toggles fullscreen With this .Xresources snippet: XTerm.vt100.translations: #override \n\ Alt Return: insert-eight-bit() XTerm also sends M-RET. Also add test for M-RET adding list items. --- CHANGES.md | 2 ++ markdown-mode.el | 2 +- tests/markdown-test.el | 10 ++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 76b5eba8..c24fa5b8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -101,6 +101,7 @@ - Fix precedence of inline code over inline links. - Improve error reporting for `markdown` and `markdown-open`. ([GH-291][]) + - Fix M-RET binding for terminals ([GH-317][]) [gh-171]: https://github.com/jrblevin/markdown-mode/issues/171 [gh-216]: https://github.com/jrblevin/markdown-mode/issues/216 @@ -141,6 +142,7 @@ [gh-291]: https://github.com/jrblevin/markdown-mode/issues/291 [gh-296]: https://github.com/jrblevin/markdown-mode/issues/296 [gh-303]: https://github.com/jrblevin/markdown-mode/pull/303 + [gh-317]: https://github.com/jrblevin/markdown-mode/pull/317 # Markdown Mode 2.3 diff --git a/markdown-mode.el b/markdown-mode.el index 790b5a24..bc22329d 100644 --- a/markdown-mode.el +++ b/markdown-mode.el @@ -5383,7 +5383,7 @@ Assumes match data is available for `markdown-regex-italic'." (define-key map (kbd "C-c S-") 'markdown-table-insert-column) (define-key map (kbd "C-c C-M-h") 'markdown-mark-subtree) (define-key map (kbd "C-x n s") 'markdown-narrow-to-subtree) - (define-key map (kbd "M-") 'markdown-insert-list-item) + (define-key map (kbd "M-RET") 'markdown-insert-list-item) (define-key map (kbd "C-c C-j") 'markdown-insert-list-item) ;; Paragraphs (Markdown context aware) (define-key map [remap backward-paragraph] 'markdown-backward-paragraph) diff --git a/tests/markdown-test.el b/tests/markdown-test.el index f818b38c..a6ed2d37 100644 --- a/tests/markdown-test.el +++ b/tests/markdown-test.el @@ -1079,6 +1079,16 @@ Don't adjust spacing if tabs are used as whitespace." (call-interactively 'markdown-insert-list-item) (should (string-equal (buffer-string) "9.\tfoo\n10.\t")))) +(ert-deftest test-markdown-insertion/list-item-bound-keys () + "Test that `markdown-insert-list-item' is bound to M-RET and equivalents." + (markdown-test-string "- foo" + (goto-char (point-max)) + (execute-kbd-macro (read-kbd-macro "M-RET bar C-M-m baz")) + (should (string-equal (buffer-string) "- foo\n- bar\n- baz")) + (when (display-graphic-p) + (execute-kbd-macro (read-kbd-macro "M- quux")) + (should (string-equal (buffer-string) "- foo\n- bar\n- baz\n- quux"))))) + (ert-deftest test-markdown-insertion/nested-list-marker () "Test marker detection for `markdown-insert-list-item'." (markdown-test-string