NAME

YATT::Lite::LanguageServer - Language Server for YATT::Lite

SYNOPSIS

# As started by editors (poly-yatt, lsp-yatt.el).
# Options must come BEFORE the subcommand.
% perl lib/YATT/Lite/LanguageServer.pm --quiet server

# With a protocol trace (also works together with --quiet):
% perl lib/YATT/Lite/LanguageServer.pm --quiet --logfile=/tmp/yatt-ls.log server
% YATT_LANGSERVER_LOG=/tmp/yatt-ls.log emacs ...

DESCRIPTION

YATT::Lite::LanguageServer is a Modulino to provide a Language Server for YATT::Lite. It speaks JSON-RPC (Content-Length framing) over stdin/stdout and delegates the actual work to YATT::Lite::Inspector.

Supported methods

initialize, initialized, shutdown, exit, $/cancelRequest
textDocument/didOpen, didChange (incremental), didSave, didClose
textDocument/publishDiagnostics (server -> client)
textDocument/definition, textDocument/implementation
textDocument/hover
textDocument/documentSymbol
textDocument/completion

Definition and hover targets

&yatt:x;  &yatt:x:foo();      argument / <yatt:my> variable / entity function
                              / page constant (pagevars): the line in the
                              pagevars module, hover shows its value
                              (GH-286, see YATT::Lite::PageConsts).
                              Page constants are also completed.
<yatt:foo ...>                widget declaration (same file, other file,
                              <!yatt:base>, <!yatt:import>)
<yatt:foo x/> <yatt:foo a=y/> the variable in scope (x, y) or the formal
                              argument of foo (GH-277)
<yatt:body/> <yatt:cb/>       the callable variable in scope: an explicit
                              body=[code] / cb=[code] argument token,
                              a <yatt:my f:code=...> variable, or the
                              declaration line of the enclosing widget for
                              the implicit body argument (GH-280). As in
                              the compiler, such a variable shadows a
                              widget of the same name.
<yatt:if> <yatt:foreach> ...  macro elements: hover only (no definition)

Options

Options must precede the server subcommand.

--quiet

Suppress the trace on STDERR. Editors should pass this.

--logfile=FILE (or $YATT_LANGSERVER_LOG)

Append a timestamped protocol trace to FILE, regardless of --quiet.

--dump_request

Hexdump the input buffer on every read (needs Data::HexDump::XXD).

Debugging the Inspector

Create an empty file named DEBUG_YATT_LANGSERVER in the workspace root (the directory given as rootUri) to get YATT::Lite::Inspector debug messages on STDERR. If a directory var/debug_yatt_ls/ also exists there, the document state after every textDocument/didChange is written into it.

Workspace root and app.psgi

On initialize the server opens the workspace (rootUri, else the first of workspaceFolders, else rootPath; the server's cwd when none is given) through "load_or_default" in YATT::Lite::Site. The app.psgi / runyatt.psgi search is limited to the workspace root itself (stop_at => $rootUri): a factory script in a parent directory is never executed, because the editor only vouched for the workspace. A workspace without its own factory script is served by a default site, as a bare template directory.

Paths and URIs

File URIs are percent-decoded to octet paths and used as they are: the server keys templates by the path form the client sends and never resolves symlinks itself. Keep the client's policy uniform for all buffers of a session (for Eglot: file-truename handling).

Position encoding

Positions are exchanged as perl character offsets, which are UTF-32 code units. When the client offers utf-32 in general.positionEncodings (Eglot does), the server answers with positionEncoding: "utf-32". Clients limited to UTF-16 get the same offsets, so for them columns after a non-BMP character (emoji, some rare kanji) on the same line are off.

Editor Integration

AUTHOR

"KOBAYASI, Hiroaki" <hkoba@cpan.org>