ensime_bridge 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []