Add format block button to status bar, when a supported block is active

This commit is contained in:
Jonatan Heyman 2023-03-03 01:40:24 +01:00
parent f3c5a49fbf
commit e1fe26b881
7 changed files with 55 additions and 6 deletions

1
public/icons/format.svg Normal file
View File

@ -0,0 +1 @@
<svg fill="none" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M2.75 4.5a.75.75 0 0 0 0 1.5h14.5a.75.75 0 0 0 0-1.5H2.75ZM2.75 7.5a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5h-8.5ZM2.75 10.5a.75.75 0 0 0 0 1.5h6.633a1.496 1.496 0 0 1-.284-1.5H2.75ZM2.75 13.5h6.628L7.876 15H2.75a.75.75 0 0 1 0-1.5ZM14.496 7.439a.5.5 0 0 0-.992 0l-.098.791a2.5 2.5 0 0 1-2.176 2.176l-.791.098a.5.5 0 0 0 0 .992l.791.098a2.5 2.5 0 0 1 2.176 2.176l.098.791a.5.5 0 0 0 .992 0l.098-.791a2.5 2.5 0 0 1 2.176-2.176l.791-.098a.5.5 0 0 0 0-.992l-.791-.098a2.5 2.5 0 0 1-2.176-2.176l-.098-.791ZM11.853 13.147a.5.5 0 0 1 0 .707l-4 3.996a.5.5 0 0 1-.706-.707l3.999-3.997a.5.5 0 0 1 .707 0Z" fill="#ffffff" class="fill-212121"></path></svg>

After

Width:  |  Height:  |  Size: 727 B

View File

@ -91,6 +91,10 @@
this.showLanguageSelector = false this.showLanguageSelector = false
this.$refs.editor.setLanguage(language) this.$refs.editor.setLanguage(language)
}, },
formatCurrentBlock() {
this.$refs.editor.formatCurrentBlock()
},
}, },
} }
@ -119,6 +123,7 @@
:systemTheme="systemTheme" :systemTheme="systemTheme"
@toggleTheme="toggleTheme" @toggleTheme="toggleTheme"
@openLanguageSelector="openLanguageSelector" @openLanguageSelector="openLanguageSelector"
@formatCurrentBlock="formatCurrentBlock"
class="status" class="status"
/> />
<div class="overlay"> <div class="overlay">

View File

@ -108,6 +108,11 @@
this.editor.focus() this.editor.focus()
}, },
formatCurrentBlock() {
this.editor.formatCurrentBlock()
this.editor.focus()
},
focus() { focus() {
this.editor.focus() this.editor.focus()
}, },

View File

@ -1,5 +1,6 @@
<script> <script>
import { LANGUAGES } from '../editor/languages.js' import { LANGUAGES } from '../editor/languages.js'
const LANGUAGE_MAP = Object.fromEntries(LANGUAGES.map(l => [l.token, l]))
const LANGUAGE_NAMES = Object.fromEntries(LANGUAGES.map(l => [l.token, l.name])) const LANGUAGE_NAMES = Object.fromEntries(LANGUAGES.map(l => [l.token, l.name]))
export default { export default {
@ -24,6 +25,11 @@
className() { className() {
return `status` return `status`
}, },
supportsFormat() {
const lang = LANGUAGE_MAP[this.language]
return !!lang ? lang.supportsFormat : false
},
}, },
} }
</script> </script>
@ -42,6 +48,14 @@
{{ languageName }} {{ languageName }}
<span v-if="languageAuto" class="auto">(auto)</span> <span v-if="languageAuto" class="auto">(auto)</span>
</div> </div>
<div
v-if="supportsFormat"
@click="$emit('formatCurrentBlock')"
class="status-block format clickable"
title="Format Block Content"
>
<span class="icon icon-format"></span>
</div>
<div class="status-block theme clickable" @click="$emit('toggleTheme')"> <div class="status-block theme clickable" @click="$emit('toggleTheme')">
<span :class="'icon ' + systemTheme"></span> <span :class="'icon ' + systemTheme"></span>
</div> </div>
@ -117,5 +131,19 @@
background-image: url("icons/light-mode.png") background-image: url("icons/light-mode.png")
&.system &.system
background-image: url("icons/both-mode.png") background-image: url("icons/both-mode.png")
.format
padding-top: 0
padding-bottom: 0
.icon
display: block
width: 14px
height: 22px
+dark-mode
opacity: 0.9
background-size: 16px
background-repeat: no-repeat
background-position: center center
background-image: url("icons/format.svg")
</style> </style>

View File

@ -49,6 +49,7 @@ export const formatBlockContent = ({ state, dispatch }) => {
selection: EditorSelection.cursor(block.content.from + formattedContent.cursorOffset) selection: EditorSelection.cursor(block.content.from + formattedContent.cursorOffset)
}, { }, {
userEvent: "input", userEvent: "input",
scrollIntoView: true,
})) }))
return true; return true;
} }

View File

@ -9,6 +9,7 @@ import { customSetup } from "./setup.js"
import { heynoteLang } from "./lang-heynote/heynote.js" import { heynoteLang } from "./lang-heynote/heynote.js"
import { noteBlockExtension, blockLineNumbers } from "./block/block.js" import { noteBlockExtension, blockLineNumbers } from "./block/block.js"
import { changeCurrentBlockLanguage } from "./block/commands.js" import { changeCurrentBlockLanguage } from "./block/commands.js"
import { formatBlockContent } from "./block/format-code.js"
import { heynoteKeymap, emacsKeymap } from "./keymap.js" import { heynoteKeymap, emacsKeymap } from "./keymap.js"
import { heynoteCopyPaste } from "./copy-paste" import { heynoteCopyPaste } from "./copy-paste"
import { languageDetection } from "./language-detection/autodetect.js" import { languageDetection } from "./language-detection/autodetect.js"
@ -131,6 +132,13 @@ export class HeynoteEditor {
effects: this.foldGutterCompartment.reconfigure(show ? [foldGutter()] : []), effects: this.foldGutterCompartment.reconfigure(show ? [foldGutter()] : []),
}) })
} }
formatCurrentBlock() {
formatBlockContent({
state: this.view.state,
dispatch: this.view.dispatch,
})
}
} }

View File

@ -14,27 +14,28 @@ import { rustLanguage } from "@codemirror/lang-rust"
class Language { class Language {
constructor(token, name, parser, highlightjs) { constructor(token, name, parser, highlightjs, supportsFormat=false) {
this.token = token this.token = token
this.name = name this.name = name
this.parser = parser this.parser = parser
this.highlightjs = highlightjs this.highlightjs = highlightjs
this.supportsFormat = supportsFormat
} }
} }
export const LANGUAGES = [ export const LANGUAGES = [
new Language("text", "Plain Text", null, "plaintext"), new Language("text", "Plain Text", null, "plaintext"),
new Language("math", "Math", null, null), new Language("math", "Math", null, null),
new Language("javascript", "JavaScript", javascriptLanguage.parser, "javascript"), new Language("javascript", "JavaScript", javascriptLanguage.parser, "javascript", true),
new Language("json", "JSON", jsonLanguage.parser, "json"), new Language("json", "JSON", jsonLanguage.parser, "json", true),
new Language("python", "Python", pythonLanguage.parser, "python"), new Language("python", "Python", pythonLanguage.parser, "python"),
new Language("html", "HTML", htmlLanguage.parser, "html"), new Language("html", "HTML", htmlLanguage.parser, "html", true),
new Language("sql", "SQL", StandardSQL.language.parser, "sql"), new Language("sql", "SQL", StandardSQL.language.parser, "sql"),
new Language("markdown", "Markdown", markdownLanguage.parser, "markdown"), new Language("markdown", "Markdown", markdownLanguage.parser, "markdown", true),
new Language("java", "Java", javaLanguage.parser, "java"), new Language("java", "Java", javaLanguage.parser, "java"),
//new Language("lezer", "Lezer", lezerLanguage.parser, "lezer"), //new Language("lezer", "Lezer", lezerLanguage.parser, "lezer"),
new Language("php", "PHP", phpLanguage.parser, "php"), new Language("php", "PHP", phpLanguage.parser, "php"),
new Language("css", "CSS", cssLanguage.parser, "css"), new Language("css", "CSS", cssLanguage.parser, "css", true),
new Language("xml", "XML", xmlLanguage.parser, "xml"), new Language("xml", "XML", xmlLanguage.parser, "xml"),
new Language("cpp", "C++", cppLanguage.parser, "cpp"), new Language("cpp", "C++", cppLanguage.parser, "cpp"),
new Language("rust", "Rust", rustLanguage.parser, "rust"), new Language("rust", "Rust", rustLanguage.parser, "rust"),