Skip to content

Commit fc08d2f

Browse files
committed
Merge branch 'master' into migrate-to-jest
# Conflicts: # tests/lib/snapshots/markdown-test.js.md # tests/lib/snapshots/markdown-test.js.snap
2 parents 3921655 + 8736666 commit fc08d2f

Some content is hidden

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

75 files changed

+4847
-3652
lines changed

.eslintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
"globals": {
1919
"FileReader": true,
2020
"localStorage": true,
21-
"fetch": true
21+
"fetch": true,
22+
"Image": true,
23+
"MutationObserver": true
2224
},
2325
"env": {
2426
"jest": true

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ node_modules/*
99
/secret
1010
*.log
1111
.idea
12-
.vscode
12+
.vscode
13+
package-lock.json

browser/components/CodeEditor.js

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ const { ipcRenderer, remote, clipboard } = require('electron')
2121
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
2222
const spellcheck = require('browser/lib/spellcheck')
2323
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder').buildEditorContextMenu
24-
import TurndownService from 'turndown'
24+
import { createTurndownService } from '../lib/turndown'
2525
import {languageMaps} from '../lib/CMLanguageList'
2626
import snippetManager from '../lib/SnippetManager'
2727
import {generateInEditor, tocExistsInEditor} from 'browser/lib/markdown-toc-generator'
2828
import markdownlint from 'markdownlint'
2929
import Jsonlint from 'jsonlint-mod'
3030
import { DEFAULT_CONFIG } from '../main/lib/ConfigManager'
31+
import prettier from 'prettier'
3132

3233
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
3334

@@ -69,7 +70,9 @@ export default class CodeEditor extends React.Component {
6970
storageKey,
7071
noteKey
7172
} = this.props
72-
debouncedDeletionOfAttachments(this.editor.getValue(), storageKey, noteKey)
73+
if (this.props.deleteUnusedAttachments === true) {
74+
debouncedDeletionOfAttachments(this.editor.getValue(), storageKey, noteKey)
75+
}
7376
}
7477
this.pasteHandler = (editor, e) => {
7578
e.preventDefault()
@@ -98,15 +101,15 @@ export default class CodeEditor extends React.Component {
98101

99102
this.editorActivityHandler = () => this.handleEditorActivity()
100103

101-
this.turndownService = new TurndownService()
104+
this.turndownService = createTurndownService()
102105
}
103106

104107
handleSearch (msg) {
105108
const cm = this.editor
106109
const component = this
107110

108111
if (component.searchState) cm.removeOverlay(component.searchState)
109-
if (msg.length < 3) return
112+
if (msg.length < 1) return
110113

111114
cm.operation(function () {
112115
component.searchState = makeOverlay(msg, 'searching')
@@ -216,6 +219,37 @@ export default class CodeEditor extends React.Component {
216219
}
217220
return CodeMirror.Pass
218221
},
222+
[translateHotkey(hotkey.prettifyMarkdown)]: cm => {
223+
// Default / User configured prettier options
224+
const currentConfig = JSON.parse(self.props.prettierConfig)
225+
226+
// Parser type will always need to be markdown so we override the option before use
227+
currentConfig.parser = 'markdown'
228+
229+
// Get current cursor position
230+
const cursorPos = cm.getCursor()
231+
currentConfig.cursorOffset = cm.doc.indexFromPos(cursorPos)
232+
233+
// Prettify contents of editor
234+
const formattedTextDetails = prettier.formatWithCursor(cm.doc.getValue(), currentConfig)
235+
236+
const formattedText = formattedTextDetails.formatted
237+
const formattedCursorPos = formattedTextDetails.cursorOffset
238+
cm.doc.setValue(formattedText)
239+
240+
// Reset Cursor position to be at the same markdown as was before prettifying
241+
const newCursorPos = cm.doc.posFromIndex(formattedCursorPos)
242+
cm.doc.setCursor(newCursorPos)
243+
},
244+
[translateHotkey(hotkey.sortLines)]: cm => {
245+
const selection = cm.doc.getSelection()
246+
const appendLineBreak = /\n$/.test(selection)
247+
248+
const sorted = _.split(selection.trim(), '\n').sort()
249+
const sortedString = _.join(sorted, '\n') + (appendLineBreak ? '\n' : '')
250+
251+
cm.doc.replaceSelection(sortedString)
252+
},
219253
[translateHotkey(hotkey.pasteSmartly)]: cm => {
220254
this.handlePaste(cm, true)
221255
}
@@ -269,7 +303,8 @@ export default class CodeEditor extends React.Component {
269303
explode: this.props.explodingPairs,
270304
override: true
271305
},
272-
extraKeys: this.defaultKeyMap
306+
extraKeys: this.defaultKeyMap,
307+
prettierConfig: this.props.prettierConfig
273308
})
274309

275310
document.querySelector('.CodeMirror-lint-markers').style.display = enableMarkdownLint ? 'inline-block' : 'none'
@@ -608,6 +643,9 @@ export default class CodeEditor extends React.Component {
608643
this.editor.addPanel(this.createSpellCheckPanel(), {position: 'bottom'})
609644
}
610645
}
646+
if (prevProps.deleteUnusedAttachments !== this.props.deleteUnusedAttachments) {
647+
this.editor.setOption('deleteUnusedAttachments', this.props.deleteUnusedAttachments)
648+
}
611649

612650
if (needRefresh) {
613651
this.editor.refresh()
@@ -836,6 +874,17 @@ export default class CodeEditor extends React.Component {
836874
this.editor.setCursor(cursor)
837875
}
838876

877+
/**
878+
* Update content of one line
879+
* @param {Number} lineNumber
880+
* @param {String} content
881+
*/
882+
setLineContent (lineNumber, content) {
883+
const prevContent = this.editor.getLine(lineNumber)
884+
const prevContentLength = prevContent ? prevContent.length : 0
885+
this.editor.replaceRange(content, { line: lineNumber, ch: 0 }, { line: lineNumber, ch: prevContentLength })
886+
}
887+
839888
handleDropImage (dropEvent) {
840889
dropEvent.preventDefault()
841890
const {
@@ -1169,7 +1218,8 @@ CodeEditor.propTypes = {
11691218
autoDetect: PropTypes.bool,
11701219
spellCheck: PropTypes.bool,
11711220
enableMarkdownLint: PropTypes.bool,
1172-
customMarkdownLintConfig: PropTypes.string
1221+
customMarkdownLintConfig: PropTypes.string,
1222+
deleteUnusedAttachments: PropTypes.bool
11731223
}
11741224

11751225
CodeEditor.defaultProps = {
@@ -1183,5 +1233,7 @@ CodeEditor.defaultProps = {
11831233
autoDetect: false,
11841234
spellCheck: false,
11851235
enableMarkdownLint: DEFAULT_CONFIG.editor.enableMarkdownLint,
1186-
customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig
1236+
customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig,
1237+
prettierConfig: DEFAULT_CONFIG.editor.prettierConfig,
1238+
deleteUnusedAttachments: DEFAULT_CONFIG.editor.deleteUnusedAttachments
11871239
}

browser/components/MarkdownEditor.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,15 @@ class MarkdownEditor extends React.Component {
169169
.split('\n')
170170

171171
const targetLine = lines[lineIndex]
172+
let newLine = targetLine
172173

173174
if (targetLine.match(checkedMatch)) {
174-
lines[lineIndex] = targetLine.replace(checkReplace, '[ ]')
175+
newLine = targetLine.replace(checkReplace, '[ ]')
175176
}
176177
if (targetLine.match(uncheckedMatch)) {
177-
lines[lineIndex] = targetLine.replace(uncheckReplace, '[x]')
178+
newLine = targetLine.replace(uncheckReplace, '[x]')
178179
}
179-
this.refs.code.setValue(lines.join('\n'))
180+
this.refs.code.setLineContent(lineIndex, newLine)
180181
}
181182
}
182183

@@ -322,6 +323,8 @@ class MarkdownEditor extends React.Component {
322323
switchPreview={config.editor.switchPreview}
323324
enableMarkdownLint={config.editor.enableMarkdownLint}
324325
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
326+
prettierConfig={config.editor.prettierConfig}
327+
deleteUnusedAttachments={config.editor.deleteUnusedAttachments}
325328
/>
326329
<MarkdownPreview styleName={this.state.status === 'PREVIEW'
327330
? 'preview'

0 commit comments

Comments
 (0)