1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 01:36:22 +00:00

new feature: auto detect snippet language

only try to detect after pasting and mode has not been set and default snippet language is "Auto Detect"
This commit is contained in:
HarlanLuo
2019-01-01 16:23:15 +08:00
parent 05da826c24
commit deb2cd0156
5 changed files with 104 additions and 7 deletions

View File

@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
import React from 'react'
import _ from 'lodash'
import CodeMirror from 'codemirror'
import hljs from 'highlight.js'
import 'codemirror-mode-elixir'
import attachmentManagement from 'browser/main/lib/dataApi/attachmentManagement'
import convertModeName from 'browser/lib/convertModeName'
@@ -37,6 +38,85 @@ function translateHotkey (hotkey) {
return hotkey.replace(/\s*\+\s*/g, '-').replace(/Command/g, 'Cmd').replace(/Control/g, 'Ctrl')
}
const languageMaps = {
brainfuck: 'Brainfuck',
cpp: 'C++',
cs: 'C#',
clojure: 'Clojure',
'clojure-repl': 'ClojureScript',
cmake: 'CMake',
coffeescript: 'CoffeeScript',
crystal: 'Crystal',
css: 'CSS',
d: 'D',
dart: 'Dart',
delphi: 'Pascal',
diff: 'Diff',
django: 'Django',
dockerfile: 'Dockerfile',
ebnf: 'EBNF',
elm: 'Elm',
erlang: 'Erlang',
'erlang-repl': 'Erlang',
fortran: 'Fortran',
fsharp: 'F#',
gherkin: 'Gherkin',
go: 'Go',
groovy: 'Groovy',
haml: 'HAML',
haskell: 'Haskell',
haxe: 'Haxe',
http: 'HTTP',
ini: 'toml',
java: 'Java',
javascript: 'JavaScript',
json: 'JSON',
julia: 'Julia',
kotlin: 'Kotlin',
less: 'LESS',
livescript: 'LiveScript',
lua: 'Lua',
markdown: 'Markdown',
mathematica: 'Mathematica',
nginx: 'Nginx',
nsis: 'NSIS',
objectivec: 'Objective-C',
ocaml: 'Ocaml',
perl: 'Perl',
php: 'PHP',
powershell: 'PowerShell',
properties: 'Properties files',
protobuf: 'ProtoBuf',
python: 'Python',
puppet: 'Puppet',
q: 'Q',
r: 'R',
ruby: 'Ruby',
rust: 'Rust',
sas: 'SAS',
scala: 'Scala',
scheme: 'Scheme',
scss: 'SCSS',
shell: 'Shell',
smalltalk: 'Smalltalk',
sml: 'SML',
sql: 'SQL',
stylus: 'Stylus',
swift: 'Swift',
tcl: 'Tcl',
tex: 'LaTex',
typescript: 'TypeScript',
twig: 'Twig',
vbnet: 'VB.NET',
vbscript: 'VBScript',
verilog: 'Verilog',
vhdl: 'VHDL',
xml: 'HTML',
xquery: 'XQuery',
yaml: 'YAML',
elixir: 'Elixir'
}
export default class CodeEditor extends React.Component {
constructor (props) {
super(props)
@@ -274,7 +354,11 @@ export default class CodeEditor extends React.Component {
extraKeys: this.defaultKeyMap
})
this.setMode(this.props.mode)
if (!this.props.mode && this.props.value) {
this.autoDetectLanguage(this.props.value)
} else {
this.setMode(this.props.mode)
}
this.editor.on('focus', this.focusHandler)
this.editor.on('blur', this.blurHandler)
@@ -644,7 +728,7 @@ export default class CodeEditor extends React.Component {
}
setMode (mode) {
let syntax = CodeMirror.findModeByName(convertModeName(mode))
let syntax = CodeMirror.findModeByName(convertModeName(mode || 'text'))
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
this.editor.setOption('mode', syntax.mime)
@@ -796,6 +880,11 @@ export default class CodeEditor extends React.Component {
this.editor.replaceSelection(imageMd)
}
autoDetectLanguage (content) {
const res = hljs.highlightAuto(content, Object.keys(languageMaps))
this.setMode(languageMaps[res.language])
}
handlePaste (editor, forceSmartPaste) {
const { storageKey, noteKey, fetchUrlTitle, enableSmartPaste } = this.props
@@ -892,6 +981,10 @@ export default class CodeEditor extends React.Component {
this.handlePasteText(editor, pastedTxt)
}
}
if (!this.props.mode) {
this.autoDetectLanguage(editor.doc.getValue())
}
}
handleScroll (e) {

View File

@@ -46,6 +46,8 @@ export function createSnippetNote (storage, folder, dispatch, location, params,
tags = params.tagname.split(' ')
}
const defaultLanguage = config.editor.snippetDefaultLanguage === 'Auto Detect' ? null : config.editor.snippetDefaultLanguage
return dataApi
.createNote(storage, {
type: 'SNIPPET_NOTE',
@@ -56,7 +58,7 @@ export function createSnippetNote (storage, folder, dispatch, location, params,
snippets: [
{
name: '',
mode: config.editor.snippetDefaultLanguage || 'text',
mode: defaultLanguage,
content: '',
linesHighlighted: []
}

View File

@@ -599,12 +599,14 @@ class SnippetNoteDetail extends React.Component {
}
addSnippet () {
const { config } = this.props
const { config: { editor: { snippetDefaultLanguage } } } = this.props
const { note } = this.state
const defaultLanguage = snippetDefaultLanguage === 'Auto Detect' ? null : snippetDefaultLanguage
note.snippets = note.snippets.concat([{
name: '',
mode: config.editor.snippetDefaultLanguage || 'text',
mode: defaultLanguage,
content: '',
linesHighlighted: []
}])
@@ -696,8 +698,6 @@ class SnippetNoteDetail extends React.Component {
const viewList = note.snippets.map((snippet, index) => {
const isActive = this.state.snippetIndex === index
let syntax = CodeMirror.findModeByName(convertModeName(snippet.mode))
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
return <div styleName='tabView'
key={index}
style={{zIndex: isActive ? 5 : 4}}

View File

@@ -481,6 +481,7 @@ class UiTab extends React.Component {
ref='editorSnippetDefaultLanguage'
onChange={(e) => this.handleUIChange(e)}
>
<option key='Auto Detect' value='Auto Detect'>Auto Detect</option>
{
_.sortBy(CodeMirror.modeInfo.map(mode => mode.name)).map(name => (<option key={name} value={name}>{name}</option>))
}

View File

@@ -66,6 +66,7 @@
"flowchart.js": "^1.6.5",
"font-awesome": "^4.3.0",
"fs-extra": "^5.0.0",
"highlight.js": "^9.13.1",
"i18n-2": "^0.7.2",
"iconv-lite": "^0.4.19",
"immutable": "^3.8.1",