1{CompositeDisposable} = require 'atom'
2{BufferedProcess} = require 'atom'
3{dirname} = require 'path'
4{statSync} = require 'fs'
5
6prettify = (args, text, workingDirectory, {onComplete, onFailure}) ->
7  lines = []
8  proc = new BufferedProcess
9    command: 'floskell'
10    args: args
11    options:
12      cwd: workingDirectory
13    stdout: (line) -> lines.push(line)
14    exit: -> onComplete?(lines.join(''))
15  proc.onWillThrowError ({error, handle}) ->
16    atom.notifications.addError "Floskell could not spawn",
17      detail: "#{error}"
18    onFailure?()
19    handle()
20  proc.process.stdin.write(text)
21  proc.process.stdin.end()
22
23prettifyFile = (args, editor, format = 'haskell') ->
24  [firstCursor, cursors...] = editor.getCursors().map (cursor) ->
25    cursor.getBufferPosition()
26  try
27    workDir = dirname(editor.getPath())
28    if not statSync(workDir).isDirectory()
29      workDir = '.'
30  catch
31    workDir = '.'
32  prettify args, editor.getText(), workDir,
33    onComplete: (text) ->
34      editor.setText(text)
35      if editor.getLastCursor()?
36        editor.getLastCursor().setBufferPosition firstCursor,
37          autoscroll: false
38        cursors.forEach (cursor) ->
39          editor.addCursorAtBufferPosition cursor,
40            autoscroll: false
41
42module.exports = Floskell =
43  disposables: null
44  menu: null
45
46  activate: (state) ->
47    @disposables = new CompositeDisposable
48    @menu = new CompositeDisposable
49
50    @disposables.add \
51      atom.commands.add 'atom-text-editor[data-grammar~="haskell"]',
52        'floskell:prettify-none': ({target}) =>
53          prettifyFile [], target.getModel()
54        'floskell:prettify-chris-done': ({target}) =>
55          prettifyFile ['--style', 'chris-done'], target.getModel()
56        'floskell:prettify-cramer': ({target}) =>
57          prettifyFile ['--style', 'cramer'], target.getModel()
58        'floskell:prettify-gibiansky': ({target}) =>
59          prettifyFile ['--style', 'gibiansky'], target.getModel()
60        'floskell:prettify-johan-tibell': ({target}) =>
61          prettifyFile ['--style', 'johan-tibell'], target.getModel()
62
63    @menu.add atom.menu.add [
64      label: 'floskell'
65      submenu : [
66        {label: 'Default', command: 'floskell:prettify-none'}
67        {label: 'Cramer', command: 'floskell:prettify-cramer'}
68        {label: 'Chris Done', command: 'floskell:prettify-chris-done'}
69        {label: 'Gibiansky', command: 'floskell:prettify-gibiansky'}
70        {label: 'Johan Tibell', command: 'floskell:prettify-johan-tibell'}
71      ]
72    ]
73
74  deactivate: ->
75    @disposables.dispose()
76    @disposables = null
77
78    @clearMenu()
79
80  clearMenu: ->
81    @menu.dispose()
82    @menu = null
83    atom.menu.update()
84