Merge pull request #155 from stuartquin/tab-autocomplete
Issue #29 Command and file autocomplete
This commit is contained in:
commit
25ce6b59fd
4 changed files with 179 additions and 0 deletions
74
lib/autocomplete.coffee
Normal file
74
lib/autocomplete.coffee
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
os = require 'os'
|
||||
Ex = require './ex'
|
||||
|
||||
module.exports =
|
||||
class AutoComplete
|
||||
constructor: (commands) ->
|
||||
@commands = commands
|
||||
@resetCompletion()
|
||||
|
||||
resetCompletion: () ->
|
||||
@autoCompleteIndex = 0
|
||||
@autoCompleteText = null
|
||||
@completions = []
|
||||
|
||||
expandTilde: (filePath) ->
|
||||
if filePath.charAt(0) == '~'
|
||||
return os.homedir() + filePath.slice(1)
|
||||
else
|
||||
return filePath
|
||||
|
||||
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.sort().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) ->
|
||||
return @filterByPrefix(@commands, command)
|
||||
|
||||
getFilePathCompletion: (command, filePath) ->
|
||||
filePath = @expandTilde(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
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -118,6 +118,11 @@ class Ex
|
|||
@registerAlias: (alias, name) =>
|
||||
@singleton()[alias] = (args) => @singleton()[name](args)
|
||||
|
||||
@getCommands: () =>
|
||||
Object.keys(Ex.singleton()).concat(Object.keys(Ex.prototype)).filter((cmd, index, list) ->
|
||||
list.indexOf(cmd) == index
|
||||
)
|
||||
|
||||
quit: ->
|
||||
atom.workspace.getActivePane().destroyActiveItem()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue