ensime_bridge 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/ensime_bridge ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ensime_bridge'
3
+ bridge = EnsimeBridge.new(ARGV.size < 2 ? ".ensime" : ARGV[1])
4
+ if ARGV.size > 1 and ARGV[0] == "stop"
5
+ bridge.remote_stop
6
+ else
7
+ bridge.run
8
+ end
data/lib/ensime.rb ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ require 'socket'
4
+ class Ensime
5
+ def is_running?
6
+ port_path = @conf_path + "_cache/http"
7
+ return false if not File.exists? port_path
8
+ begin
9
+ TCPSocket.open("127.0.0.1", File.read(port_path).chomp).close
10
+ rescue => e
11
+ return false
12
+ end
13
+ true
14
+ end
15
+ def initialize conf_path
16
+ @conf_path = conf_path
17
+ @conf = Hash[File.read(conf_path).gsub("\n", "").gsub(
18
+ "(", " ").gsub(")", " ").gsub('"', "").split(" :").collect do |x|
19
+ m = x.match("\([^ ]*\) *\(.*\)$")
20
+ [m[1], m[2]]
21
+ end]
22
+ @version = "0.9.10-SNAPSHOT"
23
+ end
24
+ def get_classpath
25
+ log = nil
26
+ classpath = nil
27
+ dir = "/tmp/classpath_project_ensime"
28
+ classpath_file = "#{dir}/classpath"
29
+ if not File.exists? classpath_file
30
+ FileUtils.mkdir_p dir
31
+ build_sbt = <<EOF
32
+ import sbt._
33
+ import IO._
34
+ import java.io._
35
+ scalaVersion := "#{@conf['scala-version']}"
36
+ ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }
37
+ // allows local builds of scala
38
+ resolvers += Resolver.mavenLocal
39
+ resolvers += Resolver.sonatypeRepo("snapshots")
40
+ resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
41
+ resolvers += "Akka Repo" at "http://repo.akka.io/repository"
42
+ libraryDependencies ++= Seq(
43
+ "org.ensime" %% "ensime" % "#{@version}",
44
+ "org.scala-lang" % "scala-compiler" % scalaVersion.value force(),
45
+ "org.scala-lang" % "scala-reflect" % scalaVersion.value force(),
46
+ "org.scala-lang" % "scalap" % scalaVersion.value force()
47
+ )
48
+ val saveClasspathTask = TaskKey[Unit]("saveClasspath", "Save the classpath to a file")
49
+ saveClasspathTask := {
50
+ val managed = (managedClasspath in Runtime).value.map(_.data.getAbsolutePath)
51
+ val unmanaged = (unmanagedClasspath in Runtime).value.map(_.data.getAbsolutePath)
52
+ val out = file("#{classpath_file}")
53
+ write(out, (unmanaged ++ managed).mkString(File.pathSeparator))
54
+ }
55
+ EOF
56
+ FileUtils.mkdir_p "#{dir}/project"
57
+ File.write("#{dir}/build.sbt", build_sbt)
58
+ File.write("#{dir}/project/build.properties", "sbt.version=0.13.8")
59
+ Dir.chdir dir do
60
+ log = `sbt saveClasspath`
61
+ end
62
+ puts log
63
+ end
64
+ classpath = File.read classpath_file
65
+ classpath + ":#{@conf['java-home']}/lib/tools.jar"
66
+ end
67
+ def run
68
+ if is_running?
69
+ puts "ensime is already running"
70
+ else
71
+ FileUtils.mkdir_p @conf['cache-dir']
72
+ @pid = Process.spawn "#{@conf['java-home']}/bin/java #{@conf['java-flags']} \
73
+ -cp #{get_classpath} -Densime.config=#{@conf_path} org.ensime.server.Server"
74
+ end
75
+ self
76
+ end
77
+ def wait
78
+ Process.wait @pid if @pid
79
+ end
80
+ def stop
81
+ Process.kill 'TERM', @pid if @pid
82
+ end
83
+ end
84
+ if __FILE__ == $0
85
+ Ensime.new(ARGV.size == 0 ? ".ensime" : ARGV[0]).run.wait
86
+ end
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+ require 'websocket-eventmachine-client'
3
+ require 'json'
4
+ require 'thread'
5
+ require_relative 'ensime'
6
+ class EnsimeBridge
7
+ attr_accessor :socket
8
+ attr_reader :cache
9
+ def get_socket
10
+ TCPSocket.open("localhost", File.read(@bridge_file).chomp)
11
+ end
12
+ def is_running?
13
+ return false if not File.exists? @bridge_file
14
+ begin
15
+ get_socket.close
16
+ rescue => e
17
+ return false
18
+ end
19
+ true
20
+ end
21
+ def initialize path
22
+ @ensime = Ensime.new(path).run
23
+ @cache = "#{path}_cache/"
24
+ @queue = Queue.new
25
+ @bridge_file = "#{@cache}bridge"
26
+ end
27
+ def remote_stop
28
+ s = get_socket
29
+ s.puts "self.stop"
30
+ s.close
31
+ end
32
+ def stop
33
+ @ensime.stop
34
+ exit
35
+ end
36
+ def connect_to_ensime
37
+ url = "ws://127.0.0.1:#{File.read("#{@cache}http").chomp}/jerky"
38
+ @socket = WebSocket::EventMachine::Client.connect(:uri => url)
39
+ @socket.onopen do
40
+ puts "Connected!"
41
+ end
42
+ @socket.onerror do |err|
43
+ p err
44
+ end
45
+ @socket.onmessage do |msg, type|
46
+ puts "Received message: #{msg}, type #{type}"
47
+ @queue << msg
48
+ end
49
+ @socket.onclose do |code, reason|
50
+ puts "Disconnected with status code: #{code} #{reason}"
51
+ end
52
+ end
53
+ def json packet
54
+ s = packet.to_json
55
+ Kernel.puts " to server => #{s}"
56
+ @socket.send s
57
+ end
58
+ def req message
59
+ @i ||= 0
60
+ @i += 1
61
+ json({"callId" => @i,"req" => message})
62
+ end
63
+ def unqueue
64
+ if @queue.size == 0
65
+ nil
66
+ else
67
+ @queue.pop(true)
68
+ end
69
+ end
70
+ def run
71
+ if is_running?
72
+ puts "bridge is already running"
73
+ return
74
+ end
75
+ Thread.new do
76
+ EventMachine.run do
77
+ connect_to_ensime
78
+ end
79
+ end
80
+ server = TCPServer.new "localhost", 0
81
+ File.write(@bridge_file, server.addr[1])
82
+ while @client = server.accept
83
+ begin
84
+ command = @client.readline
85
+ while true
86
+ result = instance_eval command
87
+ if command.chomp == "unqueue"
88
+ if not result.nil? and not result.empty?
89
+ @client.puts result.gsub("\n", "")
90
+ else
91
+ @client.puts "nil"
92
+ break
93
+ end
94
+ puts result.gsub("\n", "")
95
+ else
96
+ break
97
+ end
98
+ end
99
+ @client.close
100
+ rescue => e
101
+ p e
102
+ puts e.backtrace
103
+ end
104
+ end
105
+ end
106
+ def to_position path, row, col
107
+ i = -1
108
+ File.open(path) do |f|
109
+ (row - 1).times do
110
+ i += f.readline.size
111
+ end
112
+ i += col
113
+ end
114
+ i
115
+ end
116
+ def at_point what, path, row, col, size, where = "range"
117
+ i = to_position path, row, col
118
+ req({"typehint" => what + "AtPointReq",
119
+ "file" => path,
120
+ where => {"from" => i,"to" => i + size}})
121
+ end
122
+ def type path, row, col, size
123
+ at_point "Type", path, row, col, size
124
+ end
125
+ def doc_uri path, row, col, size
126
+ at_point "DocUri", path, row, col, size, "point"
127
+ end
128
+ def complete path, row, col
129
+ i = to_position path, row, col
130
+ req({"point"=>i, "maxResults"=>100,"typehint"=>"CompletionsReq",
131
+ "caseSens"=>true,"fileInfo"=>{"file"=>path},"reload"=>false})
132
+ end
133
+ def typecheck path
134
+ req({"typehint"=>"TypecheckFilesReq","files" => [path]})
135
+ end
136
+ end
137
+ EnsimeBridge.new(ARGV.size == 0 ? ".ensime" : ARGV[0]).run if __FILE__ == $0
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ensime_bridge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Olivier 'yazgoo' Abdesselam
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-08-31 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: bridge to use ensime with vim
15
+ email: yazgoo@github.com
16
+ executables:
17
+ - ensime_bridge
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/ensime.rb
22
+ - lib/ensime_bridge.rb
23
+ - bin/ensime_bridge
24
+ homepage: http://github.com/ensime/ensime-vim
25
+ licenses:
26
+ - MIT
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 1.8.11
46
+ signing_key:
47
+ specification_version: 3
48
+ summary: ensime bridge
49
+ test_files: []