Skip to content

Commit 3690ca2

Browse files
committed
(GH-#187) Add a stdio mode to the language server
1 parent 5f932a9 commit 3690ca2

File tree

4 files changed

+44
-8
lines changed

4 files changed

+44
-8
lines changed

server/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ Usage: puppet-languageserver.rb [options]
111111
-d, --no-preload Do not preload Puppet information when the language server starts. Default is to preload
112112
--debug=DEBUG Output debug information. Either specify a filename or 'STDOUT'. Default is no debug output
113113
-s, --slow-start Delay starting the TCP Server until Puppet initialisation has completed. Default is to start fast
114+
--stdio Runs the server in stdio mode, without a TCP listener
114115
-h, --help Prints this help
115116
-v, --version Prints the Langauge Server version
116117
```

server/lib/puppet-languageserver.rb

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class CommandLineParser
1919
def self.parse(options)
2020
# Set defaults here
2121
args = {
22+
stdio: false,
2223
port: 8081,
2324
ipaddress: '127.0.0.1',
2425
stop_on_client_exit: true,
@@ -60,6 +61,10 @@ def self.parse(options)
6061
args[:fast_start_tcpserver] = false
6162
end
6263

64+
opts.on('--stdio', "Runs the server in stdio mode, without a TCP listener") do |_misc|
65+
args[:stdio] = true
66+
end
67+
6368
opts.on('--local-workspace=PATH', 'The workspace or file path that will be used to provide module-specific functionality. Default is no workspace path.') do |path|
6469
args[:workspace] = path
6570
end
@@ -122,13 +127,29 @@ def self.init_puppet_worker(options)
122127
def self.rpc_server(options)
123128
log_message(:info, 'Starting RPC Server...')
124129

125-
server = PuppetVSCode::SimpleTCPServer.new
130+
if options[:stdio]
131+
$stdin.sync = true
132+
$stdout.sync = true
133+
134+
handler = PuppetLanguageServer::MessageRouter.new
135+
handler.socket = $stdout
136+
handler.post_init
137+
138+
loop do
139+
data = $stdin.readpartial(1048576)
140+
raise 'Receieved an empty input string' if data.length.zero?
126141

127-
options[:servicename] = 'LANGUAGE SERVER'
142+
handler.receive_data(data)
143+
end
144+
else
145+
server = PuppetVSCode::SimpleTCPServer.new
128146

129-
server.add_service(options[:ipaddress], options[:port])
130-
trap('INT') { server.stop_services(true) }
131-
server.start(PuppetLanguageServer::MessageRouter, options, 2)
147+
options[:servicename] = 'LANGUAGE SERVER'
148+
149+
server.add_service(options[:ipaddress], options[:port])
150+
trap('INT') { server.stop_services(true) }
151+
server.start(PuppetLanguageServer::MessageRouter, options, 2)
152+
end
132153

133154
log_message(:info, 'Language Server exited.')
134155
end

server/lib/puppet-languageserver/json_rpc_handler.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module PuppetLanguageServer
3737
KEY_CODE = 'code'.freeze
3838
KEY_MESSAGE = 'message'.freeze
3939

40-
class JSONRPCHandler < PuppetVSCode::SimpleTCPServerConnection
40+
class JSONRPCHandler < PuppetVSCode::SocketConnection
4141
def initialize(*_options)
4242
@key_jsonrpc = KEY_JSONRPC
4343
@key_id = KEY_ID

server/lib/puppet-vscode/simple_tcp_server.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
# http://stackoverflow.com/questions/29858113/unable-to-make-socket-accept-non-blocking-ruby-2-2
55

66
module PuppetVSCode
7-
class SimpleTCPServerConnection
7+
class SocketConnection
88
attr_accessor :socket
9-
attr_accessor :simple_tcp_server
109

1110
# Methods to override
1211
def post_init
@@ -35,6 +34,21 @@ def send_data(data)
3534
true
3635
end
3736

37+
# @api public
38+
def close_connection_after_writing
39+
true
40+
end
41+
42+
# @api public
43+
def close_connection
44+
true
45+
end
46+
end
47+
48+
class SimpleTCPServerConnection < SocketConnection
49+
attr_accessor :socket
50+
attr_accessor :simple_tcp_server
51+
3852
# @api public
3953
def close_connection_after_writing
4054
socket.flush

0 commit comments

Comments
 (0)