mirror of
https://github.com/heyman/heynote.git
synced 2025-02-17 10:41:16 +01:00
Add setting for configuring the default block language and language auto detection
This commit is contained in:
parent
e5d4d31ca2
commit
d82b3920d7
@ -35,6 +35,8 @@ const schema = {
|
|||||||
"showInMenu": {type: "boolean", default: false},
|
"showInMenu": {type: "boolean", default: false},
|
||||||
"alwaysOnTop": {type: "boolean", default: false},
|
"alwaysOnTop": {type: "boolean", default: false},
|
||||||
"bracketClosing": {type: "boolean", default: false},
|
"bracketClosing": {type: "boolean", default: false},
|
||||||
|
"defaultBlockLanguage": {type: "string"},
|
||||||
|
"defaultBlockLanguageAutoDetect": {type: "boolean"},
|
||||||
|
|
||||||
// when default font settings are used, fontFamily and fontSize is not specified in the
|
// when default font settings are used, fontFamily and fontSize is not specified in the
|
||||||
// settings file, so that it's possible for us to change the default settings in the
|
// settings file, so that it's possible for us to change the default settings in the
|
||||||
|
@ -122,6 +122,8 @@
|
|||||||
:bracketClosing="settings.bracketClosing"
|
:bracketClosing="settings.bracketClosing"
|
||||||
:fontFamily="settings.fontFamily"
|
:fontFamily="settings.fontFamily"
|
||||||
:fontSize="settings.fontSize"
|
:fontSize="settings.fontSize"
|
||||||
|
:defaultBlockLanguage="settings.defaultBlockLanguage || 'text'"
|
||||||
|
:defaultBlockLanguageAutoDetect="settings.defaultBlockLanguageAutoDetect === undefined ? true : settings.defaultBlockLanguageAutoDetect"
|
||||||
class="editor"
|
class="editor"
|
||||||
ref="editor"
|
ref="editor"
|
||||||
@openLanguageSelector="openLanguageSelector"
|
@openLanguageSelector="openLanguageSelector"
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
},
|
},
|
||||||
fontFamily: String,
|
fontFamily: String,
|
||||||
fontSize: Number,
|
fontSize: Number,
|
||||||
|
defaultBlockLanguage: String,
|
||||||
|
defaultBlockLanguageAutoDetect: Boolean,
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {},
|
components: {},
|
||||||
@ -78,6 +80,7 @@
|
|||||||
})
|
})
|
||||||
window._heynote_editor = this.editor
|
window._heynote_editor = this.editor
|
||||||
window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded)
|
window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded)
|
||||||
|
this.editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect)
|
||||||
|
|
||||||
// set up buffer change listener
|
// set up buffer change listener
|
||||||
window.heynote.buffer.onChangeCallback((event, content) => {
|
window.heynote.buffer.onChangeCallback((event, content) => {
|
||||||
@ -145,12 +148,18 @@
|
|||||||
fontSize() {
|
fontSize() {
|
||||||
this.editor.setFont(this.fontFamily, this.fontSize)
|
this.editor.setFont(this.fontFamily, this.fontSize)
|
||||||
},
|
},
|
||||||
|
defaultBlockLanguage() {
|
||||||
|
this.editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect)
|
||||||
|
},
|
||||||
|
defaultBlockLanguageAutoDetect() {
|
||||||
|
this.editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
setLanguage(language) {
|
setLanguage(language) {
|
||||||
if (language === "auto") {
|
if (language === "auto") {
|
||||||
this.editor.setCurrentLanguage("text", true)
|
this.editor.setCurrentLanguage(null, true)
|
||||||
} else {
|
} else {
|
||||||
this.editor.setCurrentLanguage(language, false)
|
this.editor.setCurrentLanguage(language, false)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { LANGUAGES } from '../../editor/languages.js'
|
||||||
|
|
||||||
import KeyboardHotkey from "./KeyboardHotkey.vue"
|
import KeyboardHotkey from "./KeyboardHotkey.vue"
|
||||||
import TabListItem from "./TabListItem.vue"
|
import TabListItem from "./TabListItem.vue"
|
||||||
import TabContent from "./TabContent.vue"
|
import TabContent from "./TabContent.vue"
|
||||||
|
|
||||||
const defaultFontFamily = window.heynote.defaultFontFamily
|
const defaultFontFamily = window.heynote.defaultFontFamily
|
||||||
const defaultFontSize = window.heynote.defaultFontSize
|
const defaultFontSize = window.heynote.defaultFontSize
|
||||||
|
const defaultDefaultBlockLanguage = "text"
|
||||||
|
const defaultDefaultBlockLanguageAutoDetect = true
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -39,6 +43,16 @@
|
|||||||
bufferPath: this.initialSettings.bufferPath,
|
bufferPath: this.initialSettings.bufferPath,
|
||||||
fontFamily: this.initialSettings.fontFamily || defaultFontFamily,
|
fontFamily: this.initialSettings.fontFamily || defaultFontFamily,
|
||||||
fontSize: this.initialSettings.fontSize || defaultFontSize,
|
fontSize: this.initialSettings.fontSize || defaultFontSize,
|
||||||
|
languageOptions: LANGUAGES.map(l => {
|
||||||
|
return {
|
||||||
|
"value": l.token,
|
||||||
|
"name": l.token == "text" ? l.name + " (default)" : l.name,
|
||||||
|
}
|
||||||
|
}).sort((a, b) => {
|
||||||
|
return a.name.localeCompare(b.name)
|
||||||
|
}),
|
||||||
|
defaultBlockLanguage: this.initialSettings.defaultBlockLanguage || defaultDefaultBlockLanguage,
|
||||||
|
defaultBlockLanguageAutoDetect: this.initialSettings.defaultBlockLanguageAutoDetect === false ? false : defaultDefaultBlockLanguageAutoDetect,
|
||||||
|
|
||||||
activeTab: "general",
|
activeTab: "general",
|
||||||
isWebApp: window.heynote.platform.isWebApp,
|
isWebApp: window.heynote.platform.isWebApp,
|
||||||
@ -89,6 +103,8 @@
|
|||||||
bufferPath: this.bufferPath,
|
bufferPath: this.bufferPath,
|
||||||
fontFamily: this.fontFamily === defaultFontFamily ? undefined : this.fontFamily,
|
fontFamily: this.fontFamily === defaultFontFamily ? undefined : this.fontFamily,
|
||||||
fontSize: this.fontSize === defaultFontSize ? undefined : this.fontSize,
|
fontSize: this.fontSize === defaultFontSize ? undefined : this.fontSize,
|
||||||
|
defaultBlockLanguage: this.defaultBlockLanguage === "text" ? undefined : this.defaultBlockLanguage,
|
||||||
|
defaultBlockLanguageAutoDetect: this.defaultBlockLanguageAutoDetect === true ? undefined : this.defaultBlockLanguageAutoDetect,
|
||||||
})
|
})
|
||||||
if (!this.showInDock) {
|
if (!this.showInDock) {
|
||||||
this.showInMenu = true
|
this.showInMenu = true
|
||||||
@ -255,6 +271,24 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="entry">
|
||||||
|
<h2>Default Block Language</h2>
|
||||||
|
<select v-model="defaultBlockLanguage" @change="updateSettings" class="block-language">
|
||||||
|
<template v-for="lang in languageOptions" :key="lang.value">
|
||||||
|
<option :selected="lang.value === defaultBlockLanguage" :value="lang.value">{{ lang.name }}</option>
|
||||||
|
</template>
|
||||||
|
</select>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
v-model="defaultBlockLanguageAutoDetect"
|
||||||
|
@change="updateSettings"
|
||||||
|
/>
|
||||||
|
Auto-detection (default: on)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|
||||||
<TabContent tab="appearance" :activeTab="activeTab">
|
<TabContent tab="appearance" :activeTab="activeTab">
|
||||||
@ -417,6 +451,7 @@
|
|||||||
overflow-y: auto
|
overflow-y: auto
|
||||||
select
|
select
|
||||||
height: 22px
|
height: 22px
|
||||||
|
margin: 4px 0
|
||||||
.row
|
.row
|
||||||
display: flex
|
display: flex
|
||||||
.entry
|
.entry
|
||||||
|
@ -7,7 +7,11 @@ import { selectAll } from "./select-all.js";
|
|||||||
export { moveLineDown, moveLineUp, selectAll }
|
export { moveLineDown, moveLineUp, selectAll }
|
||||||
|
|
||||||
|
|
||||||
export const insertNewBlockAtCursor = ({ state, dispatch }) => {
|
function getBlockDelimiter(defaultToken, autoDetect) {
|
||||||
|
return `\n∞∞∞${autoDetect ? defaultToken + '-a' : defaultToken}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const insertNewBlockAtCursor = (editor) => ({ state, dispatch }) => {
|
||||||
if (state.readOnly)
|
if (state.readOnly)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
@ -16,7 +20,7 @@ export const insertNewBlockAtCursor = ({ state, dispatch }) => {
|
|||||||
if (currentBlock) {
|
if (currentBlock) {
|
||||||
delimText = `\n∞∞∞${currentBlock.language.name}${currentBlock.language.auto ? "-a" : ""}\n`
|
delimText = `\n∞∞∞${currentBlock.language.name}${currentBlock.language.auto ? "-a" : ""}\n`
|
||||||
} else {
|
} else {
|
||||||
delimText = "\n∞∞∞text-a\n"
|
delimText = getBlockDelimiter(editor.defaultBlockToken, editor.defaultBlockAutoDetect)
|
||||||
}
|
}
|
||||||
dispatch(state.replaceSelection(delimText),
|
dispatch(state.replaceSelection(delimText),
|
||||||
{
|
{
|
||||||
@ -28,13 +32,12 @@ export const insertNewBlockAtCursor = ({ state, dispatch }) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addNewBlockBeforeCurrent = ({ state, dispatch }) => {
|
export const addNewBlockBeforeCurrent = (editor) => ({ state, dispatch }) => {
|
||||||
console.log("addNewBlockBeforeCurrent")
|
|
||||||
if (state.readOnly)
|
if (state.readOnly)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
const block = getActiveNoteBlock(state)
|
const block = getActiveNoteBlock(state)
|
||||||
const delimText = "\n∞∞∞text-a\n"
|
const delimText = getBlockDelimiter(editor.defaultBlockToken, editor.defaultBlockAutoDetect)
|
||||||
|
|
||||||
dispatch(state.update({
|
dispatch(state.update({
|
||||||
changes: {
|
changes: {
|
||||||
@ -50,12 +53,12 @@ export const addNewBlockBeforeCurrent = ({ state, dispatch }) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addNewBlockAfterCurrent = ({ state, dispatch }) => {
|
export const addNewBlockAfterCurrent = (editor) => ({ state, dispatch }) => {
|
||||||
if (state.readOnly)
|
if (state.readOnly)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
const block = getActiveNoteBlock(state)
|
const block = getActiveNoteBlock(state)
|
||||||
const delimText = "\n∞∞∞text-a\n"
|
const delimText = getBlockDelimiter(editor.defaultBlockToken, editor.defaultBlockAutoDetect)
|
||||||
|
|
||||||
dispatch(state.update({
|
dispatch(state.update({
|
||||||
changes: {
|
changes: {
|
||||||
@ -70,12 +73,12 @@ export const addNewBlockAfterCurrent = ({ state, dispatch }) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addNewBlockBeforeFirst = ({ state, dispatch }) => {
|
export const addNewBlockBeforeFirst = (editor) => ({ state, dispatch }) => {
|
||||||
if (state.readOnly)
|
if (state.readOnly)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
const block = getFirstNoteBlock(state)
|
const block = getFirstNoteBlock(state)
|
||||||
const delimText = "\n∞∞∞text-a\n"
|
const delimText = getBlockDelimiter(editor.defaultBlockToken, editor.defaultBlockAutoDetect)
|
||||||
|
|
||||||
dispatch(state.update({
|
dispatch(state.update({
|
||||||
changes: {
|
changes: {
|
||||||
@ -91,11 +94,11 @@ export const addNewBlockBeforeFirst = ({ state, dispatch }) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addNewBlockAfterLast = ({ state, dispatch }) => {
|
export const addNewBlockAfterLast = (editor) => ({ state, dispatch }) => {
|
||||||
if (state.readOnly)
|
if (state.readOnly)
|
||||||
return false
|
return false
|
||||||
const block = getLastNoteBlock(state)
|
const block = getLastNoteBlock(state)
|
||||||
const delimText = "\n∞∞∞text-a\n"
|
const delimText = getBlockDelimiter(editor.defaultBlockToken, editor.defaultBlockAutoDetect)
|
||||||
|
|
||||||
dispatch(state.update({
|
dispatch(state.update({
|
||||||
changes: {
|
changes: {
|
||||||
@ -131,6 +134,10 @@ export function changeLanguageTo(state, dispatch, block, language, auto) {
|
|||||||
|
|
||||||
export function changeCurrentBlockLanguage(state, dispatch, language, auto) {
|
export function changeCurrentBlockLanguage(state, dispatch, language, auto) {
|
||||||
const block = getActiveNoteBlock(state)
|
const block = getActiveNoteBlock(state)
|
||||||
|
// if language is null, we only want to change the auto-detect flag
|
||||||
|
if (language === null) {
|
||||||
|
language = block.language.name
|
||||||
|
}
|
||||||
changeLanguageTo(state, dispatch, block, language, auto)
|
changeLanguageTo(state, dispatch, block, language, auto)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Annotation, EditorState, Compartment } from "@codemirror/state"
|
import { Annotation, EditorState, Compartment, Facet } from "@codemirror/state"
|
||||||
import { EditorView, keymap, drawSelection, ViewPlugin, lineNumbers } from "@codemirror/view"
|
import { EditorView, keymap, drawSelection, ViewPlugin, lineNumbers } from "@codemirror/view"
|
||||||
import { indentUnit, forceParsing, foldGutter } from "@codemirror/language"
|
import { indentUnit, forceParsing, foldGutter } from "@codemirror/language"
|
||||||
import { markdown } from "@codemirror/lang-markdown"
|
import { markdown } from "@codemirror/lang-markdown"
|
||||||
@ -59,6 +59,8 @@ export class HeynoteEditor {
|
|||||||
this.deselectOnCopy = keymap === "emacs"
|
this.deselectOnCopy = keymap === "emacs"
|
||||||
this.emacsMetaKey = emacsMetaKey
|
this.emacsMetaKey = emacsMetaKey
|
||||||
this.fontTheme = new Compartment
|
this.fontTheme = new Compartment
|
||||||
|
this.defaultBlockToken = "text"
|
||||||
|
this.defaultBlockAutoDetect = true
|
||||||
|
|
||||||
const state = EditorState.create({
|
const state = EditorState.create({
|
||||||
doc: content || "",
|
doc: content || "",
|
||||||
@ -84,7 +86,7 @@ export class HeynoteEditor {
|
|||||||
}),
|
}),
|
||||||
heynoteLang(),
|
heynoteLang(),
|
||||||
noteBlockExtension(this),
|
noteBlockExtension(this),
|
||||||
languageDetection(() => this.view),
|
languageDetection(() => this),
|
||||||
|
|
||||||
// set cursor blink rate to 1 second
|
// set cursor blink rate to 1 second
|
||||||
drawSelection({cursorBlinkRate:1000}),
|
drawSelection({cursorBlinkRate:1000}),
|
||||||
@ -206,6 +208,11 @@ export class HeynoteEditor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDefaultBlockLanguage(token, autoDetect) {
|
||||||
|
this.defaultBlockToken = token
|
||||||
|
this.defaultBlockAutoDetect = autoDetect
|
||||||
|
}
|
||||||
|
|
||||||
formatCurrentBlock() {
|
formatCurrentBlock() {
|
||||||
formatBlockContent({
|
formatBlockContent({
|
||||||
state: this.view.state,
|
state: this.view.state,
|
||||||
|
@ -48,11 +48,11 @@ export function heynoteKeymap(editor) {
|
|||||||
["Mod-x", cutCommand(editor)],
|
["Mod-x", cutCommand(editor)],
|
||||||
["Tab", indentMore],
|
["Tab", indentMore],
|
||||||
["Shift-Tab", indentLess],
|
["Shift-Tab", indentLess],
|
||||||
["Alt-Shift-Enter", addNewBlockBeforeFirst],
|
["Alt-Shift-Enter", addNewBlockBeforeFirst(editor)],
|
||||||
["Mod-Shift-Enter", addNewBlockAfterLast],
|
["Mod-Shift-Enter", addNewBlockAfterLast(editor)],
|
||||||
["Alt-Enter", addNewBlockBeforeCurrent],
|
["Alt-Enter", addNewBlockBeforeCurrent(editor)],
|
||||||
["Mod-Enter", addNewBlockAfterCurrent],
|
["Mod-Enter", addNewBlockAfterCurrent(editor)],
|
||||||
["Mod-Alt-Enter", insertNewBlockAtCursor],
|
["Mod-Alt-Enter", insertNewBlockAtCursor(editor)],
|
||||||
["Mod-a", selectAll],
|
["Mod-a", selectAll],
|
||||||
["Alt-ArrowUp", moveLineUp],
|
["Alt-ArrowUp", moveLineUp],
|
||||||
["Alt-ArrowDown", moveLineDown],
|
["Alt-ArrowDown", moveLineDown],
|
||||||
|
@ -25,7 +25,7 @@ function cancelIdleCallbackCompat(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function languageDetection(getView) {
|
export function languageDetection(getEditor) {
|
||||||
const previousBlockContent = {}
|
const previousBlockContent = {}
|
||||||
let idleCallbackId = null
|
let idleCallbackId = null
|
||||||
|
|
||||||
@ -35,7 +35,8 @@ export function languageDetection(getView) {
|
|||||||
if (!event.data.guesslang.language) {
|
if (!event.data.guesslang.language) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const view = getView()
|
const editor = getEditor()
|
||||||
|
const view = editor.view
|
||||||
const state = view.state
|
const state = view.state
|
||||||
const block = getActiveNoteBlock(state)
|
const block = getActiveNoteBlock(state)
|
||||||
const newLang = GUESSLANG_TO_TOKEN[event.data.guesslang.language]
|
const newLang = GUESSLANG_TO_TOKEN[event.data.guesslang.language]
|
||||||
@ -88,11 +89,12 @@ export function languageDetection(getView) {
|
|||||||
|
|
||||||
const content = update.state.doc.sliceString(block.content.from, block.content.to)
|
const content = update.state.doc.sliceString(block.content.from, block.content.to)
|
||||||
if (content === "" && redoDepth(update.state) === 0) {
|
if (content === "" && redoDepth(update.state) === 0) {
|
||||||
// if content is cleared, set language to plaintext
|
// if content is cleared, set language to default
|
||||||
const view = getView()
|
const editor = getEditor()
|
||||||
|
const view = editor.view
|
||||||
const block = getActiveNoteBlock(view.state)
|
const block = getActiveNoteBlock(view.state)
|
||||||
if (block.language.name !== "text") {
|
if (block.language.name !== editor.defaultBlockToken) {
|
||||||
changeLanguageTo(view.state, view.dispatch, block, "text", true)
|
changeLanguageTo(view.state, view.dispatch, block, editor.defaultBlockToken, true)
|
||||||
}
|
}
|
||||||
delete previousBlockContent[idx]
|
delete previousBlockContent[idx]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user