File Coverage

blib/lib/Perl/LanguageServer.pm
Criterion Covered Total %
statement 59 292 20.2
branch 0 146 0.0
condition 0 27 0.0
subroutine 20 38 52.6
pod 1 8 12.5
total 80 511 15.6


line stmt bran cond sub pod time code
1             package Perl::LanguageServer;
2              
3 1     1   66751 use v5.16;
  1         5  
4              
5 1     1   7 use strict ;
  1         2  
  1         21  
6 1     1   625 use Moose ;
  1         476824  
  1         6  
7 1     1   7985 use Moose::Util qw( apply_all_roles );
  1         3  
  1         12  
8              
9 1     1   1128 use Coro ;
  1         9371  
  1         78  
10 1     1   483 use Coro::AIO ;
  1         18642  
  1         273  
11 1     1   504 use Coro::Handle ;
  1         32551  
  1         71  
12 1     1   13 use AnyEvent;
  1         8  
  1         28  
13 1     1   5 use AnyEvent::Socket ;
  1         2  
  1         97  
14 1     1   793 use JSON ;
  1         9553  
  1         6  
15 1     1   620 use Data::Dump qw{dump} ;
  1         4913  
  1         64  
16 1     1   458 use IO::Select ;
  1         1646  
  1         50  
17              
18 1     1   460 use Perl::LanguageServer::Req ;
  1         4  
  1         42  
19 1     1   510 use Perl::LanguageServer::Workspace ;
  1         5  
  1         63  
20              
21             with 'Perl::LanguageServer::Methods' ;
22             with 'Perl::LanguageServer::IO' ;
23              
24 1     1   8 no warnings 'uninitialized' ;
  1         2  
  1         592  
25              
26             =head1 NAME
27              
28             Perl::LanguageServer - Language Server and Debug Protocol Adapter for Perl
29              
30             =head1 VERSION
31              
32             Version 2.5.0
33              
34             =cut
35              
36             our $VERSION = '2.5.0';
37              
38              
39             =head1 SYNOPSIS
40              
41             This is a Language Server and Debug Protocol Adapter for Perl
42              
43             It implements the Language Server Protocol which provides
44             syntax-checking, symbol search, etc. Perl to various editors, for
45             example Visual Studio Code or Atom.
46              
47             L<https://microsoft.github.io/language-server-protocol/specification>
48              
49             It also implements the Debug Adapter Protocol, which allow debugging
50             with various editors/includes
51              
52             L<https://microsoft.github.io/debug-adapter-protocol/overview>
53              
54             Should work with any Editor/IDE that support the Language-Server-Protocol.
55              
56             To use both with Visual Studio Code, install the extension "perl"
57              
58             Any comments and patches are welcome.
59              
60             =cut
61              
62             our $json = JSON -> new -> utf8(1) -> ascii(1) ;
63             our $jsonpretty = JSON -> new -> utf8(1) -> ascii(1) -> pretty (1) ;
64              
65             our %running_reqs ;
66             our %running_coros ;
67             our $exit ;
68             our $workspace ;
69             our $dev_tool ;
70             our $debug1 = 0 ;
71             our $debug2 = 0 ;
72             our $log_file ;
73             our $client_version ;
74             our $reqseq = 1_000_000_000 ;
75              
76              
77             has 'channel' =>
78             (
79             is => 'ro',
80             isa => 'Coro::Channel',
81             default => sub { Coro::Channel -> new }
82             ) ;
83              
84             has 'debug' =>
85             (
86             is => 'rw',
87             isa => 'Int',
88             default => 1,
89             ) ;
90              
91             has 'listen_port' =>
92             (
93             is => 'rw',
94             isa => 'Maybe[Int]',
95             ) ;
96              
97             has 'roles' =>
98             (
99             is => 'rw',
100             isa => 'HashRef',
101             default => sub { {} },
102             ) ;
103              
104             has 'out_semaphore' =>
105             (
106             is => 'ro',
107             isa => 'Coro::Semaphore',
108             default => sub { Coro::Semaphore -> new }
109             ) ;
110              
111             has 'log_prefix' =>
112             (
113             is => 'rw',
114             isa => 'Str',
115             default => 'LS',
116             ) ;
117              
118             has 'log_req_txt' =>
119             (
120             is => 'rw',
121             isa => 'Str',
122             default => '---> Request: ',
123             ) ;
124              
125             # ---------------------------------------------------------------------------
126              
127             sub logger
128             {
129 0     0 0   my $self = shift ;
130 0           my $src ;
131 0 0 0       if (!defined ($_[0]) || ref ($_[0]))
132             {
133 0           $src = shift ;
134             }
135 0 0         $src = $self if (!$src) ;
136              
137 0 0         if ($log_file)
138             {
139 0 0         open my $fh, '>>', $log_file or warn "$log_file : $!" ;
140 0 0         print $fh $src?$src -> log_prefix . ': ':'', @_ ;
141 0           close $fh ;
142             }
143             else
144             {
145 0 0         print STDERR $src?$src -> log_prefix . ': ':'', @_ ;
146             }
147             }
148              
149              
150             # ---------------------------------------------------------------------------
151              
152             sub send_notification
153             {
154 0     0 0   my ($self, $notification, $src, $txt) = @_ ;
155              
156 0   0       $txt ||= "<--- Notification: " ;
157 0           $notification -> {jsonrpc} = '2.0' ;
158 0           my $outdata = $json -> encode ($notification) ;
159 0           my $guard = $self -> out_semaphore -> guard ;
160 1     1   10 use bytes ;
  1         2  
  1         19  
161 0           my $len = length($outdata) ;
162 0           my $wrdata = "Content-Length: $len\r\nContent-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n$outdata" ;
163 0           $self -> _write ($wrdata) ;
164 0 0         if ($debug1)
165             {
166 0           $wrdata =~ s/\r//g ;
167 0 0         $self -> logger ($src, $txt, $jsonpretty -> encode ($notification), "\n") if ($debug1) ;
168             }
169             }
170              
171             # ---------------------------------------------------------------------------
172              
173             sub call_method
174 0           {
175 0     0 0   my ($self, $reqdata, $req, $id) = @_ ;
176              
177 0 0         my $method = $req -> is_dap?$reqdata -> {command}:$reqdata -> {method} ;
178 0           my $module ;
179             my $name ;
180              
181 0 0         if ($method =~ /^(\w+)\/(\w+)$/)
    0          
    0          
182             {
183 0           $module = $1 ;
184 0           $name = $2 ;
185             }
186             elsif ($method =~ /^(\w+)$/)
187             {
188 0           $name = $1 ;
189             }
190             elsif ($method =~ /^\$\/(\w+)$/)
191             {
192 0           $name = $1 ;
193             }
194             else
195             {
196 0           die "Unknown method $method" ;
197             }
198 0 0         $module = $req -> type eq 'dbgint'?'DebugAdapterInterface':'DebugAdapter' if ($req -> is_dap) ;
    0          
199              
200 0           my $base_package = __PACKAGE__ . '::Methods' ;
201 0           my $package = $base_package ;
202 0 0         $package .= '::' . $module if ($module) ;
203              
204 0           my $fn = $package . '.pm' ;
205 0           $fn =~ s/::/\//g ;
206 0 0 0       if (!exists $INC{$fn} || !exists $self -> roles -> {$fn})
207             {
208             #$self -> logger (dump (\%INC), "\n") ;
209 0           $self -> logger ("apply_all_roles ($self, $package, $fn)\n") ;
210 0           apply_all_roles ($self, $package) ;
211 0           $self -> roles -> {$fn} = 1 ;
212             }
213              
214 0           my $perlmethod ;
215 0 0         if ($req -> is_dap)
216             {
217 0           $perlmethod = '_dapreq_' . $name ;
218             }
219             else
220             {
221 0 0         $perlmethod = (defined($id)?'_rpcreq_':'_rpcnot_') . $name ;
222             }
223 0 0         $self -> logger ("method=$perlmethod\n") if ($debug1) ;
224 0 0         die "Unknown perlmethod $perlmethod" if (!$self -> can ($perlmethod)) ;
225              
226 1     1   543 no strict ;
  1         5  
  1         57  
227 0           return $self -> $perlmethod ($workspace, $req) ;
228 1     1   9 use strict ;
  1         2  
  1         515  
229             }
230              
231             # ---------------------------------------------------------------------------
232              
233             sub process_req
234             {
235 0     0 0   my ($self, $id, $reqdata) = @_ ;
236              
237 0           my $xid = $id ;
238 0   0       $xid ||= $reqseq++ ;
239             $running_coros{$xid} = async
240             {
241             my $req_guard = Guard::guard
242             {
243 0 0         $self -> logger ("done handle_req id=$xid\n") if ($debug1) ;
244 0           delete $running_reqs{$xid} ;
245 0           delete $running_coros{$xid} ;
246 0     0     };
247              
248 0           my $type = $reqdata -> {type} ;
249 0 0         my $is_dap = $type?1:0 ;
250 0 0         $type = defined ($id)?'request':'notification' if (!$type) ;
    0          
251 0 0         $self -> logger ("handle_req id=$id\n") if ($debug1) ;
252 0 0 0       my $req = Perl::LanguageServer::Req -> new ({ id => $id, is_dap => $is_dap, type => $type, params => $is_dap?$reqdata -> {arguments} || {}:$reqdata -> {params} || {}}) ;
      0        
253 0           $running_reqs{$xid} = $req ;
254              
255 0           my $rsp ;
256             my $outdata ;
257 0           my $outjson ;
258             eval
259 0           {
260 0           $rsp = $self -> call_method ($reqdata, $req, $id) ;
261 0 0         $id = undef if (!$rsp) ;
262 0 0         if ($req -> is_dap)
263             {
264 0 0         $outjson = { request_seq => -$id, seq => -$id, command => $reqdata -> {command}, success => JSON::true, type => 'response', $rsp?(body => $rsp):()} ;
265             }
266             else
267             {
268 0 0         $outjson = { id => $id, jsonrpc => '2.0', result => $rsp} if ($rsp) ;
269             }
270 0 0         $outdata = $json -> encode ($outjson) if ($outjson) ;
271             } ;
272 0 0         if ($@)
273             {
274 0           $self -> logger ("ERROR: $@\n") ;
275 0 0         if ($req -> is_dap)
276             {
277 0           $outjson = { request_seq => -$id, command => $reqdata -> {command}, success => JSON::false, message => "$@", , type => 'response'} ;
278             }
279             else
280             {
281 0           $outjson = { id => $id, jsonrpc => '2.0', error => { code => -32001, message => "$@" }} ;
282             }
283 0 0         $outdata = $json -> encode ($outjson) if ($outjson) ;
284             }
285              
286 0 0         if (defined($id))
287             {
288 0           my $guard = $self -> out_semaphore -> guard ;
289 1     1   8 use bytes ;
  1         2  
  1         11  
290 0           my $len = length ($outdata) ;
291 0           my $wrdata = "Content-Length: $len\r\nContent-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n$outdata" ;
292 0           my $sum = 0 ;
293 0           my $cnt ;
294 0           while ($sum < length ($wrdata))
295             {
296 0           $cnt = $self -> _write ($wrdata, undef, $sum) ;
297 0 0         die "write_error ($!)" if ($cnt <= 0) ;
298 0           $sum += $cnt ;
299             }
300              
301 0 0         if ($debug1)
302             {
303 0           $wrdata =~ s/\r//g ;
304 0           $self -> logger ("<--- Response: ", $jsonpretty -> encode ($outjson), "\n") ;
305             }
306             }
307 0           } ;
308             }
309              
310             # ---------------------------------------------------------------------------
311              
312             sub mainloop
313             {
314 0     0 0   my ($self) = @_ ;
315              
316 0           my $buffer = '' ;
317 0           while (!$exit)
318             {
319 1     1   282 use bytes ;
  1         4  
  1         4  
320 0           my %header ;
321             my $line ;
322 0           my $cnt ;
323 0           my $loop ;
324             header:
325 0           while (1)
326             {
327 0 0         $self -> logger ("start aio read, buffer len = " . length ($buffer) . "\n") if ($debug2) ;
328 0 0         if ($loop)
329             {
330 0           $cnt = $self -> _read (\$buffer, 8192, length ($buffer), undef, 1) ;
331 0 0         $self -> logger ("end aio read cnt=$cnt, buffer len = " . length ($buffer) . "\n") if ($debug2) ;
332 0 0         die "read_error reading headers ($!)" if ($cnt < 0) ;
333 0 0         return if ($cnt == 0) ;
334             }
335              
336 0           while ($buffer =~ s/^(.*?)\R//)
337             {
338 0           $line = $1 ;
339 0 0         $self -> logger ("line=<$line>\n") if ($debug2) ;
340 0 0         last header if ($line eq '') ;
341 0 0         $header{$1} = $2 if ($line =~ /(.+?):\s*(.+)/) ;
342             }
343 0           $loop = 1 ;
344             }
345              
346 0           my $len = $header{'Content-Length'} ;
347 0 0         return 1 if ($len == 0);
348 0           my $data ;
349             #$self -> logger ("len=$len len buffer=", length ($buffer), "\n") if ($debug2) ;
350 0           while ($len > length ($buffer))
351             {
352 0           $cnt = $self -> _read (\$buffer, $len - length ($buffer), length ($buffer)) ;
353              
354             #$self -> logger ("cnt=$cnt len=$len len buffer=", length ($buffer), "\n") if ($debug2) ;
355 0 0         die "read_error reading data ($!)" if ($cnt < 0) ;
356 0 0         return if ($cnt == 0) ;
357             }
358 0 0         if ($len == length ($buffer))
    0          
359             {
360 0           $data = $buffer ;
361 0           $buffer = '' ;
362             }
363             elsif ($len < length ($buffer))
364             {
365 0           $data = substr ($buffer, 0, $len) ;
366 0           $buffer = substr ($buffer, $len) ;
367             }
368             else
369             {
370 0           die "to few data bytes" ;
371             }
372 0 0         $self -> logger ("read data=", $data, "\n") if ($debug2) ;
373 0 0         $self -> logger ("read header=", dump (\%header), "\n") if ($debug2) ;
374              
375 0           my $reqdata ;
376 0 0         $reqdata = $json -> decode ($data) if ($data) ;
377 0 0         if ($debug1)
378             {
379 0           $self -> logger ($self -> log_req_txt, $jsonpretty -> encode ($reqdata), "\n") ;
380             }
381 0 0         my $id = $reqdata -> {type}?-$reqdata -> {seq}:$reqdata -> {id};
382              
383 0           $self -> process_req ($id, $reqdata) ;
384 0           cede () ;
385             }
386              
387 0           return 1 ;
388             }
389              
390             # ---------------------------------------------------------------------------
391              
392             sub _run_tcp_server
393             {
394 0     0     my ($listen_port) = @_ ;
395              
396 0 0         if ($listen_port)
397             {
398 0           my $quit ;
399 0   0       while (!$quit && !$exit)
400             {
401 0           logger (undef, "tcp server start listen on port $listen_port\n") ;
402 0           my $tcpcv = AnyEvent::CondVar -> new ;
403 0           my $guard ;
404             eval
405 0           {
406             $guard = tcp_server '127.0.0.1', $listen_port, sub
407             {
408 0     0     my ($fh, $host, $port) = @_ ;
409              
410             async
411             {
412             eval
413 0           {
414 0           $fh = Coro::Handle::unblock ($fh) ;
415 0           my $self = Perl::LanguageServer -> new ({out_fh => $fh, in_fh => $fh, log_prefix => 'DAx'});
416 0           $self -> logger ("connect from $host:$port\n") ;
417 0           $self -> listen_port ($listen_port) ;
418              
419 0           $quit = $self -> mainloop () ;
420 0 0         $self -> logger ("got quit signal\n") if ($quit) ;
421             } ;
422 0 0         logger (undef, $@) if ($@) ;
423 0 0         if ($fh)
424             {
425 0           close ($fh) ;
426 0           $fh = undef ;
427             }
428 0 0 0       if ($quit || $exit)
429             {
430 0           $tcpcv -> send ;
431 0           IO::AIO::reinit () ; # stop AIO requests
432 0           exit (1) ;
433             }
434 0           } ;
435 0           } ;
436             } ;
437 0 0         if (!$@)
438             {
439 0           $tcpcv -> recv ;
440             }
441             else
442             {
443 0           $guard = undef ;
444 0           logger (undef, $@) ;
445             #$quit = 1 ;
446 0 0 0       if (!$guard && ($@ =~ /Address already in use/))
447             {
448             # stop other server
449             tcp_connect '127.0.0.1', $listen_port, sub
450             {
451 0     0     my ($fh) = @_ ;
452 0 0         syswrite ($fh, "Content-Length: 0\r\n\r\n") if ($fh) ;
453 0           } ;
454             }
455 0           $@ = undef ;
456 0           Coro::AnyEvent::sleep (2) ;
457 0           IO::AIO::reinit () ; # stop AIO requests
458 0           exit (1) ; # stop LS, vscode will restart it
459             }
460             }
461             }
462             }
463              
464             # ---------------------------------------------------------------------------
465              
466             sub run
467             {
468 0     0 1   my $listen_port ;
469             my $no_stdio ;
470 0           my $heartbeat ;
471              
472 0           while (my $opt = shift @ARGV)
473             {
474 0 0         if ($opt eq '--debug')
    0          
    0          
    0          
    0          
    0          
    0          
475             {
476 0           $debug1 = $debug2 = 1 ;
477             }
478             elsif ($opt eq '--log-level')
479             {
480 0           $debug1 = shift @ARGV ;
481 0 0         $debug2 = $debug1 > 1?1:0 ;
482             }
483             elsif ($opt eq '--log-file')
484             {
485 0           $log_file = shift @ARGV ;
486             }
487             elsif ($opt eq '--port')
488             {
489 0           $listen_port = shift @ARGV ;
490             }
491             elsif ($opt eq '--nostdio')
492             {
493 0           $no_stdio = 1 ;
494             }
495             elsif ($opt eq '--heartbeat')
496             {
497 0           $heartbeat = 1 ;
498             }
499             elsif ($opt eq '--version')
500             {
501 0           $client_version = shift @ARGV ;
502             }
503             }
504              
505 0           $|= 1 ;
506              
507 0           my $cv = AnyEvent::CondVar -> new ;
508              
509             async
510             {
511 0     0     my $i = 0 ;
512 0           while (1)
513             {
514 0 0 0       if ($heartbeat || $debug2)
515             {
516 0           logger (undef, "##### $i #####\n running: " . dump (\%running_reqs) . " coros: " . dump (\%running_coros), "\n") ;
517 0           $i++ ;
518             }
519              
520 0           Coro::AnyEvent::sleep (10) ;
521             }
522 0           } ;
523              
524 0 0         if (!$no_stdio)
525             {
526             async
527             {
528 0     0     my $self = Perl::LanguageServer -> new ({out_fh => 1, in_fh => 0});
529              
530 0           $self -> mainloop () ;
531              
532 0           $cv -> send ;
533 0           } ;
534             }
535              
536             async
537             {
538 0     0     _run_tcp_server ($listen_port) ;
539 0           } ;
540              
541 0           $cv -> recv ;
542 0           $exit = 1 ;
543             }
544              
545             # ---------------------------------------------------------------------------
546              
547             sub parsews
548             {
549 0     0 0   my $class = shift ;
550 0           my @args = @_ ;
551              
552 0           $|= 1 ;
553              
554 0           my $cv = AnyEvent::CondVar -> new ;
555              
556             async
557             {
558 0     0     my $self = Perl::LanguageServer -> new ;
559 0           $workspace = Perl::LanguageServer::Workspace -> new ({ config => {} }) ;
560 0           my %folders ;
561 0           foreach my $path (@args)
562             {
563 0           $folders{$path} = $path ;
564             }
565 0           $workspace -> folders (\%folders) ;
566 0           $workspace -> background_parser ($self) ;
567              
568 0           $cv -> send ;
569 0           } ;
570              
571 0           $cv -> recv ;
572             }
573              
574             # ---------------------------------------------------------------------------
575              
576             sub check_file
577             {
578 0     0 0   my $class = shift ;
579 0           my @args = @_ ;
580              
581 0           $|= 1 ;
582              
583 0           my $cv = AnyEvent::CondVar -> new ;
584              
585 0           my $self = Perl::LanguageServer -> new ;
586 0           $workspace = Perl::LanguageServer::Workspace -> new ({ config => {} }) ;
587             async
588             {
589 0     0     my %folders ;
590 0           foreach my $path (@args)
591             {
592 0           $folders{$path} = $path ;
593             }
594 0           $workspace -> folders (\%folders) ;
595 0           $workspace -> background_checker ($self) ;
596              
597 0           $cv -> send ;
598 0           } ;
599              
600             async
601             {
602 0     0     foreach my $path (@args)
603             {
604 0           my $text ;
605 0           aio_load ($path, $text) ;
606              
607 0           $workspace -> check_perl_syntax ($workspace, $path, $text) ;
608             }
609              
610 0           } ;
611              
612 0           $cv -> recv ;
613             }
614              
615             1 ;
616              
617             __END__
618              
619             =head1 DOCUMENTATION
620              
621             Language Server and Debug Protocol Adapter for Perl
622              
623             =head2 Features
624              
625             =over
626              
627             =item * Language Server
628              
629             =over
630              
631             =item * Syntax checking
632              
633             =item * Symbols in file
634              
635             =item * Symbols in workspace/directory
636              
637             =item * Goto Definition
638              
639             =item * Find References
640              
641             =item * Call Signatures
642              
643             =item * Supports multiple workspace folders
644              
645             =item * Document and selection formatting via perltidy
646              
647             =item * Run on remote system via ssh
648              
649             =item * Run inside docker container
650              
651             =item * Run inside kubernetes
652              
653             =back
654              
655             =item * Debugger
656              
657             =over
658              
659             =item * Run, pause, step, next, return
660              
661             =item * Support for coro threads
662              
663             =item * Breakpoints
664              
665             =item * Conditional breakpoints
666              
667             =item * Breakpoints can be set while program runs and for modules not yet loaded
668              
669             =item * Variable view, can switch to every stack frame or coro thread
670              
671             =item * Set variable
672              
673             =item * Watch variable
674              
675             =item * Tooltips with variable values
676              
677             =item * Evaluate perl code in debuggee, in context of every stack frame of coro thread
678              
679             =item * Automatically reload changed Perl modules while debugging
680              
681             =item * Debug multiple perl programs at once
682              
683             =item * Run on remote system via ssh
684              
685             =item * Run inside docker container
686              
687             =item * Run inside kubernetes
688              
689             =back
690              
691             =back
692              
693             =head2 Requirements
694              
695             You need to install the perl module Perl::LanguageServer to make this extension work,
696             e.g. run C<cpan Perl::LanguageServer> on your target system.
697              
698             Please make sure to always run the newest version of Perl::LanguageServer as well.
699              
700             NOTE: Perl::LanguageServer depend on AnyEvent::AIO and Coro. There is a warning that
701             this might not work with newer Perls. It works fine for Perl::LanguageServer. So just
702             confirm the warning and install it.
703              
704             Perl::LanguageServer depends on other Perl modules. It is a good idea to install most
705             of then with your linux package manager.
706              
707             e.g. on Debian/Ubuntu run:
708              
709              
710            
711             sudo apt install libanyevent-perl libclass-refresh-perl libcompiler-lexer-perl \
712             libdata-dump-perl libio-aio-perl libjson-perl libmoose-perl libpadwalker-perl \
713             libscalar-list-utils-perl libcoro-perl
714            
715             sudo cpan Perl::LanguageServer
716            
717              
718             e.g. on Centos 7 run:
719              
720              
721            
722             sudo yum install perl-App-cpanminus perl-AnyEvent-AIO perl-Coro
723             sudo cpanm Class::Refresh
724             sudo cpanm Compiler::Lexer
725             sudo cpanm Hash::SafeKeys
726             sudo cpanm Perl::LanguageServer
727            
728              
729             In case any of the above packages are not available for your os version, just
730             leave them out. The cpan command will install missing dependencies. In case
731             the test fails, when running cpan C<install>, you should try to run C<force install>.
732              
733             =head2 Extension Settings
734              
735             This extension contributes the following settings:
736              
737             =over
738              
739             =item * C<perl.enable>: enable/disable this extension
740              
741             =item * C<perl.sshAddr>: ip address of remote system
742              
743             =item * C<perl.sshPort>: optional, port for ssh to remote system
744              
745             =item * C<perl.sshUser>: user for ssh login
746              
747             =item * C<perl.sshCmd>: defaults to ssh on unix and plink on windows
748              
749             =item * C<perl.sshWorkspaceRoot>: path of the workspace root on remote system
750              
751             =item * C<perl.perlCmd>: defaults to perl
752              
753             =item * C<perl.perlArgs>: additional arguments passed to the perl interpreter that starts the LanguageServer
754              
755             =item * C<perl.sshArgs>: optional arguments for ssh
756              
757             =item * C<perl.pathMap>: mapping of local to remote paths
758              
759             =item * C<perl.perlInc>: array with paths to add to perl library path. This setting is used by the syntax checker and for the debuggee and also for the LanguageServer itself.
760              
761             =item * C<perl.fileFilter>: array for filtering perl file, defaults to [I<.pm,>.pl]
762              
763             =item * C<perl.ignoreDirs>: directories to ignore, defaults to [.vscode, .git, .svn]
764              
765             =item * C<perl.debugAdapterPort>: port to use for connection between vscode and debug adapter inside Perl::LanguageServer.
766              
767             =item * C<perl.debugAdapterPortRange>: if debugAdapterPort is in use try ports from debugAdapterPort to debugAdapterPort + debugAdapterPortRange. Default 100.
768              
769             =item * C<perl.showLocalVars>: if true, show also local variables in symbol view
770              
771             =item * C<perl.logLevel>: Log level 0-2.
772              
773             =item * C<perl.logFile>: If set, log output is written to the given logfile, instead of displaying it in the vscode output pane. Log output is always appended. Only use during debugging of LanguageServer itself.
774              
775             =item * C<perl.disableCache>: If true, the LanguageServer will not cache the result of parsing source files on disk, so it can be used within readonly directories
776              
777             =item * C<perl.containerCmd>: If set Perl::LanguageServer can run inside a container. Options are: 'docker', 'docker-compose', 'kubectl'
778              
779             =item * C<perl.containerArgs>: arguments for containerCmd. Varies depending on containerCmd.
780              
781             =item * C<perl.containerMode>: To start a new container, set to 'run', to execute inside an existing container set to 'exec'. Note: kubectl only supports 'exec'
782              
783             =item * C<perl.containerName>: Image to start or container to exec inside or pod to use
784              
785             =back
786              
787             =head2 Debugger Settings for launch.json
788              
789             =over
790              
791             =item * C<type>: needs to be C<perl>
792              
793             =item * C<request>: only C<launch> is supported (this is a restriction of perl itself)
794              
795             =item * C<name>: name of this debug configuration
796              
797             =item * C<program>: path to perl program to start
798              
799             =item * C<stopOnEntry>: if true, program will stop on entry
800              
801             =item * C<args>: optional, array with arguments for perl program
802              
803             =item * C<env>: optional, object with environment settings
804              
805             =item * C<cwd>: optional, change working directory before launching the debuggee
806              
807             =item * C<reloadModules>: if true, automatically reload changed Perl modules while debugging
808              
809             =back
810              
811             =head2 Remote syntax check & debugging
812              
813             If you developing on a remote machine, you can instruct the Perl::LanguageServer to
814             run on that remote machine, so the correct modules etc. are available for syntax check and debugger is started on the remote machine.
815             To do so set sshAddr and sshUser, preferably in your workspace configuration.
816              
817             Example:
818              
819              
820             "sshAddr": "10.11.12.13",
821             "sshUser": "root"
822              
823             Also set sshWorkspaceRoot, so the local workspace path can be mapped to the remote one.
824              
825             Example: if your local path is \10.11.12.13\share\path\to\ws and on the remote machine you have /path/to/ws
826              
827              
828             "sshWorkspaceRoot": "/path/to/ws"
829              
830             The other possibility is to provide a pathMap. This allows to having multiple mappings.
831              
832             Examples:
833              
834              
835             "sshpathMap": [
836             ["remote uri", "local uri"],
837             ["remote uri", "local uri"]
838             ]
839            
840             "perl.pathMap": [
841             [
842             "file:///",
843             "file:///home/systems/mountpoint/"
844             ]
845             ]
846              
847             =head2 Syntax check & debugging inside a container
848              
849             You can run the LanguageServer and/or debugger inside
850             a container by setting C<containerCmd> and C<conatinerName>.
851             There are more container options, see above.
852              
853             .vscode/settings.json
854              
855              
856             {
857             "perl": {
858             "enable": true,
859             "containerCmd": "docker",
860             "containerName": "perl_container",
861             }
862             }
863              
864             =head2 FAQ
865              
866             =head3 Working directory is not defined
867              
868             It is not defined what the current working directory is at the start of a perl program.
869             So Perl::LanguageServer makes no assumptions about it. To solve the problem you can set
870             the directory via cwd configuration parameter in launch.json for debugging.
871              
872             =head3 Module not found when debugging or during syntax check
873              
874             If you reference a module with a relative path or if you assume that the current working directory
875             is part of the Perl search path, it will not work.
876             Instead set the perl include path to a fixed absolute path. In your settings.json do something like:
877              
878              
879             "perl.perlInc": [
880             "/path/a/lib",
881             "/path/b/lib",
882             "/path/c/lib",
883             ],
884             Include path works for syntax check and inside of debugger.
885             C<perl.perlInc> should be an absolute path.
886              
887             =head3 AnyEvent, Coro Warning during install
888              
889             You need to install the AnyEvent::IO and Coro. Just ignore the warning that it might not work. For Perl::LanguageServer it works fine.
890              
891             =head3 'richterger.perl' failed: options.port should be >= 0 and < 65536
892              
893             Change port setting from string to integer
894              
895             =head3 Error "Can't locate MODULE_NAME"
896              
897             Please make sure the path to the module is in C<perl.perlInc> setting and use absolute path names in the perlInc settings
898             or make sure you are running in the expected directory by setting the C<cwd> setting in the lauch.json.
899              
900             =head3 ERROR: Unknow perlmethod I<rpcnot>setTraceNotification
901              
902             This is not an issue, that just means that not all features of the debugging protocol are implemented.
903             Also it says ERROR, it's just a warning and you can safely ignore it.
904              
905             =head3 The debugger sometimes stops at random places
906              
907             Upgrade to Version 2.4.0
908              
909             =head3 Message about Perl::LanguageServer has crashed 5 times
910              
911             This is a problem when more than one instance of Perl::LanguageServer is running.
912             Upgrade to Version 2.4.0 solves this problem.
913              
914             =head3 Carton support
915              
916             If you are using LL<https://metacpan.org/pod/Carton> to manage dependencies, add the full path to the Carton C<lib> dir to your workspace settings file at C<.vscode/settings.json>. For example:
917              
918             =head4 Linux
919              
920              
921             {
922             "perl.perlInc": ["/home/myusername/projects/myprojectname/local/lib/perl5"]
923             }
924              
925             =head4 Mac
926              
927              
928             {
929             "perl.perlInc": ["/Users/myusername/projects/myprojectname/local/lib/perl5"]
930             }
931              
932             =head2 Known Issues
933              
934             Does not yet work on windows, due to issues with reading from stdin.
935             I wasn't able to find a reliable way to do a non-blocking read from stdin on windows.
936             I would be happy, if anyone knows how to do this in Perl.
937              
938             Anyway, Perl::LanguageServer runs without problems inside of Windows Subsystem for Linux (WSL).
939              
940             =head2 Release Notes
941              
942             see CHANGELOG.md
943              
944             =head2 More Info
945              
946             =over
947              
948             =item * Presentation at German Perl Workshop 2020:
949              
950             =back
951              
952             https://github.com/richterger/Perl-LanguageServer/blob/master/docs/Perl-LanguageServer%20und%20Debugger%20f%C3%BCr%20Visual%20Studio%20Code%20u.a.%20Editoren%20-%20Perl%20Workshop%202020.pdf
953              
954             =over
955              
956             =item * Github: https://github.com/richterger/Perl-LanguageServer
957              
958             =item * MetaCPAN: https://metacpan.org/release/Perl-LanguageServer
959              
960             =back
961              
962             For reporting bugs please use GitHub issues.
963              
964             =head2 References
965              
966             This is a Language Server and Debug Protocol Adapter for Perl
967              
968             It implements the Language Server Protocol which provides
969             syntax-checking, symbol search, etc. Perl to various editors, for
970             example Visual Studio Code or Atom.
971              
972             https://microsoft.github.io/language-server-protocol/specification
973              
974             It also implements the Debug Adapter Protocol, which allows debugging
975             with various editors/includes
976              
977             https://microsoft.github.io/debug-adapter-protocol/overview
978              
979             To use both with Visual Studio Code, install the extension "perl"
980              
981             https://marketplace.visualstudio.com/items?itemName=richterger.perl
982              
983             Any comments and patches are welcome.
984              
985             =head2 LICENSE AND COPYRIGHT
986              
987             Copyright 2018-2022 Gerald Richter.
988              
989             This program is free software; you can redistribute it and/or modify it
990             under the terms of the Artistic License (2.0). You may obtain a
991             copy of the full license at:
992              
993             LL<http://www.perlfoundation.org/artistic_license_2_0>
994              
995             Any use, modification, and distribution of the Standard or Modified
996             Versions is governed by this Artistic License. By using, modifying or
997             distributing the Package, you accept this license. Do not use, modify,
998             or distribute the Package, if you do not accept this license.
999              
1000             If your Modified Version has been derived from a Modified Version made
1001             by someone other than you, you are nevertheless required to ensure that
1002             your Modified Version complies with the requirements of this license.
1003              
1004             This license does not grant you the right to use any trademark, service
1005             mark, tradename, or logo of the Copyright Holder.
1006              
1007             This license includes the non-exclusive, worldwide, free-of-charge
1008             patent license to make, have made, use, offer to sell, sell, import and
1009             otherwise transfer the Package with respect to any patent claims
1010             licensable by the Copyright Holder that are necessarily infringed by the
1011             Package. If you institute patent litigation (including a cross-claim or
1012             counterclaim) against any party alleging that the Package constitutes
1013             direct or contributory patent infringement, then this Artistic License
1014             to you shall terminate on the date that such litigation is filed.
1015              
1016             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
1017             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
1018             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
1019             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
1020             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
1021             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
1022             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
1023             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1024              
1025             =head1 Change Log
1026              
1027             =head2 2.5.0 C<2023-02-05>
1028              
1029             =over
1030              
1031             =item * Set minimal Perl version to 5.16 (#91)
1032              
1033             =item * Per default enviroment from vscode will be passed to debuggee, syntax check and perltidy.
1034              
1035             =item * Add configuration C<disablePassEnv> to not pass enviroment variables.
1036              
1037             =item * Support for C<logLevel> and C<logFile> settings via LanguageServer protocol and
1038             not only via command line options (#97) [schellj]
1039              
1040             =item * Fix: "No DB::DB routine defined" (#91) [peterdragon]
1041              
1042             =item * Fix: Typos and spelling in README (#159) [dseynhae]
1043              
1044             =item * Fix: Update call to gensym(), to fix 'strict subs' error (#164) [KohaAloha]
1045              
1046             =item * Convert identention from tabs to spaces and remove trailing whitespaces
1047              
1048             =back
1049              
1050             =head2 2.4.0 C<2022-11-18>
1051              
1052             =over
1053              
1054             =item * Choose a different port for debugAdapterPort if it is already in use. This
1055             avoids trouble with starting C<Perl::LanguageServer> if another instance
1056             of C<Perl::LanguageServer> is runing on the same machine (thanks to hakonhagland)
1057              
1058             =item * Add configuration C<debugAdapterPortRange>, for choosing range of port for dynamic
1059             port assignment
1060              
1061             =item * Add support for using LanguageServer and debugger inside a Container.
1062             Currently docker containers und containers running inside kubernetes are supported.
1063              
1064             =item * When starting debugger session and C<stopOnEntry> is false, do not switch to sourefile
1065             where debugger would stop, when C<stopOnEntry> is true.
1066              
1067             =item * Added some FAQs in README
1068              
1069             =item * Fix: Debugger stopps at random locations
1070              
1071             =item * Fix: debugAdapterPort is now numeric
1072              
1073             =item * Fix: debugging loop with each statement (#107)
1074              
1075             =item * Fix: display of arrays in variables pane on mac (#120)
1076              
1077             =item * Fix: encoding for C<perltidy> (#127)
1078              
1079             =item * Fix: return error if C<perltidy> fails, so text is not removed by failing
1080             formatting request (#87)
1081              
1082             =item * Fix: FindBin does not work when checking syntax (#16)
1083              
1084             =back
1085              
1086             =head2 2.3.0 C<2021-09-26>
1087              
1088             =over
1089              
1090             =item * Arguments section in Variable lists now C<@ARGV> and C<@_> during debugging (#105)
1091              
1092             =item * C<@_> is now correctly evaluated inside of debugger console
1093              
1094             =item * C<$#foo> is now correctly evaluated inside of debugger console
1095              
1096             =item * Default debug configuration is now automatically provided without
1097             the need to create a C<launch.json> first (#103)
1098              
1099             =item * Add Option C<cacheDir> to specify location of cache dir (#113)
1100              
1101             =item * Fix: Debugger outputted invalid thread reference causes "no such coroutine" message,
1102             so watchs and code from the debug console is not expanded properly
1103              
1104             =item * Fix: LanguageServer hangs when multiple request send at once from VSCode to LanguageServer
1105              
1106             =item * Fix: cwd parameter for debugger in launch.json had no effect (#99)
1107              
1108             =item * Fix: Correctly handle paths with drive letters on windows
1109              
1110             =item * Fix: sshArgs parameter was not declared as array (#109)
1111              
1112             =item * Disable syntax check on windows, because it blocks the whole process when running on windows,
1113             until handling of childs processes is fixed
1114              
1115             =item * Fixed spelling (#86,#96,#101) [chrstphrchvz,davorg,aluaces]
1116              
1117             =back
1118              
1119             =head2 2.2.0 C<2021-02-21>
1120              
1121             =over
1122              
1123             =item * Parser now supports Moose method modifieres before, after and around,
1124             so they can be used in symbol view and within reference search
1125              
1126             =item * Support Format Document and Format Selection via perltidy
1127              
1128             =item * Add logFile config option
1129              
1130             =item * Add perlArgs config option to pass options to Perl interpreter. Add some documentation for config options.
1131              
1132             =item * Add disableCache config option to make LanguageServer usable with readonly directories.
1133              
1134             =item * updated dependencies package.json & package-lock.json
1135              
1136             =item * Fix deep recursion in SymbolView/Parser which was caused by function prototypes.
1137             Solves also #65
1138              
1139             =item * Fix duplicate req id's that caused cleanup of still
1140             running threads which in turn caused the LanguageServer to hang
1141              
1142             =item * Prevent dereferencing an undefined value (#63) [Heiko Jansen]
1143              
1144             =item * Fix datatype of cwd config options (#47)
1145              
1146             =item * Use perlInc setting also for LanguageServer itself (based only pull request #54 from ALANVF)
1147              
1148             =item * Catch Exceptions during display of variables inside debugger
1149              
1150             =item * Fix detecting duplicate LanguageServer processes
1151              
1152             =item * Fix spelling in documentation (#56) [Christopher Chavez]
1153              
1154             =item * Remove notice about Compiler::Lexer 0.22 bugs (#55) [Christopher Chavez]
1155              
1156             =item * README: Typo and grammar fixes. Add Carton lib path instructions. (#40) [szTheory]
1157              
1158             =item * README: Markdown code block formatting (#42) [szTheory]
1159              
1160             =item * Makefile.PL: add META_MERGE with GitHub info (#32) [Christopher Chavez]
1161              
1162             =item * search.cpan.org retired, replace with metacpan.org (#31) [Christopher Chavez]
1163              
1164             =back
1165              
1166             =head2 2.1.0 C<2020-06-27>
1167              
1168             =over
1169              
1170             =item * Improve Symbol Parser (fix parsing of anonymous subs)
1171              
1172             =item * showLocalSymbols
1173              
1174             =item * function names in breadcrump
1175              
1176             =item * Signature Help for function/method arguments
1177              
1178             =item * Add Presentation on Perl Workshop 2020 to repos
1179              
1180             =item * Remove Compiler::Lexer from distribution since
1181             version is available on CPAN
1182              
1183             =item * Make stdout unbuffered while debugging
1184              
1185             =item * Make debugger use perlInc setting
1186              
1187             =item * Fix fileFilter setting
1188              
1189             =item * Sort Arrays numerically in variables view of debugger
1190              
1191             =item * Use rootUri if workspaceFolders not given
1192              
1193             =item * Fix env config setting
1194              
1195             =item * Recongnice changes in config of perlCmd
1196              
1197             =back
1198              
1199             =head2 2.0.2 C<2020-01-22>
1200              
1201             =over
1202              
1203             =item * Plugin: Fix command line parameters for plink
1204              
1205             =item * Perl::LanguageServer: Fix handling of multiple parallel request, improve symlink handling, add support for UNC paths in path mapping, improve logging for logLevel = 1
1206              
1207             =back
1208              
1209             =head2 2.0.1 C<2020-01-14>
1210              
1211             Added support for reloading Perl module while debugging, make log level configurable, make sure tooltips don't call functions
1212              
1213             =head2 2.0.0 C<2020-01-01>
1214              
1215             Added Perl debugger
1216              
1217             =head2 0.9.0 C<2019-05-03>
1218              
1219             Fix issues in the Perl part, make sure to update Perl::LanguageServer from cpan
1220              
1221             =head2 0.0.3 C<2018-09-08>
1222              
1223             Fix issue with not reading enough from stdin, which caused LanguageServer to hang sometimes
1224              
1225             =head2 0.0.2 C<2018-07-21>
1226              
1227             Fix quitting issue when starting Perl::LanguageServer, more fixes are in the Perl part
1228              
1229             =head2 0.0.1 C<2018-07-13>
1230              
1231             Initial Version