More code folding improvements. Added generic methods to not depend on the LSP when it's not available.

This commit is contained in:
Martín Lucas Golini
2024-05-30 00:56:20 -03:00
parent 416663675b
commit a4be2966fd
51 changed files with 397 additions and 180 deletions

View File

@@ -144,9 +144,9 @@ class EE_API SyntaxDefinition {
SyntaxDefinition& setFoldRangeType( FoldRangeType foldRangeType );
std::vector<std::pair<char, char>> getFoldBraces() const;
std::vector<std::pair<Int64, Int64>> getFoldBraces() const;
SyntaxDefinition& setFoldBraces( const std::vector<std::pair<char, char>>& foldBraces );
SyntaxDefinition& setFoldBraces( const std::vector<std::pair<Int64, Int64>>& foldBraces );
protected:
friend class SyntaxDefinitionManager;
@@ -162,7 +162,7 @@ class EE_API SyntaxDefinition {
std::string mLSPName;
Uint16 mLanguageIndex{ 0 };
FoldRangeType mFoldRangeType{ FoldRangeType::Undefined };
std::vector<std::pair<char, char>> mFoldBraces;
std::vector<std::pair<Int64, Int64>> mFoldBraces;
bool mAutoCloseXMLTags{ false };
bool mVisible{ true };
bool mHasExtensionPriority{ false };

View File

@@ -826,6 +826,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
LineWrapType mLineWrapType{ LineWrapType::Viewport };
Drawable* mFoldDrawable{ nullptr };
Drawable* mFoldedDrawable{ nullptr };
String::HashType mTagFoldRange{ 0 };
UICodeEditor( const std::string& elementTag, const bool& autoRegisterBaseCommands = true,
const bool& autoRegisterBaseKeybindings = true );
@@ -1016,6 +1017,10 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
size_t getTotalVisibleLines() const;
void invalidateLineWrapMaxWidth( bool force );
void findRegionsDelayed();
void refreshTag();
};
}} // namespace EE::UI

View File

@@ -1,28 +1,124 @@
#include "eepp/ui/doc/syntaxhighlighter.hpp"
#include <eepp/system/log.hpp>
#include <eepp/ui/doc/foldrangeservice.hpp>
#include <eepp/ui/doc/textdocument.hpp>
#include <stack>
namespace EE { namespace UI { namespace Doc {
static std::vector<TextRange> findFoldingRangesBraces( TextDocument* doc ) {
Clock c;
std::stack<TextPosition> braceStack;
std::vector<TextRange> regions;
const auto& braces = doc->getSyntaxDefinition().getFoldBraces();
size_t linesCount = doc->linesCount();
auto highlighter = doc->getHighlighter();
for ( size_t lineIdx = 0; lineIdx < linesCount; lineIdx++ ) {
const auto& line = doc->line( lineIdx ).getText();
size_t lineLength = line.length();
for ( size_t colIdx = 0; colIdx < lineLength; colIdx++ ) {
for ( const auto& bracePair : braces ) {
String::StringBaseType curChar = line[colIdx];
if ( curChar == bracePair.first ) {
auto textPosition = TextPosition( lineIdx, colIdx );
auto tokenType = highlighter->getTokenTypeAt( textPosition );
if ( tokenType != SyntaxStyleTypes::String &&
tokenType != SyntaxStyleTypes::Comment ) {
braceStack.push( TextPosition( lineIdx, colIdx ) );
}
} else if ( curChar == bracePair.second ) {
if ( !braceStack.empty() ) {
auto textPosition = TextPosition( lineIdx, colIdx );
auto tokenType = highlighter->getTokenTypeAt( textPosition );
if ( tokenType != SyntaxStyleTypes::String &&
tokenType != SyntaxStyleTypes::Comment ) {
auto start = braceStack.top();
braceStack.pop();
if ( start.line() != static_cast<Int64>( lineIdx ) )
regions.emplace_back( start, TextPosition( lineIdx, colIdx ) );
}
}
}
}
}
}
Log::debug( "findFoldingRangesBraces for \"%s\" took %s", doc->getFilePath(),
c.getElapsedTime().toString() );
return regions;
}
static int countLeadingSpaces( const String& line ) {
int count = 0;
for ( auto ch : line ) {
if ( ch != ' ' && ch != '\t' )
break;
++count;
}
return count;
}
static std::vector<TextRange> findFoldingRangesIndentation( TextDocument* doc ) {
Clock c;
std::stack<TextPosition> indentStack;
std::vector<TextRange> regions;
const auto& braces = doc->getSyntaxDefinition().getFoldBraces();
size_t linesCount = doc->linesCount();
int currentIndent = 0;
for ( size_t lineIdx = 0; lineIdx < linesCount; lineIdx++ ) {
const auto& line = doc->line( lineIdx ).getText();
int newIndent = countLeadingSpaces( line );
if ( newIndent > currentIndent ) {
// Block starts at the previous line
indentStack.push( { static_cast<Int64>( lineIdx - 1 ), 0 } );
} else if ( newIndent < currentIndent && !indentStack.empty() ) {
while ( !indentStack.empty() && indentStack.top().column() >= newIndent ) {
auto top = indentStack.top();
indentStack.pop();
// End at the previous line
regions.emplace_back( TextPosition( top.line(), 0 ),
TextPosition( static_cast<Int64>( lineIdx ) - 1, 0 ) );
}
}
currentIndent = newIndent;
}
// Close any remaining open blocks
while ( !indentStack.empty() ) {
auto top = indentStack.top();
indentStack.pop();
regions.emplace_back( TextPosition( top.line() + 1, 0 ),
TextPosition( static_cast<Int64>( linesCount ) - 1, 0 ) );
}
Log::debug( "findFoldingRangesIndentation for \"%s\" took %s", doc->getFilePath(),
c.getElapsedTime().toString() );
return regions;
}
FoldRangeServive::FoldRangeServive( TextDocument* doc ) : mDoc( doc ) {}
bool FoldRangeServive::canFold() const {
if ( mProvider && mProvider( mDoc, false ) )
return true;
// return mDoc->getSyntaxDefinition().getFoldRangeType() != FoldRangeType::Undefined;
return false;
// if ( mProvider && mProvider( mDoc, false ) )
// return true;
auto type = mDoc->getSyntaxDefinition().getFoldRangeType();
return type == FoldRangeType::Braces || type == FoldRangeType::Indentation;
}
void FoldRangeServive::findRegions() {
if ( mDoc == nullptr )
if ( mDoc == nullptr || !canFold() )
return;
if ( mProvider && mProvider( mDoc, true ) )
return;
// if ( mProvider && mProvider( mDoc, true ) )
// return;
switch ( mDoc->getSyntaxDefinition().getFoldRangeType() ) {
case FoldRangeType::Braces:
setFoldingRegions( findFoldingRangesBraces( mDoc ) );
break;
case FoldRangeType::Indentation:
setFoldingRegions( findFoldingRangesIndentation( mDoc ) );
case FoldRangeType::Tag:
case FoldRangeType::Undefined:
break;

View File

@@ -4,7 +4,7 @@
namespace EE { namespace UI { namespace Doc { namespace Language {
void addAdept() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Adept",
{ "%.adept$" },
{
@@ -124,6 +124,8 @@ void addAdept() {
{ "null", "literal" },
},
"//" } );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addAngelScript() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "AngelScript",
{ "%.as$", "%.asc$" },
@@ -55,6 +55,8 @@ void addAngelScript() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addBuzz() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Buzz",
{ "%.buzz$" },
@@ -48,6 +48,8 @@ void addBuzz() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -6,7 +6,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addCarbon() {
// Based in Lite-XL Rohan Vashisht implementation
// https://github.com/RohanVashisht1234/carbon_syntax_highlighter_lite-xl
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Carbon",
{ "%.carbon$" },
@@ -54,6 +54,8 @@ void addCarbon() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addContainerFile() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Containerfile",
{ "^[Cc]ontainerfile$", "^[dD]ockerfile$", "%.[dD]ockerfile$" },
@@ -41,6 +41,8 @@ void addContainerFile() {
"#",
{},
"dockerfile" } );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addCSharp() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "C#",
{ "%.cs$", "%.csx$" },
@@ -64,6 +64,8 @@ void addCSharp() {
"//",
{},
"csharp" } );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addCSS() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "CSS",
{ "%.css$" },
@@ -318,6 +318,8 @@ void addCSS() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addD() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "D",
{ "%.d$", "%.di$" },
@@ -143,6 +143,8 @@ void addD() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addDart() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Dart",
{ "%.dart$" },
@@ -47,6 +47,8 @@ void addDart() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addFantom() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Fantom",
{ "%.fan$", "%.fanx$" },
@@ -114,6 +114,8 @@ void addFantom() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -6,7 +6,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addFortran() {
// Based in Lite-XL Rohan Vashisht implementation
// https://github.com/RohanVashisht1234/fortran_syntax_highlighter_lite-xl
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Fortran",
{ "%.f$", "%.f90$", "%.f95$" },
@@ -52,6 +52,8 @@ void addFortran() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addGDScript() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "GDScript",
{ "%.gd$" },
@@ -102,6 +102,8 @@ void addGDScript() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addGLSL() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "GLSL",
{ "%.glsl$", "%.frag$", "%.vert$", "%.fs$", "%.vs$", "%.tesc", "%.tese" },
@@ -368,6 +368,8 @@ void addGLSL() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addGo() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Go",
{ "%.go$" },
@@ -56,6 +56,8 @@ void addGo() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addGroovy() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Groovy",
{ "%.groovy$" },
@@ -107,6 +107,8 @@ void addGroovy() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addHare() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Hare",
{ "%.ha$" },
@@ -64,6 +64,8 @@ void addHare() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addHLSL() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "HLSL",
{
@@ -264,6 +264,8 @@ void addHLSL() {
{ "trunc", "keyword" },
},
"//" } );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addJai() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Jai",
{ "%.jai$" },
@@ -59,6 +59,8 @@ void addJai() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addJava() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Java",
{ "%.java$", "%.bsh$" },
@@ -58,6 +58,8 @@ void addJava() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addJSON() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "JSON",
{ "%.json$", "%.cson$", "%.webmanifest" },
@@ -30,6 +30,8 @@ void addJSON() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' }, { '[', ']' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addJSX() {
SyntaxDefinitionManager::instance()
auto& sd = SyntaxDefinitionManager::instance()
->add( { "JSX",
{ "%.jsx$" },
{
@@ -58,6 +58,7 @@ void addJSX() {
.setAutoCloseXMLTags( true )
.setLSPName( "javascriptreact" );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addJulia() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Julia",
{ "%.jl$" },
@@ -68,6 +68,8 @@ void addJulia() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addKotlin() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Kotlin",
{ "%.kt$" },
@@ -70,6 +70,8 @@ void addKotlin() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addLobster() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Lobster",
{ "%.lobster$" },
@@ -46,6 +46,8 @@ void addLobster() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addLua() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Lua",
{ "%.lua$" },
@@ -41,6 +41,8 @@ void addLua() {
{ "^#!.*[ /]lua" }
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addMoonscript() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "MoonScript",
{ "%.moon$" },
@@ -49,6 +49,8 @@ void addMoonscript() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addNelua() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Nelua",
{ "%.nelua$" },
@@ -91,6 +91,8 @@ void addNelua() {
{ "^#!.*[ /]nelua" }
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -79,13 +79,15 @@ void addNim() {
nim_patterns.insert( nim_patterns.end(), nim_user_patterns.begin(), nim_user_patterns.end() );
SyntaxDefinitionManager::instance()->add( {
auto& sd = SyntaxDefinitionManager::instance()->add( {
"Nim",
{ "%.nim$", "%.nims$", "%.nimble$" },
std::move( nim_patterns ),
std::move( nim_symbols ),
"#",
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addObjeck() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Objeck",
{ "%.obs$" },
@@ -100,6 +100,8 @@ void addObjeck() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addObjectiveC() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Objective-C",
{ "%.m$" },
@@ -44,6 +44,8 @@ void addObjectiveC() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addOdin() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Odin",
{ "%.odin$" },
@@ -150,6 +150,8 @@ void addOdin() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addPHP() {
SyntaxDefinitionManager::instance()
auto& sd = SyntaxDefinitionManager::instance()
->add( { "PHP",
{ "%.php$", "%.php3$", "%.php4$", "%.php5$" },
{
@@ -103,6 +103,8 @@ void addPHP() {
{},
"php" } )
.setVisible( false );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,127 +5,129 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addPony() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{"pony",
{ "%.pony$" },
{
{ { "//.-\n" }, "comment" },
{ { "/%*", "%*/" }, "comment" },
{ { "\"\"\"", "\"\"\"" }, "comment" },
{ { "/%g", "/", "\\" }, "string" },
{ { "\"", "\"", "\\" }, "string" },
{ { "'.+'" }, "string" },
{ { "`", "`", "\\" }, "string" },
{ { "0x[%da-fA-F]+" }, "number" },
{ { "0b[%da-fA-F]+" }, "number" },
{ { "-?%d+[%d%_.eE]*" }, "number" },
{ { "-?%.?[%d]+" }, "number" },
{ { "^[0-9]{1,3}((_[0-9]{3})+)?$" }, "number" },
{ { "[%+%-=/%*%^%%<>!~|&?]" }, "operator" },
{ { "[%a_][%w_]*%f[(]" }, "function" },
{ { "[%a_][%w_]*" }, "symbol" },
{ { "%s+" }, "normal" },
{ { "%w+%f[%s]" }, "normal" },
{ "pony",
{ "%.pony$" },
{
{ { "//.-\n" }, "comment" },
{ { "/%*", "%*/" }, "comment" },
{ { "\"\"\"", "\"\"\"" }, "comment" },
{ { "/%g", "/", "\\" }, "string" },
{ { "\"", "\"", "\\" }, "string" },
{ { "'.+'" }, "string" },
{ { "`", "`", "\\" }, "string" },
{ { "0x[%da-fA-F]+" }, "number" },
{ { "0b[%da-fA-F]+" }, "number" },
{ { "-?%d+[%d%_.eE]*" }, "number" },
{ { "-?%.?[%d]+" }, "number" },
{ { "^[0-9]{1,3}((_[0-9]{3})+)?$" }, "number" },
{ { "[%+%-=/%*%^%%<>!~|&?]" }, "operator" },
{ { "[%a_][%w_]*%f[(]" }, "function" },
{ { "[%a_][%w_]*" }, "symbol" },
{ { "%s+" }, "normal" },
{ { "%w+%f[%s]" }, "normal" },
},
{
{ "then" , "keyword" },
{ "new" , "keyword" },
{ "continue" , "keyword2" },
{ "ifdef" , "keyword" },
{ "&" , "keyword2" },
{ "val" , "keyword" },
{ "I32" , "keyword" },
{ "this" , "keyword2" },
{ "Pointer" , "keyword" },
{ "consume" , "keyword2" },
{ "Array" , "keyword" },
{ "String" , "keyword" },
{ "F64" , "keyword" },
{ "xor" , "keyword2" },
{ "end" , "keyword" },
{ "addressof" , "keyword2" },
{ "U128" , "keyword" },
{ "object" , "keyword" },
{ "match" , "keyword" },
{ "with" , "keyword" },
{ "false" , "keyword2" },
{ "for" , "keyword" },
{ "while" , "keyword" },
{ "iso" , "keyword" },
{ "Stringable" , "keyword" },
{ "Iterator" , "keyword" },
{ "else" , "keyword" },
{ "recover" , "keyword2" },
{ "compile_intrinsic" , "keyword" },
{ "digestof" , "keyword2" },
{ "actor" , "keyword" },
{ "U32" , "keyword" },
{ "primitive" , "keyword" },
{ "iftype" , "keyword" },
{ "struct" , "keyword" },
{ "break" , "keyword2" },
{ "is" , "keyword2" },
{ "use" , "keyword" },
{ "or" , "keyword2" },
{ "until" , "keyword" },
{ "if" , "keyword" },
{ "let" , "keyword" },
{ "isnt" , "keyword2" },
{ "Any" , "keyword" },
{ "elseif" , "keyword" },
{ "in" , "keyword" },
{ "USize" , "keyword" },
{ "#alias" , "keyword2" },
{ "Env" , "keyword" },
{ "and" , "keyword2" },
{ "trn" , "keyword" },
{ "tag" , "keyword" },
{ "box" , "keyword" },
{ "None" , "keyword2" },
{ "trait" , "keyword" },
{ "return" , "keyword" },
{ "var" , "keyword" },
{ "U8" , "keyword" },
{ "error" , "keyword2" },
{ "try" , "keyword" },
{ "as" , "keyword2" },
{ "class" , "keyword" },
{ "ILong" , "keyword" },
{ "I8" , "keyword" },
{ "repeat" , "keyword" },
{ "U16" , "keyword" },
{ "#send" , "keyword2" },
{ "#any" , "keyword2" },
{ "#share" , "keyword2" },
{ "I128" , "keyword" },
{ "#read" , "keyword2" },
{ "F32" , "keyword" },
{ "compile_error" , "keyword" },
{ "embed" , "keyword" },
{ "where" , "keyword2" },
{ "true" , "keyword2" },
{ "not" , "keyword2" },
{ "Bool" , "keyword" },
{ "|" , "keyword2" },
{ "I64" , "keyword" },
{ "U64" , "keyword" },
{ "ULong" , "keyword" },
{ "I16" , "keyword" },
{ "interface" , "keyword" },
{ "be" , "keyword" },
{ "do" , "keyword" },
{ "fun" , "keyword" },
{ "ref" , "keyword" },
{ "ISize" , "keyword" },
{ "type" , "keyword" },
},
{
{ "then", "keyword" },
{ "new", "keyword" },
{ "continue", "keyword2" },
{ "ifdef", "keyword" },
{ "&", "keyword2" },
{ "val", "keyword" },
{ "I32", "keyword" },
{ "this", "keyword2" },
{ "Pointer", "keyword" },
{ "consume", "keyword2" },
{ "Array", "keyword" },
{ "String", "keyword" },
{ "F64", "keyword" },
{ "xor", "keyword2" },
{ "end", "keyword" },
{ "addressof", "keyword2" },
{ "U128", "keyword" },
{ "object", "keyword" },
{ "match", "keyword" },
{ "with", "keyword" },
{ "false", "keyword2" },
{ "for", "keyword" },
{ "while", "keyword" },
{ "iso", "keyword" },
{ "Stringable", "keyword" },
{ "Iterator", "keyword" },
{ "else", "keyword" },
{ "recover", "keyword2" },
{ "compile_intrinsic", "keyword" },
{ "digestof", "keyword2" },
{ "actor", "keyword" },
{ "U32", "keyword" },
{ "primitive", "keyword" },
{ "iftype", "keyword" },
{ "struct", "keyword" },
{ "break", "keyword2" },
{ "is", "keyword2" },
{ "use", "keyword" },
{ "or", "keyword2" },
{ "until", "keyword" },
{ "if", "keyword" },
{ "let", "keyword" },
{ "isnt", "keyword2" },
{ "Any", "keyword" },
{ "elseif", "keyword" },
{ "in", "keyword" },
{ "USize", "keyword" },
{ "#alias", "keyword2" },
{ "Env", "keyword" },
{ "and", "keyword2" },
{ "trn", "keyword" },
{ "tag", "keyword" },
{ "box", "keyword" },
{ "None", "keyword2" },
{ "trait", "keyword" },
{ "return", "keyword" },
{ "var", "keyword" },
{ "U8", "keyword" },
{ "error", "keyword2" },
{ "try", "keyword" },
{ "as", "keyword2" },
{ "class", "keyword" },
{ "ILong", "keyword" },
{ "I8", "keyword" },
{ "repeat", "keyword" },
{ "U16", "keyword" },
{ "#send", "keyword2" },
{ "#any", "keyword2" },
{ "#share", "keyword2" },
{ "I128", "keyword" },
{ "#read", "keyword2" },
{ "F32", "keyword" },
{ "compile_error", "keyword" },
{ "embed", "keyword" },
{ "where", "keyword2" },
{ "true", "keyword2" },
{ "not", "keyword2" },
{ "Bool", "keyword" },
{ "|", "keyword2" },
{ "I64", "keyword" },
{ "U64", "keyword" },
{ "ULong", "keyword" },
{ "I16", "keyword" },
{ "interface", "keyword" },
{ "be", "keyword" },
{ "do", "keyword" },
{ "fun", "keyword" },
{ "ref", "keyword" },
{ "ISize", "keyword" },
{ "type", "keyword" },
},
"//",
{}
},
"//",
{}
});
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addPython() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Python",
{ "%.py$", "%.pyw$", "%.bry$" },
@@ -41,6 +41,8 @@ void addPython() {
{ "^#!.*[ /]python", "^#!.*[ /]python3" }
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addRuby() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Ruby",
{ "%.rb", "%.gemspec", "%.ruby" },
@@ -78,6 +78,8 @@ void addRuby() {
{ "^#!.*[ /]ruby" }
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addRust() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Rust",
{ "%.rs$" },
@@ -56,6 +56,8 @@ void addRust() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addSolidity() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Solidity",
{ "%.sol$" },
@@ -148,6 +148,8 @@ void addSolidity() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addSwift() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Swift",
{ "%.swift$" },
@@ -225,6 +225,8 @@ void addSwift() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addTeal() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Teal",
{ "%.tl$", "%.d.tl$" },
@@ -44,6 +44,8 @@ void addTeal() {
{ "^#!.*[ /]tl" }
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addToml() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "TOML",
{ "%.toml$" },
@@ -41,6 +41,8 @@ void addToml() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addV() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "V",
{ "%.v$", "%.vsh$" },
@@ -60,6 +60,8 @@ void addV() {
{}
} ).setExtensionPriority( true );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addVala() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Vala",
{ "%.vala$", "%.genie$" },
@@ -71,6 +71,8 @@ void addVala() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addWren() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Wren",
{ "%.wren$" },
@@ -36,6 +36,8 @@ void addWren() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addYAML() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "YAML",
{ "%.yml$", "%.yaml$" },
@@ -47,6 +47,8 @@ void addYAML() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Indentation );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -5,7 +5,7 @@ namespace EE { namespace UI { namespace Doc { namespace Language {
void addZig() {
SyntaxDefinitionManager::instance()->add(
auto& sd = SyntaxDefinitionManager::instance()->add(
{ "Zig",
{ "%.zig$" },
@@ -120,6 +120,8 @@ void addZig() {
{}
} );
sd.setFoldRangeType( FoldRangeType::Braces ).setFoldBraces( { { '{', '}' } } );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -102,12 +102,12 @@ SyntaxDefinition& SyntaxDefinition::setFoldRangeType( FoldRangeType foldRangeTyp
return *this;
}
std::vector<std::pair<char, char>> SyntaxDefinition::getFoldBraces() const {
std::vector<std::pair<Int64, Int64>> SyntaxDefinition::getFoldBraces() const {
return mFoldBraces;
}
SyntaxDefinition&
SyntaxDefinition::setFoldBraces( const std::vector<std::pair<char, char>>& foldBraces ) {
SyntaxDefinition::setFoldBraces( const std::vector<std::pair<Int64, Int64>>& foldBraces ) {
mFoldBraces = foldBraces;
return *this;
}

View File

@@ -133,6 +133,7 @@ UICodeEditor::UICodeEditor( const std::string& elementTag, const bool& autoRegis
mFlags |= UI_TAB_STOP | UI_OWNS_CHILDS_POSITION | UI_SCROLLABLE;
setTextSelection( true );
setColorScheme( SyntaxColorScheme::getDefault() );
refreshTag();
mVScrollBar = UIScrollBar::NewVertical();
mVScrollBar->setParent( this );
mVScrollBar->addEventListener( Event::OnSizeChange,
@@ -621,6 +622,8 @@ void UICodeEditor::onDocumentReloaded( TextDocument* ) {
invalidateDraw();
invalidateLongestLineWidth();
invalidateLineWrapMaxWidth( true );
refreshTag();
findRegionsDelayed();
}
void UICodeEditor::onDocumentLoaded() {
@@ -630,6 +633,8 @@ void UICodeEditor::onDocumentLoaded() {
invalidateDraw();
invalidateLongestLineWidth();
invalidateLineWrapMaxWidth( true );
refreshTag();
findRegionsDelayed();
}
void UICodeEditor::onDocumentReset( TextDocument* ) {
@@ -640,6 +645,8 @@ void UICodeEditor::onDocumentReset( TextDocument* ) {
invalidateDraw();
invalidateLongestLineWidth();
invalidateLineWrapMaxWidth( true );
refreshTag();
findRegionsDelayed();
}
void UICodeEditor::onDocumentChanged() {
@@ -1915,6 +1922,8 @@ void UICodeEditor::onDocumentTextChanged( const DocumentContentChange& change )
} else {
invalidateLongestLineWidth();
}
findRegionsDelayed();
}
void UICodeEditor::onDocumentCursorChange( const Doc::TextPosition& ) {
@@ -1964,6 +1973,7 @@ void UICodeEditor::onDocumentSaved( TextDocument* doc ) {
void UICodeEditor::onDocumentMoved( TextDocument* doc ) {
DocEvent event( this, doc, Event::OnDocumentMoved );
sendEvent( &event );
refreshTag();
}
void UICodeEditor::onDocumentClosed( TextDocument* doc ) {
@@ -4750,4 +4760,19 @@ bool UICodeEditor::stopMinimapDragging( const Vector2f& mousePos ) {
return false;
}
void UICodeEditor::findRegionsDelayed() {
if ( !mDoc->getFoldRangeService().canFold() )
return;
UISceneNode* sceneNode = getUISceneNode();
if ( sceneNode ) {
sceneNode->removeActionsByTag( mTagFoldRange );
sceneNode->runOnMainThread( [this]() { mDoc->getFoldRangeService().findRegions(); },
Seconds( 1.f ), mTagFoldRange );
}
}
void UICodeEditor::refreshTag() {
mTagFoldRange = String::hash( mDoc->getURI().toString() + ":foldrange" );
}
}} // namespace EE::UI

View File

@@ -18,13 +18,13 @@ LSPDocumentClient::LSPDocumentClient( LSPClientServer* server, TextDocument* doc
notifyOpen();
requestSymbolsDelayed();
requestSemanticHighlightingDelayed();
requestFoldRangeDelayed();
doc->getFoldRangeService().setProvider( [this]( auto, bool requestFolds ) -> bool {
bool ret = mServer->getCapabilities().foldingRangeProvider;
if ( ret && requestFolds )
requestFoldRangeDelayed();
requestFoldRange();
return ret;
} );
mDoc->getFoldRangeService().findRegions();
}
LSPDocumentClient::~LSPDocumentClient() {
@@ -45,7 +45,6 @@ LSPDocumentClient::~LSPDocumentClient() {
void LSPDocumentClient::onDocumentLoaded( TextDocument* ) {
refreshTag();
requestSemanticHighlightingDelayed();
requestFoldRangeDelayed();
// requestCodeLens();
}
@@ -57,7 +56,6 @@ void LSPDocumentClient::onDocumentTextChanged( const DocumentContentChange& chan
mServer->getThreadPool()->run( [this, change]() { mServer->processDidChangeQueue(); } );
requestSymbolsDelayed();
requestSemanticHighlightingDelayed();
requestFoldRangeDelayed();
}
void LSPDocumentClient::onDocumentUndoRedo( const TextDocument::UndoRedo& /*eventType*/ ) {}
@@ -124,7 +122,7 @@ int LSPDocumentClient::getVersion() const {
void LSPDocumentClient::onServerInitialized() {
requestSymbols();
requestSemanticHighlighting();
requestFoldRange();
mDoc->getFoldRangeService().findRegions();
// requestCodeLens();
}
@@ -402,12 +400,16 @@ void LSPDocumentClient::requestFoldRange() {
if ( !server->getCapabilities().foldingRangeProvider )
return;
URI uri = mDoc->getURI();
auto handler = [uri, this]( const PluginIDType&, const std::vector<LSPFoldingRange>& res ) {
TextDocument* doc = mDoc;
auto handler = [uri, server, doc]( const PluginIDType&,
const std::vector<LSPFoldingRange>& res ) {
if ( !server->hasDocument( uri ) )
return;
std::vector<TextRange> regions;
regions.reserve( res.size() );
for ( const auto& region : res )
regions.push_back( { { region.startLine, 0 }, { region.endLine, 0 } } );
mDoc->getFoldRangeService().setFoldingRegions( regions );
doc->getFoldRangeService().setFoldingRegions( regions );
};
if ( Engine::instance()->isMainThread() ) {