markdown-mode
markdown-mode copied to clipboard
Change list syntax of promoted list elements by configuration
When I used nvim for a bit, I used bullets.vim with markdown a lot. It has a feature that I honestly miss on emacs with markdown-mode - you could pre-program different list levels, so whenever a list element was promoted or demoted, the bullet type would change. Lemme explain what I mean.
Example
Let's say for even levels, the user wants * to be the symbol used for unordered bullets, and for odd levels, the user prefers -. When the user presses Tab when in the below-left setup, the list promotion would result in the below-right setup:
|
|
The changing of the bullet type happens automatically according to the user's configuration.
Let's talk about changing list types. Let's say the user is typing an ordered list. If a list element is promoted, the user might not prefer to start a new ordered list - they might prefer to start an unordered list, or a task list. So, whatever means of configuration is exposed to the user in this feature should support different list types. For example, the following promotion should be possible:
|
|
List Syntaxes
Different list syntaxes may have different levels of indentation. In this sense, the "list indentation" variable should probably be split into variables for each list type.
As far as I can tell, these are the different list types:
- Unordered
- List Syntaxes:
-,*,+ - Default indentation offset: 2
- List Syntaxes:
- Ordered
- List Syntax:
n.(wherenis a numeral) - Default indentation offset: 3
- List Syntax:
- Tasklist
- List Syntaxes:
- [ ],- [x] - Default indentation offset: 6
- List Syntaxes:
Ideas for Configuration
So for configuration, we have to give the user a way of specifying the list type and list syntax of the newly promoted list element. We can represent syntaxes with the following symbols:
- Unordered:
'-,'*, and'+for-,*, and+, respectively - Ordered:
'n - Tasklist:
'_and'xfor- [ ]and- [x], respectively
(I'm sure that we're already using a system similar to this for list syntax right now, but I'll just use these symbols as shorthand for now so I can talk about implementation details)
We should also create a function that just returns the list type for a given list syntax. This would be trivial, as the types for each list syntax is known:
(defun markdown-get-list-type-for-syntax (syntax)
"Returns the list type for a given list SYNTAX"
(cdr (assoc syntax
'((- . unordered)
(* . unordered)
(+ . unordered)
(n . ordered)
(_ . tasklist)
(x . tasklist))))
We should then expose a variable markdown-promoted-list-type or something similar. This will be a user-overridable function that, when given a list level and the list type of that level's parent, will return the list type of the requested level. We could use this function internally to compute the type of the next level any time the user tried to promote a list element.
Here are a few drafts that implement various behaviors:
(defun markdown-promoted-list-type--continue-list (_ parent-syntax)
"Continues PARENT-SYNTAX whenever an element is promoted"
parent-type)
(defun markdown-promoted-list-type--dash-and-star (level parent-syntax)
"Alternates between dash and star syntax for unordered list types.
Warning: This function is partial over PARENT-SYNTAX, and returns nil for all
but '- and '*."
(when (member parent-syntax '(- *))
(if (oddp level) '- '*)))
(defun markdown-promoted-list-type--ordered-unordered (_ parent-syntax)
"Always promote ordered lists to unordered lists
Warning: This function is partial over PARENT-SYNTAX, and returns nil for all
but 'n"
(when (equalp parent-syntax 'n) '-))
(defun markdown-promoted-list-type--myriacores-choice (level parent-syntax)
"My personal preference"
(or (markdown-promoted-list-type--ordered-unordered level parent-syntax)
(markdown-promoted-list-type--dash-and-star level parent-syntax)
(markdown-promoted-list-type--continue-list level parent-syntax)))
;; Set my preferences :D
(setq markdown-promoted-list-type #'markdown-promoted-list-type--myriacores-choice)