mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
Merge pull request #2594 from daiyam/fix-autocomplete-codeblock
improve autocomplete within code blocks
This commit is contained in:
@@ -341,10 +341,18 @@ export default class CodeEditor extends React.Component {
|
|||||||
'CodeMirror-lint-markers'
|
'CodeMirror-lint-markers'
|
||||||
],
|
],
|
||||||
autoCloseBrackets: {
|
autoCloseBrackets: {
|
||||||
|
codeBlock: {
|
||||||
|
pairs: this.props.codeBlockMatchingPairs,
|
||||||
|
closeBefore: this.props.codeBlockMatchingCloseBefore,
|
||||||
|
triples: this.props.codeBlockMatchingTriples,
|
||||||
|
explode: this.props.codeBlockExplodingPairs
|
||||||
|
},
|
||||||
|
markdown: {
|
||||||
pairs: this.props.matchingPairs,
|
pairs: this.props.matchingPairs,
|
||||||
|
closeBefore: this.props.matchingCloseBefore,
|
||||||
triples: this.props.matchingTriples,
|
triples: this.props.matchingTriples,
|
||||||
explode: this.props.explodingPairs,
|
explode: this.props.explodingPairs
|
||||||
override: true
|
}
|
||||||
},
|
},
|
||||||
extraKeys: this.defaultKeyMap,
|
extraKeys: this.defaultKeyMap,
|
||||||
prettierConfig: this.props.prettierConfig
|
prettierConfig: this.props.prettierConfig
|
||||||
@@ -649,16 +657,32 @@ export default class CodeEditor extends React.Component {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
prevProps.matchingPairs !== this.props.matchingPairs ||
|
prevProps.matchingPairs !== this.props.matchingPairs ||
|
||||||
|
prevProps.matchingCloseBefore !== this.props.matchingCloseBefore ||
|
||||||
prevProps.matchingTriples !== this.props.matchingTriples ||
|
prevProps.matchingTriples !== this.props.matchingTriples ||
|
||||||
prevProps.explodingPairs !== this.props.explodingPairs
|
prevProps.explodingPairs !== this.props.explodingPairs ||
|
||||||
|
prevProps.codeBlockMatchingPairs !== this.props.codeBlockMatchingPairs ||
|
||||||
|
prevProps.codeBlockMatchingCloseBefore !==
|
||||||
|
this.props.codeBlockMatchingCloseBefore ||
|
||||||
|
prevProps.codeBlockMatchingTriples !==
|
||||||
|
this.props.codeBlockMatchingTriples ||
|
||||||
|
prevProps.codeBlockExplodingPairs !== this.props.codeBlockExplodingPairs
|
||||||
) {
|
) {
|
||||||
const bracketObject = {
|
const autoCloseBrackets = {
|
||||||
|
codeBlock: {
|
||||||
|
pairs: this.props.codeBlockMatchingPairs,
|
||||||
|
closeBefore: this.props.codeBlockMatchingCloseBefore,
|
||||||
|
triples: this.props.codeBlockMatchingTriples,
|
||||||
|
explode: this.props.codeBlockExplodingPairs
|
||||||
|
},
|
||||||
|
markdown: {
|
||||||
pairs: this.props.matchingPairs,
|
pairs: this.props.matchingPairs,
|
||||||
|
closeBefore: this.props.matchingCloseBefore,
|
||||||
triples: this.props.matchingTriples,
|
triples: this.props.matchingTriples,
|
||||||
explode: this.props.explodingPairs,
|
explode: this.props.explodingPairs
|
||||||
override: true
|
|
||||||
}
|
}
|
||||||
this.editor.setOption('autoCloseBrackets', bracketObject)
|
}
|
||||||
|
|
||||||
|
this.editor.setOption('autoCloseBrackets', autoCloseBrackets)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevProps.enableTableEditor !== this.props.enableTableEditor) {
|
if (prevProps.enableTableEditor !== this.props.enableTableEditor) {
|
||||||
|
|||||||
@@ -365,8 +365,15 @@ class MarkdownEditor extends React.Component {
|
|||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
lineWrapping
|
lineWrapping
|
||||||
matchingPairs={config.editor.matchingPairs}
|
matchingPairs={config.editor.matchingPairs}
|
||||||
|
matchingCloseBefore={config.editor.matchingCloseBefore}
|
||||||
matchingTriples={config.editor.matchingTriples}
|
matchingTriples={config.editor.matchingTriples}
|
||||||
explodingPairs={config.editor.explodingPairs}
|
explodingPairs={config.editor.explodingPairs}
|
||||||
|
codeBlockMatchingPairs={config.editor.codeBlockMatchingPairs}
|
||||||
|
codeBlockMatchingCloseBefore={
|
||||||
|
config.editor.codeBlockMatchingCloseBefore
|
||||||
|
}
|
||||||
|
codeBlockMatchingTriples={config.editor.codeBlockMatchingTriples}
|
||||||
|
codeBlockExplodingPairs={config.editor.codeBlockExplodingPairs}
|
||||||
scrollPastEnd={config.editor.scrollPastEnd}
|
scrollPastEnd={config.editor.scrollPastEnd}
|
||||||
storageKey={storageKey}
|
storageKey={storageKey}
|
||||||
noteKey={noteKey}
|
noteKey={noteKey}
|
||||||
|
|||||||
@@ -260,8 +260,15 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
lineWrapping
|
lineWrapping
|
||||||
matchingPairs={config.editor.matchingPairs}
|
matchingPairs={config.editor.matchingPairs}
|
||||||
|
matchingCloseBefore={config.editor.matchingCloseBefore}
|
||||||
matchingTriples={config.editor.matchingTriples}
|
matchingTriples={config.editor.matchingTriples}
|
||||||
explodingPairs={config.editor.explodingPairs}
|
explodingPairs={config.editor.explodingPairs}
|
||||||
|
codeBlockMatchingPairs={config.editor.codeBlockMatchingPairs}
|
||||||
|
codeBlockMatchingCloseBefore={
|
||||||
|
config.editor.codeBlockMatchingCloseBefore
|
||||||
|
}
|
||||||
|
codeBlockMatchingTriples={config.editor.codeBlockMatchingTriples}
|
||||||
|
codeBlockExplodingPairs={config.editor.codeBlockExplodingPairs}
|
||||||
indentType={config.editor.indentType}
|
indentType={config.editor.indentType}
|
||||||
indentSize={editorStyle.indentSize}
|
indentSize={editorStyle.indentSize}
|
||||||
enableRulers={config.editor.enableRulers}
|
enableRulers={config.editor.enableRulers}
|
||||||
|
|||||||
@@ -859,8 +859,15 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
indentSize={editorIndentSize}
|
indentSize={editorIndentSize}
|
||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
matchingPairs={config.editor.matchingPairs}
|
matchingPairs={config.editor.matchingPairs}
|
||||||
|
matchingCloseBefore={config.editor.matchingCloseBefore}
|
||||||
matchingTriples={config.editor.matchingTriples}
|
matchingTriples={config.editor.matchingTriples}
|
||||||
explodingPairs={config.editor.explodingPairs}
|
explodingPairs={config.editor.explodingPairs}
|
||||||
|
codeBlockMatchingPairs={config.editor.codeBlockMatchingPairs}
|
||||||
|
codeBlockMatchingCloseBefore={
|
||||||
|
config.editor.codeBlockMatchingCloseBefore
|
||||||
|
}
|
||||||
|
codeBlockMatchingTriples={config.editor.codeBlockMatchingTriples}
|
||||||
|
codeBlockExplodingPairs={config.editor.codeBlockExplodingPairs}
|
||||||
keyMap={config.editor.keyMap}
|
keyMap={config.editor.keyMap}
|
||||||
scrollPastEnd={config.editor.scrollPastEnd}
|
scrollPastEnd={config.editor.scrollPastEnd}
|
||||||
fetchUrlTitle={config.editor.fetchUrlTitle}
|
fetchUrlTitle={config.editor.fetchUrlTitle}
|
||||||
|
|||||||
@@ -86,8 +86,13 @@ export const DEFAULT_CONFIG = {
|
|||||||
rulers: [80, 120],
|
rulers: [80, 120],
|
||||||
displayLineNumbers: true,
|
displayLineNumbers: true,
|
||||||
matchingPairs: '()[]{}\'\'""$$**``~~__',
|
matchingPairs: '()[]{}\'\'""$$**``~~__',
|
||||||
|
matchingCloseBefore: ')]}\'":;>',
|
||||||
matchingTriples: '```"""\'\'\'',
|
matchingTriples: '```"""\'\'\'',
|
||||||
explodingPairs: '[]{}``$$',
|
explodingPairs: '[]{}``$$',
|
||||||
|
codeBlockMatchingPairs: '()[]{}\'\'""``',
|
||||||
|
codeBlockMatchingCloseBefore: ')]}\'":;>',
|
||||||
|
codeBlockMatchingTriples: '',
|
||||||
|
codeBlockExplodingPairs: '[]{}``',
|
||||||
switchPreview: 'BLUR', // 'BLUR', 'DBL_CLICK', 'RIGHTCLICK'
|
switchPreview: 'BLUR', // 'BLUR', 'DBL_CLICK', 'RIGHTCLICK'
|
||||||
delfaultStatus: 'PREVIEW', // 'PREVIEW', 'CODE'
|
delfaultStatus: 'PREVIEW', // 'PREVIEW', 'CODE'
|
||||||
scrollPastEnd: false,
|
scrollPastEnd: false,
|
||||||
|
|||||||
@@ -139,6 +139,13 @@ div[id^="firstRow"]
|
|||||||
margin-right 10px
|
margin-right 10px
|
||||||
font-size 14px
|
font-size 14px
|
||||||
|
|
||||||
|
.group-section-label-right
|
||||||
|
width 200px
|
||||||
|
text-align right
|
||||||
|
margin-right 10px
|
||||||
|
font-size 14px
|
||||||
|
padding-right 1.5rem
|
||||||
|
|
||||||
.group-section-control
|
.group-section-control
|
||||||
flex 1
|
flex 1
|
||||||
margin-left 5px
|
margin-left 5px
|
||||||
|
|||||||
@@ -35,10 +35,18 @@ class SnippetEditor extends React.Component {
|
|||||||
foldGutter: true,
|
foldGutter: true,
|
||||||
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
|
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
|
||||||
autoCloseBrackets: {
|
autoCloseBrackets: {
|
||||||
|
codeBlock: {
|
||||||
|
pairs: this.props.codeBlockMatchingPairs,
|
||||||
|
closeBefore: this.props.codeBlockMatchingCloseBefore,
|
||||||
|
triples: this.props.codeBlockMatchingTriples,
|
||||||
|
explode: this.props.codeBlockExplodingPairs
|
||||||
|
},
|
||||||
|
markdown: {
|
||||||
pairs: this.props.matchingPairs,
|
pairs: this.props.matchingPairs,
|
||||||
|
closeBefore: this.props.matchingCloseBefore,
|
||||||
triples: this.props.matchingTriples,
|
triples: this.props.matchingTriples,
|
||||||
explode: this.props.explodingPairs,
|
explode: this.props.explodingPairs
|
||||||
override: true
|
}
|
||||||
},
|
},
|
||||||
mode: 'null'
|
mode: 'null'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -152,8 +152,15 @@ class SnippetTab extends React.Component {
|
|||||||
rulers={config.editor.rulers}
|
rulers={config.editor.rulers}
|
||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
matchingPairs={config.editor.matchingPairs}
|
matchingPairs={config.editor.matchingPairs}
|
||||||
|
matchingCloseBefore={config.editor.matchingCloseBefore}
|
||||||
matchingTriples={config.editor.matchingTriples}
|
matchingTriples={config.editor.matchingTriples}
|
||||||
explodingPairs={config.editor.explodingPairs}
|
explodingPairs={config.editor.explodingPairs}
|
||||||
|
codeBlockMatchingPairs={config.editor.codeBlockMatchingPairs}
|
||||||
|
codeBlockMatchingCloseBefore={
|
||||||
|
config.editor.codeBlockMatchingCloseBefore
|
||||||
|
}
|
||||||
|
codeBlockMatchingTriples={config.editor.codeBlockMatchingTriples}
|
||||||
|
codeBlockExplodingPairs={config.editor.codeBlockExplodingPairs}
|
||||||
scrollPastEnd={config.editor.scrollPastEnd}
|
scrollPastEnd={config.editor.scrollPastEnd}
|
||||||
onRef={ref => {
|
onRef={ref => {
|
||||||
this.snippetEditor = ref
|
this.snippetEditor = ref
|
||||||
|
|||||||
@@ -124,8 +124,14 @@ class UiTab extends React.Component {
|
|||||||
enableFrontMatterTitle: this.refs.enableFrontMatterTitle.checked,
|
enableFrontMatterTitle: this.refs.enableFrontMatterTitle.checked,
|
||||||
frontMatterTitleField: this.refs.frontMatterTitleField.value,
|
frontMatterTitleField: this.refs.frontMatterTitleField.value,
|
||||||
matchingPairs: this.refs.matchingPairs.value,
|
matchingPairs: this.refs.matchingPairs.value,
|
||||||
|
matchingCloseBefore: this.refs.matchingCloseBefore.value,
|
||||||
matchingTriples: this.refs.matchingTriples.value,
|
matchingTriples: this.refs.matchingTriples.value,
|
||||||
explodingPairs: this.refs.explodingPairs.value,
|
explodingPairs: this.refs.explodingPairs.value,
|
||||||
|
codeBlockMatchingPairs: this.refs.codeBlockMatchingPairs.value,
|
||||||
|
codeBlockMatchingCloseBefore: this.refs.codeBlockMatchingCloseBefore
|
||||||
|
.value,
|
||||||
|
codeBlockMatchingTriples: this.refs.codeBlockMatchingTriples.value,
|
||||||
|
codeBlockExplodingPairs: this.refs.codeBlockExplodingPairs.value,
|
||||||
spellcheck: this.refs.spellcheck.checked,
|
spellcheck: this.refs.spellcheck.checked,
|
||||||
enableSmartPaste: this.refs.enableSmartPaste.checked,
|
enableSmartPaste: this.refs.enableSmartPaste.checked,
|
||||||
enableMarkdownLint: this.refs.enableMarkdownLint.checked,
|
enableMarkdownLint: this.refs.enableMarkdownLint.checked,
|
||||||
@@ -746,6 +752,126 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Matching character pairs')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.matchingPairs}
|
||||||
|
ref='matchingPairs'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label-right'>
|
||||||
|
{i18n.__('in code blocks')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.codeBlockMatchingPairs}
|
||||||
|
ref='codeBlockMatchingPairs'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Close pairs before')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.matchingCloseBefore}
|
||||||
|
ref='matchingCloseBefore'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label-right'>
|
||||||
|
{i18n.__('in code blocks')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.codeBlockMatchingCloseBefore}
|
||||||
|
ref='codeBlockMatchingCloseBefore'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Matching character triples')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.matchingTriples}
|
||||||
|
ref='matchingTriples'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label-right'>
|
||||||
|
{i18n.__('in code blocks')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.codeBlockMatchingTriples}
|
||||||
|
ref='codeBlockMatchingTriples'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Exploding character pairs')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.explodingPairs}
|
||||||
|
ref='explodingPairs'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label-right'>
|
||||||
|
{i18n.__('in code blocks')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input
|
||||||
|
styleName='group-section-control-input'
|
||||||
|
value={this.state.config.editor.codeBlockExplodingPairs}
|
||||||
|
ref='codeBlockExplodingPairs'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
type='text'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div styleName='group-checkBoxSection'>
|
<div styleName='group-checkBoxSection'>
|
||||||
<label>
|
<label>
|
||||||
<input
|
<input
|
||||||
@@ -889,50 +1015,6 @@ class UiTab extends React.Component {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div styleName='group-section'>
|
|
||||||
<div styleName='group-section-label'>
|
|
||||||
{i18n.__('Matching character pairs')}
|
|
||||||
</div>
|
|
||||||
<div styleName='group-section-control'>
|
|
||||||
<input
|
|
||||||
styleName='group-section-control-input'
|
|
||||||
value={this.state.config.editor.matchingPairs}
|
|
||||||
ref='matchingPairs'
|
|
||||||
onChange={e => this.handleUIChange(e)}
|
|
||||||
type='text'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='group-section'>
|
|
||||||
<div styleName='group-section-label'>
|
|
||||||
{i18n.__('Matching character triples')}
|
|
||||||
</div>
|
|
||||||
<div styleName='group-section-control'>
|
|
||||||
<input
|
|
||||||
styleName='group-section-control-input'
|
|
||||||
value={this.state.config.editor.matchingTriples}
|
|
||||||
ref='matchingTriples'
|
|
||||||
onChange={e => this.handleUIChange(e)}
|
|
||||||
type='text'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div styleName='group-section'>
|
|
||||||
<div styleName='group-section-label'>
|
|
||||||
{i18n.__('Exploding character pairs')}
|
|
||||||
</div>
|
|
||||||
<div styleName='group-section-control'>
|
|
||||||
<input
|
|
||||||
styleName='group-section-control-input'
|
|
||||||
value={this.state.config.editor.explodingPairs}
|
|
||||||
ref='explodingPairs'
|
|
||||||
onChange={e => this.handleUIChange(e)}
|
|
||||||
type='text'
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
{i18n.__('Custom MarkdownLint Rules')}
|
{i18n.__('Custom MarkdownLint Rules')}
|
||||||
|
|||||||
196
extra_scripts/codemirror/addon/edit/closebrackets.js
vendored
Normal file
196
extra_scripts/codemirror/addon/edit/closebrackets.js
vendored
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||||
|
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
||||||
|
|
||||||
|
(function(mod) {
|
||||||
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||||
|
mod(require("../../lib/codemirror"));
|
||||||
|
else if (typeof define == "function" && define.amd) // AMD
|
||||||
|
define(["../../lib/codemirror"], mod);
|
||||||
|
else // Plain browser env
|
||||||
|
mod(CodeMirror);
|
||||||
|
})(function(CodeMirror) {
|
||||||
|
var defaults = {
|
||||||
|
pairs: "()[]{}''\"\"",
|
||||||
|
closeBefore: ")]}'\":;>",
|
||||||
|
triples: "",
|
||||||
|
explode: "[]{}"
|
||||||
|
};
|
||||||
|
|
||||||
|
var Pos = CodeMirror.Pos;
|
||||||
|
|
||||||
|
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
|
||||||
|
if (old && old != CodeMirror.Init) {
|
||||||
|
cm.removeKeyMap(keyMap);
|
||||||
|
cm.state.closeBrackets = null;
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
ensureBound(getOption(val.markdown, "pairs"))
|
||||||
|
cm.state.closeBrackets = val;
|
||||||
|
cm.addKeyMap(keyMap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getOption(conf, name) {
|
||||||
|
if (name == "pairs" && typeof conf == "string") return conf;
|
||||||
|
if (typeof conf == "object" && conf[name] != null) return conf[name];
|
||||||
|
return defaults[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
|
||||||
|
function ensureBound(chars) {
|
||||||
|
for (var i = 0; i < chars.length; i++) {
|
||||||
|
var ch = chars.charAt(i), key = "'" + ch + "'"
|
||||||
|
if (!keyMap[key]) keyMap[key] = handler(ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ensureBound(defaults.pairs + "`")
|
||||||
|
|
||||||
|
function handler(ch) {
|
||||||
|
return function(cm) { return handleChar(cm, ch); };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConfig(cm) {
|
||||||
|
var cursor = cm.getCursor();
|
||||||
|
var token = cm.getTokenAt(cursor);
|
||||||
|
var inCodeBlock = !!token.state.fencedEndRE;
|
||||||
|
|
||||||
|
if (inCodeBlock) {
|
||||||
|
return cm.state.closeBrackets.codeBlock
|
||||||
|
} else {
|
||||||
|
return cm.state.closeBrackets.markdown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBackspace(cm) {
|
||||||
|
var conf = getConfig(cm);
|
||||||
|
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var pairs = getOption(conf, "pairs");
|
||||||
|
var ranges = cm.listSelections();
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
if (!ranges[i].empty()) return CodeMirror.Pass;
|
||||||
|
var around = charsAround(cm, ranges[i].head);
|
||||||
|
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
for (var i = ranges.length - 1; i >= 0; i--) {
|
||||||
|
var cur = ranges[i].head;
|
||||||
|
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEnter(cm) {
|
||||||
|
var conf = getConfig(cm);
|
||||||
|
var explode = conf && getOption(conf, "explode");
|
||||||
|
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var ranges = cm.listSelections();
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
if (!ranges[i].empty()) return CodeMirror.Pass;
|
||||||
|
var around = charsAround(cm, ranges[i].head);
|
||||||
|
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
cm.operation(function() {
|
||||||
|
var linesep = cm.lineSeparator() || "\n";
|
||||||
|
cm.replaceSelection(linesep + linesep, null);
|
||||||
|
cm.execCommand("goCharLeft");
|
||||||
|
ranges = cm.listSelections();
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
var line = ranges[i].head.line;
|
||||||
|
cm.indentLine(line, null, true);
|
||||||
|
cm.indentLine(line + 1, null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function contractSelection(sel) {
|
||||||
|
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
|
||||||
|
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
|
||||||
|
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChar(cm, ch) {
|
||||||
|
var conf = getConfig(cm);
|
||||||
|
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var pairs = getOption(conf, "pairs");
|
||||||
|
var pos = pairs.indexOf(ch);
|
||||||
|
if (pos == -1) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var closeBefore = getOption(conf,"closeBefore");
|
||||||
|
|
||||||
|
var triples = getOption(conf, "triples");
|
||||||
|
|
||||||
|
var identical = pairs.charAt(pos + 1) == ch;
|
||||||
|
var ranges = cm.listSelections();
|
||||||
|
var opening = pos % 2 == 0;
|
||||||
|
|
||||||
|
var type;
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
var range = ranges[i], cur = range.head, curType;
|
||||||
|
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
|
||||||
|
if (opening && !range.empty()) {
|
||||||
|
curType = "surround";
|
||||||
|
} else if ((identical || !opening) && next == ch) {
|
||||||
|
if (identical && stringStartsAfter(cm, cur))
|
||||||
|
curType = "both";
|
||||||
|
else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
|
||||||
|
curType = "skipThree";
|
||||||
|
else
|
||||||
|
curType = "skip";
|
||||||
|
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
|
||||||
|
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
|
||||||
|
if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
|
||||||
|
curType = "addFour";
|
||||||
|
} else if (identical) {
|
||||||
|
var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
|
||||||
|
if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
|
||||||
|
else return CodeMirror.Pass;
|
||||||
|
} else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
|
||||||
|
curType = "both";
|
||||||
|
} else {
|
||||||
|
return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
if (!type) type = curType;
|
||||||
|
else if (type != curType) return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
|
||||||
|
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
|
||||||
|
cm.operation(function() {
|
||||||
|
if (type == "skip") {
|
||||||
|
cm.execCommand("goCharRight");
|
||||||
|
} else if (type == "skipThree") {
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
cm.execCommand("goCharRight");
|
||||||
|
} else if (type == "surround") {
|
||||||
|
var sels = cm.getSelections();
|
||||||
|
for (var i = 0; i < sels.length; i++)
|
||||||
|
sels[i] = left + sels[i] + right;
|
||||||
|
cm.replaceSelections(sels, "around");
|
||||||
|
sels = cm.listSelections().slice();
|
||||||
|
for (var i = 0; i < sels.length; i++)
|
||||||
|
sels[i] = contractSelection(sels[i]);
|
||||||
|
cm.setSelections(sels);
|
||||||
|
} else if (type == "both") {
|
||||||
|
cm.replaceSelection(left + right, null);
|
||||||
|
cm.triggerElectric(left + right);
|
||||||
|
cm.execCommand("goCharLeft");
|
||||||
|
} else if (type == "addFour") {
|
||||||
|
cm.replaceSelection(left + left + left + left, "before");
|
||||||
|
cm.execCommand("goCharRight");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function charsAround(cm, pos) {
|
||||||
|
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
|
||||||
|
Pos(pos.line, pos.ch + 1));
|
||||||
|
return str.length == 2 ? str : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringStartsAfter(cm, pos) {
|
||||||
|
var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
|
||||||
|
return /\bstring/.test(token.type) && token.start == pos.ch &&
|
||||||
|
(pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
|
||||||
|
}
|
||||||
|
});
|
||||||
74
extra_scripts/codemirror/mode/bfm/bfm.js
vendored
74
extra_scripts/codemirror/mode/bfm/bfm.js
vendored
@@ -55,9 +55,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.defineMode(
|
CodeMirror.defineMode('bfm', function (config, baseConfig) {
|
||||||
'bfm',
|
|
||||||
function(config, baseConfig) {
|
|
||||||
baseConfig.name = 'yaml-frontmatter'
|
baseConfig.name = 'yaml-frontmatter'
|
||||||
const baseMode = CodeMirror.getMode(config, baseConfig)
|
const baseMode = CodeMirror.getMode(config, baseConfig)
|
||||||
|
|
||||||
@@ -88,9 +86,7 @@
|
|||||||
overlayCur: null,
|
overlayCur: null,
|
||||||
|
|
||||||
fencedMode: s.fencedMode,
|
fencedMode: s.fencedMode,
|
||||||
fencedState: s.fencedMode
|
fencedState: s.fencedMode ? CodeMirror.copyState(s.fencedMode, s.fencedState) : null,
|
||||||
? CodeMirror.copyState(s.fencedMode, s.fencedState)
|
|
||||||
: null,
|
|
||||||
|
|
||||||
fencedEndRE: s.fencedEndRE,
|
fencedEndRE: s.fencedEndRE,
|
||||||
|
|
||||||
@@ -101,27 +97,28 @@
|
|||||||
token: function(stream, state) {
|
token: function(stream, state) {
|
||||||
const initialPos = stream.pos
|
const initialPos = stream.pos
|
||||||
|
|
||||||
if (state.fencedEndRE && stream.match(state.fencedEndRE)) {
|
if (state.fencedEndRE) {
|
||||||
|
if (stream.match(state.fencedEndRE)) {
|
||||||
state.fencedEndRE = null
|
state.fencedEndRE = null
|
||||||
state.fencedMode = null
|
state.fencedMode = null
|
||||||
state.fencedState = null
|
state.fencedState = null
|
||||||
|
|
||||||
stream.pos = initialPos
|
stream.pos = initialPos
|
||||||
} else {
|
} else if (state.fencedMode) {
|
||||||
if (state.fencedMode) {
|
|
||||||
return state.fencedMode.token(stream, state.fencedState)
|
return state.fencedMode.token(stream, state.fencedState)
|
||||||
}
|
} else {
|
||||||
|
state.overlayCur = this.overlayToken(stream, state)
|
||||||
|
state.overlayPos = stream.pos
|
||||||
|
|
||||||
|
return state.overlayCur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
const match = stream.match(fencedCodeRE, true)
|
const match = stream.match(fencedCodeRE, true)
|
||||||
if (match) {
|
if (match) {
|
||||||
state.fencedEndRE = new RegExp(match[1] + '+ *$')
|
state.fencedEndRE = new RegExp(match[1] + '+ *$')
|
||||||
|
|
||||||
state.fencedMode = getMode(
|
state.fencedMode = getMode(match[2], match[3], config, stream.lineOracle.doc.cm)
|
||||||
match[2],
|
|
||||||
match[3],
|
|
||||||
config,
|
|
||||||
stream.lineOracle.doc.cm
|
|
||||||
)
|
|
||||||
if (state.fencedMode) {
|
if (state.fencedMode) {
|
||||||
state.fencedState = CodeMirror.startState(state.fencedMode)
|
state.fencedState = CodeMirror.startState(state.fencedMode)
|
||||||
}
|
}
|
||||||
@@ -130,10 +127,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) {
|
||||||
stream != state.streamSeen ||
|
|
||||||
Math.min(state.basePos, state.overlayPos) < stream.start
|
|
||||||
) {
|
|
||||||
state.streamSeen = stream
|
state.streamSeen = stream
|
||||||
state.basePos = state.overlayPos = stream.start
|
state.basePos = state.overlayPos = stream.start
|
||||||
}
|
}
|
||||||
@@ -151,44 +145,21 @@
|
|||||||
|
|
||||||
if (state.overlayCur == null) {
|
if (state.overlayCur == null) {
|
||||||
return state.baseCur
|
return state.baseCur
|
||||||
} else if (state.baseCur != null && state.combineTokens) {
|
}
|
||||||
|
else if (state.baseCur != null && state.combineTokens) {
|
||||||
return state.baseCur + ' ' + state.overlayCur
|
return state.baseCur + ' ' + state.overlayCur
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return state.overlayCur
|
return state.overlayCur
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
overlayToken: function(stream, state) {
|
overlayToken: function(stream, state) {
|
||||||
state.combineTokens = false
|
state.combineTokens = false
|
||||||
|
|
||||||
if (state.fencedEndRE && stream.match(state.fencedEndRE)) {
|
|
||||||
state.fencedEndRE = null
|
|
||||||
state.localMode = null
|
|
||||||
state.localState = null
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.localMode) {
|
if (state.localMode) {
|
||||||
return state.localMode.token(stream, state.localState) || ''
|
return state.localMode.token(stream, state.localState) || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = stream.match(fencedCodeRE, true)
|
|
||||||
if (match) {
|
|
||||||
state.fencedEndRE = new RegExp(match[1] + '+ *$')
|
|
||||||
|
|
||||||
state.localMode = getMode(
|
|
||||||
match[2],
|
|
||||||
match[3],
|
|
||||||
config,
|
|
||||||
stream.lineOracle.doc.cm
|
|
||||||
)
|
|
||||||
if (state.localMode) {
|
|
||||||
state.localState = CodeMirror.startState(state.localMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
state.combineTokens = true
|
state.combineTokens = true
|
||||||
|
|
||||||
if (state.inTable) {
|
if (state.inTable) {
|
||||||
@@ -239,18 +210,13 @@
|
|||||||
state.inTable = false
|
state.inTable = false
|
||||||
|
|
||||||
if (state.fencedMode) {
|
if (state.fencedMode) {
|
||||||
return (
|
return state.fencedMode.blankLine && state.fencedMode.blankLine(state.fencedState)
|
||||||
state.fencedMode.blankLine &&
|
|
||||||
state.fencedMode.blankLine(state.fencedState)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
return baseMode.blankLine(state.baseState)
|
return baseMode.blankLine(state.baseState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, 'yaml-frontmatter')
|
||||||
'yaml-frontmatter'
|
|
||||||
)
|
|
||||||
|
|
||||||
CodeMirror.defineMIME('text/x-bfm', 'bfm')
|
CodeMirror.defineMIME('text/x-bfm', 'bfm')
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
<script src="../extra_scripts/codemirror/mode/gfm/gfm.js"></script>
|
<script src="../extra_scripts/codemirror/mode/gfm/gfm.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
<script src="../extra_scripts/codemirror/addon/edit/closebrackets.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/search/search.js"></script>
|
<script src="../node_modules/codemirror/addon/search/search.js"></script>
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
<script src="../extra_scripts/codemirror/mode/gfm/gfm.js"></script>
|
<script src="../extra_scripts/codemirror/mode/gfm/gfm.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
<script src="../extra_scripts/codemirror/addon/edit/closebrackets.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/search/search.js"></script>
|
<script src="../node_modules/codemirror/addon/search/search.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user