view release on metacpan or search on metacpan
Changes.pod view on Meta::CPAN
=item * C<@_> is now correctly evaluated inside of debugger console
=item * C<$#foo> is now correctly evaluated inside of debugger console
=item * Default debug configuration is now automatically provided without
the need to create a C<launch.json> first (#103)
=item * Add Option C<cacheDir> to specify location of cache dir (#113)
=item * Fix: Debugger outputted invalid thread reference causes "no such coroutine" message,
so watchs and code from the debug console is not expanded properly
=item * Fix: LanguageServer hangs when multiple request send at once from VSCode to LanguageServer
=item * Fix: cwd parameter for debugger in launch.json had no effect (#99)
=item * Fix: Correctly handle paths with drive letters on windows
=item * Fix: sshArgs parameter was not declared as array (#109)
=item * Run inside kubernetes
=back
=item * Debugger
=over
=item * Run, pause, step, next, return
=item * Support for coro threads
=item * Breakpoints
=item * Conditional breakpoints
=item * Breakpoints can be set while program runs and for modules not yet loaded
=item * Variable view, can switch to every stack frame or coro thread
=item * Set variable
=item * Watch variable
=item * Tooltips with variable values
=item * Evaluate perl code in debuggee, in context of every stack frame of coro thread
=item * Automatically reload changed Perl modules while debugging
=item * Debug multiple perl programs at once
=item * Run on remote system via ssh
=item * Run inside docker container
=item * Run inside kubernetes
Perl::LanguageServer depends on other Perl modules. It is a good idea to install most
of then with your linux package manager.
e.g. on Debian/Ubuntu run:
sudo apt install libanyevent-perl libclass-refresh-perl libcompiler-lexer-perl \
libdata-dump-perl libio-aio-perl libjson-perl libmoose-perl libpadwalker-perl \
libscalar-list-utils-perl libcoro-perl
sudo cpan Perl::LanguageServer
e.g. on Centos 7 run:
sudo yum install perl-App-cpanminus perl-AnyEvent-AIO perl-Coro
sudo cpanm Class::Refresh
lib/Perl/LanguageServer.pm view on Meta::CPAN
To use both with Visual Studio Code, install the extension "perl"
Any comments and patches are welcome.
=cut
our $json = JSON -> new -> utf8(1) -> ascii(1) ;
our $jsonpretty = JSON -> new -> utf8(1) -> ascii(1) -> pretty (1) ;
our %running_reqs ;
our %running_coros ;
our $exit ;
our $workspace ;
our $dev_tool ;
our $debug1 = 0 ;
our $debug2 = 0 ;
our $log_file ;
our $client_version ;
our $reqseq = 1_000_000_000 ;
lib/Perl/LanguageServer.pm view on Meta::CPAN
}
# ---------------------------------------------------------------------------
sub process_req
{
my ($self, $id, $reqdata) = @_ ;
my $xid = $id ;
$xid ||= $reqseq++ ;
$running_coros{$xid} = async
{
my $req_guard = Guard::guard
{
$self -> logger ("done handle_req id=$xid\n") if ($debug1) ;
delete $running_reqs{$xid} ;
delete $running_coros{$xid} ;
};
my $type = $reqdata -> {type} ;
my $is_dap = $type?1:0 ;
$type = defined ($id)?'request':'notification' if (!$type) ;
$self -> logger ("handle_req id=$id\n") if ($debug1) ;
my $req = Perl::LanguageServer::Req -> new ({ id => $id, is_dap => $is_dap, type => $type, params => $is_dap?$reqdata -> {arguments} || {}:$reqdata -> {params} || {}}) ;
$running_reqs{$xid} = $req ;
my $rsp ;
lib/Perl/LanguageServer.pm view on Meta::CPAN
my $cv = AnyEvent::CondVar -> new ;
async
{
my $i = 0 ;
while (1)
{
if ($heartbeat || $debug2)
{
logger (undef, "##### $i #####\n running: " . dump (\%running_reqs) . " coros: " . dump (\%running_coros), "\n") ;
$i++ ;
}
Coro::AnyEvent::sleep (10) ;
}
} ;
if (!$no_stdio)
{
async
lib/Perl/LanguageServer.pm view on Meta::CPAN
=item * Run inside kubernetes
=back
=item * Debugger
=over
=item * Run, pause, step, next, return
=item * Support for coro threads
=item * Breakpoints
=item * Conditional breakpoints
=item * Breakpoints can be set while program runs and for modules not yet loaded
=item * Variable view, can switch to every stack frame or coro thread
=item * Set variable
=item * Watch variable
=item * Tooltips with variable values
=item * Evaluate perl code in debuggee, in context of every stack frame of coro thread
=item * Automatically reload changed Perl modules while debugging
=item * Debug multiple perl programs at once
=item * Run on remote system via ssh
=item * Run inside docker container
=item * Run inside kubernetes
lib/Perl/LanguageServer.pm view on Meta::CPAN
Perl::LanguageServer depends on other Perl modules. It is a good idea to install most
of then with your linux package manager.
e.g. on Debian/Ubuntu run:
sudo apt install libanyevent-perl libclass-refresh-perl libcompiler-lexer-perl \
libdata-dump-perl libio-aio-perl libjson-perl libmoose-perl libpadwalker-perl \
libscalar-list-utils-perl libcoro-perl
sudo cpan Perl::LanguageServer
e.g. on Centos 7 run:
sudo yum install perl-App-cpanminus perl-AnyEvent-AIO perl-Coro
sudo cpanm Class::Refresh
lib/Perl/LanguageServer.pm view on Meta::CPAN
=item * C<@_> is now correctly evaluated inside of debugger console
=item * C<$#foo> is now correctly evaluated inside of debugger console
=item * Default debug configuration is now automatically provided without
the need to create a C<launch.json> first (#103)
=item * Add Option C<cacheDir> to specify location of cache dir (#113)
=item * Fix: Debugger outputted invalid thread reference causes "no such coroutine" message,
so watchs and code from the debug console is not expanded properly
=item * Fix: LanguageServer hangs when multiple request send at once from VSCode to LanguageServer
=item * Fix: cwd parameter for debugger in launch.json had no effect (#99)
=item * Fix: Correctly handle paths with drive letters on windows
=item * Fix: sshArgs parameter was not declared as array (#109)
lib/Perl/LanguageServer/DebuggerInterface.pm view on Meta::CPAN
# ---------------------------------------------------------------------------
sub req_vars
{
my ($class, $params, $recurse) = @_ ;
my $thread_ref = $params -> {thread_ref} ;
my $tid = defined ($Coro::current)?$Coro::current+0:1 ;
if ($thread_ref != $tid && !$recurse && ($params -> {type} !~ /^eg:/))
{
my $coro ;
$coro = $class -> find_coro ($thread_ref) ;
return { variables => [] } if (!$coro) ;
my $ret ;
$coro -> call (sub {
$ret = $class -> req_vars ($params, $recurse + 1) ;
}) ;
return $ret ;
}
my $frame_ref = $params -> {frame_ref} - $recurse ;
my $package = $params -> {'package'} ;
my $type = $params -> {type} ;
my $filter = $params -> {filter} ;
my @vars ;
lib/Perl/LanguageServer/DebuggerInterface.pm view on Meta::CPAN
sub req_evaluate
{
my ($class, $params, $recurse) = @_ ;
return undef if ($params -> {'context'} eq 'hover' && ($params -> {'expression'} !~ /^\s*\\?[\$\@\%]/)) ;
my $thread_ref = $params -> {thread_ref} ;
my $tid = defined ($Coro::current)?$Coro::current+0:1 ;
if ($thread_ref != $tid && !$recurse)
{
my $coro ;
$coro = $class -> find_coro ($thread_ref) ;
return undef if (!$coro) ;
my $ret ;
$coro -> call (sub {
$ret = $class -> req_evaluate ($params, $recurse + 1) ;
}) ;
return $ret ;
}
my $frame_ref = $params -> {frame_ref} - $recurse ;
my $package = $params -> {'package'} ;
my $expression = $params -> {'expression'} ;
my @vars ;
my $varsrc ;
lib/Perl/LanguageServer/DebuggerInterface.pm view on Meta::CPAN
}
# ---------------------------------------------------------------------------
sub req_threads
{
my @threads ;
if (defined &Coro::State::list)
{
foreach my $coro (Coro::State::list())
{
push @threads,
{
name => $coro->debug_desc,
thread_ref => $coro+0,
} ;
}
}
else
{
@threads = { thread_ref => 1, name => 'single'} ;
}
return { threads => \@threads } ;
}
# ---------------------------------------------------------------------------
sub find_coro
{
my ($class, $pid) = @_;
return if (!defined &Coro::State::list) ;
if (my ($coro) = grep ($_ == $pid, Coro::State::list()))
{
return $coro ;
}
else
{
$class -> logger ("$pid: no such coroutine\n") ;
}
return ;
}
# ---------------------------------------------------------------------------
sub req_stack
{
my ($class, $params, $recurse) = @_ ;
my $thread_ref = $params -> {thread_ref} ;
my $tid = defined ($Coro::current)?$Coro::current+0:1 ;
if ($thread_ref != $tid && !$recurse)
{
my $coro ;
$coro = $class -> find_coro ($thread_ref) ;
return { stackFrames => [] } if (!$coro) ;
my $ret ;
$coro -> call (sub {
$ret = $class -> req_stack ($params, 1) ;
}) ;
return $ret ;
}
my $levels = $params -> {levels} || 999 ;
my $start_frame = $params -> {start} || 0 ;
$start_frame += 3 ;
my @stack ;
{