mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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" },
|
||||
|
||||
@@ -98,7 +98,7 @@ void addTypeScript() {
|
||||
},
|
||||
{},
|
||||
"//" } )
|
||||
.setSymbols( ts.getSymbols() )
|
||||
.setSymbols( ts.getSymbols(), ts.getSymbolNames() )
|
||||
.setLSPName( "typescriptreact" )
|
||||
.setFoldRangeType( FoldRangeType::Braces )
|
||||
.setFoldBraces( { { '{', '}' } } );
|
||||
|
||||
@@ -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" } );
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ) )
|
||||
|
||||
Reference in New Issue
Block a user