Exercise Language Server Transport
By the end of this advanced exercise, you will have started a configured peer, exchanged framed bytes, synchronized current text, and stopped the child.
Current Availability
rur currently exposes process ownership, framed message exchange, and explicit text synchronization for Rust and Ruby files. It does not implement language server protocol initialization, completion, diagnostics, or navigation requests. These commands are transport primitives rather than a ready-to-use LSP client.
The following peer echoes the transport envelope. It is an exercise helper, not a language server. Use the syntax chapter for currently available language-aware editing that needs no external process.
Prepare the Peer
From the repository root, save this as guide-peer.rb:
File.write('peer.pid', Process.pid.to_s)
while (header = STDIN.gets)
raise 'Invalid length header' unless header.match?(/\AContent-Length: [0-9]+\r\n\z/)
length = header.delete_prefix('Content-Length: ').to_i
raise 'Invalid separator' unless STDIN.gets == "\r\n"
body = STDIN.read(length)
raise 'Incomplete body' unless body && body.bytesize == length
File.binwrite('last-request.bin', body)
STDOUT.write("Content-Length: #{body.bytesize}\r\n\r\n")
STDOUT.write(body)
STDOUT.flush
end
Save this trusted configuration as guide-language.rb:
require 'rbconfig'
configuration = Rur.configuration
configuration.language_server('ruby', [RbConfig.ruby, File.expand_path('guide-peer.rb')])
configuration.language_server_message('ruby', 'guide ping')
Create a saved Ruby document and open it with that configuration:
printf "puts 'hello'\n" > guide-document.rb
env -u RUBYOPT -u RUBYLIB -u GEM_HOME -u GEM_PATH \
cargo run --locked -p rur-editor --bin rur-terminal-proof -- \
--config guide-language.rb --profile nonmodal guide-document.rb
The child runs in the saved document's directory. Configuration and this child are trusted local code running with the process's permissions.
Exchange and Synchronize
Use Alt-x start-language-server. The helper records its PID in peer.pid.
Starting it again retains the same child.
Invoke exchange-language-server to send guide ping and read its echoed body.
The response does not replace document text or create an undo entry.
Invoke synchronize-language-server. rur sends revision N followed by a
newline and the exact current text. The helper echoes that complete body;
only a response matching the current revision is admitted. Editing does not
send text automatically. An obsolete response is discarded while editing
and the child remain available.
Invoke stop-language-server, then Ctrl-Q to leave. The helper exits on EOF.
At the shell, inspect the last request:
cat last-request.bin
The first line identifies a revision; the remaining text is puts 'hello'.
The source document is unchanged. Start and exchange on a plain-text file or
an unassociated buffer do not acquire a language peer.
A missing executable or failed exchange leaves ordinary editing available. The helper must exit on EOF for an ordinary stop to finish. Read the process and transport reference for failure handling and message limits before configuring other programs.
Previous: Use Rust and Ruby Syntax | Part | User Guide | Next: Structured Documents