Skip to content
This repository was archived by the owner on Mar 14, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions lib/completion-backend/completion-backend.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,26 @@ class CompletionBackend
position = Range.fromPointWithDelta(position, 0, 0) if position?
prefix = prefix.slice 1 if prefix.startsWith '_'
@process.getTypeInBuffer(buffer, position).then ({type}) =>
@getSymbolsForBuffer(buffer).then (symbols) ->
@getSymbolsForBuffer(buffer).then (symbols) =>
ts = symbols.filter (s) ->
return false unless s.typeSignature?
tl = s.typeSignature.split(' -> ').slice(-1)[0]
return false if tl.match(/^[a-z]$/)
ts = tl.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")
rx = RegExp ts.replace(/\b[a-z]\b/g, '.+'), ''
rx.test(type)
if prefix.length is 0
ts.sort (a, b) ->
FZ.score(b.typeSignature, type) - FZ.score(a.typeSignature, type)
else
FZ.filter ts, prefix, key: 'qname'
ts2 =
if prefix.length is 0
ts.sort (a, b) ->
FZ.score(b.typeSignature, type) - FZ.score(a.typeSignature, type)
else
FZ.filter ts, prefix, key: 'qname'
@process.doHoleFill(buffer, position).then ({suggestions}) ->
return ts2 unless suggestions?
ts2.unshift (suggestions.map (text) ->
name: text
qname: text
typeSignature: type
symbolType: 'snippet'
)...
return ts2
18 changes: 13 additions & 5 deletions lib/ghc-mod/ghc-modi-process-real.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ CP = require('child_process')
InteractiveProcess = require './interactive-process'
{debug, warn, mkError, withTempFile, EOT} = Util = require '../util'
{EOL} = require('os')
_ = require 'underscore-plus'

module.exports =
class GhcModiProcessReal
constructor: (@caps, @rootDir, @options) ->
@disposables = new CompositeDisposable
@disposables.add @emitter = new Emitter

run: ({interactive, command, text, uri, dashArgs, args, suppressErrors}) ->
run: ({interactive, command, text, uri, dashArgs, args, suppressErrors, timeout}) ->
if timeout? and interactive
throw new Error('Can not have interactive action with set timeout! This
is an error in haskell-ghc-mod. Please report it.')
args ?= []
dashArgs ?= []
if atom.config.get('haskell-ghc-mod.lowMemorySystem')
Expand All @@ -25,9 +29,9 @@ class GhcModiProcessReal
P =
if text? and not @caps.fileMap
withTempFile text, uri, (tempuri) ->
fun {command, uri: tempuri, args}
fun {command, uri: tempuri, args, timeout}
else
fun {command, text, uri, args}
fun {command, text, uri, args, timeout}
P.catch (err) =>
debug err
if err.name is 'InteractiveActionTimeout'
Expand All @@ -44,6 +48,10 @@ class GhcModiProcessReal
"""
stack: err.stack
dismissable: true
return []
else if err.name is 'NonInteractiveActionTimeout'
warn err
return []
else if not suppressErrors
atom.notifications.addFatalError "
Haskell-ghc-mod: ghc-mod
Expand Down Expand Up @@ -77,7 +85,7 @@ class GhcModiProcessReal
@proc = null
return @proc

runModCmd: ({command, text, uri, args}) =>
runModCmd: ({command, text, uri, args, timeout}) =>
modPath = atom.config.get('haskell-ghc-mod.ghcModPath')
result = []
err = []
Expand All @@ -88,7 +96,7 @@ class GhcModiProcessReal
if text?
cmd = ['--map-file', uri].concat cmd
stdin = "#{text}#{EOT}" if text?
Util.execPromise modPath, cmd, @options, stdin
Util.execPromise modPath, cmd, _.extend({timeout}, @options), stdin
.then (stdout) ->
stdout.split(EOL).slice(0, -1).map (line) -> line.replace /\0/g, '\n'

Expand Down
22 changes: 22 additions & 0 deletions lib/ghc-mod/ghc-modi-process.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,28 @@ class GhcModiProcess
]
replacement: text

doHoleFill: (buffer, crange) =>
return Promise.resolve [] unless buffer.getUri()?
crange = Util.tabShiftForRange(buffer, crange)
@queueCmd 'typeinfo',
interactive: false
buffer: buffer
command: 'auto'
uri: buffer.getUri()
text: buffer.getText() if buffer.isModified()
args: [crange.start.row + 1, crange.start.column + 1]
timeout: 5000 # TODO: Make configurable
.then (lines) ->
return {} if lines.length == 0 or lines[1] == ""

[line_, rowstart, colstart, rowend, colend, text] = lines[0].match(/^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)

range: Range.fromObject [
[parseInt(rowstart) - 1, parseInt(colstart) - 1],
[parseInt(rowend) - 1, parseInt(colend) - 1]
]
suggestions: lines[1..]

doSigFill: (buffer, crange) =>
return Promise.resolve [] unless buffer.getUri()?
crange = Util.tabShiftForRange(buffer, crange)
Expand Down
2 changes: 2 additions & 0 deletions lib/util.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ module.exports = Util =
Util.warn("Running #{cmd} #{args} failed with ", error)
Util.warn stdout if stdout
error.stack = (new Error).stack
if child.killed and opts.timeout?
error.name = 'NonInteractiveActionTimeout'
reject error
else
Util.debug "Got response from #{cmd} #{args}", stdout: stdout, stderr: stderr
Expand Down