Issue #29 Command and file autocomplete

This commit is contained in:
Stuart Quin 2016-08-03 18:41:13 +01:00
parent dfa44b5fa2
commit 7e1e03284a
4 changed files with 169 additions and 0 deletions

66
lib/autocomplete.coffee Normal file
View file

@ -0,0 +1,66 @@
fs = require 'fs'
path = require 'path'
Ex = require './ex'
module.exports =
class AutoComplete
constructor: (commands) ->
@commands = commands
@resetCompletion()
resetCompletion: () ->
@autoCompleteIndex = 0
@autoCompleteText = null
@completions = []
getAutocomplete: (text) ->
if !@autoCompleteText
@autoCompleteText = text
parts = @autoCompleteText.split(' ')
cmd = parts[0]
if parts.length > 1
filePath = parts.slice(1).join(' ')
return @getCompletion(() => @getFilePathCompletion(cmd, filePath))
else
return @getCompletion(() => @getCommandCompletion(cmd))
filterByPrefix: (commands, prefix) ->
commands.filter((f) => f.startsWith(prefix))
getCompletion: (completeFunc) ->
if @completions.length == 0
@completions = completeFunc()
if @completions.length
complete = @completions[@autoCompleteIndex % @completions.length]
@autoCompleteIndex++
# Only one result so lets return this directory
if complete.endsWith('/') && @completions.length == 1
@resetCompletion()
return complete
getCommandCompletion: (command) ->
if @completions.length == 0
return @filterByPrefix(@commands, command)
getFilePathCompletion: (command, filePath) ->
if filePath.endsWith(path.sep)
basePath = path.dirname(filePath + '.')
baseName = ''
else
basePath = path.dirname(filePath)
baseName = path.basename(filePath)
files = fs.readdirSync(basePath)
return @filterByPrefix(files, baseName).map((f) =>
filePath = path.join(basePath, f)
if fs.lstatSync(filePath).isDirectory()
return command + ' ' + filePath + path.sep
else
return command + ' ' + filePath
)

View file

@ -1,4 +1,6 @@
{ViewModel, Input} = require './view-model'
AutoComplete = require './autocomplete'
Ex = require './ex'
module.exports =
class ExViewModel extends ViewModel
@ -6,15 +8,31 @@ class ExViewModel extends ViewModel
super(@exCommand, class: 'command')
@historyIndex = -1
@view.editorElement.addEventListener('keydown', @tabAutocomplete)
atom.commands.add(@view.editorElement, 'core:move-up', @increaseHistoryEx)
atom.commands.add(@view.editorElement, 'core:move-down', @decreaseHistoryEx)
@autoComplete = new AutoComplete(Ex.getCommands())
restoreHistory: (index) ->
@view.editorElement.getModel().setText(@history(index).value)
history: (index) ->
@exState.getExHistoryItem(index)
tabAutocomplete: (event) =>
if event.keyCode == 9
event.stopPropagation()
event.preventDefault()
completed = @autoComplete.getAutocomplete(@view.editorElement.getModel().getText())
if completed
@view.editorElement.getModel().setText(completed)
return false
else
@autoComplete.resetCompletion()
increaseHistoryEx: =>
if @history(@historyIndex + 1)?
@historyIndex += 1

View file

@ -109,6 +109,9 @@ class Ex
@registerAlias: (alias, name) =>
@singleton()[alias] = (args) => @singleton()[name](args)
@getCommands: () =>
Object.keys(@singleton())
quit: ->
atom.workspace.getActivePane().destroyActiveItem()