Skip to content

Commit

Permalink
Bind markdown-insert-list-item to M-RET rather than M-<return>
Browse files Browse the repository at this point in the history
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):

- <return> 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-<return> 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 <return> into
  RET if there is no binding for <return>.

Using M-RET rather than M-<return> 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) <TAB>
    > and  ‘C-i’,  make just  one  binding,  for the  ASCII  character
    > <TAB> (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 <TAB>  and ‘C-i’  (and likewise  for other  such pairs),
    > because the terminal sends the same character in both cases.

- Xah Lee:

    - <http://ergoemacs.org/emacs/emacs_key_notation_return_vs_RET.html>
    - <http://ergoemacs.org/emacs/keyboard_shortcuts.html>
    - <http://ergoemacs.org/emacs/keystroke_rep.html>

- a *scratch* buffer:

        (kbd "RET")         ; "^M"
        (kbd "\r")          ; "^M"
        (kbd "C-m")         ; "^M"
        (kbd "<return>")    ; [return]

- on X:

        C-h c ⏎ ; RET (translated from <return>) 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 <Key>Return: insert-eight-bit()

    XTerm also sends M-RET.

Also add test for M-RET adding list items.
  • Loading branch information
peniblec authored and jrblevin committed May 26, 2018
1 parent 668de4a commit c0fc524
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion markdown-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -5383,7 +5383,7 @@ Assumes match data is available for `markdown-regex-italic'."
(define-key map (kbd "C-c S-<right>") '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-<return>") '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)
Expand Down
10 changes: 10 additions & 0 deletions tests/markdown-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -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-<return> 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
Expand Down

0 comments on commit c0fc524

Please sign in to comment.