aboutsummaryrefslogtreecommitdiff
path: root/atom/packages/ex-mode/lib/ex-state.coffee
blob: 7c0f37c342e061cf2cec32b23bb99bb53b4a236f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'

Command = require './command'
CommandError = require './command-error'

class ExState
  constructor: (@editorElement, @globalExState) ->
    @emitter = new Emitter
    @subscriptions = new CompositeDisposable
    @editor = @editorElement.getModel()
    @opStack = []
    @history = []

    @registerOperationCommands
      open: (e) => new Command(@editor, @)

  destroy: ->
    @subscriptions.dispose()

  getExHistoryItem: (index) ->
    @globalExState.commandHistory[index]

  pushExHistory: (command) ->
    @globalExState.commandHistory.unshift command

  registerOperationCommands: (commands) ->
    for commandName, fn of commands
      do (fn) =>
        pushFn = (e) => @pushOperations(fn(e))
        @subscriptions.add(
          atom.commands.add(@editorElement, "ex-mode:#{commandName}", pushFn)
        )

  onDidFailToExecute: (fn) ->
    @emitter.on('failed-to-execute', fn)

  onDidProcessOpStack: (fn) ->
    @emitter.on('processed-op-stack', fn)

  pushOperations: (operations) ->
    @opStack.push operations

    @processOpStack() if @opStack.length == 2

  clearOpStack: ->
    @opStack = []

  processOpStack: ->
    [command, input] = @opStack
    if input.characters.length > 0
      @history.unshift command
      try
        command.execute(input)
      catch e
        if (e instanceof CommandError)
          atom.notifications.addError("Command error: #{e.message}")
          @emitter.emit('failed-to-execute')
        else
          throw e
    @clearOpStack()
    @emitter.emit('processed-op-stack')

module.exports = ExState