|
|
@@ -1,22 +1,4 @@
|
|
|
-/* eslint-disable
|
|
|
- max-len,
|
|
|
- no-cond-assign,
|
|
|
- no-return-assign,
|
|
|
- no-undef,
|
|
|
- no-unused-vars,
|
|
|
- no-useless-escape,
|
|
|
-*/
|
|
|
-// TODO: This file was created by bulk-decaffeinate.
|
|
|
-// Fix any style issues and re-enable lint.
|
|
|
-/*
|
|
|
- * decaffeinate suggestions:
|
|
|
- * DS101: Remove unnecessary use of Array.from
|
|
|
- * DS102: Remove unnecessary code created because of implicit returns
|
|
|
- * DS103: Rewrite code to no longer use __guard__
|
|
|
- * DS202: Simplify dynamic range loops
|
|
|
- * DS207: Consider shorter variations of null checks
|
|
|
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
- */
|
|
|
+/* global _ */
|
|
|
define([
|
|
|
'ide/editor/directives/aceEditor/auto-complete/CommandManager',
|
|
|
'ide/editor/directives/aceEditor/auto-complete/EnvironmentManager',
|
|
|
@@ -25,11 +7,10 @@ define([
|
|
|
'ace/ace',
|
|
|
'ace/ext-language_tools'
|
|
|
], function(CommandManager, EnvironmentManager, PackageManager, Helpers) {
|
|
|
- let AutoCompleteManager
|
|
|
const { Range } = ace.require('ace/range')
|
|
|
const aceSnippetManager = ace.require('ace/snippets').snippetManager
|
|
|
|
|
|
- return (AutoCompleteManager = class AutoCompleteManager {
|
|
|
+ class AutoCompleteManager {
|
|
|
constructor(
|
|
|
$scope,
|
|
|
editor,
|
|
|
@@ -50,19 +31,19 @@ define([
|
|
|
|
|
|
this.$scope.$watch('autoComplete', autocomplete => {
|
|
|
if (autocomplete) {
|
|
|
- return this.enable()
|
|
|
+ this.enable()
|
|
|
} else {
|
|
|
- return this.disable()
|
|
|
+ this.disable()
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const onChange = change => {
|
|
|
- return this.onChange(change)
|
|
|
+ this.onChange(change)
|
|
|
}
|
|
|
|
|
|
this.editor.on('changeSession', e => {
|
|
|
e.oldSession.off('change', onChange)
|
|
|
- return e.session.on('change', onChange)
|
|
|
+ e.session.on('change', onChange)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
@@ -89,14 +70,13 @@ define([
|
|
|
/^~?\\(includegraphics(?:\[.*])?){([^}]*, *)?(\w*)/
|
|
|
)
|
|
|
if (match) {
|
|
|
- let [_ignore1, commandName, _ignore2, currentArg] = Array.from(
|
|
|
- match
|
|
|
- )
|
|
|
+ // eslint-disable-next-line no-unused-vars
|
|
|
+ let commandName = match[1]
|
|
|
const graphicsPaths = Preamble.getGraphicsPaths()
|
|
|
const result = []
|
|
|
- for (let graphic of Array.from(Graphics.getGraphicsFiles())) {
|
|
|
+ for (let graphic of Graphics.getGraphicsFiles()) {
|
|
|
let { path } = graphic
|
|
|
- for (let graphicsPath of Array.from(graphicsPaths)) {
|
|
|
+ for (let graphicsPath of graphicsPaths) {
|
|
|
if (path.indexOf(graphicsPath) === 0) {
|
|
|
path = path.slice(graphicsPath.length)
|
|
|
break
|
|
|
@@ -109,7 +89,7 @@ define([
|
|
|
score: 50
|
|
|
})
|
|
|
}
|
|
|
- return callback(null, result)
|
|
|
+ callback(null, result)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -122,9 +102,10 @@ define([
|
|
|
if (commandFragment) {
|
|
|
const match = commandFragment.match(/^\\(input|include){(\w*)/)
|
|
|
if (match) {
|
|
|
- const [_, commandName, currentArg] = Array.from(match)
|
|
|
+ // eslint-disable-next-line no-unused-vars
|
|
|
+ const commandName = match[1]
|
|
|
const result = []
|
|
|
- for (let file of Array.from(Files.getTeXFiles())) {
|
|
|
+ for (let file of Files.getTeXFiles()) {
|
|
|
if (file.id !== this.$scope.docId) {
|
|
|
const { path } = file
|
|
|
result.push({
|
|
|
@@ -135,7 +116,7 @@ define([
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
- return callback(null, result)
|
|
|
+ callback(null, result)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -149,7 +130,8 @@ define([
|
|
|
/^~?\\([a-zA-Z]*ref){([^}]*, *)?(\w*)/
|
|
|
)
|
|
|
if (refMatch) {
|
|
|
- const [_, commandName, currentArg] = Array.from(refMatch)
|
|
|
+ // eslint-disable-next-line no-unused-vars
|
|
|
+ const commandName = refMatch[1]
|
|
|
const result = []
|
|
|
if (commandName !== 'ref') {
|
|
|
// ref is in top 100 commands
|
|
|
@@ -160,7 +142,7 @@ define([
|
|
|
score: 60
|
|
|
})
|
|
|
}
|
|
|
- for (let label of Array.from(metadataManager.getAllLabels())) {
|
|
|
+ for (let label of metadataManager.getAllLabels()) {
|
|
|
result.push({
|
|
|
caption: `\\${commandName}{${label}}`,
|
|
|
value: `\\${commandName}{${label}}`,
|
|
|
@@ -168,7 +150,7 @@ define([
|
|
|
score: 50
|
|
|
})
|
|
|
}
|
|
|
- return callback(null, result)
|
|
|
+ callback(null, result)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -183,9 +165,8 @@ define([
|
|
|
/^~?\\([a-z]*cite[a-z]*(?:\[.*])?){([^}]*, *)?(\w*)/
|
|
|
)
|
|
|
if (citeMatch) {
|
|
|
- let [_, commandName, previousArgs, currentArg] = Array.from(
|
|
|
- citeMatch
|
|
|
- )
|
|
|
+ // eslint-disable-next-line no-unused-vars
|
|
|
+ let [_ignore, commandName, previousArgs] = citeMatch
|
|
|
if (previousArgs == null) {
|
|
|
previousArgs = ''
|
|
|
}
|
|
|
@@ -209,16 +190,16 @@ define([
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
- return callback(null, result)
|
|
|
+ callback(null, result)
|
|
|
} else {
|
|
|
- return callback(null, result)
|
|
|
+ callback(null, result)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return (this.editor.completers = [
|
|
|
+ this.editor.completers = [
|
|
|
CommandCompleter,
|
|
|
SnippetCompleter,
|
|
|
PackageCompleter,
|
|
|
@@ -226,7 +207,7 @@ define([
|
|
|
LabelsCompleter,
|
|
|
GraphicsCompleter,
|
|
|
FilesCompleter
|
|
|
- ])
|
|
|
+ ]
|
|
|
}
|
|
|
|
|
|
disable() {
|
|
|
@@ -254,16 +235,15 @@ define([
|
|
|
const lastTwoChars = lineUpToCursor.slice(-2)
|
|
|
// Don't offer autocomplete on double-backslash, backslash-colon, etc
|
|
|
if (/^\\[^a-zA-Z]$/.test(lastTwoChars)) {
|
|
|
- __guardMethod__(
|
|
|
- this.editor != null ? this.editor.completer : undefined,
|
|
|
- 'detach',
|
|
|
- o => o.detach()
|
|
|
- )
|
|
|
+ if (this.editor.completer) {
|
|
|
+ this.editor.completer.detach()
|
|
|
+ }
|
|
|
return
|
|
|
}
|
|
|
// Check that this change was made by us, not a collaborator
|
|
|
// (Cursor is still one place behind)
|
|
|
- // NOTE: this is also the case when a user backspaces over a highlighted region
|
|
|
+ // NOTE: this is also the case when a user backspaces over a highlighted
|
|
|
+ // region
|
|
|
if (
|
|
|
change.action === 'insert' &&
|
|
|
end.row === cursorPosition.row &&
|
|
|
@@ -274,18 +254,21 @@ define([
|
|
|
lastCharIsBackslash
|
|
|
) {
|
|
|
setTimeout(() => {
|
|
|
- return this.editor.execCommand('startAutocomplete')
|
|
|
+ this.editor.execCommand('startAutocomplete')
|
|
|
}, 0)
|
|
|
}
|
|
|
}
|
|
|
+ const match = change.lines[0].match(/\\(\w+){}/)
|
|
|
if (
|
|
|
change.action === 'insert' &&
|
|
|
+ (match && match[1]) &&
|
|
|
+ // eslint-disable-next-line max-len
|
|
|
/(begin|end|[a-zA-Z]*ref|usepackage|[a-z]*cite[a-z]*|input|include)/.test(
|
|
|
- __guard__(change.lines[0].match(/\\(\w+){}/), x => x[1])
|
|
|
+ match[1]
|
|
|
)
|
|
|
) {
|
|
|
return setTimeout(() => {
|
|
|
- return this.editor.execCommand('startAutocomplete')
|
|
|
+ this.editor.execCommand('startAutocomplete')
|
|
|
}, 0)
|
|
|
}
|
|
|
}
|
|
|
@@ -306,16 +289,21 @@ define([
|
|
|
|
|
|
// If we are in \begin{it|}, then we need to remove the trailing }
|
|
|
// since it will be adding in with the autocomplete of \begin{item}...
|
|
|
- if (/^\\\w+{/.test(this.completions.filterText) && nextChar === '}') {
|
|
|
+ if (
|
|
|
+ /^\\\w+(\[[\w\\,= ]*\])?{/.test(this.completions.filterText) &&
|
|
|
+ nextChar === '}'
|
|
|
+ ) {
|
|
|
editor.session.remove(range)
|
|
|
}
|
|
|
|
|
|
// Provide our own `insertMatch` implementation.
|
|
|
- // See the `insertMatch` method of Autocomplete in `ext-language_tools.js`.
|
|
|
- // We need this to account for editing existing commands, particularly when
|
|
|
- // adding a prefix.
|
|
|
- // We fix this by detecting when the cursor is in the middle of an existing
|
|
|
- // command, and adjusting the insertions/deletions accordingly.
|
|
|
+ // See the `insertMatch` method of Autocomplete in
|
|
|
+ // `ext-language_tools.js`.
|
|
|
+ // We need this to account for editing existing commands, particularly
|
|
|
+ // when adding a prefix.
|
|
|
+ // We fix this by detecting when the cursor is in the middle of an
|
|
|
+ // existing command, and adjusting the insertions/deletions
|
|
|
+ // accordingly.
|
|
|
// Example:
|
|
|
// when changing `\ref{}` to `\href{}`, ace default behaviour
|
|
|
// is likely to end up with `\href{}ref{}`
|
|
|
@@ -325,7 +313,7 @@ define([
|
|
|
data = popup.getData(popup.getRow())
|
|
|
data.completer = {
|
|
|
insertMatch(editor, matchData) {
|
|
|
- for (range of Array.from(editor.selection.getAllRanges())) {
|
|
|
+ for (range of editor.selection.getAllRanges()) {
|
|
|
const leftRange = _.clone(range)
|
|
|
const rightRange = _.clone(range)
|
|
|
// trim to left of cursor
|
|
|
@@ -362,35 +350,34 @@ define([
|
|
|
)
|
|
|
|
|
|
if (lineBeyondCursor) {
|
|
|
- var partialCommandMatch
|
|
|
- if (
|
|
|
- (partialCommandMatch = lineBeyondCursor.match(
|
|
|
- /^([a-zA-Z0-9]+)\{/
|
|
|
- ))
|
|
|
- ) {
|
|
|
+ const partialCommandMatch = lineBeyondCursor.match(
|
|
|
+ /^([a-zA-Z0-9]+)\{/
|
|
|
+ )
|
|
|
+ if (partialCommandMatch) {
|
|
|
// We've got a partial command after the cursor
|
|
|
const commandTail = partialCommandMatch[1]
|
|
|
// remove rest of the partial command, right of cursor
|
|
|
rightRange.end.column +=
|
|
|
commandTail.length - completions.filterText.length
|
|
|
editor.session.remove(rightRange)
|
|
|
- // trim the completion text to just the command, without braces or brackets
|
|
|
+ // trim the completion text to just the command, without
|
|
|
+ // braces or brackets
|
|
|
// example: '\cite{}' -> '\cite'
|
|
|
if (matchData.snippet != null) {
|
|
|
matchData.snippet = matchData.snippet.replace(
|
|
|
- /[{\[].*[}\]]/,
|
|
|
+ /[{[].*[}\]]/,
|
|
|
''
|
|
|
)
|
|
|
}
|
|
|
if (matchData.caption != null) {
|
|
|
matchData.caption = matchData.caption.replace(
|
|
|
- /[{\[].*[}\]]/,
|
|
|
+ /[{[].*[}\]]/,
|
|
|
''
|
|
|
)
|
|
|
}
|
|
|
if (matchData.value != null) {
|
|
|
matchData.value = matchData.value.replace(
|
|
|
- /[{\[].*[}\]]/,
|
|
|
+ /[{[].*[}\]]/,
|
|
|
''
|
|
|
)
|
|
|
}
|
|
|
@@ -399,12 +386,9 @@ define([
|
|
|
}
|
|
|
// finally, insert the match
|
|
|
if (matchData.snippet) {
|
|
|
- return aceSnippetManager.insertSnippet(
|
|
|
- editor,
|
|
|
- matchData.snippet
|
|
|
- )
|
|
|
+ aceSnippetManager.insertSnippet(editor, matchData.snippet)
|
|
|
} else {
|
|
|
- return editor.execCommand(
|
|
|
+ editor.execCommand(
|
|
|
'insertstring',
|
|
|
matchData.value || matchData
|
|
|
)
|
|
|
@@ -413,7 +397,7 @@ define([
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return Autocomplete.prototype._insertMatch.call(this, data)
|
|
|
+ Autocomplete.prototype._insertMatch.call(this, data)
|
|
|
}
|
|
|
|
|
|
// Overwrite this to set autoInsert = false and set font size
|
|
|
@@ -435,15 +419,10 @@ define([
|
|
|
)
|
|
|
container.css({ 'font-size': this.$scope.fontSize + 'px' })
|
|
|
// Dynamically set width of autocomplete popup
|
|
|
- if (
|
|
|
- (filtered = __guard__(
|
|
|
- __guard__(
|
|
|
- editor != null ? editor.completer : undefined,
|
|
|
- x1 => x1.completions
|
|
|
- ),
|
|
|
- x => x.filtered
|
|
|
- ))
|
|
|
- ) {
|
|
|
+ filtered =
|
|
|
+ editor.completer.completions &&
|
|
|
+ editor.completer.completions.filtered
|
|
|
+ if (filtered) {
|
|
|
const longestCaption = _.max(filtered.map(c => c.caption.length))
|
|
|
const longestMeta = _.max(filtered.map(c => c.meta.length))
|
|
|
const charWidth = editor.renderer.characterWidth
|
|
|
@@ -461,31 +440,17 @@ define([
|
|
|
)
|
|
|
container.css({ width: `${width}px` })
|
|
|
}
|
|
|
- if (
|
|
|
- __guard__(
|
|
|
- __guard__(
|
|
|
- editor.completer != null
|
|
|
- ? editor.completer.completions
|
|
|
- : undefined,
|
|
|
- x3 => x3.filtered
|
|
|
- ),
|
|
|
- x2 => x2.length
|
|
|
- ) === 0
|
|
|
- ) {
|
|
|
- return editor.completer.detach()
|
|
|
+ if (filtered.length === 0) {
|
|
|
+ editor.completer.detach()
|
|
|
}
|
|
|
},
|
|
|
bindKey: 'Ctrl-Space|Ctrl-Shift-Space|Alt-Space'
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return (Util.retrievePrecedingIdentifier = function(text, pos, regex) {
|
|
|
+ Util.retrievePrecedingIdentifier = function(text, pos, regex) {
|
|
|
let currentLineOffset = 0
|
|
|
- for (
|
|
|
- let start = pos - 1, i = start, asc = start <= 0;
|
|
|
- asc ? i <= 0 : i >= 0;
|
|
|
- asc ? i++ : i--
|
|
|
- ) {
|
|
|
+ for (let i = pos - 1; i <= 0; i++) {
|
|
|
if (text[i] === '\n') {
|
|
|
currentLineOffset = i + 1
|
|
|
break
|
|
|
@@ -494,24 +459,9 @@ define([
|
|
|
const currentLine = text.slice(currentLineOffset, pos)
|
|
|
const fragment = Helpers.getLastCommandFragment(currentLine) || ''
|
|
|
return fragment
|
|
|
- })
|
|
|
+ }
|
|
|
}
|
|
|
- })
|
|
|
-})
|
|
|
-
|
|
|
-function __guardMethod__(obj, methodName, transform) {
|
|
|
- if (
|
|
|
- typeof obj !== 'undefined' &&
|
|
|
- obj !== null &&
|
|
|
- typeof obj[methodName] === 'function'
|
|
|
- ) {
|
|
|
- return transform(obj, methodName)
|
|
|
- } else {
|
|
|
- return undefined
|
|
|
}
|
|
|
-}
|
|
|
-function __guard__(value, transform) {
|
|
|
- return typeof value !== 'undefined' && value !== null
|
|
|
- ? transform(value)
|
|
|
- : undefined
|
|
|
-}
|
|
|
+
|
|
|
+ return AutoCompleteManager
|
|
|
+})
|