summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-03-17 03:01:42 +0000
committerNorbert Preining <norbert@preining.info>2024-03-17 03:01:42 +0000
commit55140d5421e1ad0024c9acbfa72bd06402c2aa9f (patch)
treeb6c0d76888f025b58f1221d8dadbefb0264e9f6c /support
parent966f9ba332e49c29e961cb86e08f97d70eda51f6 (diff)
CTAN sync 202403170301
Diffstat (limited to 'support')
-rw-r--r--support/latexindent/LatexIndent/BackUpFileProcedure.pm18
-rw-r--r--support/latexindent/LatexIndent/Document.pm30
-rw-r--r--support/latexindent/LatexIndent/FileExtension.pm27
-rw-r--r--support/latexindent/LatexIndent/GetYamlSettings.pm17
-rw-r--r--support/latexindent/LatexIndent/LogFile.pm18
-rw-r--r--support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm209
-rw-r--r--support/latexindent/LatexIndent/Version.pm4
-rw-r--r--support/latexindent/README2
-rw-r--r--support/latexindent/bin/linux/latexindentbin6173561 -> 6464832 bytes
-rw-r--r--support/latexindent/bin/macos/latexindentbin6402796 -> 6448296 bytes
-rw-r--r--support/latexindent/defaultSettings.yaml2
-rw-r--r--support/latexindent/documentation/latexindent-yaml-schema.json2
-rw-r--r--support/latexindent/documentation/latexindent.pdfbin1280496 -> 1285393 bytes
-rwxr-xr-xsupport/latexindent/latexindent.pl48
-rw-r--r--support/texlab/CHANGELOG.md28
-rw-r--r--support/texlab/Cargo.lock223
-rw-r--r--support/texlab/crates/base-db/Cargo.toml2
-rw-r--r--support/texlab/crates/base-db/src/document.rs1
-rw-r--r--support/texlab/crates/base-db/src/semantics/bib.rs10
-rw-r--r--support/texlab/crates/base-db/src/workspace.rs13
-rw-r--r--support/texlab/crates/bibtex-utils/src/field.rs5
-rw-r--r--support/texlab/crates/bibtex-utils/src/field/author.rs6
-rw-r--r--support/texlab/crates/bibtex-utils/src/field/date.rs6
-rw-r--r--support/texlab/crates/bibtex-utils/src/field/number.rs6
-rw-r--r--support/texlab/crates/bibtex-utils/src/field/text.rs46
-rw-r--r--support/texlab/crates/citeproc/Cargo.toml1
-rw-r--r--support/texlab/crates/citeproc/src/driver.rs5
-rw-r--r--support/texlab/crates/citeproc/src/entry.rs34
-rw-r--r--support/texlab/crates/citeproc/src/lib.rs5
-rw-r--r--support/texlab/crates/citeproc/src/tests.rs8
-rw-r--r--support/texlab/crates/commands/Cargo.toml8
-rw-r--r--support/texlab/crates/completion-data/Cargo.toml2
-rw-r--r--support/texlab/crates/completion/Cargo.toml2
-rw-r--r--support/texlab/crates/diagnostics/Cargo.toml4
-rw-r--r--support/texlab/crates/diagnostics/src/citations.rs24
-rw-r--r--support/texlab/crates/diagnostics/src/labels.rs25
-rw-r--r--support/texlab/crates/diagnostics/src/manager.rs43
-rw-r--r--support/texlab/crates/diagnostics/src/tests.rs2
-rw-r--r--support/texlab/crates/distro/src/file_name_db.rs5
-rw-r--r--support/texlab/crates/hover/src/citation.rs2
-rw-r--r--support/texlab/crates/hover/src/string_ref.rs2
-rw-r--r--support/texlab/crates/parser/Cargo.toml2
-rw-r--r--support/texlab/crates/parser/src/config.rs28
-rw-r--r--support/texlab/crates/parser/src/latex.rs32
-rw-r--r--support/texlab/crates/parser/src/latex/lexer/commands.rs4
-rw-r--r--support/texlab/crates/parser/src/latex/tests.rs69
-rw-r--r--support/texlab/crates/texlab/Cargo.toml14
-rw-r--r--support/texlab/crates/texlab/src/client.rs10
-rw-r--r--support/texlab/crates/texlab/src/features/completion.rs16
-rw-r--r--support/texlab/crates/texlab/src/server.rs2
-rw-r--r--support/texlab/crates/texlab/src/server/options.rs6
-rw-r--r--support/texlab/texlab.16
-rw-r--r--support/texlab/texlab.pdfbin26470 -> 26407 bytes
53 files changed, 823 insertions, 261 deletions
diff --git a/support/latexindent/LatexIndent/BackUpFileProcedure.pm b/support/latexindent/LatexIndent/BackUpFileProcedure.pm
index 7828c44be3..f88304fc6c 100644
--- a/support/latexindent/LatexIndent/BackUpFileProcedure.pm
+++ b/support/latexindent/LatexIndent/BackUpFileProcedure.pm
@@ -26,6 +26,10 @@ use Exporter qw/import/;
use Encode qw/decode/;
our @EXPORT_OK = qw/create_back_up_file check_if_different/;
+use LatexIndent::UTF8CmdLineArgsFileOperation
+ qw/copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode/;
+use utf8;
+
# copy main file to a backup in the case of the overwrite switch being active
sub create_back_up_file {
@@ -36,7 +40,7 @@ sub create_back_up_file {
# if we want to overwrite the current file create a backup first
$logger->info("*Backup procedure (-w flag active):");
- my $fileName = decode( "utf-8", ${$self}{fileName} );
+ my $fileName = ${$self}{fileName};
# grab the file extension preferences
my %fileExtensionPreference = %{ $mainSettings{fileExtensionPreference} };
@@ -49,7 +53,7 @@ sub create_back_up_file {
my $backupFileNoExt = basename( ${$self}{fileName}, @fileExtensions );
# add the user's backup directory to the backup path
- $backupFileNoExt = decode( "utf-8", "${$self}{cruftDirectory}/$backupFileNoExt" );
+ $backupFileNoExt = "${$self}{cruftDirectory}/$backupFileNoExt";
# local variables, determined from the YAML settings
my $onlyOneBackUp = $mainSettings{onlyOneBackUp};
@@ -74,7 +78,7 @@ sub create_back_up_file {
# if the file already exists, increment the number until either
# the file does not exist, or you reach the maximal number of backups
- while ( -e ( $backupFile . $backupCounter ) and $backupCounter != ( $maxNumberOfBackUps - 1 ) ) {
+ while ( exist_with_encode( $backupFile . $backupCounter ) and $backupCounter != ( $maxNumberOfBackUps - 1 ) ) {
$logger->info("$backupFile$backupCounter already exists, incrementing by 1 (see maxNumberOfBackUps)");
$backupCounter++;
}
@@ -83,7 +87,7 @@ sub create_back_up_file {
# if the backup file already exists, output some information in the log file
# and proceed to cycleThroughBackUps if the latter is set
- if ( -e $backupFile ) {
+ if ( exist_with_encode($backupFile) ) {
if ($onlyOneBackUp) {
$logger->info("$backupFile will be overwritten (see onlyOneBackUp)");
}
@@ -105,9 +109,9 @@ sub create_back_up_file {
$newBackupFile = $backupFileNoExt . $backupExtension . ( $i - 1 );
# check that the oldBackupFile exists
- if ( -e $oldBackupFile ) {
+ if ( exist_with_encode($oldBackupFile) ) {
$logger->info("Copying $oldBackupFile to $newBackupFile...");
- if ( !( copy( $oldBackupFile, $newBackupFile ) ) ) {
+ if ( !( copy_with_encode( $oldBackupFile, $newBackupFile ) ) ) {
$logger->fatal("*Could not write to backup file $newBackupFile. Please check permissions.");
$logger->fatal("Exiting, no indentation done.");
$self->output_logfile();
@@ -122,7 +126,7 @@ sub create_back_up_file {
# output these lines to the log file
$logger->info("Backing up $fileName to $backupFile...");
$logger->info("$fileName will be overwritten after indentation");
- if ( !( copy( $fileName, $backupFile ) ) ) {
+ if ( !( copy_with_encode( $fileName, $backupFile ) ) ) {
$logger->fatal("*Could not write to backup file $backupFile. Please check permissions.");
$logger->fatal("Exiting, no indentation done.");
$self->output_logfile();
diff --git a/support/latexindent/LatexIndent/Document.pm b/support/latexindent/LatexIndent/Document.pm
index 04c8e638dc..b6d2fa582a 100644
--- a/support/latexindent/LatexIndent/Document.pm
+++ b/support/latexindent/LatexIndent/Document.pm
@@ -19,7 +19,8 @@ use strict;
use warnings;
use Data::Dumper;
use File::Basename; # to get the filename and directory path
-use open ':std', ':encoding(UTF-8)';
+
+#use open ':std', ':encoding(UTF-8)';
use Encode qw/decode/;
# gain access to subroutines in the following modules
@@ -73,6 +74,10 @@ use LatexIndent::Heading qw/find_heading construct_headings_levels $allHead
use LatexIndent::FileContents qw/find_file_contents_environments_and_preamble/;
use LatexIndent::Preamble;
+use LatexIndent::UTF8CmdLineArgsFileOperation
+ qw/copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode/;
+use utf8;
+
sub new {
# Create new objects, with optional key/value pairs
@@ -98,7 +103,7 @@ sub latexindent {
# one-time operations
$self->store_switches;
- ${$self}{fileName} = decode( "utf-8", $fileNames[0] );
+ ${$self}{fileName} = $fileNames[0];
$self->process_switches( \@fileNames );
$self->yaml_read_settings;
@@ -231,19 +236,18 @@ sub output_indented_text {
if ( ${$self}{overwrite} ) {
# diacritics in file names (highlighted in https://github.com/cmhughes/latexindent.pl/pull/439)
- ${$self}{fileName} = decode( "utf-8", ${$self}{fileName} );
+ ${$self}{fileName} = ${$self}{fileName};
$logger->info("Overwriting file ${$self}{fileName}");
- open( OUTPUTFILE, ">", ${$self}{fileName} );
- print OUTPUTFILE ${$self}{body};
- close(OUTPUTFILE);
+ my $OUTPUTFILE = open_with_encode( '>:encoding(UTF-8)', ${$self}{fileName} );
+ print $OUTPUTFILE ${$self}{body};
+ close($OUTPUTFILE);
}
elsif ( $switches{outputToFile} ) {
-
$logger->info("Outputting to file ${$self}{outputToFile}");
- open( OUTPUTFILE, ">", ${$self}{outputToFile} );
- print OUTPUTFILE ${$self}{body};
- close(OUTPUTFILE);
+ my $OUTPUTFILE = open_with_encode( '>:encoding(UTF-8)', ${$self}{outputToFile} );
+ print $OUTPUTFILE ${$self}{body};
+ close($OUTPUTFILE);
}
else {
$logger->info("Not outputting to file; see -w and -o switches for more options.");
@@ -268,10 +272,10 @@ sub output_logfile {
if ${ $mainSettings{logFilePreferences} }{showGitHubInfoFooter};
# open log file
- my $logfileName = $switches{logFileName} || "indent.log";
- my $logfile;
+ my $logfileName = $switches{logFileName} || "indent.log";
my $logfilePossible = 1;
- open( $logfile, ">", "${$self}{cruftDirectory}/$logfileName" ) or $logfilePossible = 0;
+ my $logfile = open_with_encode( '>:encoding(UTF-8)', "${$self}{cruftDirectory}/$logfileName" )
+ or $logfilePossible = 0;
if ($logfilePossible) {
foreach my $line ( @{LatexIndent::Logger::logFileLines} ) {
diff --git a/support/latexindent/LatexIndent/FileExtension.pm b/support/latexindent/LatexIndent/FileExtension.pm
index bd909b2f60..64b5f0a37e 100644
--- a/support/latexindent/LatexIndent/FileExtension.pm
+++ b/support/latexindent/LatexIndent/FileExtension.pm
@@ -18,7 +18,8 @@ package LatexIndent::FileExtension;
use strict;
use warnings;
use PerlIO::encoding;
-use open ':std', ':encoding(UTF-8)';
+
+#use open ':std', ':encoding(UTF-8)';
use File::Basename; # to get the filename and directory path
use Exporter qw/import/;
use Encode qw/decode/;
@@ -27,6 +28,10 @@ use LatexIndent::Switches qw/%switches $is_check_switch_active/;
use LatexIndent::LogFile qw/$logger/;
our @EXPORT_OK = qw/file_extension_check/;
+use LatexIndent::UTF8CmdLineArgsFileOperation
+ qw/copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode/;
+use utf8;
+
sub file_extension_check {
my $self = shift;
@@ -59,7 +64,7 @@ sub file_extension_check {
# loop through the known file extensions (see @fileExtensions)
foreach (@fileExtensions) {
- if ( -e $fileName . $_ ) {
+ if ( exist_with_encode( $fileName . $_ ) ) {
$logger->info("$fileName$_ found!");
$fileName .= $_;
$logger->info("Updated fileName to $fileName");
@@ -91,7 +96,7 @@ sub file_extension_check {
}
else {
# if the file has a recognised extension, check that the file exists
- unless ( -e $fileName ) {
+ unless ( exist_with_encode($fileName) ) {
if ( defined ${$self}{multipleFiles} ) {
$logger->warn("*I couldn't find $fileName, are you sure it exists?");
$logger->warn("moving on, no indentation done for ${$self}{fileName}.");
@@ -120,7 +125,7 @@ sub file_extension_check {
# note, related:
#
# git config --add core.quotePath false
- ${$self}{outputToFile} = decode( "utf-8", $switches{outputToFile} );
+ ${$self}{outputToFile} = $switches{outputToFile};
if ( $fileName eq "-" and $switches{outputToFile} =~ m/^\+/ ) {
$logger->info("STDIN input mode active, -o switch is removing all + symbols");
@@ -130,7 +135,7 @@ sub file_extension_check {
# the -o file name might begin with a + symbol
if ( $switches{outputToFile} =~ m/^\+(.*)/ and $1 ne "+" ) {
$logger->info("-o switch called with + symbol at the beginning: ${$self}{outputToFile}");
- ${$self}{outputToFile} = decode( "utf-8", ${$self}{baseName} . $1 );
+ ${$self}{outputToFile} = ${$self}{baseName} . $1;
$logger->info("output file is now: ${$self}{outputToFile}");
}
@@ -143,9 +148,9 @@ sub file_extension_check {
# if there is no extension, then add the extension from the file to be operated upon
if ( !$ext ) {
- $logger->info(
- "-o switch called with file name without extension: " . decode( "utf-8", $switches{outputToFile} ) );
+ $logger->info( "-o switch called with file name without extension: " . $switches{outputToFile} );
${$self}{outputToFile} = $name . ( $name =~ m/\.\z/ ? q() : "." ) . $strippedFileExtension;
+
$logger->info(
"Updated to ${$self}{outputToFile} as the file extension of the input file is $strippedFileExtension");
}
@@ -160,7 +165,7 @@ sub file_extension_check {
my $outputFileCounter = 0;
my $fileName = $name . $outputFileCounter . "." . $strippedFileExtension;
$logger->info("will search for existence and increment counter, starting with $fileName");
- while ( -e $fileName ) {
+ while ( exist_with_encode($fileName) ) {
$logger->info("$fileName exists, incrementing counter");
$outputFileCounter++;
$fileName = $name . $outputFileCounter . "." . $strippedFileExtension;
@@ -174,7 +179,7 @@ sub file_extension_check {
my @lines;
if ( $fileName ne "-" ) {
my $openFilePossible = 1;
- open( MAINFILE, $fileName ) or ( $openFilePossible = 0 );
+ my $MAINFILE = open_with_encode( '<:encoding(UTF-8)', $fileName ) or ( $openFilePossible = 0 );
if ( $openFilePossible == 0 ) {
if ( defined ${$self}{multipleFiles} ) {
$logger->warn("*$fileName exists, but could not open it");
@@ -188,8 +193,8 @@ sub file_extension_check {
exit(4);
}
}
- push( @lines, $_ ) while (<MAINFILE>);
- close(MAINFILE);
+ push( @lines, $_ ) while (<$MAINFILE>);
+ close($MAINFILE);
}
else {
push( @lines, $_ ) while (<>);
diff --git a/support/latexindent/LatexIndent/GetYamlSettings.pm b/support/latexindent/LatexIndent/GetYamlSettings.pm
index 7f3f507076..9e5ff7a853 100644
--- a/support/latexindent/LatexIndent/GetYamlSettings.pm
+++ b/support/latexindent/LatexIndent/GetYamlSettings.pm
@@ -34,6 +34,10 @@ our $defaultSettings;
# master yaml settings is a hash, global to this module
our %mainSettings;
+use LatexIndent::UTF8CmdLineArgsFileOperation
+ qw/copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode/;
+use utf8;
+
# previously found settings is a hash, global to this module
our %previouslyFoundSettings;
@@ -344,14 +348,15 @@ sub yaml_read_settings {
}
# diacritics in YAML names (highlighted in https://github.com/cmhughes/latexindent.pl/pull/439)
- $_ = decode( "utf-8", $_ );
+ #$_ = decode( "utf-8", $_ );
+ $_ = $_;
# check for existence and non-emptiness
- if ( ( -e $_ ) and !( -z $_ ) ) {
+ if ( exist_with_encode($_) and !( zero_with_encode($_) ) ) {
$logger->info("Adding $_ to YAML read paths");
push( @absPaths, "$_" );
}
- elsif ( !( -e $_ ) ) {
+ elsif ( !( exist_with_encode($_) ) ) {
if (( $_ =~ m/localSettings|latexindent/s
and !( -e 'localSettings.yaml' )
and !( -e '.localSettings.yaml' )
@@ -373,9 +378,9 @@ sub yaml_read_settings {
foreach my $settings (@absPaths) {
# check that the settings file exists and that it isn't empty
- if ( -e $settings and !( -z $settings ) ) {
+ if ( exist_with_encode($settings) and !( zero_with_encode($settings) ) ) {
$logger->info("Reading USER settings from $settings");
- $userSettings = YAML::Tiny->read("$settings");
+ $userSettings = read_yaml_with_encode("$settings");
# if we can read userSettings
if ($userSettings) {
@@ -513,7 +518,7 @@ sub yaml_read_settings {
else {
# otherwise keep going, but put a warning in the log file
$logger->warn("*$homeDir/indentconfig.yaml");
- if ( -z $settings ) {
+ if ( zero_with_encode($settings) ) {
$logger->info("specifies $settings but this file is EMPTY -- not reading from it");
}
else {
diff --git a/support/latexindent/LatexIndent/LogFile.pm b/support/latexindent/LatexIndent/LogFile.pm
index b72655b686..7418f1024c 100644
--- a/support/latexindent/LatexIndent/LogFile.pm
+++ b/support/latexindent/LatexIndent/LogFile.pm
@@ -27,6 +27,12 @@ use Encode qw/decode/;
our @EXPORT_OK = qw/process_switches $logger/;
our $logger;
+use utf8;
+binmode( STDOUT, ":encoding(utf8)" );
+
+use LatexIndent::UTF8CmdLineArgsFileOperation
+ qw/copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode isdir_with_encode mkdir_with_encode/;
+
sub process_switches {
# -v switch is just to show the version number
@@ -133,10 +139,10 @@ ENDQUOTE
my $cruftDirectoryCreation = 0;
# if cruft directory does not exist, create it
- if ( !( -d ${$self}{cruftDirectory} ) ) {
- eval { make_path( ${$self}{cruftDirectory} ) };
+ if ( !( isdir_with_encode( ${$self}{cruftDirectory} ) ) ) {
+ eval { mkdir_with_encode( ${$self}{cruftDirectory} ) };
if ($@) {
- $logger->fatal( "*Could not create cruft directory " . decode( "utf-8", ${$self}{cruftDirectory} ) );
+ $logger->fatal( "*Could not create cruft directory " . ${$self}{cruftDirectory} );
$logger->fatal("Exiting, no indentation done.");
$self->output_logfile();
exit(6);
@@ -147,7 +153,7 @@ ENDQUOTE
my $logfileName = ( $switches{cruftDirectory} ? ${$self}{cruftDirectory} . "/" : '' )
. ( $switches{logFileName} || "indent.log" );
- $logfileName = decode( "utf-8", $logfileName );
+ $logfileName = $logfileName;
# details of the script to log file
$logger->info("*$FindBin::Script version $versionNumber, $versionDate, a script to indent .tex files");
@@ -204,6 +210,8 @@ ENDQUOTE
$logger->info("-c|--cruft: cruft directory") if ( $switches{cruftDirectory} );
$logger->info("-r|--replacement: replacement mode") if ( $switches{replacement} );
$logger->info("-rr|--onlyreplacement: *only* replacement mode, no indentation") if ( $switches{onlyreplacement} );
+ $logger->info("-rv|--replacementrespectverb replacement mode, respecting verbatim")
+ if ( $switches{replacementRespectVerb} );
$logger->info("-k|--check mode: will exit with 0 if document body unchanged, 1 if changed") if ( $switches{check} );
$logger->info("-kv|--check mode verbose: as in check mode, but outputs diff to screen")
if ( $switches{checkverbose} );
@@ -253,7 +261,7 @@ ENDQUOTE
}
$logger->info("*Directory for backup files and $logfileName:");
- $logger->info( $switches{cruftDirectory} ? decode( "utf-8", ${$self}{cruftDirectory} ) : ${$self}{cruftDirectory} );
+ $logger->info( $switches{cruftDirectory} ? ${$self}{cruftDirectory} : ${$self}{cruftDirectory} );
$logger->info("cruft directory creation: ${$self}{cruftDirectory}") if $cruftDirectoryCreation;
# output location of modules
diff --git a/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm b/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm
new file mode 100644
index 0000000000..a2ba0b1d2f
--- /dev/null
+++ b/support/latexindent/LatexIndent/UTF8CmdLineArgsFileOperation.pm
@@ -0,0 +1,209 @@
+package LatexIndent::UTF8CmdLineArgsFileOperation;
+
+use strict;
+use warnings;
+use feature qw( say state );
+use utf8;
+use Config qw( %Config );
+use Encode qw( decode encode );
+
+use Exporter qw/import/;
+our @EXPORT_OK
+ = qw/commandlineargs_with_encode @new_args copy_with_encode exist_with_encode open_with_encode zero_with_encode read_yaml_with_encode isdir_with_encode mkdir_with_encode/;
+
+sub copy_with_encode {
+ use File::Copy;
+ my ( $source, $destination ) = @_;
+
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::Unicode::File;
+ Win32::Unicode::File->import(qw(copyW));
+ copyW( $source, $destination, 1 );
+ }
+ else {
+ copy( $source, $destination );
+ }
+}
+
+sub exist_with_encode {
+ my ($filename) = @_;
+
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::Unicode::File;
+ Win32::Unicode::File->import(qw(statW));
+ return statW($filename);
+ }
+ else {
+ return -e $filename;
+ }
+}
+
+sub zero_with_encode {
+ my ($filename) = @_;
+
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::Unicode::File;
+ Win32::Unicode::File->import(qw(file_size));
+ my $size = file_size($filename);
+ if ($size) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+ else {
+ return -z $filename;
+ }
+}
+
+sub open_with_encode {
+ my $mode = shift;
+ my $filename = shift;
+ my $fh;
+
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::Unicode::File;
+ Win32::Unicode::File->import;
+ $fh = Win32::Unicode::File->new;
+ open $fh, $mode, $filename or die "Can't open file: $!";
+ return $fh;
+ }
+ else {
+ open( $fh, $mode, $filename ) or die "Can't open file: $!";
+ return $fh;
+ }
+}
+
+sub read_yaml_with_encode {
+ use YAML::Tiny;
+ my $filename = shift;
+
+ my $fh = open_with_encode( '<:encoding(UTF-8)', $filename ) or die $!;
+ my $yaml_string = join( "", <$fh> );
+ return YAML::Tiny->read_string($yaml_string);
+}
+
+sub isdir_with_encode {
+ my $path = shift;
+
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::Unicode::File;
+ Win32::Unicode::File->import(qw(file_type));
+
+ return file_type( 'd', $path );
+ }
+ else {
+ return -d $path;
+ }
+}
+
+sub mkdir_with_encode {
+ my $path = shift;
+
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::Unicode::Dir;
+ Win32::Unicode::Dir->import(qw(mkdirW));
+
+ mkdirW($path) or die "Cannot create directory $path: $!";
+ }
+ else {
+ require File::Path;
+ File::Path->import(qw(make_path));
+
+ my $created = make_path($path);
+ die "Cannot create directory $path" unless $created;
+ }
+}
+
+#https://stackoverflow.com/a/63868721
+#https://stackoverflow.com/a/44489228
+sub commandlineargs_with_encode {
+ if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32::API;
+ import Win32::API qw( ReadMemory );
+
+ #use open ':std', ':encoding('.do { require Win32; "cp".Win32::GetConsoleOutputCP() }.')';
+
+ use constant ptr_size => $Config{ptrsize};
+
+ use constant ptr_pack_format => ptr_size == 8 ? 'Q'
+ : ptr_size == 4 ? 'L'
+ : die("Unrecognized ptrsize\n");
+
+ use constant ptr_win32api_type => ptr_size == 8 ? 'Q'
+ : ptr_size == 4 ? 'N'
+ : die("Unrecognized ptrsize\n");
+
+ sub lstrlenw {
+ my ($ptr) = @_;
+
+ state $lstrlenw = Win32::API->new( 'kernel32', 'lstrlenW', ptr_win32api_type, 'i' )
+ or die($^E);
+
+ return $lstrlenw->Call($ptr);
+ }
+
+ sub decode_lpcwstr {
+ my ($ptr) = @_;
+ return undef if !$ptr;
+
+ my $num_chars = lstrlenw($ptr)
+ or return '';
+
+ return decode( 'UTF-16le', ReadMemory( $ptr, $num_chars * 2 ) );
+ }
+
+ # Returns true on success. Returns false and sets $^E on error.
+ sub localfree {
+ my ($ptr) = @_;
+
+ state $localfree = Win32::API->new( 'kernel32', 'LocalFree', ptr_win32api_type, ptr_win32api_type )
+ or die($^E);
+
+ return $localfree->Call($ptr) == 0;
+ }
+
+ sub getcommandline {
+ state $getcommandline = Win32::API->new( 'kernel32', 'GetCommandLineW', '', ptr_win32api_type )
+ or die($^E);
+
+ return decode_lpcwstr( $getcommandline->Call() );
+ }
+
+ # Returns a reference to an array on success. Returns undef and sets $^E on error.
+ sub commandlinetoargv {
+ my ($cmd_line) = @_;
+
+ state $commandlinetoargv = Win32::API->new( 'shell32', 'CommandLineToArgvW', 'PP', ptr_win32api_type )
+ or die($^E);
+
+ my $cmd_line_encoded = encode( 'UTF-16le', $cmd_line . "\0" );
+ my $num_args_buf = pack( 'i', 0 ); # Allocate space for an "int".
+
+ my $arg_ptrs_ptr = $commandlinetoargv->Call( $cmd_line_encoded, $num_args_buf )
+ or return undef;
+
+ my $num_args = unpack( 'i', $num_args_buf );
+ my @args = map { decode_lpcwstr($_) } unpack ptr_pack_format . '*',
+ ReadMemory( $arg_ptrs_ptr, ptr_size * $num_args );
+
+ localfree($arg_ptrs_ptr);
+ return \@args;
+ }
+
+ my $cmd_line = getcommandline();
+ our @new_args = $cmd_line;
+ $cmd_line =~ s/(^(.*?)\.pl\"? )//g;
+ $cmd_line =~ s/(^(.*?)\.exe\"? )//g;
+ my $args = commandlinetoargv($cmd_line) or die("CommandLineToArgv: $^E\n");
+ @ARGV = @{$args};
+ }
+ else {
+ my $encodingObject = "utf-8";
+ @ARGV = map { decode( $encodingObject, $_ ) } @ARGV;
+ our @new_args = @ARGV;
+ }
+}
+
+1;
diff --git a/support/latexindent/LatexIndent/Version.pm b/support/latexindent/LatexIndent/Version.pm
index f56a438ec0..5da34c49b7 100644
--- a/support/latexindent/LatexIndent/Version.pm
+++ b/support/latexindent/LatexIndent/Version.pm
@@ -20,6 +20,6 @@ use warnings;
use Exporter qw/import/;
our @EXPORT_OK = qw/$versionNumber $versionDate/;
-our $versionNumber = '3.23.6';
-our $versionDate = '2024-01-17';
+our $versionNumber = '3.23.7';
+our $versionDate = '2024-03-16';
1
diff --git a/support/latexindent/README b/support/latexindent/README
index 9a21dd77ce..c1336ed578 100644
--- a/support/latexindent/README
+++ b/support/latexindent/README
@@ -1,5 +1,5 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- latexindent.pl, version 3.23.6, 2024-01-17
+ latexindent.pl, version 3.23.7, 2024-03-16
PERL script to indent code within environments, and align delimited
environments in .tex files.
diff --git a/support/latexindent/bin/linux/latexindent b/support/latexindent/bin/linux/latexindent
index 831e122a92..1932df3381 100644
--- a/support/latexindent/bin/linux/latexindent
+++ b/support/latexindent/bin/linux/latexindent
Binary files differ
diff --git a/support/latexindent/bin/macos/latexindent b/support/latexindent/bin/macos/latexindent
index ad7ab51add..150f294502 100644
--- a/support/latexindent/bin/macos/latexindent
+++ b/support/latexindent/bin/macos/latexindent
Binary files differ
diff --git a/support/latexindent/defaultSettings.yaml b/support/latexindent/defaultSettings.yaml
index a00474e143..221bdb6b5d 100644
--- a/support/latexindent/defaultSettings.yaml
+++ b/support/latexindent/defaultSettings.yaml
@@ -1,5 +1,5 @@
#
-# latexindent.pl, version 3.23.6, 2024-01-17
+# latexindent.pl, version 3.23.7, 2024-03-16
#
# defaultSettings.yaml, the default settings for latexindent.pl
#
diff --git a/support/latexindent/documentation/latexindent-yaml-schema.json b/support/latexindent/documentation/latexindent-yaml-schema.json
index 0bb03ddc43..9d6102987c 100644
--- a/support/latexindent/documentation/latexindent-yaml-schema.json
+++ b/support/latexindent/documentation/latexindent-yaml-schema.json
@@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/schema",
"$id": "latexindent-yaml-schema.json",
"title": "latexindent.pl YAML schema",
- "description": "latexindent.pl YAML schema helper, V3.23.6 2024-01-17",
+ "description": "latexindent.pl YAML schema helper, V3.23.7 2024-03-16",
"type": "object",
"properties": {
"fileExtensionPreference": {
diff --git a/support/latexindent/documentation/latexindent.pdf b/support/latexindent/documentation/latexindent.pdf
index fe0fa82176..4029dee3cd 100644
--- a/support/latexindent/documentation/latexindent.pdf
+++ b/support/latexindent/documentation/latexindent.pdf
Binary files differ
diff --git a/support/latexindent/latexindent.pl b/support/latexindent/latexindent.pl
index e5c034dd77..dbb083cc48 100755
--- a/support/latexindent/latexindent.pl
+++ b/support/latexindent/latexindent.pl
@@ -1,6 +1,6 @@
#!/usr/bin/env perl
#
-# latexindent.pl, version 3.23.6, 2024-01-17
+# latexindent.pl, version 3.23.7, 2024-03-16
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -27,6 +27,16 @@ use Getopt::Long; # to get the switches/options/flags
use lib $FindBin::RealBin;
use LatexIndent::Document;
+use utf8;
+use Encode qw/ encode decode find_encoding /;
+
+use LatexIndent::LogFile qw/$logger/;
+use LatexIndent::UTF8CmdLineArgsFileOperation
+ qw/commandlineargs_with_encode @new_args/;
+
+commandlineargs_with_encode();
+my $commandlineargs = join( ", ", @ARGV );
+
# get the options
my %switches = ( readLocalSettings => 0 );
@@ -56,6 +66,34 @@ GetOptions(
"GCString" => \$switches{GCString},
);
+$logger = LatexIndent::Logger->new();
+our $consoleoutcp;
+if ( $FindBin::Script eq 'latexindent.exe' ) {
+ require Win32;
+ import Win32;
+
+ my $encoding_sys = Win32::GetACP()
+ ; #https://stackoverflow.com/a/63868721HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
+ $consoleoutcp = Win32::GetConsoleOutputCP();
+ Win32::SetConsoleOutputCP(65001);
+
+ $logger->info("*ANSI Code Page: $encoding_sys");
+ if ( $switches{screenlog} ) {
+ print "INFO: ANSI Code Page: $encoding_sys\n"
+ ; #The values of ACP in the registry
+ print "INFO: Current console output code page: $consoleoutcp \n";
+ print "INFO: Change the current console output code page to 65001\n";
+ }
+}
+
+if ( $switches{screenlog} ) {
+ $logger->info("*Command line:");
+ $logger->info("@new_args");
+ $logger->info( "Command line arguments:\n" . $commandlineargs );
+ print "INFO: Command line:\n @new_args\n";
+ print " Command line arguments:\n " . $commandlineargs . "\n\n";
+}
+
# conditionally load the GCString module
eval "use Unicode::GCString" if $switches{GCString};
@@ -86,4 +124,12 @@ my $document = bless(
"LatexIndent::Document"
);
$document->latexindent( \@ARGV );
+
+if ( $FindBin::Script eq 'latexindent.exe' ) {
+ Win32::SetConsoleOutputCP($consoleoutcp);
+ if ( $switches{screenlog} ) {
+ print
+ "\n\nINFO: Restore the console output code page: $consoleoutcp\n";
+ }
+}
exit(0);
diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md
index 928eb0c10b..fdf40bd102 100644
--- a/support/texlab/CHANGELOG.md
+++ b/support/texlab/CHANGELOG.md
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [5.13.1] - 2024-03-16
+
+### Fixed
+
+- Fix clearing stale diagnostics reported by the server ([#1042](https://github.com/latex-lsp/texlab/issues/1042))
+- Speed up reading bibliographies with many string definitions ([#1039](https://github.com/latex-lsp/texlab/pull/1039))
+
+## [5.13.0] - 2024-03-10
+
+### Added
+
+- Add experimental `texlab.experimental.labelReferenceCommands` setting to customize the list of `\ref`-like commands
+ ([#1032](https://github.com/latex-lsp/texlab/issues/1032))
+
+### Fixed
+
+- Don't report diagnostics for files that are part of the TeX distro ([#1028](https://github.com/latex-lsp/texlab/issues/1028))
+
+## [5.12.4] - 2024-02-22
+
+### Fixed
+
+- When `workspace/didChangeConfiguration` contains the configuration of multiple LSP servers, `texlab` will try
+ to extract the `texlab` configuration instead of falling back to the default settings
+ ([#1003](https://github.com/latex-lsp/texlab/issues/1003))
+- Keep filtering completion lists server-side if prefix matcher is set ([#1003](https://github.com/latex-lsp/texlab/issues/1003))
+- Allow brackets and parentheses in label names and similar constructs ([#1016](https://github.com/latex-lsp/texlab/issues/1016))
+
## [5.12.3] - 2024-01-27
### Fixed
diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock
index 64669f9f36..143c0137d7 100644
--- a/support/texlab/Cargo.lock
+++ b/support/texlab/Cargo.lock
@@ -25,9 +25,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstream"
-version = "0.6.4"
+version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
+checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -58,7 +58,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -68,7 +68,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
dependencies = [
"anstyle",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -150,9 +150,9 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "bstr"
-version = "1.8.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
+checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc"
dependencies = [
"memchr",
"regex-automata",
@@ -172,15 +172,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
-name = "cc"
-version = "1.0.83"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
-dependencies = [
- "libc",
-]
-
-[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -226,6 +217,7 @@ dependencies = [
name = "citeproc"
version = "0.0.0"
dependencies = [
+ "base-db",
"bibtex-utils",
"expect-test",
"isocountry",
@@ -241,9 +233,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.4.10"
+version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272"
+checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
dependencies = [
"clap_builder",
"clap_derive",
@@ -251,9 +243,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.4.9"
+version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1"
+checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
dependencies = [
"anstream",
"anstyle",
@@ -481,7 +473,7 @@ dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -524,23 +516,12 @@ dependencies = [
[[package]]
name = "errno"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
-dependencies = [
- "errno-dragonfly",
- "libc",
- "windows-sys",
-]
-
-[[package]]
-name = "errno-dragonfly"
-version = "0.1.2"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
- "cc",
"libc",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -555,9 +536,9 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.0.0"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
+checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "fern"
@@ -574,7 +555,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6584280525fb2059cba3db2c04abf947a1a29a45ddae89f3870f8281704fafc9"
dependencies = [
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -586,7 +567,7 @@ dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.3.5",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -770,7 +751,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi",
"rustix",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -850,9 +831,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.150"
+version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "line-index"
@@ -873,9 +854,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.4.11"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
@@ -889,9 +870,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.20"
+version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "logos"
@@ -939,9 +920,9 @@ dependencies = [
[[package]]
name = "lsp-types"
-version = "0.94.1"
+version = "0.95.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1"
+checksum = "158c1911354ef73e8fe42da6b10c0484cb65c7f1007f28022e847706c1ab6984"
dependencies = [
"bitflags 1.3.2",
"serde",
@@ -952,9 +933,9 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.6.3"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "memoffset"
@@ -976,21 +957,21 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.8.8"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
name = "multimap"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1a5d38b9b352dbd913288736af36af41c48d61b1a8cd34bcecd727561b7d511"
+checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
dependencies = [
"serde",
]
@@ -1011,7 +992,7 @@ dependencies = [
"log",
"mio",
"walkdir",
- "windows-sys",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1085,7 +1066,7 @@ dependencies = [
"libc",
"redox_syscall 0.3.5",
"smallvec",
- "windows-targets",
+ "windows-targets 0.48.5",
]
[[package]]
@@ -1209,9 +1190,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rayon"
-version = "1.8.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
+checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051"
dependencies = [
"either",
"rayon-core",
@@ -1219,9 +1200,9 @@ dependencies = [
[[package]]
name = "rayon-core"
-version = "1.12.0"
+version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
@@ -1246,15 +1227,6 @@ dependencies = [
]
[[package]]
-name = "redox_syscall"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
-dependencies = [
- "bitflags 1.3.2",
-]
-
-[[package]]
name = "redox_users"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1342,15 +1314,15 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
-version = "0.38.21"
+version = "0.38.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
+checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -1396,9 +1368,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.108"
+version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
+checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
@@ -1417,9 +1389,9 @@ dependencies = [
[[package]]
name = "serde_repr"
-version = "0.1.17"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
+checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
dependencies = [
"proc-macro2",
"quote",
@@ -1491,15 +1463,14 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.8.1"
+version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand",
- "redox_syscall 0.4.1",
"rustix",
- "windows-sys",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -1515,7 +1486,7 @@ dependencies = [
[[package]]
name = "texlab"
-version = "5.12.3"
+version = "5.13.1"
dependencies = [
"anyhow",
"base-db",
@@ -1570,18 +1541,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "thiserror"
-version = "1.0.56"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
+checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.56"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
+checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [
"proc-macro2",
"quote",
@@ -1817,7 +1788,16 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
- "windows-targets",
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.4",
]
[[package]]
@@ -1826,13 +1806,28 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.4",
+ "windows_aarch64_msvc 0.52.4",
+ "windows_i686_gnu 0.52.4",
+ "windows_i686_msvc 0.52.4",
+ "windows_x86_64_gnu 0.52.4",
+ "windows_x86_64_gnullvm 0.52.4",
+ "windows_x86_64_msvc 0.52.4",
]
[[package]]
@@ -1842,37 +1837,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
+
+[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
+
+[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
+name = "windows_i686_gnu"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
+
+[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
+name = "windows_i686_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
+
+[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
+
+[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
+
+[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml
index 0aceff8e5f..010c83d0e4 100644
--- a/support/texlab/crates/base-db/Cargo.toml
+++ b/support/texlab/crates/base-db/Cargo.toml
@@ -12,7 +12,7 @@ dirs = "5.0.1"
distro = { path = "../distro" }
itertools = "0.12.0"
line-index = { path = "../line-index" }
-log = "0.4.20"
+log = "0.4.21"
notify = "6.0.1"
once_cell = "1.19.0"
parser = { path = "../parser" }
diff --git a/support/texlab/crates/base-db/src/document.rs b/support/texlab/crates/base-db/src/document.rs
index 9f45876d7e..25607a1bf5 100644
--- a/support/texlab/crates/base-db/src/document.rs
+++ b/support/texlab/crates/base-db/src/document.rs
@@ -12,6 +12,7 @@ use crate::{semantics, Config};
pub enum Owner {
Client,
Server,
+ Distro,
}
#[derive(Debug)]
diff --git a/support/texlab/crates/base-db/src/semantics/bib.rs b/support/texlab/crates/base-db/src/semantics/bib.rs
index 14fa98fb6e..1a03fbb2c2 100644
--- a/support/texlab/crates/base-db/src/semantics/bib.rs
+++ b/support/texlab/crates/base-db/src/semantics/bib.rs
@@ -2,6 +2,7 @@ use bibtex_utils::field::text::TextFieldData;
use itertools::Itertools;
use rowan::{ast::AstNode, TextRange};
use syntax::bibtex::{self, HasName, HasType, HasValue};
+use rustc_hash::FxHashMap;
use crate::data::{BibtexEntryType, BibtexEntryTypeCategory};
@@ -11,6 +12,8 @@ use super::Span;
pub struct Semantics {
pub entries: Vec<Entry>,
pub strings: Vec<StringDef>,
+ /// Map from string definition keys to their expanded values.
+ pub expanded_defs: FxHashMap<String, String>,
}
impl Semantics {
@@ -32,7 +35,7 @@ impl Semantics {
let field_values = entry
.fields()
- .filter_map(|field| Some(TextFieldData::parse(&field.value()?)?.text));
+ .filter_map(|field| Some(TextFieldData::parse(&field.value()?, &self.expanded_defs)?.text));
let keywords = [name.text().into(), type_token.text().into()]
.into_iter()
@@ -60,6 +63,11 @@ impl Semantics {
},
full_range: string.syntax().text_range(),
});
+ if let Some(value) = string.value() {
+ if let Some(data) = TextFieldData::parse(&value, &self.expanded_defs) {
+ self.expanded_defs.insert(name.text().into(), data.text);
+ }
+ }
}
}
}
diff --git a/support/texlab/crates/base-db/src/workspace.rs b/support/texlab/crates/base-db/src/workspace.rs
index 330ed5a493..0fe347f1b3 100644
--- a/support/texlab/crates/base-db/src/workspace.rs
+++ b/support/texlab/crates/base-db/src/workspace.rs
@@ -67,7 +67,7 @@ impl Workspace {
}));
}
- pub fn load(&mut self, path: &Path, language: Language, owner: Owner) -> std::io::Result<()> {
+ pub fn load(&mut self, path: &Path, language: Language) -> std::io::Result<()> {
log::debug!("Loading document {} from disk...", path.display());
let uri = Url::from_file_path(path).unwrap();
let data = std::fs::read(path)?;
@@ -76,6 +76,12 @@ impl Workspace {
Cow::Owned(text) => text,
};
+ let owner = if self.distro.file_name_db.contains(&path) {
+ Owner::Distro
+ } else {
+ Owner::Server
+ };
+
if let Some(document) = self.lookup_path(path) {
if document.text == text {
return Ok(());
@@ -329,7 +335,7 @@ impl Workspace {
}
if self.lookup_path(&file).is_none() && file.exists() {
- changed |= self.load(&file, lang, Owner::Server).is_ok();
+ changed |= self.load(&file, lang).is_ok();
checked_paths.insert(file);
}
}
@@ -350,8 +356,9 @@ impl Workspace {
let mut changed = false;
for file in files {
let language = Language::from_path(&file).unwrap_or(Language::Tex);
+
if self.lookup_path(&file).is_none() && file.exists() {
- changed |= self.load(&file, language, Owner::Server).is_ok();
+ changed |= self.load(&file, language).is_ok();
checked_paths.insert(file);
}
}
diff --git a/support/texlab/crates/bibtex-utils/src/field.rs b/support/texlab/crates/bibtex-utils/src/field.rs
index d9f3adacab..71bd25f6d0 100644
--- a/support/texlab/crates/bibtex-utils/src/field.rs
+++ b/support/texlab/crates/bibtex-utils/src/field.rs
@@ -1,4 +1,9 @@
+use rustc_hash::FxHashMap;
+
pub mod author;
pub mod date;
pub mod number;
pub mod text;
+
+/// A cache used to accelerate related field parses.
+pub type FieldParseCache = FxHashMap<String, String>; \ No newline at end of file
diff --git a/support/texlab/crates/bibtex-utils/src/field/author.rs b/support/texlab/crates/bibtex-utils/src/field/author.rs
index d8576cbaa4..4be999efbd 100644
--- a/support/texlab/crates/bibtex-utils/src/field/author.rs
+++ b/support/texlab/crates/bibtex-utils/src/field/author.rs
@@ -4,7 +4,7 @@ use human_name::Name;
use itertools::Itertools;
use syntax::bibtex::Value;
-use super::text::TextFieldData;
+use super::{text::TextFieldData, FieldParseCache};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum AuthorField {
@@ -58,8 +58,8 @@ impl fmt::Display for AuthorFieldData {
}
impl AuthorFieldData {
- pub fn parse(value: &Value) -> Option<Self> {
- let TextFieldData { text } = TextFieldData::parse(value)?;
+ pub fn parse(value: &Value, cache: &FieldParseCache) -> Option<Self> {
+ let TextFieldData { text } = TextFieldData::parse(value, cache)?;
let mut authors = Vec::new();
let mut words = Vec::new();
for word in text.split_whitespace() {
diff --git a/support/texlab/crates/bibtex-utils/src/field/date.rs b/support/texlab/crates/bibtex-utils/src/field/date.rs
index 8e2c0b7d72..4e3dfd19d9 100644
--- a/support/texlab/crates/bibtex-utils/src/field/date.rs
+++ b/support/texlab/crates/bibtex-utils/src/field/date.rs
@@ -3,7 +3,7 @@ use std::{fmt, ops::Add, str::FromStr};
use chrono::{Datelike, Month, NaiveDate};
use syntax::bibtex::Value;
-use super::text::TextFieldData;
+use super::{text::TextFieldData, FieldParseCache};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum DateField {
@@ -73,8 +73,8 @@ impl fmt::Display for DateFieldData {
}
impl DateFieldData {
- pub fn parse(value: &Value) -> Option<Self> {
- let TextFieldData { text } = TextFieldData::parse(value)?;
+ pub fn parse(value: &Value, cache: &FieldParseCache) -> Option<Self> {
+ let TextFieldData { text } = TextFieldData::parse(value, cache)?;
NaiveDate::from_str(&text)
.ok()
.map(Self::Date)
diff --git a/support/texlab/crates/bibtex-utils/src/field/number.rs b/support/texlab/crates/bibtex-utils/src/field/number.rs
index 227f3d5b75..34240bcfb3 100644
--- a/support/texlab/crates/bibtex-utils/src/field/number.rs
+++ b/support/texlab/crates/bibtex-utils/src/field/number.rs
@@ -2,7 +2,7 @@ use std::fmt;
use syntax::bibtex::Value;
-use super::text::TextFieldData;
+use super::{text::TextFieldData, FieldParseCache};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum NumberField {
@@ -48,8 +48,8 @@ impl fmt::Display for NumberFieldData {
}
impl NumberFieldData {
- pub fn parse(value: &Value) -> Option<Self> {
- let TextFieldData { text } = TextFieldData::parse(value)?;
+ pub fn parse(value: &Value, cache: &FieldParseCache) -> Option<Self> {
+ let TextFieldData { text } = TextFieldData::parse(value, cache)?;
text.split_once("--")
.or_else(|| text.split_once('-'))
.and_then(|(a, b)| Some((a.parse().ok()?, b.parse().ok()?)))
diff --git a/support/texlab/crates/bibtex-utils/src/field/text.rs b/support/texlab/crates/bibtex-utils/src/field/text.rs
index 9689264779..b3eabaff0e 100644
--- a/support/texlab/crates/bibtex-utils/src/field/text.rs
+++ b/support/texlab/crates/bibtex-utils/src/field/text.rs
@@ -1,11 +1,12 @@
use rowan::{ast::AstNode, NodeOrToken};
-use rustc_hash::FxHashSet;
use syntax::bibtex::{
- Accent, Command, CurlyGroup, HasAccentName, HasCommandName, HasName, HasValue, HasWord, Join,
- Literal, QuoteGroup, Root, SyntaxKind::*, SyntaxToken, Value,
+ Accent, Command, CurlyGroup, HasAccentName, HasCommandName, HasName, HasWord, Join,
+ Literal, QuoteGroup, SyntaxKind::*, SyntaxToken, Value,
};
+use super::FieldParseCache;
+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub enum TextField {
Abstract,
@@ -118,20 +119,28 @@ pub struct TextFieldData {
}
impl TextFieldData {
- pub fn parse(value: &Value) -> Option<Self> {
- let mut builder = TextFieldDataBuilder::default();
+ pub fn parse(value: &Value, cache: &FieldParseCache) -> Option<Self> {
+ let mut builder = TextFieldDataBuilder::new(cache);
builder.visit_value(value)?;
Some(builder.data)
}
}
-#[derive(Default)]
-struct TextFieldDataBuilder {
+struct TextFieldDataBuilder<'a> {
data: TextFieldData,
- string_stack: FxHashSet<String>,
+ cache: &'a FieldParseCache,
+}
+
+impl<'a> TextFieldDataBuilder<'a> {
+ fn new(cache: &'a FieldParseCache) -> Self {
+ TextFieldDataBuilder {
+ data: Default::default(),
+ cache,
+ }
+ }
}
-impl TextFieldDataBuilder {
+impl<'a> TextFieldDataBuilder<'a> {
fn visit_value(&mut self, value: &Value) -> Option<()> {
match value {
Value::Literal(lit) => {
@@ -170,24 +179,9 @@ impl TextFieldDataBuilder {
}
fn visit_string_reference(&mut self, name: &SyntaxToken) -> Option<()> {
- let root = Root::cast(name.parent_ancestors().last()?)?;
let name = name.text();
-
- let value = root
- .strings()
- .filter(|string| {
- string
- .name_token()
- .map_or(false, |token| token.text() == name)
- })
- .find_map(|string| string.value())?;
-
- if !self.string_stack.insert(name.to_string()) {
- return None;
- }
-
- let _ = self.visit_value(&value);
- self.string_stack.remove(name);
+ let value = self.cache.get(name)?;
+ self.data.text.push_str(value);
Some(())
}
diff --git a/support/texlab/crates/citeproc/Cargo.toml b/support/texlab/crates/citeproc/Cargo.toml
index c87b2d17c3..9d356b3778 100644
--- a/support/texlab/crates/citeproc/Cargo.toml
+++ b/support/texlab/crates/citeproc/Cargo.toml
@@ -8,6 +8,7 @@ rust-version.workspace = true
[dependencies]
bibtex-utils = { path = "../bibtex-utils" }
+base-db = { path = "../base-db" }
isocountry = "0.3.2"
itertools = "0.12.0"
rowan = "0.15.15"
diff --git a/support/texlab/crates/citeproc/src/driver.rs b/support/texlab/crates/citeproc/src/driver.rs
index 778e2539b5..cee6bb097e 100644
--- a/support/texlab/crates/citeproc/src/driver.rs
+++ b/support/texlab/crates/citeproc/src/driver.rs
@@ -1,3 +1,4 @@
+use base_db::semantics::bib::Semantics;
use bibtex_utils::field::{
author::AuthorField,
date::DateField,
@@ -21,8 +22,8 @@ pub struct Driver {
}
impl Driver {
- pub fn process(&mut self, entry: &bibtex::Entry) {
- let entry = EntryData::from(entry);
+ pub fn process(&mut self, entry: &bibtex::Entry, semantics: &Semantics) {
+ let entry = EntryData::from_entry(entry, semantics);
match entry.kind {
EntryKind::Article
| EntryKind::DataSet
diff --git a/support/texlab/crates/citeproc/src/entry.rs b/support/texlab/crates/citeproc/src/entry.rs
index 243908da95..f544858efc 100644
--- a/support/texlab/crates/citeproc/src/entry.rs
+++ b/support/texlab/crates/citeproc/src/entry.rs
@@ -3,7 +3,9 @@ use bibtex_utils::field::{
date::{DateField, DateFieldData},
number::{NumberField, NumberFieldData},
text::{TextField, TextFieldData},
+ FieldParseCache,
};
+use base_db::semantics::bib::Semantics;
use rustc_hash::FxHashMap;
use syntax::bibtex::{Entry, Field, HasName, HasType, HasValue, Value};
@@ -103,8 +105,8 @@ pub struct EntryData {
pub number: FxHashMap<NumberField, NumberFieldData>,
}
-impl From<&Entry> for EntryData {
- fn from(entry: &Entry) -> Self {
+impl EntryData {
+ pub fn from_entry(entry: &Entry, semantics: &Semantics) -> Self {
let mut data = EntryData {
kind: entry.type_token().map_or(EntryKind::Unknown, |token| {
EntryKind::parse(&token.text()[1..])
@@ -113,7 +115,7 @@ impl From<&Entry> for EntryData {
};
for field in entry.fields() {
- let _ = data.parse_field(&field);
+ let _ = data.parse_field(&field, &semantics.expanded_defs);
}
data
@@ -121,40 +123,40 @@ impl From<&Entry> for EntryData {
}
impl EntryData {
- fn parse_field(&mut self, field: &Field) -> Option<()> {
+ fn parse_field(&mut self, field: &Field, expanded_defs: &FieldParseCache) -> Option<()> {
let name = field.name_token()?;
let name = name.text();
let value = field.value()?;
- self.parse_author_field(name, &value)
- .or_else(|| self.parse_date_field(name, &value))
- .or_else(|| self.parse_number_field(name, &value))
- .or_else(|| self.parse_text_field(name, &value))
+ self.parse_author_field(name, &value, expanded_defs)
+ .or_else(|| self.parse_date_field(name, &value, expanded_defs))
+ .or_else(|| self.parse_number_field(name, &value, expanded_defs))
+ .or_else(|| self.parse_text_field(name, &value, expanded_defs))
}
- fn parse_author_field(&mut self, name: &str, value: &Value) -> Option<()> {
+ fn parse_author_field(&mut self, name: &str, value: &Value, expanded_defs: &FieldParseCache) -> Option<()> {
let name = AuthorField::parse(name)?;
- let data = AuthorFieldData::parse(value)?;
+ let data = AuthorFieldData::parse(value, expanded_defs)?;
self.author.insert(name, data);
Some(())
}
- fn parse_date_field(&mut self, name: &str, value: &Value) -> Option<()> {
+ fn parse_date_field(&mut self, name: &str, value: &Value, expanded_defs: &FieldParseCache) -> Option<()> {
let name = DateField::parse(name)?;
- let data = DateFieldData::parse(value)?;
+ let data = DateFieldData::parse(value, expanded_defs)?;
self.date.insert(name, data);
Some(())
}
- fn parse_number_field(&mut self, name: &str, value: &Value) -> Option<()> {
+ fn parse_number_field(&mut self, name: &str, value: &Value, expanded_defs: &FieldParseCache) -> Option<()> {
let name = NumberField::parse(name)?;
- let data = NumberFieldData::parse(value)?;
+ let data = NumberFieldData::parse(value, expanded_defs)?;
self.number.insert(name, data);
Some(())
}
- fn parse_text_field(&mut self, name: &str, value: &Value) -> Option<()> {
+ fn parse_text_field(&mut self, name: &str, value: &Value, expanded_defs: &FieldParseCache) -> Option<()> {
let name = TextField::parse(name).unwrap_or(TextField::Unknown);
- let data = TextFieldData::parse(value)?;
+ let data = TextFieldData::parse(value, expanded_defs)?;
self.text.insert(name, data);
Some(())
}
diff --git a/support/texlab/crates/citeproc/src/lib.rs b/support/texlab/crates/citeproc/src/lib.rs
index de24306583..915d3d69ba 100644
--- a/support/texlab/crates/citeproc/src/lib.rs
+++ b/support/texlab/crates/citeproc/src/lib.rs
@@ -2,16 +2,17 @@ mod driver;
mod entry;
mod output;
+use base_db::semantics::bib::Semantics;
use syntax::bibtex;
use unicode_normalization::UnicodeNormalization;
use self::{driver::Driver, output::Inline};
#[must_use]
-pub fn render(entry: &bibtex::Entry) -> Option<String> {
+pub fn render(entry: &bibtex::Entry, semantics: &Semantics) -> Option<String> {
let mut output = String::new();
let mut driver = Driver::default();
- driver.process(entry);
+ driver.process(entry, semantics);
driver.finish().for_each(|(inline, punct)| {
let text = match inline {
Inline::Regular(text) => text,
diff --git a/support/texlab/crates/citeproc/src/tests.rs b/support/texlab/crates/citeproc/src/tests.rs
index 1c91580f39..b5838b52b5 100644
--- a/support/texlab/crates/citeproc/src/tests.rs
+++ b/support/texlab/crates/citeproc/src/tests.rs
@@ -1,3 +1,4 @@
+use base_db::semantics::bib::Semantics;
use expect_test::{expect, Expect};
use parser::parse_bibtex;
use rowan::ast::AstNode;
@@ -5,9 +6,12 @@ use syntax::bibtex;
fn check(input: &str, expect: Expect) {
let green = parse_bibtex(input);
- let root = bibtex::Root::cast(bibtex::SyntaxNode::new_root(green)).unwrap();
+ let root = bibtex::SyntaxNode::new_root(green);
+ let mut semantics = Semantics::default();
+ semantics.process_root(&root);
+ let root = bibtex::Root::cast(root).unwrap();
let entry = root.entries().next().unwrap();
- let output = super::render(&entry).unwrap();
+ let output = super::render(&entry, &semantics).unwrap();
expect.assert_eq(&output);
}
diff --git a/support/texlab/crates/commands/Cargo.toml b/support/texlab/crates/commands/Cargo.toml
index c54d77abf4..512a05ee61 100644
--- a/support/texlab/crates/commands/Cargo.toml
+++ b/support/texlab/crates/commands/Cargo.toml
@@ -9,15 +9,15 @@ rust-version.workspace = true
[dependencies]
anyhow = "1.0.72"
base-db = { path = "../base-db" }
-bstr = "1.8.0"
+bstr = "1.9.0"
crossbeam-channel = "0.5.11"
itertools = "0.12.0"
-libc = "0.2.150"
-log = "0.4.19"
+libc = "0.2.153"
+log = "0.4.21"
rowan = "0.15.15"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
-thiserror = "1.0.56"
+thiserror = "1.0.57"
url = "2.5.0"
[dev-dependencies]
diff --git a/support/texlab/crates/completion-data/Cargo.toml b/support/texlab/crates/completion-data/Cargo.toml
index c32c02d3bc..37ecf1b3cf 100644
--- a/support/texlab/crates/completion-data/Cargo.toml
+++ b/support/texlab/crates/completion-data/Cargo.toml
@@ -12,7 +12,7 @@ itertools = "0.12.0"
once_cell = "1.19.0"
rustc-hash = "1.1.0"
serde = { version = "1.0.195", features = ["derive"] }
-serde_json = "1.0.108"
+serde_json = "1.0.114"
[lib]
doctest = false
diff --git a/support/texlab/crates/completion/Cargo.toml b/support/texlab/crates/completion/Cargo.toml
index 5bcebea435..fbdd2d7201 100644
--- a/support/texlab/crates/completion/Cargo.toml
+++ b/support/texlab/crates/completion/Cargo.toml
@@ -11,7 +11,7 @@ base-db = { path = "../base-db" }
completion-data = { path = "../completion-data" }
fuzzy-matcher = { version = "0.3.7", features = ["compact"] }
line-index = { path = "../line-index" }
-rayon = "1.7.0"
+rayon = "1.8.1"
rowan = "0.15.15"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
diff --git a/support/texlab/crates/diagnostics/Cargo.toml b/support/texlab/crates/diagnostics/Cargo.toml
index 1fb4b2171d..91c2ff9dbd 100644
--- a/support/texlab/crates/diagnostics/Cargo.toml
+++ b/support/texlab/crates/diagnostics/Cargo.toml
@@ -14,8 +14,8 @@ encoding_rs = "0.8.33"
encoding_rs_io = "0.1.7"
itertools = "0.12.0"
line-index = { path = "../line-index" }
-log = "0.4.20"
-multimap = "0.9.1"
+log = "0.4.21"
+multimap = "0.10.0"
once_cell = "1.19.0"
parking_lot = "0.12.1"
regex = "1.10.2"
diff --git a/support/texlab/crates/diagnostics/src/citations.rs b/support/texlab/crates/diagnostics/src/citations.rs
index 403d2f5bfc..ea4ef03d58 100644
--- a/support/texlab/crates/diagnostics/src/citations.rs
+++ b/support/texlab/crates/diagnostics/src/citations.rs
@@ -3,8 +3,7 @@ use base_db::{
util::queries::{self, Object},
Document, Project, Workspace,
};
-use multimap::MultiMap;
-use rustc_hash::FxHashSet;
+use rustc_hash::{FxHashMap, FxHashSet};
use url::Url;
use crate::types::{BibError, Diagnostic, TexError};
@@ -14,7 +13,7 @@ const MAX_UNUSED_ENTRIES: usize = 1000;
pub fn detect_undefined_citations<'a>(
project: &Project<'a>,
document: &'a Document,
- results: &mut MultiMap<Url, Diagnostic>,
+ results: &mut FxHashMap<Url, Vec<Diagnostic>>,
) -> Option<()> {
let data = document.data.as_tex()?;
@@ -26,7 +25,10 @@ pub fn detect_undefined_citations<'a>(
let name = citation.name_text();
if name != "*" && !entries.contains(name) {
let diagnostic = Diagnostic::Tex(citation.name.range, TexError::UndefinedCitation);
- results.insert(document.uri.clone(), diagnostic);
+ results
+ .entry(document.uri.clone())
+ .or_default()
+ .push(diagnostic);
}
}
@@ -36,7 +38,7 @@ pub fn detect_undefined_citations<'a>(
pub fn detect_unused_entries<'a>(
project: &Project<'a>,
document: &'a Document,
- results: &mut MultiMap<Url, Diagnostic>,
+ results: &mut FxHashMap<Url, Vec<Diagnostic>>,
) -> Option<()> {
let data = document.data.as_bib()?;
@@ -52,7 +54,10 @@ pub fn detect_unused_entries<'a>(
for entry in &data.semantics.entries {
if !citations.contains(entry.name.text.as_str()) {
let diagnostic = Diagnostic::Bib(entry.name.range, BibError::UnusedEntry);
- results.insert(document.uri.clone(), diagnostic);
+ results
+ .entry(document.uri.clone())
+ .or_default()
+ .push(diagnostic);
}
}
@@ -61,7 +66,7 @@ pub fn detect_unused_entries<'a>(
pub fn detect_duplicate_entries<'a>(
workspace: &'a Workspace,
- results: &mut MultiMap<Url, Diagnostic>,
+ results: &mut FxHashMap<Url, Vec<Diagnostic>>,
) {
for conflict in queries::Conflict::find_all::<Entry>(workspace) {
let others = conflict
@@ -71,6 +76,9 @@ pub fn detect_duplicate_entries<'a>(
.collect();
let diagnostic = Diagnostic::Bib(conflict.main.range, BibError::DuplicateEntry(others));
- results.insert(conflict.main.document.uri.clone(), diagnostic);
+ results
+ .entry(conflict.main.document.uri.clone())
+ .or_default()
+ .push(diagnostic);
}
}
diff --git a/support/texlab/crates/diagnostics/src/labels.rs b/support/texlab/crates/diagnostics/src/labels.rs
index 92f9072918..9a39f3f24b 100644
--- a/support/texlab/crates/diagnostics/src/labels.rs
+++ b/support/texlab/crates/diagnostics/src/labels.rs
@@ -4,15 +4,14 @@ use base_db::{
DocumentData, Workspace,
};
use itertools::Itertools;
-use multimap::MultiMap;
-use rustc_hash::FxHashSet;
+use rustc_hash::{FxHashMap, FxHashSet};
use url::Url;
use crate::types::{Diagnostic, TexError};
pub fn detect_undefined_and_unused_labels(
workspace: &Workspace,
- results: &mut MultiMap<Url, Diagnostic>,
+ results: &mut FxHashMap<Url, Vec<Diagnostic>>,
) {
let graphs: Vec<_> = workspace
.iter()
@@ -45,18 +44,27 @@ pub fn detect_undefined_and_unused_labels(
for label in &data.semantics.labels {
if label.kind != LabelKind::Definition && !label_defs.contains(&label.name.text) {
let diagnostic = Diagnostic::Tex(label.name.range, TexError::UndefinedLabel);
- results.insert(document.uri.clone(), diagnostic);
+ results
+ .entry(document.uri.clone())
+ .or_default()
+ .push(diagnostic);
}
if label.kind == LabelKind::Definition && !label_refs.contains(&label.name.text) {
let diagnostic = Diagnostic::Tex(label.name.range, TexError::UnusedLabel);
- results.insert(document.uri.clone(), diagnostic);
+ results
+ .entry(document.uri.clone())
+ .or_default()
+ .push(diagnostic);
}
}
}
}
-pub fn detect_duplicate_labels(workspace: &Workspace, results: &mut MultiMap<Url, Diagnostic>) {
+pub fn detect_duplicate_labels(
+ workspace: &Workspace,
+ results: &mut FxHashMap<Url, Vec<Diagnostic>>,
+) {
for conflict in queries::Conflict::find_all::<Label>(workspace) {
let others = conflict
.rest
@@ -65,6 +73,9 @@ pub fn detect_duplicate_labels(workspace: &Workspace, results: &mut MultiMap<Url
.collect();
let diagnostic = Diagnostic::Tex(conflict.main.range, TexError::DuplicateLabel(others));
- results.insert(conflict.main.document.uri.clone(), diagnostic);
+ results
+ .entry(conflict.main.document.uri.clone())
+ .or_default()
+ .push(diagnostic);
}
}
diff --git a/support/texlab/crates/diagnostics/src/manager.rs b/support/texlab/crates/diagnostics/src/manager.rs
index 1ce5e194b8..38c0a514f4 100644
--- a/support/texlab/crates/diagnostics/src/manager.rs
+++ b/support/texlab/crates/diagnostics/src/manager.rs
@@ -16,6 +16,10 @@ pub struct Manager {
impl Manager {
/// Updates the syntax-based diagnostics for the given document.
pub fn update_syntax(&mut self, workspace: &Workspace, document: &Document) {
+ if !Self::is_relevant(document) {
+ return;
+ }
+
self.grammar.remove(&document.uri);
super::grammar::tex::update(document, workspace.config(), &mut self.grammar);
super::grammar::bib::update(document, &mut self.grammar);
@@ -30,14 +34,20 @@ impl Manager {
}
/// Returns all filtered diagnostics for the given workspace.
- pub fn get(&self, workspace: &Workspace) -> MultiMap<Url, Diagnostic> {
- let mut results = MultiMap::default();
+ pub fn get(&self, workspace: &Workspace) -> FxHashMap<Url, Vec<Diagnostic>> {
+ let mut results: FxHashMap<Url, Vec<Diagnostic>> = FxHashMap::default();
for (uri, diagnostics) in &self.grammar {
- results.insert_many_from_slice(uri.clone(), diagnostics);
+ results
+ .entry(uri.clone())
+ .or_default()
+ .extend(diagnostics.iter().cloned());
}
for (uri, diagnostics) in self.build_log.values().flatten() {
- results.insert_many_from_slice(uri.clone(), diagnostics);
+ results
+ .entry(uri.clone())
+ .or_default()
+ .extend(diagnostics.iter().cloned());
}
for (uri, diagnostics) in &self.chktex {
@@ -45,11 +55,17 @@ impl Manager {
.lookup(uri)
.map_or(false, |document| document.owner == Owner::Client)
{
- results.insert_many_from_slice(uri.clone(), diagnostics);
+ results
+ .entry(uri.clone())
+ .or_default()
+ .extend(diagnostics.iter().cloned());
}
}
- for document in workspace.iter() {
+ for document in workspace
+ .iter()
+ .filter(|document| Self::is_relevant(document))
+ {
let project = workspace.project(document);
super::citations::detect_undefined_citations(&project, document, &mut results);
super::citations::detect_unused_entries(&project, document, &mut results);
@@ -60,6 +76,13 @@ impl Manager {
super::labels::detect_undefined_and_unused_labels(workspace, &mut results);
let config = &workspace.config().diagnostics;
+
+ results.retain(|uri, _| {
+ workspace
+ .lookup(uri)
+ .map_or(false, |document| Self::is_relevant(document))
+ });
+
for (_, diagnostics) in &mut results {
diagnostics.retain(|diagnostic| {
filter_regex_patterns(
@@ -72,4 +95,12 @@ impl Manager {
results
}
+
+ fn is_relevant(document: &Document) -> bool {
+ match document.owner {
+ Owner::Client => true,
+ Owner::Server => true,
+ Owner::Distro => false,
+ }
+ }
}
diff --git a/support/texlab/crates/diagnostics/src/tests.rs b/support/texlab/crates/diagnostics/src/tests.rs
index b7c6004d19..3688abeaf4 100644
--- a/support/texlab/crates/diagnostics/src/tests.rs
+++ b/support/texlab/crates/diagnostics/src/tests.rs
@@ -11,7 +11,7 @@ fn check(input: &str, expect: Expect) {
let results = manager.get(&fixture.workspace);
let results = results
- .iter_all()
+ .iter()
.filter(|(_, diags)| !diags.is_empty())
.sorted_by(|(uri1, _), (uri2, _)| uri1.cmp(&uri2))
.map(|(uri, diags)| (uri.as_str(), diags))
diff --git a/support/texlab/crates/distro/src/file_name_db.rs b/support/texlab/crates/distro/src/file_name_db.rs
index 06871bde83..fd6750fffa 100644
--- a/support/texlab/crates/distro/src/file_name_db.rs
+++ b/support/texlab/crates/distro/src/file_name_db.rs
@@ -55,6 +55,11 @@ impl FileNameDB {
self.files.get(name).map(|file| file.path())
}
+ pub fn contains(&self, path: &Path) -> bool {
+ let name = path.file_name().unwrap().to_str().unwrap();
+ self.get(name) == Some(path)
+ }
+
pub fn iter(&self) -> impl Iterator<Item = (&str, &Path)> + '_ {
self.files.iter().map(|file| (file.name(), file.path()))
}
diff --git a/support/texlab/crates/hover/src/citation.rs b/support/texlab/crates/hover/src/citation.rs
index 372668997e..a39ea2e5f5 100644
--- a/support/texlab/crates/hover/src/citation.rs
+++ b/support/texlab/crates/hover/src/citation.rs
@@ -31,7 +31,7 @@ pub(super) fn find_hover<'a>(params: &HoverParams<'a>) -> Option<Hover<'a>> {
let data = document.data.as_bib()?;
let root = bibtex::Root::cast(data.root_node())?;
let entry = root.find_entry(name)?;
- citeproc::render(&entry)
+ citeproc::render(&entry, &data.semantics)
})?;
let data = HoverData::Citation(text);
diff --git a/support/texlab/crates/hover/src/string_ref.rs b/support/texlab/crates/hover/src/string_ref.rs
index 6726041af2..cf8062a5a0 100644
--- a/support/texlab/crates/hover/src/string_ref.rs
+++ b/support/texlab/crates/hover/src/string_ref.rs
@@ -24,7 +24,7 @@ pub(super) fn find_hover<'a>(params: &HoverParams<'a>) -> Option<Hover<'a>> {
continue;
}
- let value = TextFieldData::parse(&string.value()?)?.text;
+ let value = TextFieldData::parse(&string.value()?, &data.semantics.expanded_defs)?.text;
return Some(Hover {
range: name.text_range(),
data: HoverData::StringRef(value),
diff --git a/support/texlab/crates/parser/Cargo.toml b/support/texlab/crates/parser/Cargo.toml
index c3e31b7022..0fd8889899 100644
--- a/support/texlab/crates/parser/Cargo.toml
+++ b/support/texlab/crates/parser/Cargo.toml
@@ -13,7 +13,7 @@ regex = "1.10.2"
rowan = "0.15.15"
rustc-hash = "1.1.0"
syntax = { path = "../syntax" }
-tempfile = "3.8.1"
+tempfile = "3.10.1"
[dev-dependencies]
expect-test = "1.4.1"
diff --git a/support/texlab/crates/parser/src/config.rs b/support/texlab/crates/parser/src/config.rs
index 3a2e9e3e93..6537d21b0d 100644
--- a/support/texlab/crates/parser/src/config.rs
+++ b/support/texlab/crates/parser/src/config.rs
@@ -7,6 +7,7 @@ pub struct SyntaxConfig {
pub enum_environments: FxHashSet<String>,
pub verbatim_environments: FxHashSet<String>,
pub citation_commands: FxHashSet<String>,
+ pub label_reference_commands: FxHashSet<String>,
}
impl Default for SyntaxConfig {
@@ -31,12 +32,18 @@ impl Default for SyntaxConfig {
.map(ToString::to_string)
.collect();
+ let label_reference_commands = DEFAULT_LABEL_REFERENCE_COMMANDS
+ .iter()
+ .map(ToString::to_string)
+ .collect();
+
Self {
follow_package_links: false,
math_environments,
enum_environments,
verbatim_environments,
citation_commands,
+ label_reference_commands,
}
}
}
@@ -155,3 +162,24 @@ static DEFAULT_CITATION_COMMANDS: &[&str] = &[
"citeA",
"citeA*",
];
+
+static DEFAULT_LABEL_REFERENCE_COMMANDS: &[&str] = &[
+ "ref",
+ "vref",
+ "Vref",
+ "autoref",
+ "pageref",
+ "cref",
+ "cref*",
+ "Cref",
+ "Cref*",
+ "namecref",
+ "nameCref",
+ "lcnamecref",
+ "namecrefs",
+ "nameCrefs",
+ "lcnamecrefs",
+ "labelcref",
+ "labelcpageref",
+ "eqref",
+];
diff --git a/support/texlab/crates/parser/src/latex.rs b/support/texlab/crates/parser/src/latex.rs
index d88eb39556..4a6fabae21 100644
--- a/support/texlab/crates/parser/src/latex.rs
+++ b/support/texlab/crates/parser/src/latex.rs
@@ -25,6 +25,13 @@ impl Default for ParserContext {
}
}
+#[derive(Debug, Clone, Copy)]
+struct KeyOptions {
+ allow_eq: bool,
+ allow_parens: bool,
+ allow_bracks: bool,
+}
+
#[derive(Debug)]
struct Parser<'a> {
lexer: Lexer<'a>,
@@ -309,7 +316,11 @@ impl<'a> Parser<'a> {
self.trivia();
match self.peek() {
Some(Token::Word | Token::Pipe) => {
- self.key();
+ self.key_with_opts(KeyOptions {
+ allow_eq: true,
+ allow_bracks: false,
+ allow_parens: true,
+ });
}
Some(_) | None => {}
}
@@ -340,16 +351,22 @@ impl<'a> Parser<'a> {
}
fn key(&mut self) {
- self.key_with_eq(true);
+ self.key_with_opts(KeyOptions {
+ allow_eq: true,
+ allow_parens: true,
+ allow_bracks: true,
+ });
}
- fn key_with_eq(&mut self, allow_eq: bool) {
+ fn key_with_opts(&mut self, options: KeyOptions) {
self.builder.start_node(KEY.into());
self.eat();
while let Some(kind) = self.peek() {
match kind {
Token::Whitespace | Token::LineComment | Token::Word | Token::Pipe => self.eat(),
- Token::Eq if allow_eq => self.eat(),
+ Token::LBrack | Token::RBrack if options.allow_bracks => self.eat(),
+ Token::LParen | Token::RParen if options.allow_parens => self.eat(),
+ Token::Eq if options.allow_eq => self.eat(),
_ => break,
}
}
@@ -374,7 +391,12 @@ impl<'a> Parser<'a> {
fn key_value_pair(&mut self) {
self.builder.start_node(KEY_VALUE_PAIR.into());
- self.key_with_eq(false);
+ self.key_with_opts(KeyOptions {
+ allow_eq: false,
+ allow_parens: true,
+ allow_bracks: false,
+ });
+
if self.peek() == Some(Token::Eq) {
self.eat();
self.trivia();
diff --git a/support/texlab/crates/parser/src/latex/lexer/commands.rs b/support/texlab/crates/parser/src/latex/lexer/commands.rs
index b6e1d11737..95eef4becd 100644
--- a/support/texlab/crates/parser/src/latex/lexer/commands.rs
+++ b/support/texlab/crates/parser/src/latex/lexer/commands.rs
@@ -30,9 +30,6 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
CommandName::Import
}
"label" => CommandName::LabelDefinition,
- "ref" | "vref" | "Vref" | "autoref" | "pageref" | "cref" | "cref*" | "Cref" | "Cref*"
- | "namecref" | "nameCref" | "lcnamecref" | "namecrefs" | "nameCrefs" | "lcnamecrefs"
- | "labelcref" | "labelcpageref" | "eqref" => CommandName::LabelReference,
"crefrange" | "crefrange*" | "Crefrange" | "Crefrange*" => CommandName::LabelReferenceRange,
"newlabel" => CommandName::LabelNumber,
"newcommand"
@@ -81,6 +78,7 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName {
"fi" => CommandName::EndBlockComment,
"verb" => CommandName::VerbatimBlock,
_ if config.citation_commands.contains(name) => CommandName::Citation,
+ _ if config.label_reference_commands.contains(name) => CommandName::LabelReference,
_ => CommandName::Generic,
}
}
diff --git a/support/texlab/crates/parser/src/latex/tests.rs b/support/texlab/crates/parser/src/latex/tests.rs
index 6e5019776f..5e1a4044cd 100644
--- a/support/texlab/crates/parser/src/latex/tests.rs
+++ b/support/texlab/crates/parser/src/latex/tests.rs
@@ -3542,3 +3542,72 @@ fn test_command_subscript() {
"#]],
);
}
+
+#[test]
+fn test_label_parens() {
+ check(
+ r#"\label{foo (bar)}"#,
+ expect![[r#"
+ ROOT@0..17
+ PREAMBLE@0..17
+ LABEL_DEFINITION@0..17
+ COMMAND_NAME@0..6 "\\label"
+ CURLY_GROUP_WORD@6..17
+ L_CURLY@6..7 "{"
+ KEY@7..16
+ WORD@7..10 "foo"
+ WHITESPACE@10..11 " "
+ L_PAREN@11..12 "("
+ WORD@12..15 "bar"
+ R_PAREN@15..16 ")"
+ R_CURLY@16..17 "}"
+
+ "#]],
+ );
+}
+
+#[test]
+fn test_label_brackets() {
+ check(
+ r#"\label{foo [bar]}"#,
+ expect![[r#"
+ ROOT@0..17
+ PREAMBLE@0..17
+ LABEL_DEFINITION@0..17
+ COMMAND_NAME@0..6 "\\label"
+ CURLY_GROUP_WORD@6..17
+ L_CURLY@6..7 "{"
+ KEY@7..16
+ WORD@7..10 "foo"
+ WHITESPACE@10..11 " "
+ L_BRACK@11..12 "["
+ WORD@12..15 "bar"
+ R_BRACK@15..16 "]"
+ R_CURLY@16..17 "}"
+
+ "#]],
+ );
+}
+
+#[test]
+fn test_label_brackets_unbalanced() {
+ check(
+ r#"\label{foo ]bar[}"#,
+ expect![[r#"
+ ROOT@0..17
+ PREAMBLE@0..17
+ LABEL_DEFINITION@0..17
+ COMMAND_NAME@0..6 "\\label"
+ CURLY_GROUP_WORD@6..17
+ L_CURLY@6..7 "{"
+ KEY@7..16
+ WORD@7..10 "foo"
+ WHITESPACE@10..11 " "
+ R_BRACK@11..12 "]"
+ WORD@12..15 "bar"
+ L_BRACK@15..16 "["
+ R_CURLY@16..17 "}"
+
+ "#]],
+ );
+}
diff --git a/support/texlab/crates/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml
index 53b63ded3e..ccc02bff01 100644
--- a/support/texlab/crates/texlab/Cargo.toml
+++ b/support/texlab/crates/texlab/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "texlab"
description = "LaTeX Language Server"
-version = "5.12.3"
+version = "5.13.1"
license.workspace = true
readme = "README.md"
authors.workspace = true
@@ -26,7 +26,7 @@ anyhow = "1.0.75"
base-db = { path = "../base-db" }
bibfmt = { path = "../bibfmt" }
citeproc = { path = "../citeproc" }
-clap = { version = "4.4.10", features = ["derive"] }
+clap = { version = "4.4.18", features = ["derive"] }
commands = { path = "../commands" }
completion = { path = "../completion" }
completion-data = { path = "../completion-data" }
@@ -43,9 +43,9 @@ hover = { path = "../hover" }
inlay-hints = { path = "../inlay-hints" }
line-index = { path = "../line-index" }
links = { path = "../links" }
-log = "0.4.19"
+log = "0.4.21"
lsp-server = "0.7.6"
-lsp-types = "0.94.1"
+lsp-types = "0.95.0"
notify = "6.1.1"
notify-debouncer-full = "0.3.1"
once_cell = "1.19.0"
@@ -57,12 +57,12 @@ rename = { path = "../rename" }
rowan = "0.15.15"
rustc-hash = "1.1.0"
serde = "1.0.195"
-serde_json = "1.0.108"
+serde_json = "1.0.114"
serde_regex = "1.1.0"
-serde_repr = "0.1.17"
+serde_repr = "0.1.18"
symbols = { path = "../symbols" }
syntax = { path = "../syntax" }
-tempfile = "3.8.0"
+tempfile = "3.10.1"
threadpool = "1.8.1"
[dev-dependencies]
diff --git a/support/texlab/crates/texlab/src/client.rs b/support/texlab/crates/texlab/src/client.rs
index 9bbace9938..b79f876436 100644
--- a/support/texlab/crates/texlab/src/client.rs
+++ b/support/texlab/crates/texlab/src/client.rs
@@ -93,8 +93,14 @@ impl LspClient {
Ok(())
}
- pub fn parse_options(&self, value: serde_json::Value) -> Result<Options> {
- let options = match serde_json::from_value(value) {
+ pub fn parse_options(&self, mut value: serde_json::Value) -> Result<Options> {
+ // if there are multiple servers, we need to extract the options for texlab first
+ let options = match value.get_mut("texlab") {
+ Some(section) => section.take(),
+ None => value,
+ };
+
+ let options = match serde_json::from_value(options) {
Ok(new_options) => new_options,
Err(why) => {
let message = format!(
diff --git a/support/texlab/crates/texlab/src/features/completion.rs b/support/texlab/crates/texlab/src/features/completion.rs
index 5d32588970..5bca0070ef 100644
--- a/support/texlab/crates/texlab/src/features/completion.rs
+++ b/support/texlab/crates/texlab/src/features/completion.rs
@@ -1,4 +1,4 @@
-use base_db::{util::RenderedObject, Workspace};
+use base_db::{util::RenderedObject, MatchingAlgo, Workspace};
use completion::{ArgumentData, CompletionItem, CompletionItemData, EntryTypeData, FieldTypeData};
use line_index::LineIndex;
use rowan::ast::AstNode;
@@ -20,8 +20,16 @@ pub fn complete(
client_flags,
};
- let is_incomplete =
- client_flags.completion_always_incomplete || result.items.len() >= completion::LIMIT;
+ let is_fuzzy = match workspace.config().completion.matcher {
+ MatchingAlgo::Skim => true,
+ MatchingAlgo::SkimIgnoreCase => true,
+ MatchingAlgo::Prefix => false,
+ MatchingAlgo::PrefixIgnoreCase => false,
+ };
+
+ let is_incomplete = client_flags.completion_always_incomplete
+ || !is_fuzzy
+ || result.items.len() >= completion::LIMIT;
let items = result
.items
@@ -53,7 +61,7 @@ pub fn resolve(workspace: &Workspace, item: &mut lsp_types::CompletionItem) -> O
let data = workspace.lookup(&uri)?.data.as_bib()?;
let root = bibtex::Root::cast(data.root_node())?;
let entry = root.find_entry(&key)?;
- let value = citeproc::render(&entry)?;
+ let value = citeproc::render(&entry, &data.semantics)?;
item.documentation = Some(lsp_types::Documentation::MarkupContent(
lsp_types::MarkupContent {
kind: lsp_types::MarkupKind::Markdown,
diff --git a/support/texlab/crates/texlab/src/server.rs b/support/texlab/crates/texlab/src/server.rs
index 0fb186f688..fc16775bc9 100644
--- a/support/texlab/crates/texlab/src/server.rs
+++ b/support/texlab/crates/texlab/src/server.rs
@@ -813,7 +813,7 @@ impl Server {
.map_or(true, |document| document.owner == Owner::Server)
{
if let Some(language) = Language::from_path(&path) {
- changed |= workspace.load(&path, language, Owner::Server).is_ok();
+ changed |= workspace.load(&path, language).is_ok();
if let Some(document) = workspace.lookup_path(&path) {
self.diagnostic_manager.update_syntax(&workspace, document);
diff --git a/support/texlab/crates/texlab/src/server/options.rs b/support/texlab/crates/texlab/src/server/options.rs
index 72b2b127fb..60c0bf90f7 100644
--- a/support/texlab/crates/texlab/src/server/options.rs
+++ b/support/texlab/crates/texlab/src/server/options.rs
@@ -128,6 +128,7 @@ pub struct ExperimentalOptions {
pub enum_environments: Vec<String>,
pub verbatim_environments: Vec<String>,
pub citation_commands: Vec<String>,
+ pub label_reference_commands: Vec<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
@@ -283,5 +284,10 @@ impl From<Options> for Config {
.extend(value.experimental.citation_commands);
config
+ .syntax
+ .label_reference_commands
+ .extend(value.experimental.label_reference_commands);
+
+ config
}
}
diff --git a/support/texlab/texlab.1 b/support/texlab/texlab.1
index ea5ac6ec05..10a9e2d48d 100644
--- a/support/texlab/texlab.1
+++ b/support/texlab/texlab.1
@@ -1,7 +1,7 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
-.TH TEXLAB "1" "January 2024" "texlab 5.12.3" "User Commands"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1.
+.TH TEXLAB "1" "March 2024" "texlab 5.13.1" "User Commands"
.SH NAME
-texlab \- manual page for texlab 5.12.3
+texlab \- manual page for texlab 5.13.1
.SH SYNOPSIS
.B texlab
[\fI\,OPTIONS\/\fR]
diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf
index 6e2ddb1b35..efbde26dd6 100644
--- a/support/texlab/texlab.pdf
+++ b/support/texlab/texlab.pdf
Binary files differ