Pull out autocomplete package into a separate repo

This commit is contained in:
Kevin Sawicki 2013-08-13 11:06:34 -07:00
parent dc775f93ff
commit 52e8e3aaf3
7 changed files with 1 additions and 700 deletions

View File

@ -66,6 +66,7 @@
"xml-tmbundle": "1.0.0",
"yaml-tmbundle": "1.0.0",
"archive-view": "0.1.0",
"autocomplete": "0.1.0",
"autoflow": "0.1.0",
"bookmarks": "0.1.0",
"bracket-matcher": "0.1.0",

View File

@ -1,8 +0,0 @@
'.editor':
'ctrl-space': 'autocomplete:attach'
'.autocomplete .editor':
'ctrl-space': 'core:cancel'
'.autocomplete .mini.editor input':
'enter': 'core:confirm'

View File

@ -1,190 +0,0 @@
$ = require 'jquery'
{$$} = require 'space-pen'
_ = require 'underscore'
Range = require 'range'
SelectList = require 'select-list'
module.exports =
class AutocompleteView extends SelectList
@viewClass: -> "autocomplete #{super} popover-list"
editor: null
currentBuffer: null
wordList: null
wordRegex: /\w+/g
originalSelectionBufferRange: null
originalCursorPosition: null
aboveCursor: false
filterKey: 'word'
initialize: (@editor) ->
super
@handleEvents()
@setCurrentBuffer(@editor.getBuffer())
itemForElement: (match) ->
$$ ->
@li =>
@span match.word
handleEvents: ->
@list.on 'mousewheel', (event) -> event.stopPropagation()
@editor.on 'editor:path-changed', => @setCurrentBuffer(@editor.getBuffer())
@editor.command 'autocomplete:attach', => @attach()
@editor.command 'autocomplete:next', => @selectNextItem()
@editor.command 'autocomplete:previous', => @selectPreviousItem()
@miniEditor.preempt 'textInput', (e) =>
text = e.originalEvent.data
unless text.match(@wordRegex)
@confirmSelection()
@editor.insertText(text)
false
setCurrentBuffer: (@currentBuffer) ->
selectItem: (item) ->
super
match = @getSelectedElement()
@replaceSelectedTextWithMatch(match) if match
selectNextItem: ->
super
false
selectPreviousItem: ->
super
false
getCompletionsForCursorScope: ->
cursorScope = @editor.scopesForBufferPosition(@editor.getCursorBufferPosition())
completions = syntax.propertiesForScope(cursorScope, 'editor.completions')
completions = completions.map (properties) -> _.valueForKeyPath(properties, 'editor.completions')
_.uniq(_.flatten(completions))
buildWordList: ->
wordHash = {}
matches = @currentBuffer.getText().match(@wordRegex)
wordHash[word] ?= true for word in matches ? []
wordHash[word] ?= true for word in @getCompletionsForCursorScope()
@wordList = Object.keys(wordHash).sort (word1, word2) ->
word1 = word1.toLowerCase()
word2 = word2.toLowerCase()
if word1 > word2
1
else if word1 < word2
-1
else
0
confirmed: (match) ->
@editor.getSelection().clear()
@cancel()
return unless match
@replaceSelectedTextWithMatch match
position = @editor.getCursorBufferPosition()
@editor.setCursorBufferPosition([position.row, position.column + match.suffix.length])
cancelled: ->
super
@editor.abort()
@editor.setSelectedBufferRange(@originalSelectionBufferRange)
rootView.focus() if @miniEditor.isFocused
attach: ->
@editor.transact()
@aboveCursor = false
@originalSelectionBufferRange = @editor.getSelection().getBufferRange()
@originalCursorPosition = @editor.getCursorScreenPosition()
@buildWordList()
matches = @findMatchesForCurrentSelection()
@setArray(matches)
if matches.length is 1
@confirmSelection()
else
@editor.appendToLinesView(this)
@setPosition()
@miniEditor.focus()
detach: ->
super
@editor.off(".autocomplete")
@editor.focus()
setPosition: ->
{ left, top } = @editor.pixelPositionForScreenPosition(@originalCursorPosition)
height = @outerHeight()
potentialTop = top + @editor.lineHeight
potentialBottom = potentialTop - @editor.scrollTop() + height
if @aboveCursor or potentialBottom > @editor.outerHeight()
@aboveCursor = true
@css(left: left, top: top - height, bottom: 'inherit')
else
@css(left: left, top: potentialTop, bottom: 'inherit')
findMatchesForCurrentSelection: ->
selection = @editor.getSelection()
{prefix, suffix} = @prefixAndSuffixOfSelection(selection)
if (prefix.length + suffix.length) > 0
regex = new RegExp("^#{prefix}.+#{suffix}$", "i")
currentWord = prefix + @editor.getSelectedText() + suffix
for word in @wordList when regex.test(word) and word != currentWord
{prefix, suffix, word}
else
{word, prefix, suffix} for word in @wordList
replaceSelectedTextWithMatch: (match) ->
selection = @editor.getSelection()
startPosition = selection.getBufferRange().start
buffer = @editor.getBuffer()
selection.deleteSelectedText()
cursorPosition = @editor.getCursorBufferPosition()
buffer.delete(Range.fromPointWithDelta(cursorPosition, 0, match.suffix.length))
buffer.delete(Range.fromPointWithDelta(cursorPosition, 0, -match.prefix.length))
@editor.insertText(match.word)
infixLength = match.word.length - match.prefix.length - match.suffix.length
@editor.setSelectedBufferRange([startPosition, [startPosition.row, startPosition.column + infixLength]])
prefixAndSuffixOfSelection: (selection) ->
selectionRange = selection.getBufferRange()
lineRange = [[selectionRange.start.row, 0], [selectionRange.end.row, @editor.lineLengthForBufferRow(selectionRange.end.row)]]
[prefix, suffix] = ["", ""]
@currentBuffer.scanInRange @wordRegex, lineRange, ({match, range, stop}) ->
stop() if range.start.isGreaterThan(selectionRange.end)
if range.intersectsWith(selectionRange)
prefixOffset = selectionRange.start.column - range.start.column
suffixOffset = selectionRange.end.column - range.end.column
prefix = match[0][0...prefixOffset] if range.start.isLessThan(selectionRange.start)
suffix = match[0][suffixOffset..] if range.end.isGreaterThan(selectionRange.end)
{prefix, suffix}
afterAttach: (onDom) ->
if onDom
widestCompletion = parseInt(@css('min-width')) or 0
@list.find('span').each ->
widestCompletion = Math.max(widestCompletion, $(this).outerWidth())
@list.width(widestCompletion)
@width(@list.outerWidth())
populateList: ->
super
@setPosition()

View File

@ -1,16 +0,0 @@
AutocompleteView = require './autocomplete-view'
module.exports =
autoCompleteViews: []
editorSubscription: null
activate: ->
@editorSubscription = rootView.eachEditor (editor) =>
if editor.attached and not editor.mini
@autoCompleteViews.push new AutocompleteView(editor)
deactivate: ->
@editorSubscription?.off()
@editorSubscription = null
@autoCompleteViews.forEach (autoCompleteView) -> autoCompleteView.remove()
@autoCompleteViews = []

View File

@ -1,4 +0,0 @@
'main': './lib/autocomplete'
'description': 'Display possible completions from the current editor with `ctrl-space`.'
'activationEvents':
'autocomplete:attach': '.editor'

View File

@ -1,456 +0,0 @@
$ = require 'jquery'
AutocompleteView = require 'autocomplete/lib/autocomplete-view'
Autocomplete = require 'autocomplete/lib/autocomplete'
Buffer = require 'text-buffer'
Editor = require 'editor'
RootView = require 'root-view'
describe "Autocomplete", ->
beforeEach ->
window.rootView = new RootView
rootView.open('sample.js')
rootView.simulateDomAttachment()
describe "@activate()", ->
it "activates autocomplete on all existing and future editors (but not on autocomplete's own mini editor)", ->
spyOn(AutocompleteView.prototype, 'initialize').andCallThrough()
autocompletePackage = atom.activatePackage("autocomplete")
expect(AutocompleteView.prototype.initialize).not.toHaveBeenCalled()
leftEditor = rootView.getActiveView()
rightEditor = leftEditor.splitRight()
leftEditor.trigger 'autocomplete:attach'
expect(leftEditor.find('.autocomplete')).toExist()
expect(rightEditor.find('.autocomplete')).not.toExist()
expect(AutocompleteView.prototype.initialize).toHaveBeenCalled()
autoCompleteView = leftEditor.find('.autocomplete').view()
autoCompleteView.trigger 'core:cancel'
expect(leftEditor.find('.autocomplete')).not.toExist()
rightEditor.trigger 'autocomplete:attach'
expect(rightEditor.find('.autocomplete')).toExist()
describe "@deactivate()", ->
it "removes all autocomplete views and doesn't create new ones when new editors are opened", ->
atom.activatePackage('autocomplete')
rootView.getActiveView().trigger "autocomplete:attach"
expect(rootView.getActiveView().find('.autocomplete')).toExist()
atom.deactivatePackage('autocomplete')
expect(rootView.getActiveView().find('.autocomplete')).not.toExist()
rootView.getActiveView().splitRight()
rootView.getActiveView().trigger "autocomplete:attach"
expect(rootView.getActiveView().find('.autocomplete')).not.toExist()
describe "AutocompleteView", ->
autocomplete = null
editor = null
miniEditor = null
beforeEach ->
window.rootView = new RootView
editor = new Editor(editSession: project.open('sample.js'))
atom.activatePackage('autocomplete')
autocomplete = new AutocompleteView(editor)
miniEditor = autocomplete.miniEditor
describe 'autocomplete:attach event', ->
it "shows autocomplete view and focuses its mini-editor", ->
expect(editor.find('.autocomplete')).not.toExist()
editor.trigger "autocomplete:attach"
expect(editor.find('.autocomplete')).toExist()
expect(autocomplete.editor.isFocused).toBeFalsy()
expect(autocomplete.miniEditor.isFocused).toBeTruthy()
describe "when no text is selected", ->
it 'autocompletes word when there is only a prefix', ->
editor.getBuffer().insert([10,0] ,"extra:s:extra")
editor.setCursorBufferPosition([10,7])
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,11]
expect(editor.getSelection().getBufferRange()).toEqual [[10,7], [10,11]]
expect(autocomplete.list.find('li').length).toBe 2
expect(autocomplete.list.find('li:eq(0)')).toHaveText('shift')
expect(autocomplete.list.find('li:eq(1)')).toHaveText('sort')
it 'autocompletes word when there is only a suffix', ->
editor.getBuffer().insert([10,0] ,"extra:n:extra")
editor.setCursorBufferPosition([10,6])
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:function:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,13]
expect(editor.getSelection().getBufferRange()).toEqual [[10,6], [10,13]]
expect(autocomplete.list.find('li').length).toBe 2
expect(autocomplete.list.find('li:eq(0)')).toHaveText('function')
expect(autocomplete.list.find('li:eq(1)')).toHaveText('return')
it 'autocompletes word when there is a single prefix and suffix match', ->
editor.getBuffer().insert([8,43] ,"q")
editor.setCursorBufferPosition([8,44])
autocomplete.attach()
expect(editor.lineForBufferRow(8)).toBe " return sort(left).concat(pivot).concat(quicksort(right));"
expect(editor.getCursorBufferPosition()).toEqual [8,52]
expect(editor.getSelection().getBufferRange().isEmpty()).toBeTruthy()
expect(autocomplete.list.find('li').length).toBe 0
it "shows all words there is no prefix or suffix", ->
editor.setCursorBufferPosition([10, 0])
autocomplete.attach()
expect(autocomplete.list.find('li:eq(0)')).toHaveText('0')
expect(autocomplete.list.find('li:eq(1)')).toHaveText('1')
expect(autocomplete.list.find('li').length).toBe 22
it "autocompletes word and replaces case of prefix with case of word", ->
editor.getBuffer().insert([10,0] ,"extra:SO:extra")
editor.setCursorBufferPosition([10,8])
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:sort:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,10]
expect(editor.getSelection().isEmpty()).toBeTruthy()
describe "when text is selected", ->
it 'autocompletes word when there is only a prefix', ->
editor.getBuffer().insert([10,0] ,"extra:sort:extra")
editor.setSelectedBufferRange [[10,7], [10,10]]
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,11]
expect(editor.getSelection().getBufferRange().isEmpty()).toBeTruthy()
expect(autocomplete.list.find('li').length).toBe 0
it 'autocompletes word when there is only a suffix', ->
editor.getBuffer().insert([10,0] ,"extra:current:extra")
editor.setSelectedBufferRange [[10,6],[10,12]]
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:concat:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,11]
expect(editor.getSelection().getBufferRange()).toEqual [[10,6],[10,11]]
expect(autocomplete.list.find('li').length).toBe 7
expect(autocomplete.list.find('li:contains(current)')).not.toExist()
it 'autocompletes word when there is a prefix and suffix', ->
editor.setSelectedBufferRange [[5,7],[5,12]]
autocomplete.attach()
expect(editor.lineForBufferRow(5)).toBe " concat = items.shift();"
expect(editor.getCursorBufferPosition()).toEqual [5,12]
expect(editor.getSelection().getBufferRange().isEmpty()).toBeTruthy()
expect(autocomplete.list.find('li').length).toBe 0
it 'replaces selection with selected match, moves the cursor to the end of the match, and removes the autocomplete menu', ->
editor.getBuffer().insert([10,0] ,"extra:sort:extra")
editor.setSelectedBufferRange [[10,7], [10,9]]
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,11]
expect(editor.getSelection().isEmpty()).toBeTruthy()
expect(editor.find('.autocomplete')).not.toExist()
describe "when the editor is scrolled to the right", ->
it "does not scroll it to the left", ->
editor.width(300)
editor.height(300)
editor.attachToDom()
editor.setCursorBufferPosition([6, 6])
previousScrollLeft = editor.scrollLeft()
autocomplete.attach()
expect(editor.scrollLeft()).toBe previousScrollLeft
describe 'core:confirm event', ->
describe "where there are matches", ->
describe "where there is no selection", ->
it "closes the menu and moves the cursor to the end", ->
editor.getBuffer().insert([10,0] ,"extra:sh:extra")
editor.setCursorBufferPosition([10,8])
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,11]
expect(editor.getSelection().isEmpty()).toBeTruthy()
expect(editor.find('.autocomplete')).not.toExist()
describe 'core:cancel event', ->
describe "when there are no matches", ->
it "closes the menu without changing the buffer", ->
editor.getBuffer().insert([10,0] ,"xxx")
editor.setCursorBufferPosition [10, 3]
autocomplete.attach()
expect(autocomplete.error).toHaveText "No matches found"
miniEditor.trigger "core:cancel"
expect(editor.lineForBufferRow(10)).toBe "xxx"
expect(editor.getCursorBufferPosition()).toEqual [10,3]
expect(editor.getSelection().isEmpty()).toBeTruthy()
expect(editor.find('.autocomplete')).not.toExist()
it 'does not replace selection, removes autocomplete view and returns focus to editor', ->
editor.getBuffer().insert([10,0] ,"extra:so:extra")
editor.setSelectedBufferRange [[10,7], [10,8]]
originalSelectionBufferRange = editor.getSelection().getBufferRange()
autocomplete.attach()
editor.setCursorBufferPosition [0, 0] # even if selection changes before cancel, it should work
miniEditor.trigger "core:cancel"
expect(editor.lineForBufferRow(10)).toBe "extra:so:extra"
expect(editor.getSelection().getBufferRange()).toEqual originalSelectionBufferRange
expect(editor.find('.autocomplete')).not.toExist()
it "does not clear out a previously confirmed selection when canceling with an empty list", ->
editor.getBuffer().insert([10, 0], "ort\n")
editor.setCursorBufferPosition([10, 0])
autocomplete.attach()
miniEditor.trigger 'core:confirm'
expect(editor.lineForBufferRow(10)).toBe 'quicksort'
editor.setCursorBufferPosition([11, 0])
autocomplete.attach()
miniEditor.trigger 'core:cancel'
expect(editor.lineForBufferRow(10)).toBe 'quicksort'
it "restores the case of the prefix to the original value", ->
editor.getBuffer().insert([10,0] ,"extra:S:extra")
editor.setCursorBufferPosition([10,7])
autocomplete.attach()
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,11]
autocomplete.trigger 'core:cancel'
expect(editor.lineForBufferRow(10)).toBe "extra:S:extra"
expect(editor.getCursorBufferPosition()).toEqual [10,7]
it "restores the original buffer contents even if there was an additional operation after autocomplete attached (regression)", ->
editor.getBuffer().insert([10,0] ,"extra:s:extra")
editor.setCursorBufferPosition([10,7])
autocomplete.attach()
editor.getBuffer().append('hi')
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
autocomplete.trigger 'core:cancel'
expect(editor.lineForBufferRow(10)).toBe "extra:s:extra"
editor.redo()
expect(editor.lineForBufferRow(10)).toBe "extra:s:extra"
describe 'move-up event', ->
it "highlights the previous match and replaces the selection with it", ->
editor.getBuffer().insert([10,0] ,"extra:t:extra")
editor.setCursorBufferPosition([10,6])
autocomplete.attach()
miniEditor.trigger "core:move-up"
expect(editor.lineForBufferRow(10)).toBe "extra:sort:extra"
expect(autocomplete.find('li:eq(0)')).not.toHaveClass('selected')
expect(autocomplete.find('li:eq(1)')).not.toHaveClass('selected')
expect(autocomplete.find('li:eq(7)')).toHaveClass('selected')
miniEditor.trigger "core:move-up"
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(autocomplete.find('li:eq(0)')).not.toHaveClass('selected')
expect(autocomplete.find('li:eq(7)')).not.toHaveClass('selected')
expect(autocomplete.find('li:eq(6)')).toHaveClass('selected')
describe 'move-down event', ->
it "highlights the next match and replaces the selection with it", ->
editor.getBuffer().insert([10,0] ,"extra:s:extra")
editor.setCursorBufferPosition([10,7])
autocomplete.attach()
miniEditor.trigger "core:move-down"
expect(editor.lineForBufferRow(10)).toBe "extra:sort:extra"
expect(autocomplete.find('li:eq(0)')).not.toHaveClass('selected')
expect(autocomplete.find('li:eq(1)')).toHaveClass('selected')
miniEditor.trigger "core:move-down"
expect(editor.lineForBufferRow(10)).toBe "extra:shift:extra"
expect(autocomplete.find('li:eq(0)')).toHaveClass('selected')
expect(autocomplete.find('li:eq(1)')).not.toHaveClass('selected')
describe "when a match is clicked in the match list", ->
it "selects and confirms the match", ->
editor.getBuffer().insert([10,0] ,"t")
editor.setCursorBufferPosition([10, 0])
autocomplete.attach()
matchToSelect = autocomplete.list.find('li:eq(1)')
matchToSelect.mousedown()
expect(matchToSelect).toMatchSelector('.selected')
matchToSelect.mouseup()
expect(autocomplete.parent()).not.toExist()
expect(editor.lineForBufferRow(10)).toBe matchToSelect.text()
describe "when the mini-editor receives keyboard input", ->
beforeEach ->
editor.attachToDom()
describe "when text is removed from the mini-editor", ->
it "reloads the match list based on the mini-editor's text", ->
editor.getBuffer().insert([10,0] ,"t")
editor.setCursorBufferPosition([10,0])
autocomplete.attach()
expect(autocomplete.list.find('li').length).toBe 8
miniEditor.textInput('c')
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.list.find('li').length).toBe 3
miniEditor.backspace()
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.list.find('li').length).toBe 8
describe "when the text contains only word characters", ->
it "narrows the list of completions with the fuzzy match algorithm", ->
editor.getBuffer().insert([10,0] ,"t")
editor.setCursorBufferPosition([10,0])
autocomplete.attach()
expect(autocomplete.list.find('li').length).toBe 8
miniEditor.textInput('i')
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.list.find('li').length).toBe 4
expect(autocomplete.list.find('li:eq(0)')).toHaveText 'pivot'
expect(autocomplete.list.find('li:eq(0)')).toHaveClass 'selected'
expect(autocomplete.list.find('li:eq(1)')).toHaveText 'right'
expect(autocomplete.list.find('li:eq(2)')).toHaveText 'shift'
expect(autocomplete.list.find('li:eq(3)')).toHaveText 'quicksort'
expect(editor.lineForBufferRow(10)).toEqual 'pivot'
miniEditor.textInput('o')
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.list.find('li').length).toBe 2
expect(autocomplete.list.find('li:eq(0)')).toHaveText 'pivot'
expect(autocomplete.list.find('li:eq(1)')).toHaveText 'quicksort'
describe "when a non-word character is typed in the mini-editor", ->
it "immediately confirms the current completion choice and inserts that character into the buffer", ->
editor.getBuffer().insert([10,0] ,"t")
editor.setCursorBufferPosition([10,0])
autocomplete.attach()
miniEditor.textInput('iv')
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.list.find('li:eq(0)')).toHaveText 'pivot'
miniEditor.textInput(' ')
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.parent()).not.toExist()
expect(editor.lineForBufferRow(10)).toEqual 'pivot '
describe 'when the mini-editor loses focus before the selection is confirmed', ->
it "cancels the autocomplete", ->
editor.attachToDom()
autocomplete.attach()
spyOn(autocomplete, "cancel")
editor.focus()
expect(autocomplete.cancel).toHaveBeenCalled()
describe ".attach()", ->
beforeEach ->
editor.attachToDom()
setEditorHeightInLines(editor, 13)
editor.resetDisplay() # Ensures the editor only has 13 lines visible
describe "when the autocomplete view fits below the cursor", ->
it "adds the autocomplete view to the editor below the cursor", ->
editor.setCursorBufferPosition [1, 2]
cursorPixelPosition = editor.pixelPositionForScreenPosition(editor.getCursorScreenPosition())
autocomplete.attach()
expect(editor.find('.autocomplete')).toExist()
expect(autocomplete.position().top).toBe cursorPixelPosition.top + editor.lineHeight
expect(autocomplete.position().left).toBe cursorPixelPosition.left
describe "when the autocomplete view does not fit below the cursor", ->
it "adds the autocomplete view to the editor above the cursor", ->
editor.setCursorScreenPosition([11, 0])
editor.insertText('t ')
editor.setCursorScreenPosition([11, 0])
cursorPixelPosition = editor.pixelPositionForScreenPosition(editor.getCursorScreenPosition())
autocomplete.attach()
expect(autocomplete.parent()).toExist()
autocompleteBottom = autocomplete.position().top + autocomplete.outerHeight()
expect(autocompleteBottom).toBe cursorPixelPosition.top
expect(autocomplete.position().left).toBe cursorPixelPosition.left
it "updates the position when the list is filtered and the height of the list decreases", ->
editor.setCursorScreenPosition([11, 0])
editor.insertText('s')
editor.setCursorScreenPosition([11, 0])
cursorPixelPosition = editor.pixelPositionForScreenPosition(editor.getCursorScreenPosition())
autocomplete.attach()
expect(autocomplete.parent()).toExist()
autocompleteBottom = autocomplete.position().top + autocomplete.outerHeight()
expect(autocompleteBottom).toBe cursorPixelPosition.top
expect(autocomplete.position().left).toBe cursorPixelPosition.left
miniEditor.textInput('sh')
window.advanceClock(autocomplete.inputThrottle)
expect(autocomplete.parent()).toExist()
autocompleteBottom = autocomplete.position().top + autocomplete.outerHeight()
expect(autocompleteBottom).toBe cursorPixelPosition.top
expect(autocomplete.position().left).toBe cursorPixelPosition.left
describe ".cancel()", ->
it "clears the mini-editor and unbinds autocomplete event handlers for move-up and move-down", ->
autocomplete.attach()
miniEditor.setText('foo')
autocomplete.cancel()
expect(miniEditor.getText()).toBe ''
editor.trigger 'core:move-down'
expect(editor.getCursorBufferPosition().row).toBe 1
editor.trigger 'core:move-up'
expect(editor.getCursorBufferPosition().row).toBe 0
it "sets the width of the view to be wide enough to contain the longest completion without scrolling", ->
editor.attachToDom()
editor.insertText('thisIsAReallyReallyReallyLongCompletion ')
editor.moveCursorToBottom()
editor.insertNewline()
editor.insertText('t')
autocomplete.attach()
expect(autocomplete.list.prop('scrollWidth')).toBe autocomplete.list.width()
it "includes completions for the scope's completion preferences", ->
atom.activatePackage('css-tmbundle', sync: true)
cssEditor = new Editor(editSession: project.open('css.css'))
autocomplete = new AutocompleteView(cssEditor)
cssEditor.attachToDom()
cssEditor.moveCursorToEndOfLine()
cssEditor.insertText(' out')
cssEditor.moveCursorToEndOfLine()
autocomplete.attach()
expect(autocomplete.list.find('li').length).toBe 4
expect(autocomplete.list.find('li:eq(0)')).toHaveText 'outline'
expect(autocomplete.list.find('li:eq(1)')).toHaveText 'outline-color'
expect(autocomplete.list.find('li:eq(2)')).toHaveText 'outline-style'
expect(autocomplete.list.find('li:eq(3)')).toHaveText 'outline-width'

View File

@ -1,26 +0,0 @@
.autocomplete {
&.select-list {
box-sizing: content-box;
margin-left: 0;
ol li {
padding: 5px 0 5px 0;
}
}
ol {
box-sizing: content-box;
position: relative;
overflow-y: scroll;
max-height: 200px;
}
span {
padding-left: 5px;
padding-right: 5px;
}
.error-message {
margin: 2px;
}
}