Skip to content

Commit a7f802d

Browse files
committed
Merge branch 'master' into filter-tags-and-folders
2 parents db78f1b + 3779016 commit a7f802d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+548
-292
lines changed

browser/components/CodeEditor.js

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {
1414
import TextEditorInterface from 'browser/lib/TextEditorInterface'
1515
import eventEmitter from 'browser/main/lib/eventEmitter'
1616
import iconv from 'iconv-lite'
17+
18+
import { isMarkdownTitleURL } from 'browser/lib/utils'
1719
import styles from '../components/CodeEditor.styl'
1820
const { ipcRenderer, remote, clipboard } = require('electron')
1921
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
@@ -22,6 +24,8 @@ const buildEditorContextMenu = require('browser/lib/contextMenuBuilder')
2224
import TurndownService from 'turndown'
2325
import {languageMaps} from '../lib/CMLanguageList'
2426
import snippetManager from '../lib/SnippetManager'
27+
import {generateInEditor, tocExistsInEditor} from 'browser/lib/markdown-toc-generator'
28+
import markdownlint from 'markdownlint'
2529

2630
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
2731

@@ -34,6 +38,38 @@ function translateHotkey (hotkey) {
3438
return hotkey.replace(/\s*\+\s*/g, '-').replace(/Command/g, 'Cmd').replace(/Control/g, 'Ctrl')
3539
}
3640

41+
const validatorOfMarkdown = (text, updateLinting) => {
42+
const lintOptions = {
43+
'strings': {
44+
'content': text
45+
}
46+
}
47+
48+
return markdownlint(lintOptions, (err, result) => {
49+
if (!err) {
50+
const foundIssues = []
51+
result.content.map(item => {
52+
let ruleNames = ''
53+
item.ruleNames.map((ruleName, index) => {
54+
ruleNames += ruleName
55+
if (index === item.ruleNames.length - 1) {
56+
ruleNames += ': '
57+
} else {
58+
ruleNames += '/'
59+
}
60+
})
61+
foundIssues.push({
62+
from: CodeMirror.Pos(item.lineNumber, 0),
63+
to: CodeMirror.Pos(item.lineNumber, 1),
64+
message: ruleNames + item.ruleDescription,
65+
severity: 'warning'
66+
})
67+
})
68+
updateLinting(foundIssues)
69+
}
70+
})
71+
}
72+
3773
export default class CodeEditor extends React.Component {
3874
constructor (props) {
3975
super(props)
@@ -197,6 +233,26 @@ export default class CodeEditor extends React.Component {
197233
'Cmd-T': function (cm) {
198234
// Do nothing
199235
},
236+
'Ctrl-/': function (cm) {
237+
if (global.process.platform === 'darwin') { return }
238+
const dateNow = new Date()
239+
cm.replaceSelection(dateNow.toLocaleDateString())
240+
},
241+
'Cmd-/': function (cm) {
242+
if (global.process.platform !== 'darwin') { return }
243+
const dateNow = new Date()
244+
cm.replaceSelection(dateNow.toLocaleDateString())
245+
},
246+
'Shift-Ctrl-/': function (cm) {
247+
if (global.process.platform === 'darwin') { return }
248+
const dateNow = new Date()
249+
cm.replaceSelection(dateNow.toLocaleString())
250+
},
251+
'Shift-Cmd-/': function (cm) {
252+
if (global.process.platform !== 'darwin') { return }
253+
const dateNow = new Date()
254+
cm.replaceSelection(dateNow.toLocaleString())
255+
},
200256
Enter: 'boostNewLineAndIndentContinueMarkdownList',
201257
'Ctrl-C': cm => {
202258
if (cm.getOption('keyMap').substr(0, 3) === 'vim') {
@@ -233,6 +289,7 @@ export default class CodeEditor extends React.Component {
233289
snippetManager.init()
234290
this.updateDefaultKeyMap()
235291

292+
const checkMarkdownNoteIsOpening = this.props.mode === 'Boost Flavored Markdown'
236293
this.value = this.props.value
237294
this.editor = CodeMirror(this.refs.root, {
238295
rulers: buildCMRulers(rulers, enableRulers),
@@ -249,7 +306,11 @@ export default class CodeEditor extends React.Component {
249306
inputStyle: 'textarea',
250307
dragDrop: false,
251308
foldGutter: true,
252-
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
309+
lint: checkMarkdownNoteIsOpening ? {
310+
'getAnnotations': validatorOfMarkdown,
311+
'async': true
312+
} : false,
313+
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
253314
autoCloseBrackets: {
254315
pairs: this.props.matchingPairs,
255316
triples: this.props.matchingTriples,
@@ -594,6 +655,34 @@ export default class CodeEditor extends React.Component {
594655
handleChange (editor, changeObject) {
595656
spellcheck.handleChange(editor, changeObject)
596657

658+
// The current note contains an toc. We'll check for changes on headlines.
659+
// origin is undefined when markdownTocGenerator replace the old tod
660+
if (tocExistsInEditor(editor) && changeObject.origin !== undefined) {
661+
let requireTocUpdate
662+
663+
// Check if one of the changed lines contains a headline
664+
for (let line = 0; line < changeObject.text.length; line++) {
665+
if (this.linePossibleContainsHeadline(editor.getLine(changeObject.from.line + line))) {
666+
requireTocUpdate = true
667+
break
668+
}
669+
}
670+
671+
if (!requireTocUpdate) {
672+
// Check if one of the removed lines contains a headline
673+
for (let line = 0; line < changeObject.removed.length; line++) {
674+
if (this.linePossibleContainsHeadline(changeObject.removed[line])) {
675+
requireTocUpdate = true
676+
break
677+
}
678+
}
679+
}
680+
681+
if (requireTocUpdate) {
682+
generateInEditor(editor)
683+
}
684+
}
685+
597686
this.updateHighlight(editor, changeObject)
598687

599688
this.value = editor.getValue()
@@ -602,6 +691,12 @@ export default class CodeEditor extends React.Component {
602691
}
603692
}
604693

694+
linePossibleContainsHeadline (currentLine) {
695+
// We can't check if the line start with # because when some write text before
696+
// the # we also need to update the toc
697+
return currentLine.includes('# ')
698+
}
699+
605700
incrementLines (start, linesAdded, linesRemoved, editor) {
606701
const highlightedLines = editor.options.linesHighlighted
607702

@@ -809,6 +904,8 @@ export default class CodeEditor extends React.Component {
809904

810905
if (isInFencedCodeBlock(editor)) {
811906
this.handlePasteText(editor, pastedTxt)
907+
} else if (fetchUrlTitle && isMarkdownTitleURL(pastedTxt) && !isInLinkTag(editor)) {
908+
this.handlePasteUrl(editor, pastedTxt)
812909
} else if (fetchUrlTitle && isURL(pastedTxt) && !isInLinkTag(editor)) {
813910
this.handlePasteUrl(editor, pastedTxt)
814911
} else if (attachmentManagement.isAttachmentLink(pastedTxt)) {
@@ -850,7 +947,17 @@ export default class CodeEditor extends React.Component {
850947
}
851948

852949
handlePasteUrl (editor, pastedTxt) {
853-
const taggedUrl = `<${pastedTxt}>`
950+
let taggedUrl = `<${pastedTxt}>`
951+
let urlToFetch = pastedTxt
952+
let titleMark = ''
953+
954+
if (isMarkdownTitleURL(pastedTxt)) {
955+
const pastedTxtSplitted = pastedTxt.split(' ')
956+
titleMark = `${pastedTxtSplitted[0]} `
957+
urlToFetch = pastedTxtSplitted[1]
958+
taggedUrl = `<${urlToFetch}>`
959+
}
960+
854961
editor.replaceSelection(taggedUrl)
855962

856963
const isImageReponse = response => {
@@ -862,22 +969,23 @@ export default class CodeEditor extends React.Component {
862969
const replaceTaggedUrl = replacement => {
863970
const value = editor.getValue()
864971
const cursor = editor.getCursor()
865-
const newValue = value.replace(taggedUrl, replacement)
972+
const newValue = value.replace(taggedUrl, titleMark + replacement)
866973
const newCursor = Object.assign({}, cursor, {
867-
ch: cursor.ch + newValue.length - value.length
974+
ch: cursor.ch + newValue.length - (value.length - titleMark.length)
868975
})
976+
869977
editor.setValue(newValue)
870978
editor.setCursor(newCursor)
871979
}
872980

873-
fetch(pastedTxt, {
981+
fetch(urlToFetch, {
874982
method: 'get'
875983
})
876984
.then(response => {
877985
if (isImageReponse(response)) {
878-
return this.mapImageResponse(response, pastedTxt)
986+
return this.mapImageResponse(response, urlToFetch)
879987
} else {
880-
return this.mapNormalResponse(response, pastedTxt)
988+
return this.mapNormalResponse(response, urlToFetch)
881989
}
882990
})
883991
.then(replacement => {

browser/components/CodeEditor.styl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@
33

44
.spellcheck-select
55
border: none
6-
text-decoration underline wavy red

0 commit comments

Comments
 (0)