XML Tools fixes.

V lang LSP server updated to the new official LSP.
This commit is contained in:
Martín Lucas Golini
2023-08-05 14:42:27 -03:00
parent 3e4ae1b1da
commit d9ccaf2597
4 changed files with 111 additions and 18 deletions

View File

@@ -254,9 +254,9 @@
},
{
"language": "v",
"name": "vls",
"url": "https://github.com/vlang/vls",
"command": "v ls",
"name": "v-analyzer",
"url": "https://github.com/v-analyzer/v-analyzer",
"command": "v-analyzer --stdio",
"file_patterns": ["%.v$"]
},
{

View File

@@ -548,11 +548,12 @@ class EE_API TextDocument {
TextPosition getMatchingBracket( TextPosition startPosition,
const String::StringBaseType& openBracket,
const String::StringBaseType& closeBracket,
MatchDirection dir );
const String::StringBaseType& closeBracket, MatchDirection dir,
bool allowDepth = true );
TextRange getMatchingBracket( TextPosition startPosition, const String& openBracket,
const String& closeBracket, MatchDirection dir );
const String& closeBracket, MatchDirection dir,
bool matchingXMLTags = false );
SyntaxHighlighter* getHighlighter() const;

View File

@@ -2529,7 +2529,7 @@ static inline void changeDepth( SyntaxHighlighter* highlighter, int& depth, cons
TextPosition TextDocument::getMatchingBracket( TextPosition sp,
const String::StringBaseType& openBracket,
const String::StringBaseType& closeBracket,
MatchDirection dir ) {
MatchDirection dir, bool allowDepth ) {
SyntaxHighlighter* highlighter = getHighlighter();
int depth = 0;
while ( sp.isValid() ) {
@@ -2538,10 +2538,14 @@ TextPosition TextDocument::getMatchingBracket( TextPosition sp,
changeDepth( highlighter, depth, sp, 1 );
if ( depth == 0 )
return sp;
if ( !allowDepth && depth > 1 )
return {};
} else if ( byte == closeBracket ) {
changeDepth( highlighter, depth, sp, -1 );
if ( depth == 0 )
return sp;
if ( !allowDepth && depth > 1 )
return {};
}
auto prevPos = sp;
@@ -2553,7 +2557,8 @@ TextPosition TextDocument::getMatchingBracket( TextPosition sp,
}
TextRange TextDocument::getMatchingBracket( TextPosition start, const String& openBracket,
const String& closeBracket, MatchDirection dir ) {
const String& closeBracket, MatchDirection dir,
bool matchingXMLTags ) {
if ( !start.isValid() )
return {};
SyntaxHighlighter* highlighter = getHighlighter();
@@ -2579,9 +2584,34 @@ TextRange TextDocument::getMatchingBracket( TextPosition start, const String& op
do {
// Find all the open brackets between the first open bracket and the first close bracket
do {
foundOpen =
find( openBracket, start, true, false, TextDocument::FindReplaceType::Normal,
{ start, foundClose.start() } );
if ( matchingXMLTags ) {
// Ignore closed XML tags
do {
foundOpen = find( openBracket, start, true, false,
TextDocument::FindReplaceType::Normal,
{ start, foundClose.start() } );
if ( foundOpen.isValid() ) {
TextPosition closePosition =
getMatchingBracket( foundOpen.start(), openBracket[0], '>',
MatchDirection::Forward, false );
if ( closePosition.isValid() ) {
if ( getChar( positionOffset( closePosition, -1 ) ) != '/' ) {
break;
} else {
start = closePosition;
}
} else {
break;
}
}
} while ( foundOpen.isValid() );
} else {
foundOpen = find( openBracket, start, true, false,
TextDocument::FindReplaceType::Normal,
{ start, foundClose.start() } );
}
if ( foundOpen.isValid() ) {
start = foundOpen.end();
changeDepth( highlighter, depth, start, 1 );
@@ -2612,7 +2642,28 @@ TextRange TextDocument::getMatchingBracket( TextPosition start, const String& op
}
// Ensure there's an open bracket
auto foundOpen = findLast( openBracket, start );
TextRange foundOpen;
if ( matchingXMLTags ) {
do {
foundOpen = findLast( openBracket, start );
if ( foundOpen.isValid() ) {
TextPosition closePosition =
getMatchingBracket( foundOpen.normalized().start(), openBracket[0], '>',
MatchDirection::Forward, false );
if ( closePosition.isValid() ) {
if ( getChar( positionOffset( closePosition, -1 ) ) != '/' ) {
break;
} else {
start = foundOpen.normalized().start();
}
} else {
break;
}
}
} while ( foundOpen.isValid() );
} else {
foundOpen = findLast( openBracket, start );
}
if ( !foundOpen.isValid() )
return {}; // Not found, exit
@@ -2637,7 +2688,28 @@ TextRange TextDocument::getMatchingBracket( TextPosition start, const String& op
if ( depth > 0 ) {
// Find the next open bracket from the last open bracket
foundOpen = findLast( openBracket, start );
if ( matchingXMLTags ) {
do {
foundOpen = findLast( openBracket, start );
if ( foundOpen.isValid() ) {
TextPosition closePosition =
getMatchingBracket( foundOpen.normalized().start(), openBracket[0],
'>', MatchDirection::Forward, false );
if ( closePosition.isValid() ) {
if ( getChar( positionOffset( closePosition, -1 ) ) != '/' ) {
break;
} else {
start = foundOpen.normalized().start();
}
} else {
break;
}
}
} while ( foundOpen.isValid() );
} else {
foundOpen = findLast( openBracket, start );
}
if ( !foundOpen.isValid() )
break;
}

View File

@@ -231,7 +231,7 @@ void XMLToolsPlugin::XMLToolsClient::updateMatch( const TextRange& sel ) {
if ( !def.getAutoCloseXMLTags() ) // getAutoCloseXMLTags means that it supports XML element tags
return clearMatch();
TextRange range = mDoc->getWordRangeInPosition( sel.start(), false );
if ( !range.isValid() )
if ( !range.isValid() || !range.hasSelection() )
return clearMatch();
range.normalize();
if ( range.start().column() == 0 || line.size() <= 1 )
@@ -250,21 +250,41 @@ void XMLToolsPlugin::XMLToolsClient::updateMatch( const TextRange& sel ) {
return; // Moving inside match
}
String tag( mDoc->getText( range ) );
TextRange found;
const auto ensureMatchesWord = [&]( int offset ) {
if ( found.isValid() && found.hasSelection() ) {
found.normalize();
auto start( mDoc->positionOffset( found.start(), offset ) );
TextRange wordRange = mDoc->getWordRangeInPosition( start, false );
if ( !wordRange.isValid() ||
wordRange.normalized() != TextRange( start, found.end() ).normalized() ) {
found = TextRange();
}
}
};
if ( isCloseBracket ) {
String openBracket( tag );
openBracket.erase( 1 );
found = mDoc->getMatchingBracket( range.start(), openBracket, tag,
TextDocument::MatchDirection::Backward );
TextDocument::MatchDirection::Backward, true );
ensureMatchesWord( 1 );
} else {
// Ensure the current bracket is closed, otherwise don't try to match
TextPosition matchClose( mDoc->getMatchingBracket(
range.start(), '<', '>', TextDocument::MatchDirection::Forward, false ) );
if ( !matchClose.isValid() )
return;
String closeBracket( tag );
closeBracket.insert( 1, '/' );
found = mDoc->getMatchingBracket( range.start(), tag, closeBracket,
TextDocument::MatchDirection::Forward );
TextDocument::MatchDirection::Forward, true );
ensureMatchesWord( 2 );
}
if ( found.isValid() ) {
if ( found.isValid() && found.hasSelection() ) {
ClientMatch match{ range.normalized(), found.normalized(), isCloseBracket };
mParent->mMatches[mDoc] = std::move( match );
} else {