Merge pull request #1654 from hackmdio/feature/autofix-linting

Autofix linter errors
This commit is contained in:
Yukai Huang 2021-03-12 11:46:51 +08:00 committed by GitHub
commit a7d392c6ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 208 additions and 757 deletions

860
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -105,7 +105,7 @@
"ws": "~7.1.1"
},
"devDependencies": {
"@hackmd/codemirror": "~5.49.8",
"@hackmd/codemirror": "~5.57.7",
"@hackmd/emojify.js": "^2.1.0",
"@hackmd/idle-js": "~1.0.1",
"@hackmd/js-sequence-diagrams": "~0.0.1-alpha.3",
@ -163,7 +163,8 @@
"markdown-it-ruby": "^0.1.1",
"markdown-it-sub": "~1.0.0",
"markdown-it-sup": "~1.0.0",
"markdownlint": "^0.17.0",
"markdownlint": "^0.22.0",
"markdownlint-rule-helpers": "^0.13.0",
"markmap-lib": "^0.4.2",
"mathjax": "~2.7.5",
"mermaid": "~8.6.4",

View File

@ -6,7 +6,7 @@ import * as utils from './utils'
import config from './config'
import statusBarTemplate from './statusbar.html'
import toolBarTemplate from './toolbar.html'
import './markdown-lint'
import { linterOptions } from './markdown-lint'
import CodeMirrorSpellChecker, { supportLanguages, supportLanguageCodes } from './spellcheck'
import { initTableEditor } from './table-editor'
import { availableThemes } from './constants'
@ -674,7 +674,7 @@ export default class Editor {
this.editor.setOption('gutters', gutters.filter(g => g !== lintGutter))
Cookies.remove('linter')
}
this.editor.setOption('lint', enable)
this.editor.setOption('lint', enable ? linterOptions : false)
}
setLinter () {
@ -685,7 +685,7 @@ export default class Editor {
}
linterToggle.click(() => {
const lintEnable = this.editor.getOption('lint')
const lintEnable = !!this.editor.getOption('lint')
this.toggleLinter.bind(this)(!lintEnable)
updateLinterStatus(!lintEnable)
})

View File

@ -3,6 +3,9 @@
// load CM lint plugin explicitly
import '@hackmd/codemirror/addon/lint/lint'
import '@hackmd/codemirror/addon/hint/show-hint.css'
import helpers from 'markdownlint-rule-helpers'
window.markdownit = require('markdown-it')
// eslint-disable-next-line
require('script-loader!markdownlint');
@ -26,10 +29,11 @@ require('script-loader!markdownlint');
}
return {
messageHTML: `${ruleNames.join('/')}: ${ruleDescription}`,
messageHTML: `${ruleNames.join('/')}: ${ruleDescription} <small>markdownlint(${ruleNames[0]})</small>`,
severity: 'error',
from: CodeMirror.Pos(lineNumber, start),
to: CodeMirror.Pos(lineNumber, end)
to: CodeMirror.Pos(lineNumber, end),
__error: error
}
})
}
@ -37,11 +41,84 @@ require('script-loader!markdownlint');
CodeMirror.registerHelper('lint', 'markdown', validator)
})
export const linterOptions = {
fixedTooltip: true,
contextmenu: annotations => {
const singleFixMenus = annotations
.map(annotation => {
const error = annotation.__error
const ruleNameAlias = error.ruleNames.join('/')
if (annotation.__error.fixInfo) {
return {
content: `Click to fix this violoation of ${ruleNameAlias}`,
onClick () {
const doc = window.editor.doc
const fixInfo = normalizeFixInfo(error.fixInfo, error.lineNumber)
const line = fixInfo.lineNumber - 1
const lineContent = doc.getLine(line) || ''
const fixedText = helpers.applyFix(lineContent, fixInfo, '\n')
let from = { line, ch: 0 }
let to = { line, ch: lineContent ? lineContent.length : 0 }
if (typeof fixedText === 'string') {
doc.replaceRange(fixedText, from, to)
} else {
if (fixInfo.lineNumber === 1) {
if (doc.lineCount() > 1) {
const nextLineStart = doc.indexFromPos({
line: to.line + 1,
ch: 0
})
to = doc.posFromIndex(nextLineStart)
}
} else {
const previousLineEnd = doc.indexFromPos(from) - 1
from = doc.posFromIndex(previousLineEnd)
}
doc.replaceRange('', from, to)
}
}
}
} else {
return {
content: `Click for more information about ${ruleNameAlias}`,
onClick () {
window.open(error.ruleInformation, '_blank')
}
}
}
})
return singleFixMenus
}
}
function lint (content) {
const { content: errors } = window.markdownlint.sync({
strings: {
content
}
},
resultVersion: 3
})
return errors
}
// Taken from https://github.com/DavidAnson/markdownlint/blob/2a9274ece586514ba3e2819cec3eb74312dc1b84/helpers/helpers.js#L611
/**
* Normalizes the fields of a RuleOnErrorFixInfo instance.
*
* @param {Object} fixInfo RuleOnErrorFixInfo instance.
* @param {number} [lineNumber] Line number.
* @returns {Object} Normalized RuleOnErrorFixInfo instance.
*/
function normalizeFixInfo (fixInfo, lineNumber) {
return {
lineNumber: fixInfo.lineNumber || lineNumber,
editColumn: fixInfo.editColumn || 1,
deleteCount: fixInfo.deleteCount || 0,
insertText: fixInfo.insertText || ''
}
}

View File

@ -71,3 +71,11 @@
background-position: right bottom;
width: 100%; height: 100%;
}
.CodeMirror-hints {
background: #333;
}
.CodeMirror-hint {
color: white;
}

View File

@ -522,7 +522,8 @@ module.exports = {
}]
},
node: {
fs: 'empty'
fs: 'empty',
os: 'empty'
},
stats: {