overleaf/services/web/public/coffee/auto-complete/AutoCompleteManager.coffee

78 lines
2.4 KiB
CoffeeScript
Raw Normal View History

2014-02-12 10:23:40 +00:00
define [
"auto-complete/SuggestionManager"
2014-03-05 11:05:59 +00:00
"auto-complete/Snippets"
2014-03-04 17:29:26 +00:00
"ace/autocomplete/util"
"ace/autocomplete"
2014-02-12 10:23:40 +00:00
"ace/range"
2014-03-04 17:29:26 +00:00
"ace/ext/language_tools"
], (SuggestionManager, Snippets, Util, AutoComplete) ->
2014-02-12 10:23:40 +00:00
Range = require("ace/range").Range
Autocomplete = AutoComplete.Autocomplete
2014-02-12 10:23:40 +00:00
2014-03-04 17:29:26 +00:00
Util.retrievePrecedingIdentifier = (text, pos, regex) ->
currentLineOffset = 0
for i in [(pos-1)..0]
if text[i] == "\n"
currentLineOffset = i + 1
break
currentLine = text.slice(currentLineOffset, pos)
fragment = getLastCommandFragment(currentLine) or ""
return fragment
getLastCommandFragment = (lineUpToCursor) ->
if m = lineUpToCursor.match(/(\\[^\\ ]+)$/)
return m[1]
else
return null
2014-02-12 10:23:40 +00:00
class AutoCompleteManager
constructor: (@ide) ->
2014-03-04 17:29:26 +00:00
@aceEditor = @ide.editor.aceEditor
@aceEditor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true
})
2014-03-05 11:05:59 +00:00
SnippetCompleter =
getCompletions: (editor, session, pos, prefix, callback) ->
callback null, Snippets
@suggestionManager = new SuggestionManager()
@aceEditor.completers = [@suggestionManager, SnippetCompleter]
2014-03-04 17:29:26 +00:00
insertMatch = Autocomplete::insertMatch
editor = @aceEditor
Autocomplete::insertMatch = (data) ->
pos = editor.getCursorPosition()
range = new Range(pos.row, pos.column, pos.row, pos.column + 1)
nextChar = editor.session.getTextRange(range)
# 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 this.completions.filterText.match(/^\\begin\{/) and nextChar == "}"
editor.session.remove(range)
insertMatch.call editor.completer, data
2014-02-12 10:23:40 +00:00
@bindToEditorEvents()
bindToEditorEvents: () ->
@ide.editor.on "change:doc", (@aceSession) =>
@aceSession.on "change", (change) => @onChange(change)
onChange: (change) ->
cursorPosition = @aceEditor.getCursorPosition()
end = change.data.range.end
# Check that this change was made by us, not a collaborator
# (Cursor is still one place behind)
if end.row == cursorPosition.row and end.column == cursorPosition.column + 1
if change.data.action == "insertText"
range = new Range(end.row, 0, end.row, end.column)
lineUpToCursor = @aceSession.getTextRange(range)
2014-03-04 17:29:26 +00:00
commandFragment = getLastCommandFragment(lineUpToCursor)
2014-02-12 10:23:40 +00:00
2014-03-05 11:05:59 +00:00
if commandFragment? and commandFragment.length > 2
2014-03-04 17:29:26 +00:00
setTimeout () =>
@aceEditor.execCommand("startAutocomplete")
, 0