kjk / edna

Note taking for developers and power users
https://edna.arslexis.io
Other
390 stars 18 forks source link

Add a markdown-specific configuration for bracket closing #38

Closed nosas closed 4 months ago

nosas commented 4 months ago

When writing in markdown - specifically, when bolding or italicizing text in markdown - it's useful to have asterisks automatically wrap the selected text. Same goes for backticks and underscores.

This functionality is available through codemirror's automatic bracket closing, but it only supports characters ["(", "[", "{", "'", '"'] by default.

From a technical standpoint, this change adds a custom closeBrackets configuration to include asterisks, backticks, and underscores. From a user standpoint, it allows users to select text, type the asterisk key (*) and have the text be wrapped in asterisks. It allows for easy italicizing and bolding of texts.

## Issues

Unfortunately, I do not yet have the Javascript knowledge to enable this change only for markdown blocks and/or selected text.

This means that when the "Auto-close quotation marks and brackets" setting is enabled and an asterisk is typed, it results in two asterisks being typed. This is an issue if typing in math blocks or other programming language blocks.

I do not recommend merging this PR until a more appropriate solution is developed.

I've made the appropriate changes such that the markdown-specific closeBrackets configuration is only ran in markdown blocks.

kjk commented 4 months ago

The CodeMirror part was written by original Heynote developer, so I don't know much about it either.

I've looked at current code and if you have view, you can get current block with const block = getActiveNoteBlock(view.state).

block is an object that looks:

{
  language: {
    name: language,
    auto: isAuto,
  },
  content: {
    from: contentNode.from,
    to: contentNode.to,
  },
  delimiter: {
    from: type.from,
    to: type.to,
  },
  range: {
    from: type.node.from,
    to: contentNode.to,
  },
}

I don't know how to use that information, though.

One option would be to fork @codemirror/autocomplete and assuming the logic that does bracket closing has access to view, it could implement block-aware bracket closing.

Or maybe clone just closeBracket extension.

Or maybe it's possible to write a wrapper extension that says: if block.language.name == "markdown" then run closeBracket extension, otherwise do nothing.

As for selection, see getCurrentSelection(). I think isSelectionEmpty would be view.state.selection.from === view.state.selection.to

NoahAndrews commented 4 months ago

Surrounding text with underscores and backticks is also useful for Markdown.

nosas commented 4 months ago

The changes have been made such that the markdown-specific closeBrackets configuration is only ran in markdown blocks. I've also added support for backtick and underscore characters.

kjk commented 4 months ago

Awesome, thanks.

BTW: https://silverbullet.md/ has a very extensive customized Markdown mode for CodeMirror. Lots of good stuff, very similar to Obsidian's new markdown almost-wysiwyg editor.

Their code could be re-used in Edna for markdown blocks.