Added C3 syntax highlighting and LSP support.

Refactored TextUndoStack, now uses std::variant and avoids heap allocating each command.
Fix possible crash in Process::readAll.
Fix SyntaxDefinition::setSymbols.
Some minor improvements for Odin and Ü syntax definitions.
Fix Git plugin silent configuration.
This commit is contained in:
Martín Lucas Golini
2025-04-04 01:48:39 -03:00
parent 8c131b2487
commit da85af1246
21 changed files with 333 additions and 188 deletions

View File

@@ -127,7 +127,7 @@
"cheapest": true
},
{
"name": "gemini-2.5-pro-exp-03-25",
"name": "gemini-2.0-pro-exp",
"display_name": "Gemini 2.5 Pro Experimental",
"max_tokens": 1000000
}

View File

@@ -398,6 +398,14 @@
"command": "md-lsp",
"file_patterns": ["%.md$"],
"rootIndicationFileNames": [".git"]
},
{
"language": "c3",
"name": "c3-lsp",
"url": "https://github.com/pherrymason/c3-lsp",
"command": "c3lsp",
"file_patterns": ["%.c3$"],
"rootIndicationFileNames": [".git"]
}
]
}

View File

@@ -104,7 +104,8 @@ class EE_API SyntaxDefinition {
SyntaxDefinition& addSymbols( const std::vector<std::string>& symbolNames,
const std::string& typeName );
SyntaxDefinition& setSymbols( const UnorderedMap<std::string, SyntaxStyleType>& symbols );
SyntaxDefinition& setSymbols( const UnorderedMap<std::string, SyntaxStyleType>& symbols,
const UnorderedMap<std::string, std::string>& symbolNames );
/** Sets the comment string used for auto-comment functionality. */
SyntaxDefinition& setComment( const std::string& comment );

View File

@@ -1,12 +1,16 @@
#ifndef EE_UI_DOC_TEXTUNDOSTACK_HPP
#define EE_UI_DOC_TEXTUNDOSTACK_HPP
#include <deque>
#include <eepp/config.hpp>
#include <eepp/core/string.hpp>
#include <eepp/system/time.hpp>
#include <eepp/ui/doc/textrange.hpp>
#include <nlohmann/json_fwd.hpp>
#include <deque>
#include <variant>
using namespace EE::System;
namespace EE { namespace UI { namespace Doc {
@@ -16,11 +20,93 @@ class TextUndoCommand;
enum class TextUndoCommandType { Insert = 1, Remove = 2, Selection = 3 };
using UndoStackContainer = std::deque<TextUndoCommand*>;
class TextUndoCommand {
public:
TextUndoCommand( const Uint64& id, const TextUndoCommandType& type, const Time& timestamp );
virtual ~TextUndoCommand();
const Uint64& getId() const;
const TextUndoCommandType& getType() const;
const Time& getTimestamp() const;
virtual nlohmann::json toJSON() const = 0;
protected:
Uint64 mId;
TextUndoCommandType mType;
Time mTimestamp;
nlohmann::json baseJSON() const;
};
class TextUndoCommandInsert : public TextUndoCommand {
public:
TextUndoCommandInsert( const Uint64& id, const size_t& cursorIdx, const String& text,
const TextPosition& position, const Time& timestamp );
const String& getText() const;
const TextPosition& getPosition() const;
size_t getCursorIdx() const;
nlohmann::json toJSON() const;
static TextUndoCommandInsert fromJSON( nlohmann::json j, Uint64 id );
protected:
String mText;
TextPosition mPosition;
size_t mCursorIdx;
};
class TextUndoCommandRemove : public TextUndoCommand {
public:
TextUndoCommandRemove( const Uint64& id, const size_t& cursorIdx, const TextRange& range,
const Time& timestamp );
const TextRange& getRange() const;
size_t getCursorIdx() const;
nlohmann::json toJSON() const;
static TextUndoCommandRemove fromJSON( nlohmann::json j, Uint64 id );
protected:
TextRange mRange;
size_t mCursorIdx;
};
class TextUndoCommandSelection : public TextUndoCommand {
public:
TextUndoCommandSelection( const Uint64& id, const size_t& cursorIdx,
const TextRanges& selection, const Time& timestamp );
const TextRanges& getSelection() const;
size_t getCursorIdx() const;
nlohmann::json toJSON() const;
static TextUndoCommandSelection fromJSON( nlohmann::json j, Uint64 id );
protected:
TextRanges mSelection;
size_t mCursorIdx;
};
using UndoCommandVariant =
std::variant<TextUndoCommandInsert, TextUndoCommandRemove, TextUndoCommandSelection>;
using UndoStackContainer = std::deque<UndoCommandVariant>;
class EE_API TextUndoStack {
public:
TextUndoStack( TextDocument* owner, const Uint32& maxStackSize = 10000 );
TextUndoStack( TextDocument* owner, const Uint32& maxStackSize = 20000 );
~TextUndoStack();
@@ -60,7 +146,7 @@ class EE_API TextUndoStack {
UndoStackContainer mRedoStack;
Time mMergeTimeout;
void pushUndo( UndoStackContainer& undoStack, TextUndoCommand* cmd );
void pushUndo( UndoStackContainer& undoStack, UndoCommandVariant&& cmd );
void pushInsert( UndoStackContainer& undoStack, const String& string, const size_t& cursorIdx,
const TextPosition& position, const Time& time );
@@ -76,6 +162,8 @@ class EE_API TextUndoStack {
UndoStackContainer& getRedoStackContainer();
void popUndo( UndoStackContainer& undoStack, UndoStackContainer& redoStack );
void limitStackSize( UndoStackContainer& stack );
};
}}} // namespace EE::UI::Doc

View File

@@ -133,7 +133,7 @@ inline bool consumeDigitsWithSep( const char* input, int& pos, int length, int b
inline size_t isNumberLiteralBase( const char* stringSearch, int stringStartOffset,
PatternMatcher::Range* matchList, size_t stringLength,
bool underscoreSeparatorSupported, bool supportsOctal,
bool supportsBinary ) {
bool supportsBinary, bool supportsBigInt ) {
if ( stringStartOffset < 0 || (size_t)stringStartOffset >= stringLength )
return 0;
@@ -380,7 +380,8 @@ inline size_t isNumberLiteralBase( const char* stringSearch, int stringStartOffs
if ( pos > start && stringSearch[pos - 1] == '_' ) {
return 0;
}
pos++; // Consume 'n'
if ( supportsBigInt )
pos++; // Consume 'n'
}
// Final check: Ensure we actually consumed something valid beyond just a sign
@@ -849,28 +850,28 @@ void ParserMatcherManager::registerBaseParsers() {
[]( const char* stringSearch, int stringStartOffset,
PatternMatcher::Range* matchList, size_t stringLength ) {
return isNumberLiteralBase( stringSearch, stringStartOffset, matchList,
stringLength, false, false, false );
stringLength, false, false, false, false );
} );
registerParser( "common_number_parser_o",
[]( const char* stringSearch, int stringStartOffset,
PatternMatcher::Range* matchList, size_t stringLength ) {
return isNumberLiteralBase( stringSearch, stringStartOffset, matchList,
stringLength, false, true, false );
stringLength, false, true, false, false );
} );
registerParser( "common_number_parser_ob",
[]( const char* stringSearch, int stringStartOffset,
PatternMatcher::Range* matchList, size_t stringLength ) {
return isNumberLiteralBase( stringSearch, stringStartOffset, matchList,
stringLength, false, true, true );
stringLength, false, true, true, false );
} );
registerParser( "js_number_parser",
[]( const char* stringSearch, int stringStartOffset,
PatternMatcher::Range* matchList, size_t stringLength ) {
return isNumberLiteralBase( stringSearch, stringStartOffset, matchList,
stringLength, true, true, true );
stringLength, true, true, true, true );
} );
}

View File

@@ -296,6 +296,10 @@ bool Process::isShuttingDown() const {
size_t Process::readAll( std::string& buffer, bool readErr, Time timeout ) {
eeASSERT( mProcess != nullptr );
if ( ( readErr && PROCESS_PTR->stderr_file == nullptr ) ||
( !readErr && PROCESS_PTR->stdout_file == nullptr ) ) {
return 0;
}
if ( buffer.empty() || buffer.size() < CHUNK_SIZE )
buffer.resize( CHUNK_SIZE );
size_t totalBytesRead = 0;

View File

@@ -176,8 +176,10 @@ SyntaxDefinition& SyntaxDefinition::addSymbols( const std::vector<std::string>&
}
SyntaxDefinition&
SyntaxDefinition::setSymbols( const UnorderedMap<std::string, SyntaxStyleType>& symbols ) {
SyntaxDefinition::setSymbols( const UnorderedMap<std::string, SyntaxStyleType>& symbols,
const UnorderedMap<std::string, std::string>& symbolNames ) {
mSymbols = symbols;
mSymbolNames = symbolNames;
return *this;
}

View File

@@ -482,7 +482,7 @@ bool SyntaxDefinitionManager::loadFromStream( IOStream& stream,
buffer.resize( stream.getSize() );
stream.read( buffer.data(), buffer.size() );
nlohmann::json j = nlohmann::json::parse( buffer );
nlohmann::json j = nlohmann::json::parse( buffer, nullptr, false, true );
if ( j.is_array() ) {
for ( const auto& lang : j ) {

View File

@@ -9,123 +9,56 @@ using namespace EE::System;
namespace EE { namespace UI { namespace Doc {
using json = nlohmann::json;
nlohmann::json TextUndoCommand::baseJSON() const {
nlohmann::json j;
j["type"] = mType;
j["timestamp"] = mTimestamp.toString();
return j;
}
class TextUndoCommand {
public:
TextUndoCommand( const Uint64& id, const TextUndoCommandType& type, const Time& timestamp );
nlohmann::json TextUndoCommandInsert::toJSON() const {
auto j = baseJSON();
j["text"] = mText.toUtf8();
j["position"] = mPosition.toString();
j["cursorIdx"] = mCursorIdx;
return j;
}
virtual ~TextUndoCommand();
TextUndoCommandInsert TextUndoCommandInsert::fromJSON( nlohmann::json j, Uint64 id ) {
auto timestamp = Time::fromString( j["timestamp"].get<std::string>() );
auto text = String::fromUtf8( j["text"].get<std::string>() );
auto position = TextPosition::fromString( j["position"].get<std::string>() );
auto cursorIdx = j["cursorIdx"].get<size_t>();
return TextUndoCommandInsert( id, cursorIdx, text, position, timestamp );
}
const Uint64& getId() const;
nlohmann::json TextUndoCommandRemove::toJSON() const {
auto j = baseJSON();
j["range"] = mRange.toString();
j["cursorIdx"] = mCursorIdx;
return j;
}
const TextUndoCommandType& getType() const;
TextUndoCommandRemove TextUndoCommandRemove::fromJSON( nlohmann::json j, Uint64 id ) {
auto timestamp = Time::fromString( j["timestamp"].get<std::string>() );
auto range = TextRange::fromString( j["range"].get<std::string>() );
auto cursorIdx = j["cursorIdx"].get<size_t>();
return TextUndoCommandRemove( id, cursorIdx, range, timestamp );
}
const Time& getTimestamp() const;
nlohmann::json TextUndoCommandSelection::toJSON() const {
auto j = baseJSON();
j["range"] = mSelection.toString();
j["cursorIdx"] = mCursorIdx;
return j;
}
virtual json toJSON() = 0;
protected:
Uint64 mId;
TextUndoCommandType mType;
Time mTimestamp;
json baseJSON() {
json j;
j["type"] = mType;
j["timestamp"] = mTimestamp.toString();
return j;
}
};
class TextUndoCommandInsert : public TextUndoCommand {
public:
TextUndoCommandInsert( const Uint64& id, const size_t& cursorIdx, const String& text,
const TextPosition& position, const Time& timestamp );
const String& getText() const;
const TextPosition& getPosition() const;
size_t getCursorIdx() const;
json toJSON() {
auto j = baseJSON();
j["text"] = mText.toUtf8();
j["position"] = mPosition.toString();
j["cursorIdx"] = mCursorIdx;
return j;
}
static TextUndoCommandInsert* fromJSON( json j, Uint64 id ) {
auto timestamp = Time::fromString( j["timestamp"].get<std::string>() );
auto text = String::fromUtf8( j["text"].get<std::string>() );
auto position = TextPosition::fromString( j["position"].get<std::string>() );
auto cursorIdx = j["cursorIdx"].get<size_t>();
return eeNew( TextUndoCommandInsert, ( id, cursorIdx, text, position, timestamp ) );
}
protected:
String mText;
TextPosition mPosition;
size_t mCursorIdx;
};
class TextUndoCommandRemove : public TextUndoCommand {
public:
TextUndoCommandRemove( const Uint64& id, const size_t& cursorIdx, const TextRange& range,
const Time& timestamp );
const TextRange& getRange() const;
size_t getCursorIdx() const;
json toJSON() {
auto j = baseJSON();
j["range"] = mRange.toString();
j["cursorIdx"] = mCursorIdx;
return j;
}
static TextUndoCommandRemove* fromJSON( json j, Uint64 id ) {
auto timestamp = Time::fromString( j["timestamp"].get<std::string>() );
auto range = TextRange::fromString( j["range"].get<std::string>() );
auto cursorIdx = j["cursorIdx"].get<size_t>();
return eeNew( TextUndoCommandRemove, ( id, cursorIdx, range, timestamp ) );
}
protected:
TextRange mRange;
size_t mCursorIdx;
};
class TextUndoCommandSelection : public TextUndoCommand {
public:
TextUndoCommandSelection( const Uint64& id, const size_t& cursorIdx,
const TextRanges& selection, const Time& timestamp );
const TextRanges& getSelection() const;
size_t getCursorIdx() const;
json toJSON() {
auto j = baseJSON();
j["range"] = mSelection.toString();
j["cursorIdx"] = mCursorIdx;
return j;
}
static TextUndoCommandSelection* fromJSON( json j, Uint64 id ) {
auto timestamp = Time::fromString( j["timestamp"].get<std::string>() );
auto range = TextRange::fromString( j["range"].get<std::string>() );
auto cursorIdx = j["cursorIdx"].get<size_t>();
return eeNew( TextUndoCommandSelection, ( id, cursorIdx, range, timestamp ) );
}
protected:
TextRanges mSelection;
size_t mCursorIdx;
};
TextUndoCommandSelection TextUndoCommandSelection::fromJSON( nlohmann::json j, Uint64 id ) {
auto timestamp = Time::fromString( j["timestamp"].get<std::string>() );
auto range = TextRange::fromString( j["range"].get<std::string>() );
auto cursorIdx = j["cursorIdx"].get<size_t>();
return TextUndoCommandSelection( id, cursorIdx, range, timestamp );
}
TextUndoCommand::TextUndoCommand( const Uint64& id, const TextUndoCommandType& type,
const Time& timestamp ) :
@@ -210,80 +143,78 @@ void TextUndoStack::clear() {
}
void TextUndoStack::clearUndoStack() {
for ( TextUndoCommand* cmd : mUndoStack ) {
eeDelete( cmd );
}
mUndoStack.clear();
}
void TextUndoStack::clearRedoStack() {
for ( TextUndoCommand* cmd : mRedoStack ) {
eeDelete( cmd );
}
mRedoStack.clear();
}
void TextUndoStack::pushUndo( UndoStackContainer& undoStack, TextUndoCommand* cmd ) {
undoStack.push_back( cmd );
while ( undoStack.size() > mMaxStackSize ) {
eeDelete( undoStack.front() );
undoStack.pop_front();
}
void TextUndoStack::limitStackSize( UndoStackContainer& stack ) {
while ( stack.size() > mMaxStackSize )
stack.pop_front();
}
void TextUndoStack::pushUndo( UndoStackContainer& undoStack, UndoCommandVariant&& cmd ) {
undoStack.emplace_back( std::move( cmd ) );
limitStackSize( undoStack );
}
void TextUndoStack::pushInsert( UndoStackContainer& undoStack, const String& string,
const size_t& cursorIdx, const TextPosition& position,
const Time& time ) {
pushUndo( undoStack, eeNew( TextUndoCommandInsert,
( ++mChangeIdCounter, cursorIdx, string, position, time ) ) );
pushUndo( undoStack,
TextUndoCommandInsert( ++mChangeIdCounter, cursorIdx, string, position, time ) );
}
void TextUndoStack::pushRemove( UndoStackContainer& undoStack, const size_t& cursorIdx,
const TextRange& range, const Time& time ) {
pushUndo( undoStack,
eeNew( TextUndoCommandRemove, ( ++mChangeIdCounter, cursorIdx, range, time ) ) );
pushUndo( undoStack, TextUndoCommandRemove( ++mChangeIdCounter, cursorIdx, range, time ) );
}
void TextUndoStack::pushSelection( UndoStackContainer& undoStack, const size_t& cursorIdx,
const TextRanges& selection, const Time& time ) {
pushUndo( undoStack, eeNew( TextUndoCommandSelection,
( ++mChangeIdCounter, cursorIdx, selection, time ) ) );
pushUndo( undoStack,
TextUndoCommandSelection( ++mChangeIdCounter, cursorIdx, selection, time ) );
}
void TextUndoStack::popUndo( UndoStackContainer& undoStack, UndoStackContainer& redoStack ) {
if ( undoStack.empty() )
return;
TextUndoCommand* cmd = undoStack.back();
Time lastTimestamp = cmd->getTimestamp();
UndoCommandVariant cmdVariant = std::move( undoStack.back() );
undoStack.pop_back();
switch ( cmd->getType() ) {
case TextUndoCommandType::Insert: {
TextUndoCommandInsert* insert = static_cast<TextUndoCommandInsert*>( cmd );
mDoc->insert( insert->getCursorIdx(), insert->getPosition(), insert->getText(),
redoStack, cmd->getTimestamp(), true );
break;
}
case TextUndoCommandType::Remove: {
TextUndoCommandRemove* remove = static_cast<TextUndoCommandRemove*>( cmd );
mDoc->remove( remove->getCursorIdx(), remove->getRange(), redoStack,
cmd->getTimestamp(), true );
break;
}
case TextUndoCommandType::Selection: {
TextUndoCommandSelection* selection = static_cast<TextUndoCommandSelection*>( cmd );
mDoc->resetSelection( selection->getSelection() );
break;
}
}
Time lastTimestamp;
eeSAFE_DELETE( cmd );
std::visit(
[&]( auto& cmd ) {
lastTimestamp = cmd.getTimestamp();
if ( !undoStack.empty() &&
eeabs( ( lastTimestamp - undoStack.back()->getTimestamp() ).asMilliseconds() ) <
using T = std::decay_t<decltype( cmd )>;
if constexpr ( std::is_same_v<T, TextUndoCommandInsert> ) {
mDoc->insert( cmd.getCursorIdx(), cmd.getPosition(), cmd.getText(), redoStack,
cmd.getTimestamp(), true );
} else if constexpr ( std::is_same_v<T, TextUndoCommandRemove> ) {
mDoc->remove( cmd.getCursorIdx(), cmd.getRange(), redoStack, cmd.getTimestamp(),
true );
} else if constexpr ( std::is_same_v<T, TextUndoCommandSelection> ) {
mDoc->resetSelection( cmd.getSelection() );
}
},
cmdVariant );
if ( !undoStack.empty() ) {
Time prevTimestamp;
std::visit(
[&prevTimestamp]( const auto& prevCmd ) { prevTimestamp = prevCmd.getTimestamp(); },
undoStack.back() );
if ( eeabs( ( lastTimestamp - prevTimestamp ).asMilliseconds() ) <
mMergeTimeout.asMilliseconds() ) {
popUndo( undoStack, redoStack );
popUndo( undoStack, redoStack );
}
}
}
@@ -318,35 +249,35 @@ void TextUndoStack::setMergeTimeout( const Time& mergeTimeout ) {
Uint64 TextUndoStack::getCurrentChangeId() const {
if ( mUndoStack.empty() )
return 0;
return mUndoStack.back()->getId();
return std::visit( []( const auto& cmd ) { return cmd.getId(); }, mUndoStack.back() );
}
std::string TextUndoStack::toJSON( bool inverted ) {
json j = json::array();
nlohmann::json j = nlohmann::json::array();
if ( inverted ) {
while ( hasUndo() )
undo();
for ( auto it = mRedoStack.rbegin(); it != mRedoStack.rend(); it++ ) {
auto cmd = *it;
j.push_back( cmd->toJSON() );
const auto& cmdVariant = *it;
std::visit( [&]( const auto& cmd ) { j.push_back( cmd.toJSON() ); }, cmdVariant );
}
while ( hasRedo() )
redo();
} else {
for ( auto it = mUndoStack.rbegin(); it != mUndoStack.rend(); it++ ) {
auto cmd = *it;
j.push_back( cmd->toJSON() );
const auto& cmdVariant = *it;
std::visit( [&]( const auto& cmd ) { j.push_back( cmd.toJSON() ); }, cmdVariant );
}
}
return j.dump();
}
void TextUndoStack::fromJSON( const std::string& jsonString ) {
json j;
nlohmann::json j;
try {
j = json::parse( jsonString, nullptr, true, true );
j = nlohmann::json::parse( jsonString, nullptr, true, true );
if ( !j.is_array() )
return;
for ( auto it = j.rbegin(); it != j.rend(); it++ ) {
@@ -367,7 +298,7 @@ void TextUndoStack::fromJSON( const std::string& jsonString ) {
break;
}
}
} catch ( const json::exception& ) {
} catch ( const nlohmann::json::exception& ) {
Log::error( "TextUndoStack::fromJSON - Error parsing json string:\n%s", jsonString );
}
}

View File

@@ -0,0 +1,77 @@
#include <eepp/ui/doc/languages/c3.hpp>
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
namespace EE { namespace UI { namespace Doc { namespace Language {
void addC3() {
SyntaxDefinitionManager::instance()->add(
{ "C3",
{ "%.c3$" },
{
{ { "//.-\n" }, "comment" },
{ { "/%*", "%*/" }, "comment" },
{ { "<%*", "%*>" }, "comment" },
{ { "\"", "\"", "\\" }, "string" },
{ { "'", "'", "\\" }, "string" },
{ { "`", "`" }, "string" },
{ { "(enum)%s+([%a][%w_]*)" }, { "keyword", "keyword", "keyword2" } },
{ { "(interface)%s+([%a][%w_]*)" }, { "keyword", "keyword", "keyword2" } },
{ { "(alias)%s+([%a][%w_]*)" }, { "keyword", "keyword", "keyword2" } },
{ { "(struct)%s+([%a][%w_]*)" }, { "keyword", "keyword", "keyword2" } },
{ { "(typedef)%s+([%a][%w_]*)" }, { "keyword", "keyword", "keyword2" } },
{ { "^%s*(import)%s+([%a][%w_%:,%s]*)%f[@;\n]" },
{ "normal", "keyword", "literal" } },
{ { "^%s*(module)%s+([%a][%w_%:%s%{%},]*)%s*%f[@;\n]" },
{ "normal", "keyword", "literal" } },
{ { "(fn)%s+([%a][%w_]*%*?%\?\?)%s+([%a][%w_]*)%.([%a_][%w_]*)%f[%(]" },
{ "normal", "keyword", "keyword2", "keyword2", "function" } },
{ { "(macro)%s+([%a][%w_]*%*?%\?\?)%s+([%a][%w_]*)%.([%a_][%w_]*)%f[%(]" },
{ "normal", "keyword", "keyword2", "keyword2", "function" } },
{ { "(fn)%s+([%a][%w_]*%*?%\?\?)%s+([%a][%w_]*)%f[%(]" },
{ "normal", "keyword", "keyword2", "function" } },
{ { "common_number_parser_ob" }, "number", "", SyntaxPatternMatchType::Parser },
{ { "[%a_][%w_]*%f[(]" }, "function" },
{ { "[<>~=+-*/%?]=" }, "operator" },
{ { "%.%." }, "operator" },
{ { "(@)([%a][%w_]*)" }, { "normal", "operator", "keyword" } },
{ { "$[%a_][%w_]*" }, "symbol" },
{ { "[%a_][%w_]*" }, "symbol" },
},
{
{ "anyfault", "keyword2" }, { "int", "keyword2" }, { "continue", "keyword" },
{ "asm", "keyword" }, { "BigInt", "keyword2" }, { "default", "keyword" },
{ "char", "keyword2" }, { "isz", "keyword2" }, { "define", "keyword" },
{ "bool", "keyword2" }, { "attribute", "keyword" }, { "faultdef", "keyword" },
{ "extern", "keyword" }, { "long", "keyword2" }, { "foreach", "keyword" },
{ "String", "keyword2" }, { "union", "keyword" }, { "short", "keyword2" },
{ "float16", "keyword2" }, { "any", "keyword2" }, { "usz", "keyword2" },
{ "false", "literal" }, { "for", "keyword" }, { "while", "keyword" },
{ "const", "keyword" }, { "$if", "keyword" }, { "float128", "keyword2" },
{ "null", "literal" }, { "else", "keyword" }, { "enum", "keyword" },
{ "$else", "keyword" }, { "struct", "keyword" }, { "break", "keyword" },
{ "uptr", "keyword2" }, { "if", "keyword" }, { "$endif", "keyword" },
{ "alias", "keyword" }, { "macro", "keyword" }, { "fault", "keyword" },
{ "switch", "keyword" }, { "nextcase", "keyword" }, { "double", "keyword2" },
{ "typeid", "keyword2" }, { "ulong", "keyword2" }, { "return", "keyword" },
{ "var", "keyword" }, { "import", "keyword" }, { "tlocal", "keyword" },
{ "try", "keyword" }, { "int128", "keyword2" }, { "void", "keyword" },
{ "byte", "keyword2" }, { "static", "keyword" }, { "inline", "keyword" },
{ "defer", "keyword" }, { "module", "keyword" }, { "uint", "keyword2" },
{ "iptr", "keyword2" }, { "assert", "keyword" }, { "typedef", "keyword" },
{ "def", "keyword" }, { "catch", "keyword" }, { "true", "literal" },
{ "ushort", "keyword2" }, { "float", "keyword2" }, { "local", "keyword" },
{ "foreach_r", "keyword" }, { "fn", "keyword" }, { "case", "keyword" },
{ "bitstruct", "keyword" }, { "interface", "keyword" }, { "uint128", "keyword2" },
{ "distinct", "keyword" }, { "do", "keyword" },
},
"//",
{}
} );
}
}}}} // namespace EE::UI::Doc::Language

View File

@@ -0,0 +1,10 @@
#ifndef EE_UI_DOC_C3
#define EE_UI_DOC_C3
namespace EE { namespace UI { namespace Doc { namespace Language {
extern void addC3();
}}}} // namespace EE::UI::Doc::Language
#endif

View File

@@ -11,10 +11,12 @@ void addOdin() {
{ "%.odin$" },
{
{ { "//.-\n" }, "comment" },
{ { "^%s*#.-\n" }, "comment" },
{ { "/%*", "%*/" }, "comment" },
{ { "\"", "\"", "\\" }, "string" },
{ { "'", "'", "\\" }, "string" },
{ { "`", "`" }, "string" },
{ { "(package)%s+(.-)\n" }, { "normal", "keyword", "keyword2" } },
{ { "0b[01_]+" }, "number" },
{ { "0o[0-7_]+" }, "number" },
{ { "0[dz][%d_]+" }, "number" },
@@ -22,6 +24,12 @@ void addOdin() {
{ { "-?%d+[%d%._e]*i?" }, "number" },
{ { "[<>~=+-*/]=" }, "operator" },
{ { "%.%." }, "operator" },
{ { "([%a_][%w_]*)%s+(%:%:)%s+(proc)%f[%(]" },
{ "normal", "function", "operator", "function" } },
{ { "([%a_][%w_]*)%s+(%:%:)%s+(union)%f[%(]" },
{ "normal", "keyword2", "operator", "keyword" } },
{ { "([%a_][%w_]*)%s+(%:%:)%s+(struct)%f[%(]" },
{ "normal", "keyword2", "operator", "keyword" } },
{ { "[%+%-=/%*%^%%<>!~|&:%?]" }, "operator" },
{ { "%$[%a_][%w_]*" }, "operator" },
{ { "[%a_][%w_]*%f[(]" }, "function" },

View File

@@ -98,7 +98,7 @@ void addTypeScript() {
},
{},
"//" } )
.setSymbols( ts.getSymbols() )
.setSymbols( ts.getSymbols(), ts.getSymbolNames() )
.setLSPName( "typescriptreact" )
.setFoldRangeType( FoldRangeType::Braces )
.setFoldBraces( { { '{', '}' } } );

View File

@@ -16,6 +16,11 @@ void addU() {
{ { "/%*", "%*/" }, "comment" },
{ { "\"", "[\"\n]", "\\" }, "string" },
{ { "'", "'", "\\" }, "string" },
{ { "(class|template|namespace|enum)\\s+([A-Za-z]\\w*)" },
{ "keyword", "keyword", "keyword2" },
"",
SyntaxPatternMatchType::RegEx },
{ { "$%(([%a_]%w*)%)" }, { "operator", "keyword2", "keyword2" } },
{ { "^%s*(import)%s+([<%\"][%w%d%.%\\%/%_%-]+[>%\"])" },
{ "keyword", "keyword", "literal" } },
{ { "cpp_number_parser" }, "number", "", SyntaxPatternMatchType::Parser },
@@ -26,6 +31,8 @@ void addU() {
},
{
{ "pretty_main", "function" },
{ "fn", "keyword" },
{ "op", "keyword" },
{ "var", "keyword" },
@@ -155,8 +162,7 @@ void addU() {
{ "byte2048", "keyword2" },
{ "byte4096", "keyword2" },
{ "size_type", "keyword2" },
{ "ssize_type", "keyword2" }
},
{ "ssize_type", "keyword2" } },
"//",
{},
"u" } );

View File

@@ -9,6 +9,7 @@
#include <eepp/ui/doc/languages/blueprint.hpp>
#include <eepp/ui/doc/languages/brainfuck.hpp>
#include <eepp/ui/doc/languages/buzz.hpp>
#include <eepp/ui/doc/languages/c3.hpp>
#include <eepp/ui/doc/languages/carbon.hpp>
#include <eepp/ui/doc/languages/clojure.hpp>
#include <eepp/ui/doc/languages/cmake.hpp>
@@ -114,6 +115,7 @@ void LanguagesSyntaxHighlighting::load() {
addBlueprint();
addBrainfuck();
addBuzz();
addC3();
addCarbon();
addContainerFile();
addCovScript();

View File

@@ -3549,7 +3549,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe
mThreadPool->run( [this] {
// Load language definitions
Clock defClock;
SyntaxDefinitionManager::createSingleton( 119 );
SyntaxDefinitionManager::createSingleton( 120 );
Language::LanguagesSyntaxHighlighting::load();
SyntaxDefinitionManager::instance()->setLanguageExtensionsPriority(
mConfig.languagesExtensions.priorities );

View File

@@ -52,7 +52,8 @@ int Git::git( const std::string& args, const std::string& projectDir, std::strin
Log::instance()->writef( mLogLevel, "GitPlugin cmd in %s (%d): %s %s",
clock.getElapsedTime().toString(), retCode, mGitPath, args );
}
Log::debug( "%s", buf );
if ( !mSilent )
Log::debug( "%s", buf );
return retCode;
}

View File

@@ -353,6 +353,10 @@ class Git {
LogLevel getLogLevel() const { return mLogLevel; }
void setSilent( bool set ) { mSilent = set; }
bool isSilent() const { return mSilent; }
Result stashPush( std::vector<std::string> files, const std::string& name, bool keepIndex,
const std::string& projectDir = "" );
@@ -369,6 +373,7 @@ class Git {
LogLevel mLogLevel{ LogLevel::Error };
Mutex mSubModulesMutex;
bool mSubModulesUpdated{ false };
bool mSilent{ false };
};
} // namespace ecode

View File

@@ -196,9 +196,9 @@ void GitPlugin::load( PluginManager* pluginManager ) {
}
if ( config.contains( "silent" ) )
mSilence = config.value( "silent", true );
mSilent = config.value( "silent", true );
else {
config["silent"] = mSilence;
config["silent"] = mSilent;
updateConfigFile = true;
}
}
@@ -230,7 +230,8 @@ void GitPlugin::load( PluginManager* pluginManager ) {
}
mGit = std::make_unique<Git>( pluginManager->getWorkspaceFolder() );
mGit->setLogLevel( mSilence ? LogLevel::Warning : LogLevel::Info );
mGit->setLogLevel( Log::instance()->getLogLevelThreshold() );
mGit->setSilent( mSilent );
mGitFound = !mGit->getGitPath().empty();
mProjectPath = mRepoSelected = mGit->getProjectPath();

View File

@@ -75,7 +75,7 @@ class GitPlugin : public PluginBase {
void updateRepos();
bool isSilent() const { return mSilence; }
bool isSilent() const { return mSilent; }
protected:
std::unique_ptr<Git> mGit;
@@ -97,7 +97,7 @@ class GitPlugin : public PluginBase {
bool mOldDontAutoHideOnMouseMove{ false };
bool mOldUsingCustomStyling{ false };
bool mInitialized{ false };
bool mSilence{ true };
bool mSilent{ true };
Uint32 mOldTextStyle{ 0 };
Uint32 mOldTextAlign{ 0 };
Color mOldBackgroundColor;

View File

@@ -752,7 +752,7 @@ static LSPMarkupContent parseMarkupContent( const json& v ) {
static LSPHover parseHover( const json& result ) {
LSPHover ret;
if ( result.is_null() || !result.contains( "contains" ) )
if ( result.is_null() || result.empty() )
return ret;
if ( result.contains( MEMBER_RANGE ) )