Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added functionality to make atom-racer find racer_bin on the path #60

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
159 changes: 93 additions & 66 deletions lib/racer-client.coffee
Original file line number Diff line number Diff line change
@@ -1,88 +1,105 @@
# disable max line length because it's annoying
# coffeelint: disable=max_line_length
{BufferedProcess} = require 'atom'
_ = require 'underscore-plus'
fs = require 'fs'
temp = require('temp').track()
path = require 'path'

module.exports =
class RacerClient
racer_bin: null
rust_src: null
project_path: null
candidates: null
last_stderr: null
last_process: null

check_generator = (racer_action) ->
(editor, row, col, cb) ->
if !@process_env_vars()
atom.notifications.addFatalError "Atom racer is not properly configured."
module.exports = class RacerClient
constructor: ->
@racer_bin = null
@rust_src = null
@project_path = null
@candidates = null
@last_stderr = null
@last_process = null

check_generator: (racer_action, editor, row, col, cb) ->
if !@process_env_vars()
# atom.notifications.addFatalError "Atom racer is not properly configured."
cb null
return

temp_folder_path = path.dirname(editor.getPath())
original_file_name = path.basename(editor.getPath())
# temp_folder_path will be '.' for unsaved files
if temp_folder_path == "."
temp_folder_path = @project_path

tempOptions =
prefix: "._" + original_file_name + ".racertmp"
dir: temp_folder_path

temp.open tempOptions, (err, info) =>
if err
atom.notifications.addFatalError "Unable to create temp file: #{err}"
cb null
return
else
tempFilePath = info.path
cb null unless tempFilePath

temp_folder_path = path.dirname(editor.getPath())
original_file_name = path.basename(editor.getPath())
# temp_folder_path will be '.' for unsaved files
if temp_folder_path == "."
temp_folder_path = @project_path
text = editor.getText()
fs.writeFileSync tempFilePath, text
fs.close(info.fd)

tempOptions =
prefix: "._" + original_file_name + ".racertmp"
dir: temp_folder_path
console.log "#{@racer_bin} #{racer_action} #{row + 1} #{col} #{tempFilePath}"

temp.open tempOptions, (err, info) =>
if err
atom.notifications.addFatalError "Unable to create temp file: #{err}"
cb null
else
tempFilePath = info.path
cb null unless tempFilePath

text = editor.getText()
fs.writeFileSync tempFilePath, text
fs.close(info.fd);
options =
command: @racer_bin
args: [racer_action, row + 1, col, tempFilePath]
stdout: (output) =>
return unless this_process == @latest_process
parsed = @parse_single(output)
@candidates.push(parsed) if parsed
return
stderr: (output) =>
return unless this_process == @latest_process
@last_stderr = output
return
exit: (code) =>
return unless this_process == @latest_process
@candidates = _.uniq(_.compact(_.flatten(@candidates)), (e) => e.word + e.file + e.type )
cb @candidates
temp.cleanup()
if code == 3221225781
atom.notifications.addWarning "racer could not find a required DLL; copy racer to your Rust bin directory"
else if code != 0
atom.notifications.addWarning "racer returned a non-zero exit code: #{code}\n#{@last_stderr}"
return

@candidates = []
@latest_process = this_process = new BufferedProcess(options)
return
return
options =
command: @racer_bin
args: [racer_action, row + 1, col, tempFilePath]
stdout: (output) =>
return unless this_process == @latest_process
parsed = @parse_single(output)
@candidates.push(parsed) if parsed
return
stderr: (output) =>
return unless this_process == @latest_process
@last_stderr = output
return
exit: (code) =>
return unless this_process == @latest_process
@candidates = _.uniq(_.compact(_.flatten(@candidates)), (e) -> e.word + e.file + e.type )
cb @candidates
temp.cleanup()
if code == 3221225781
atom.notifications.addWarning "racer could not find a required DLL; copy racer to your Rust bin directory"
else if code != 0
atom.notifications.addWarning "racer returned a non-zero exit code: #{code}\n#{@last_stderr}"
return

check_completion: check_generator("complete")
@candidates = []
@latest_process = this_process = new BufferedProcess(options)
return
return

check_definition: check_generator("find-definition")
check_completion: (editor, row, col, cb) ->
@check_generator("complete", editor, row, col, cb)

check_definition: (editor, row, col, cb) ->
@check_generator("find-definition", editor, row, col, cb)

find_racer_path: () ->
for p in process.env.PATH.split(':')
pArray = p.split('/')
if pArray[pArray.length - 1] == 'racer'
return p

process_env_vars: ->
# This is where the env varialbes are set
config_is_valid = true

atom.config.set('racer.racerBinPath', @find_racer_path())

if !@racer_bin?
conf_bin = atom.config.get("racer.racerBinPath")
if conf_bin

if conf_bin?
try
stats = fs.statSync(conf_bin);
stats = fs.statSync conf_bin
if stats?.isFile()
@racer_bin = conf_bin

if !@racer_bin?
config_is_valid = false
atom.notifications.addFatalError "racer.racerBinPath is not set in your config."
Expand All @@ -91,7 +108,7 @@ class RacerClient
conf_src = atom.config.get("racer.rustSrcPath")
if conf_src
try
stats = fs.statSync(conf_src);
stats = fs.statSync conf_src
if stats?.isDirectory()
@rust_src = conf_src
if !@rust_src?
Expand All @@ -108,11 +125,21 @@ class RacerClient
rcrgex = /MATCH (\w*)\,(\d*)\,(\d*)\,([^\,]*)\,(\w*)\,(.*)\n/mg
while match = rcrgex.exec(line)
if match?.length > 4
candidate = {word: match[1], line: parseInt(match[2], 10), column: parseInt(match[3], 10), filePath: match[4], file: "this", type: match[5], context: match[6]}
candidate =
word: match[1],
line: parseInt(match[2], 10),
column: parseInt(match[3], 10),
filePath: match[4],
file: "this",
type: match[5],
context: match[6]
file_name = path.basename(match[4])

if path.extname(match[4]).indexOf(".racertmp") == 0
candidate.filePath = path.dirname(match[4]) + path.sep + file_name.match(/\._(.*)\.racertmp.*?$/)[1]

else
candidate.file = file_name

matches.push(candidate)
return matches
41 changes: 21 additions & 20 deletions lib/racer-provider.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class RacerProvider
racerClient: null

constructor: ->
console.log 'creating a new racer client'
@disableForSelector = atom.config.get('racer.autocompleteBlacklist')
@racerClient = new RacerClient

Expand All @@ -35,31 +36,31 @@ class RacerProvider
# Example: @splitNested('foo; (bar; baz); qux', /;\s+/)
# => ['foo', '(bar; baz)', 'qux']
splitNested: (str, split) ->
depth = 0
depth = 0

openDelims = ['(', '<', '[']
closeDelims = [')', '>', ']']
openDelims = ['(', '<', '[']
closeDelims = [')', '>', ']']

splits = []
splits = []

lastSplit = 0
i = 0
while i < str?.length
match = str.slice(i).match(split)
shouldSplit = depth == 0 && match?.index == 0
lastSplit = 0
i = 0
while i < str?.length
match = str.slice(i).match(split)
shouldSplit = depth == 0 && match?.index == 0

if openDelims.indexOf(str[i]) >= 0
depth += 1
else if closeDelims.indexOf(str[i]) >= 0
depth -= 1
else if shouldSplit
splits.push(str.slice(lastSplit, i))
lastSplit = i + match[0].length
if openDelims.indexOf(str[i]) >= 0
depth += 1
else if closeDelims.indexOf(str[i]) >= 0
depth -= 1
else if shouldSplit
splits.push(str.slice(lastSplit, i))
lastSplit = i + match[0].length

i += 1
i += 1

splits.push(str?.slice(lastSplit))
splits
splits.push(str?.slice(lastSplit))
splits

# If the start of `str` matches the regex/substring `matcher`, then
# return an array consisting of [matched part, remaining part]; else,
Expand Down Expand Up @@ -189,7 +190,7 @@ class RacerProvider
findSuggestionsForPrefix: (prefix, completions) ->
if completions?.length
# Sort the candidates
words = _.sortBy( completions, (e) => e.word )
words = _.sortBy( completions, (e) -> e.word )

# Builds suggestions for the candidate words
suggestions = []
Expand Down