mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-27 00:28:34 +03:00
System::Process now supports set working directory.
ecode: Started working on the LSP plugin. Some minor refactor. Fixed "Editor Font Size". Fixed Formatter and Linter in single thread mode.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <eepp/system/pack.hpp>
|
||||
#include <eepp/system/packmanager.hpp>
|
||||
#include <eepp/system/pak.hpp>
|
||||
#include <eepp/system/process.hpp>
|
||||
#include <eepp/system/rc4.hpp>
|
||||
#include <eepp/system/resourceloader.hpp>
|
||||
#include <eepp/system/resourcemanager.hpp>
|
||||
|
||||
@@ -49,7 +49,8 @@ class EE_API Process {
|
||||
** @param command Command line to execute for this process.
|
||||
** @param options A bit field of Options's to pass. */
|
||||
Process( const std::string& command, const Uint32& options = getDefaultOptions(),
|
||||
const size_t& bufferSize = 132072 );
|
||||
const std::map<std::string, std::string>& environment = {},
|
||||
const std::string& workingDirectory = "", const size_t& bufferSize = 132072 );
|
||||
|
||||
~Process();
|
||||
|
||||
@@ -58,7 +59,8 @@ class EE_API Process {
|
||||
** @param options A bit field of Options's to pass.
|
||||
** @return On success true is returned. */
|
||||
bool create( const std::string& command, const Uint32& options = getDefaultOptions(),
|
||||
const std::map<std::string, std::string>& environment = {} );
|
||||
const std::map<std::string, std::string>& environment = {},
|
||||
const std::string& workingDirectory = "" );
|
||||
|
||||
/** @brief Starts a new thread to receive all stdout and stderr data */
|
||||
void startAsyncRead( ReadFn readStdOut = nullptr, ReadFn readStdErr = nullptr );
|
||||
|
||||
@@ -15,28 +15,32 @@ class EE_API SyntaxDefinitionManager {
|
||||
|
||||
const SyntaxDefinition& getPlainStyle() const;
|
||||
|
||||
const SyntaxDefinition& getStyleByExtension( const std::string& filePath ) const;
|
||||
const SyntaxDefinition& getByExtension( const std::string& filePath ) const;
|
||||
|
||||
const SyntaxDefinition& getStyleByHeader( const std::string& header ) const;
|
||||
const SyntaxDefinition& getByHeader( const std::string& header ) const;
|
||||
|
||||
const SyntaxDefinition& find( const std::string& filePath, const std::string& header );
|
||||
|
||||
SyntaxDefinition& getStyleByExtensionRef( const std::string& filePath );
|
||||
SyntaxDefinition& getByExtensionRef( const std::string& filePath );
|
||||
|
||||
const SyntaxDefinition& getStyleByLanguageName( const std::string& name ) const;
|
||||
const SyntaxDefinition& getByLanguageName( const std::string& name ) const;
|
||||
|
||||
const SyntaxDefinition& getStyleByLanguageId( const String::HashType& id ) const;
|
||||
const SyntaxDefinition& getByLanguageId( const String::HashType& id ) const;
|
||||
|
||||
SyntaxDefinition& getStyleByLanguageNameRef( const std::string& name );
|
||||
SyntaxDefinition& getByLanguageNameRef( const std::string& name );
|
||||
|
||||
std::vector<std::string> getLanguageNames() const;
|
||||
|
||||
std::vector<std::string> getExtensionsPatternsSupported() const;
|
||||
|
||||
const SyntaxDefinition* getPtrByLanguageName( const std::string& name ) const;
|
||||
|
||||
const SyntaxDefinition* getPtrByLanguageId( const String::HashType& id ) const;
|
||||
|
||||
protected:
|
||||
SyntaxDefinitionManager();
|
||||
|
||||
std::vector<SyntaxDefinition> mStyles;
|
||||
std::vector<SyntaxDefinition> mDefinitions;
|
||||
|
||||
void addPlainText();
|
||||
|
||||
|
||||
@@ -551,7 +551,6 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
linkoptions { "-s TOTAL_MEMORY=67108864" }
|
||||
linkoptions { "-s USE_SDL=2" }
|
||||
buildoptions { "-s USE_SDL=2" }
|
||||
defines { "NO_POSIX_SPAWN" }
|
||||
|
||||
if _OPTIONS["with-emscripten-pthreads"] then
|
||||
buildoptions { "-s USE_PTHREADS=1" }
|
||||
|
||||
@@ -39,7 +39,6 @@ EEPP_C_FLAGS := \
|
||||
-DEE_MBEDTLS \
|
||||
-D$(EE_SDL_VERSION) \
|
||||
-DAL_LIBTYPE_STATIC \
|
||||
-DNO_POSIX_SPAWN \
|
||||
-I$(EEPP_INC_PATH) \
|
||||
-I$(EEPP_BASE_PATH)
|
||||
|
||||
|
||||
@@ -1166,6 +1166,12 @@
|
||||
../../src/tools/ecode/notificationcenter.hpp
|
||||
../../src/tools/ecode/plugins/linter/linterplugin.cpp
|
||||
../../src/tools/ecode/plugins/linter/linterplugin.hpp
|
||||
../../src/tools/ecode/plugins/lsp/lspclient.cpp
|
||||
../../src/tools/ecode/plugins/lsp/lspclient.hpp
|
||||
../../src/tools/ecode/plugins/lsp/lspclientmanager.cpp
|
||||
../../src/tools/ecode/plugins/lsp/lspclientmanager.hpp
|
||||
../../src/tools/ecode/plugins/lsp/lspplugin.cpp
|
||||
../../src/tools/ecode/plugins/lsp/lspplugin.hpp
|
||||
../../src/tools/ecode/plugins/pluginmanager.cpp
|
||||
../../src/tools/ecode/plugins/pluginmanager.hpp
|
||||
../../src/tools/ecode/projectdirectorytree.cpp
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <eepp/core/debug.hpp>
|
||||
#include <eepp/core/memorymanager.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/lock.hpp>
|
||||
#include <eepp/system/process.hpp>
|
||||
#include <thirdparty/subprocess/subprocess.h>
|
||||
@@ -21,9 +22,11 @@ namespace EE { namespace System {
|
||||
|
||||
Process::Process() {}
|
||||
|
||||
Process::Process( const std::string& command, const Uint32& options, const size_t& bufferSize ) :
|
||||
Process::Process( const std::string& command, const Uint32& options,
|
||||
const std::map<std::string, std::string>& environment,
|
||||
const std::string& workingDirectory, const size_t& bufferSize ) :
|
||||
mBufferSize( bufferSize ) {
|
||||
create( command, options );
|
||||
create( command, options, environment, workingDirectory );
|
||||
}
|
||||
|
||||
Process::~Process() {
|
||||
@@ -36,7 +39,8 @@ Process::~Process() {
|
||||
}
|
||||
|
||||
bool Process::create( const std::string& command, const Uint32& options,
|
||||
const std::map<std::string, std::string>& environment ) {
|
||||
const std::map<std::string, std::string>& environment,
|
||||
const std::string& workingDirectory ) {
|
||||
if ( mProcess )
|
||||
return false;
|
||||
std::vector<std::string> cmdArr = String::split( command, " ", "", "\"", true );
|
||||
@@ -54,9 +58,22 @@ bool Process::create( const std::string& command, const Uint32& options,
|
||||
envStrings.push_back( envArr[envArr.size() - 1].c_str() );
|
||||
}
|
||||
envStrings.push_back( NULL );
|
||||
return 0 == subprocess_create_ex( strings.data(), options, envStrings.data(), PROCESS_PTR );
|
||||
|
||||
std::string cwd;
|
||||
if ( !workingDirectory.empty() ) {
|
||||
cwd = FileSystem::getCurrentWorkingDirectory();
|
||||
}
|
||||
|
||||
auto ret = 0 == subprocess_create_ex( strings.data(), options, envStrings.data(),
|
||||
!workingDirectory.empty() ? workingDirectory.c_str()
|
||||
: nullptr,
|
||||
PROCESS_PTR );
|
||||
|
||||
return ret;
|
||||
}
|
||||
return 0 == subprocess_create( strings.data(), options, PROCESS_PTR );
|
||||
return 0 == subprocess_create_ex(
|
||||
strings.data(), options, nullptr,
|
||||
!workingDirectory.empty() ? workingDirectory.c_str() : nullptr, PROCESS_PTR );
|
||||
}
|
||||
|
||||
size_t Process::readAllStdOut( std::string& buffer ) {
|
||||
|
||||
@@ -3724,43 +3724,43 @@ void SyntaxDefinitionManager::addxit() {
|
||||
}
|
||||
|
||||
SyntaxDefinition& SyntaxDefinitionManager::add( SyntaxDefinition&& syntaxStyle ) {
|
||||
mStyles.emplace_back( std::move( syntaxStyle ) );
|
||||
return mStyles.back();
|
||||
mDefinitions.emplace_back( std::move( syntaxStyle ) );
|
||||
return mDefinitions.back();
|
||||
}
|
||||
|
||||
const SyntaxDefinition& SyntaxDefinitionManager::getPlainStyle() const {
|
||||
return mStyles[0];
|
||||
return mDefinitions[0];
|
||||
}
|
||||
|
||||
SyntaxDefinition& SyntaxDefinitionManager::getStyleByExtensionRef( const std::string& filePath ) {
|
||||
return const_cast<SyntaxDefinition&>( getStyleByExtension( filePath ) );
|
||||
SyntaxDefinition& SyntaxDefinitionManager::getByExtensionRef( const std::string& filePath ) {
|
||||
return const_cast<SyntaxDefinition&>( getByExtension( filePath ) );
|
||||
}
|
||||
|
||||
const SyntaxDefinition&
|
||||
SyntaxDefinitionManager::getStyleByLanguageName( const std::string& name ) const {
|
||||
for ( auto& style : mStyles ) {
|
||||
SyntaxDefinitionManager::getByLanguageName( const std::string& name ) const {
|
||||
for ( auto& style : mDefinitions ) {
|
||||
if ( style.getLanguageName() == name )
|
||||
return style;
|
||||
}
|
||||
return mStyles[0];
|
||||
return mDefinitions[0];
|
||||
}
|
||||
|
||||
const SyntaxDefinition&
|
||||
SyntaxDefinitionManager::getStyleByLanguageId( const String::HashType& id ) const {
|
||||
for ( auto& style : mStyles ) {
|
||||
SyntaxDefinitionManager::getByLanguageId( const String::HashType& id ) const {
|
||||
for ( auto& style : mDefinitions ) {
|
||||
if ( style.getLanguageId() == id )
|
||||
return style;
|
||||
}
|
||||
return mStyles[0];
|
||||
return mDefinitions[0];
|
||||
}
|
||||
|
||||
SyntaxDefinition& SyntaxDefinitionManager::getStyleByLanguageNameRef( const std::string& name ) {
|
||||
return const_cast<SyntaxDefinition&>( getStyleByLanguageName( name ) );
|
||||
SyntaxDefinition& SyntaxDefinitionManager::getByLanguageNameRef( const std::string& name ) {
|
||||
return const_cast<SyntaxDefinition&>( getByLanguageName( name ) );
|
||||
}
|
||||
|
||||
std::vector<std::string> SyntaxDefinitionManager::getLanguageNames() const {
|
||||
std::vector<std::string> names;
|
||||
for ( auto& style : mStyles ) {
|
||||
for ( auto& style : mDefinitions ) {
|
||||
names.push_back( style.getLanguageName() );
|
||||
}
|
||||
std::sort( names.begin(), names.end() );
|
||||
@@ -3769,14 +3769,24 @@ std::vector<std::string> SyntaxDefinitionManager::getLanguageNames() const {
|
||||
|
||||
std::vector<std::string> SyntaxDefinitionManager::getExtensionsPatternsSupported() const {
|
||||
std::vector<std::string> exts;
|
||||
for ( auto& style : mStyles )
|
||||
for ( auto& style : mDefinitions )
|
||||
for ( auto& pattern : style.getFiles() )
|
||||
exts.emplace_back( pattern );
|
||||
return exts;
|
||||
}
|
||||
|
||||
const SyntaxDefinition*
|
||||
SyntaxDefinitionManager::getPtrByLanguageName( const std::string& name ) const {
|
||||
return &getByLanguageName( name );
|
||||
}
|
||||
|
||||
const SyntaxDefinition*
|
||||
SyntaxDefinitionManager::getPtrByLanguageId( const String::HashType& id ) const {
|
||||
return &getByLanguageId( id );
|
||||
}
|
||||
|
||||
const SyntaxDefinition&
|
||||
SyntaxDefinitionManager::getStyleByExtension( const std::string& filePath ) const {
|
||||
SyntaxDefinitionManager::getByExtension( const std::string& filePath ) const {
|
||||
std::string extension( FileSystem::fileExtension( filePath ) );
|
||||
std::string fileName( FileSystem::fileNameFromPath( filePath ) );
|
||||
|
||||
@@ -3785,7 +3795,7 @@ SyntaxDefinitionManager::getStyleByExtension( const std::string& filePath ) cons
|
||||
extension = FileSystem::fileNameFromPath( filePath );
|
||||
|
||||
if ( !extension.empty() ) {
|
||||
for ( auto style = mStyles.rbegin(); style != mStyles.rend(); ++style ) {
|
||||
for ( auto style = mDefinitions.rbegin(); style != mDefinitions.rend(); ++style ) {
|
||||
for ( const auto& ext : style->getFiles() ) {
|
||||
if ( String::startsWith( ext, "%." ) || String::startsWith( ext, "^" ) ||
|
||||
String::endsWith( ext, "$" ) ) {
|
||||
@@ -3799,13 +3809,12 @@ SyntaxDefinitionManager::getStyleByExtension( const std::string& filePath ) cons
|
||||
}
|
||||
}
|
||||
}
|
||||
return mStyles[0];
|
||||
return mDefinitions[0];
|
||||
}
|
||||
|
||||
const SyntaxDefinition&
|
||||
SyntaxDefinitionManager::getStyleByHeader( const std::string& header ) const {
|
||||
const SyntaxDefinition& SyntaxDefinitionManager::getByHeader( const std::string& header ) const {
|
||||
if ( !header.empty() ) {
|
||||
for ( auto style = mStyles.rbegin(); style != mStyles.rend(); ++style ) {
|
||||
for ( auto style = mDefinitions.rbegin(); style != mDefinitions.rend(); ++style ) {
|
||||
for ( const auto& hdr : style->getHeaders() ) {
|
||||
LuaPattern words( hdr );
|
||||
int start, end;
|
||||
@@ -3815,14 +3824,14 @@ SyntaxDefinitionManager::getStyleByHeader( const std::string& header ) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
return mStyles[0];
|
||||
return mDefinitions[0];
|
||||
}
|
||||
|
||||
const SyntaxDefinition& SyntaxDefinitionManager::find( const std::string& filePath,
|
||||
const std::string& header ) {
|
||||
const SyntaxDefinition& def = getStyleByHeader( header );
|
||||
if ( def.getLanguageName() == mStyles[0].getLanguageName() )
|
||||
return getStyleByExtension( filePath );
|
||||
const SyntaxDefinition& def = getByHeader( header );
|
||||
if ( def.getLanguageName() == mDefinitions[0].getLanguageName() )
|
||||
return getByExtension( filePath );
|
||||
return def;
|
||||
}
|
||||
}}} // namespace EE::UI::Doc
|
||||
|
||||
@@ -98,7 +98,7 @@ SyntaxState SyntaxTokenizer::retrieveSyntaxState( const SyntaxDefinition& syntax
|
||||
syntaxState.subsyntaxInfo =
|
||||
&syntaxState.currentSyntax->getPatterns()[target - 1];
|
||||
syntaxState.currentSyntax =
|
||||
&SyntaxDefinitionManager::instance()->getStyleByLanguageName(
|
||||
&SyntaxDefinitionManager::instance()->getByLanguageName(
|
||||
syntaxState.subsyntaxInfo->syntax );
|
||||
syntaxState.currentPatternIdx = SYNTAX_TOKENIZER_STATE_NONE;
|
||||
syntaxState.currentLevel++;
|
||||
@@ -141,7 +141,7 @@ SyntaxTokenizer::tokenize( const SyntaxDefinition& syntax, const std::string& te
|
||||
setSubsyntaxPatternIdx( patternIndex );
|
||||
curState.currentLevel++;
|
||||
curState.subsyntaxInfo = &enteringSubsyntax;
|
||||
curState.currentSyntax = &SyntaxDefinitionManager::instance()->getStyleByLanguageName(
|
||||
curState.currentSyntax = &SyntaxDefinitionManager::instance()->getByLanguageName(
|
||||
curState.subsyntaxInfo->syntax );
|
||||
setSubsyntaxPatternIdx( SYNTAX_TOKENIZER_STATE_NONE );
|
||||
};
|
||||
|
||||
+14
-3
@@ -113,6 +113,7 @@ subprocess_weak int subprocess_create(const char *const command_line[],
|
||||
subprocess_weak int
|
||||
subprocess_create_ex(const char *const command_line[], int options,
|
||||
const char *const environment[],
|
||||
const char *working_directory,
|
||||
struct subprocess_s *const out_process);
|
||||
|
||||
/// @brief Get the standard input file for a process.
|
||||
@@ -451,11 +452,12 @@ int subprocess_create_named_pipe_helper(void **rd, void **wr) {
|
||||
int subprocess_create(const char *const commandLine[], int options,
|
||||
struct subprocess_s *const out_process) {
|
||||
return subprocess_create_ex(commandLine, options, SUBPROCESS_NULL,
|
||||
out_process);
|
||||
SUBPROCESS_NULL, out_process);
|
||||
}
|
||||
|
||||
int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
const char *const environment[],
|
||||
const char* working_directory,
|
||||
struct subprocess_s *const out_process) {
|
||||
#if defined(_WIN32)
|
||||
int fd;
|
||||
@@ -710,7 +712,7 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
1, // handles are inherited
|
||||
flags, // creation flags
|
||||
used_environment, // used environment
|
||||
SUBPROCESS_NULL, // use parent's current directory
|
||||
working_directory, // set process working directory
|
||||
SUBPROCESS_PTR_CAST(LPSTARTUPINFOA,
|
||||
&startInfo), // STARTUPINFO pointer
|
||||
SUBPROCESS_PTR_CAST(LPPROCESS_INFORMATION, &processInfo))) {
|
||||
@@ -764,7 +766,7 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NO_POSIX_SPAWN)
|
||||
#if defined(SUBPROCESS_USE_POSIX_SPAWN)
|
||||
extern char **environ;
|
||||
posix_spawn_file_actions_t actions;
|
||||
char *const *used_environment;
|
||||
@@ -837,6 +839,13 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
}
|
||||
}
|
||||
|
||||
if (working_directory) {
|
||||
if (0 != posix_spawn_file_actions_addchdir_np(&actions, working_directory)) {
|
||||
posix_spawn_file_actions_destroy(&actions);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||
@@ -921,6 +930,8 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#endif
|
||||
if (working_directory)
|
||||
chdir(working_directory);
|
||||
|
||||
if (environment) {
|
||||
_Exit(execve(commandLine[0], (char *const *)commandLine,
|
||||
|
||||
+103
-89
@@ -2,6 +2,7 @@
|
||||
#include "plugins/autocomplete/autocompleteplugin.hpp"
|
||||
#include "plugins/formatter/formatterplugin.hpp"
|
||||
#include "plugins/linter/linterplugin.hpp"
|
||||
// #include "plugins/lsp/lspplugin.hpp"
|
||||
#include "version.hpp"
|
||||
#include <algorithm>
|
||||
#include <args/args.hxx>
|
||||
@@ -368,6 +369,7 @@ void App::initPluginManager() {
|
||||
mPluginManager->registerPlugin( LinterPlugin::Definition() );
|
||||
mPluginManager->registerPlugin( FormatterPlugin::Definition() );
|
||||
mPluginManager->registerPlugin( AutoCompletePlugin::Definition() );
|
||||
// mPluginManager->registerPlugin( LSPPlugin::Definition() );
|
||||
}
|
||||
|
||||
void App::loadConfig( const LogLevel& logLevel ) {
|
||||
@@ -682,6 +684,101 @@ UIMenu* App::createHelpMenu() {
|
||||
return helpMenu;
|
||||
}
|
||||
|
||||
void App::setUIScaleFactor() {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::INPUT,
|
||||
i18n( "set_ui_scale_factor", "Set the UI scale factor (pixel density):\nMinimum value is "
|
||||
"1, and maximum 6. Requires restart." ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( String::format( "%.2f", mConfig.windowState.pixelDensity ) );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
msgBox->closeWindow();
|
||||
Float val;
|
||||
if ( String::fromString( val, msgBox->getTextInput()->getText() ) && val >= 1 &&
|
||||
val <= 6 ) {
|
||||
if ( mConfig.windowState.pixelDensity != val ) {
|
||||
mConfig.windowState.pixelDensity = val;
|
||||
UIMessageBox* msg = UIMessageBox::New(
|
||||
UIMessageBox::OK,
|
||||
i18n( "new_ui_scale_factor", "New UI scale factor assigned.\nPlease "
|
||||
"restart the application." ) );
|
||||
msg->show();
|
||||
setFocusEditorOnClose( msg );
|
||||
} else if ( mSplitter && mSplitter->getCurWidget() ) {
|
||||
mSplitter->getCurWidget()->setFocus();
|
||||
}
|
||||
} else {
|
||||
UIMessageBox* msg = UIMessageBox::New( UIMessageBox::OK, "Invalid value!" );
|
||||
msg->show();
|
||||
setFocusEditorOnClose( msg );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
void App::setEditorFontSize() {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::INPUT, i18n( "set_editor_font_size", "Set the editor font size:" ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( mConfig.editor.fontSize.toString() );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
mConfig.editor.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
|
||||
mSplitter->forEachEditor( [&]( UICodeEditor* editor ) {
|
||||
editor->setFontSize( mConfig.editor.fontSize.asDp( 0, Sizef(), mDisplayDPI ) );
|
||||
} );
|
||||
} );
|
||||
setFocusEditorOnClose( msgBox );
|
||||
}
|
||||
|
||||
void App::setTerminalFontSize() {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::INPUT, i18n( "set_terminal_font_size", "Set the terminal font size:" ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( mConfig.term.fontSize.toString() );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
mConfig.term.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
|
||||
mSplitter->forEachWidget( [&]( UIWidget* widget ) {
|
||||
if ( widget && widget->isType( UI_TYPE_TERMINAL ) )
|
||||
widget->asType<UITerminal>()->setFontSize(
|
||||
mConfig.term.fontSize.asPixels( 0, Sizef(), mDisplayDPI ) );
|
||||
} );
|
||||
} );
|
||||
setFocusEditorOnClose( msgBox );
|
||||
}
|
||||
|
||||
void App::setUIFontSize() {
|
||||
UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::INPUT,
|
||||
i18n( "set_ui_font_size", "Set the UI font size:" ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( mConfig.ui.fontSize.toString() );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
mConfig.ui.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
|
||||
Float fontSize = mConfig.ui.fontSize.asDp( 0, Sizef(), mDisplayDPI );
|
||||
UIThemeManager* manager = mUISceneNode->getUIThemeManager();
|
||||
manager->setDefaultFontSize( fontSize );
|
||||
manager->getDefaultTheme()->setDefaultFontSize( fontSize );
|
||||
mUISceneNode->forEachNode( [&]( Node* node ) {
|
||||
if ( node->isType( UI_TYPE_TEXTVIEW ) ) {
|
||||
UITextView* textView = node->asType<UITextView>();
|
||||
if ( !textView->getUIStyle()->hasProperty( PropertyId::FontSize ) ) {
|
||||
textView->setFontSize(
|
||||
mConfig.ui.fontSize.asDp( node->getParent()->getPixelsSize().getWidth(),
|
||||
Sizef(), mUISceneNode->getDPI() ) );
|
||||
}
|
||||
}
|
||||
} );
|
||||
msgBox->closeWindow();
|
||||
} );
|
||||
setFocusEditorOnClose( msgBox );
|
||||
}
|
||||
|
||||
UIMenu* App::createWindowMenu() {
|
||||
mWindowMenu = UIPopUpMenu::New();
|
||||
UIPopUpMenu* colorsMenu = UIPopUpMenu::New();
|
||||
@@ -797,98 +894,15 @@ UIMenu* App::createWindowMenu() {
|
||||
return;
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
if ( item->getId() == "show-side-panel" ) {
|
||||
mConfig.ui.showSidePanel = item->asType<UIMenuCheckBox>()->isActive();
|
||||
showSidePanel( mConfig.ui.showSidePanel );
|
||||
switchSidePanel();
|
||||
} else if ( item->getId() == "ui-scale-factor" ) {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::INPUT,
|
||||
i18n( "set_ui_scale_factor",
|
||||
"Set the UI scale factor (pixel density):\nMinimum value is "
|
||||
"1, and maximum 6. Requires restart." ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText(
|
||||
String::format( "%.2f", mConfig.windowState.pixelDensity ) );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
msgBox->closeWindow();
|
||||
Float val;
|
||||
if ( String::fromString( val, msgBox->getTextInput()->getText() ) && val >= 1 &&
|
||||
val <= 6 ) {
|
||||
if ( mConfig.windowState.pixelDensity != val ) {
|
||||
mConfig.windowState.pixelDensity = val;
|
||||
UIMessageBox* msg = UIMessageBox::New(
|
||||
UIMessageBox::OK,
|
||||
i18n( "new_ui_scale_factor", "New UI scale factor assigned.\nPlease "
|
||||
"restart the application." ) );
|
||||
msg->show();
|
||||
setFocusEditorOnClose( msg );
|
||||
} else if ( mSplitter && mSplitter->getCurWidget() ) {
|
||||
mSplitter->getCurWidget()->setFocus();
|
||||
}
|
||||
} else {
|
||||
UIMessageBox* msg = UIMessageBox::New( UIMessageBox::OK, "Invalid value!" );
|
||||
msg->show();
|
||||
setFocusEditorOnClose( msg );
|
||||
}
|
||||
} );
|
||||
setUIScaleFactor();
|
||||
} else if ( item->getId() == "editor-font-size" ) {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::INPUT, i18n( "set_editor_font_size", "Set the editor font size:" ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( mConfig.editor.fontSize.toString() );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
mConfig.term.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
|
||||
mSplitter->forEachEditor( [&]( UICodeEditor* editor ) {
|
||||
editor->setFontSize( mConfig.editor.fontSize.asDp( 0, Sizef(), mDisplayDPI ) );
|
||||
} );
|
||||
} );
|
||||
setFocusEditorOnClose( msgBox );
|
||||
setEditorFontSize();
|
||||
} else if ( item->getId() == "terminal-font-size" ) {
|
||||
UIMessageBox* msgBox =
|
||||
UIMessageBox::New( UIMessageBox::INPUT, i18n( "set_terminal_font_size",
|
||||
"Set the terminal font size:" ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( mConfig.term.fontSize.toString() );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
mConfig.term.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
|
||||
mSplitter->forEachWidget( [&]( UIWidget* widget ) {
|
||||
if ( widget && widget->isType( UI_TYPE_TERMINAL ) )
|
||||
widget->asType<UITerminal>()->setFontSize(
|
||||
mConfig.term.fontSize.asPixels( 0, Sizef(), mDisplayDPI ) );
|
||||
} );
|
||||
} );
|
||||
setFocusEditorOnClose( msgBox );
|
||||
setTerminalFontSize();
|
||||
} else if ( item->getId() == "ui-font-size" ) {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::INPUT, i18n( "set_ui_font_size", "Set the UI font size:" ) );
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setText( mConfig.ui.fontSize.toString() );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
mConfig.ui.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
|
||||
Float fontSize = mConfig.ui.fontSize.asDp( 0, Sizef(), mDisplayDPI );
|
||||
UIThemeManager* manager = mUISceneNode->getUIThemeManager();
|
||||
manager->setDefaultFontSize( fontSize );
|
||||
manager->getDefaultTheme()->setDefaultFontSize( fontSize );
|
||||
mUISceneNode->forEachNode( [&]( Node* node ) {
|
||||
if ( node->isType( UI_TYPE_TEXTVIEW ) ) {
|
||||
UITextView* textView = node->asType<UITextView>();
|
||||
if ( !textView->getUIStyle()->hasProperty( PropertyId::FontSize ) ) {
|
||||
textView->setFontSize( mConfig.ui.fontSize.asDp(
|
||||
node->getParent()->getPixelsSize().getWidth(), Sizef(),
|
||||
mUISceneNode->getDPI() ) );
|
||||
}
|
||||
}
|
||||
} );
|
||||
msgBox->closeWindow();
|
||||
} );
|
||||
setFocusEditorOnClose( msgBox );
|
||||
setUIFontSize();
|
||||
} else if ( item->getId() == "serif-font" ) {
|
||||
openFontDialog( mConfig.ui.serifFont, false );
|
||||
} else if ( item->getId() == "monospace-font" ) {
|
||||
@@ -2865,7 +2879,7 @@ UIMenu* App::createFileTypeMenu() {
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
const String& name = item->getText();
|
||||
if ( mSplitter->curEditorExistsAndFocused() ) {
|
||||
mSplitter->getCurEditor()->setSyntaxDefinition( dM->getStyleByLanguageName( name ) );
|
||||
mSplitter->getCurEditor()->setSyntaxDefinition( dM->getByLanguageName( name ) );
|
||||
updateCurrentFileType();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -155,6 +155,16 @@ class App : public UICodeEditorSplitter::Client {
|
||||
|
||||
void debugDrawData();
|
||||
|
||||
void setUIFontSize();
|
||||
|
||||
void setEditorFontSize();
|
||||
|
||||
void setTerminalFontSize();
|
||||
|
||||
void setUIScaleFactor();
|
||||
|
||||
void toggleSidePanel();
|
||||
|
||||
protected:
|
||||
EE::Window::Window* mWindow{ nullptr };
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
|
||||
@@ -31,7 +31,7 @@ FormatterPlugin::FormatterPlugin( const PluginManager* pluginManager ) :
|
||||
#if FORMATTER_THREADED
|
||||
mPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} );
|
||||
#else
|
||||
load( formattersPath );
|
||||
load( pluginManager );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ LinterPlugin::LinterPlugin( const PluginManager* pluginManager ) :
|
||||
#if LINTER_THREADED
|
||||
mPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} );
|
||||
#else
|
||||
load( lintersPath );
|
||||
load( pluginManager );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "lspclient.hpp"
|
||||
|
||||
namespace ecode {
|
||||
|
||||
LSPClient::LSPClient() {}
|
||||
|
||||
} // namespace ecode
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef ECODE_LSPCLIENT_HPP
|
||||
#define ECODE_LSPCLIENT_HPP
|
||||
|
||||
#include <eepp/system/process.hpp>
|
||||
#include <eepp/ui/doc/textdocument.hpp>
|
||||
#include <memory>
|
||||
|
||||
using namespace EE::System;
|
||||
using namespace EE::UI;
|
||||
using namespace EE::UI::Doc;
|
||||
|
||||
namespace ecode {
|
||||
|
||||
class LSPClient {
|
||||
public:
|
||||
static std::shared_ptr<LSPClient> get( const std::shared_ptr<TextDocument>& doc );
|
||||
|
||||
protected:
|
||||
|
||||
LSPClient();
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
#endif // ECODE_LSPCLIENT_HPP
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "lspclientmanager.hpp"
|
||||
|
||||
namespace ecode {
|
||||
|
||||
LSPClientManager::LSPClientManager() {}
|
||||
|
||||
void LSPClientManager::load( const PluginManager* pluginManager ) {}
|
||||
|
||||
size_t LSPClientManager::clientCount() const {
|
||||
return mClients.size();
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef ECODE_LSPCLIENTMANAGER_HPP
|
||||
#define ECODE_LSPCLIENTMANAGER_HPP
|
||||
|
||||
#include "../pluginmanager.hpp"
|
||||
#include "lspclient.hpp"
|
||||
#include <eepp/core.hpp>
|
||||
|
||||
using namespace EE;
|
||||
|
||||
namespace ecode {
|
||||
|
||||
class LSPClientManager {
|
||||
public:
|
||||
LSPClientManager();
|
||||
|
||||
void load( const PluginManager* pluginManager );
|
||||
|
||||
size_t clientCount() const;
|
||||
|
||||
protected:
|
||||
std::map<String::HashType, std::unique_ptr<LSPClient>> mClients;
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
#endif // ECODE_LSPCLIENTMANAGER_HPP
|
||||
@@ -0,0 +1,123 @@
|
||||
#include "lspplugin.hpp"
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/lock.hpp>
|
||||
#include <eepp/system/luapattern.hpp>
|
||||
#include <eepp/ui/uiscenenode.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace ecode {
|
||||
|
||||
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
|
||||
#define LSP_THREADED 1
|
||||
#else
|
||||
#define LSP_THREADED 0
|
||||
#endif
|
||||
|
||||
UICodeEditorPlugin* LSPPlugin::New( const PluginManager* pluginManager ) {
|
||||
return eeNew( LSPPlugin, ( pluginManager ) );
|
||||
}
|
||||
|
||||
LSPPlugin::LSPPlugin( const PluginManager* pluginManager ) :
|
||||
mPool( pluginManager->getThreadPool() ) {
|
||||
#if LSP_THREADED
|
||||
mPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} );
|
||||
#else
|
||||
load( pluginManager );
|
||||
#endif
|
||||
}
|
||||
|
||||
void LSPPlugin::load( const PluginManager* pluginManager ) {
|
||||
std::vector<std::string> paths;
|
||||
std::string path( pluginManager->getResourcesPath() + "plugins/lsp.json" );
|
||||
if ( FileSystem::fileExists( path ) )
|
||||
paths.emplace_back( path );
|
||||
path = pluginManager->getPluginsPath() + "lsp.json";
|
||||
if ( FileSystem::fileExists( path ) ||
|
||||
FileSystem::fileWrite( path, "{\n\"config\":{},\n\"lsp\":[]\n}\n" ) ) {
|
||||
mConfigPath = path;
|
||||
paths.emplace_back( path );
|
||||
}
|
||||
if ( paths.empty() )
|
||||
return;
|
||||
for ( const auto& path : paths ) {
|
||||
try {
|
||||
loadLSPConfig( path );
|
||||
} catch ( json::exception& e ) {
|
||||
Log::error( "Parsing linter \"%s\" failed:\n%s", path.c_str(), e.what() );
|
||||
}
|
||||
}
|
||||
mReady = mClientManager.clientCount() > 0;
|
||||
if ( mReady )
|
||||
fireReadyCbs();
|
||||
}
|
||||
|
||||
void LSPPlugin::loadLSPConfig( const std::string& path ) {
|
||||
|
||||
}
|
||||
|
||||
LSPPlugin::~LSPPlugin() {
|
||||
mClosing = true;
|
||||
Lock l( mDocMutex );
|
||||
for ( const auto& editor : mEditors ) {
|
||||
for ( auto listener : editor.second )
|
||||
editor.first->removeEventListener( listener );
|
||||
editor.first->unregisterPlugin( this );
|
||||
}
|
||||
}
|
||||
|
||||
void LSPPlugin::onRegister( UICodeEditor* editor ) {
|
||||
Lock l( mDocMutex );
|
||||
std::vector<Uint32> listeners;
|
||||
listeners.push_back( editor->addEventListener( Event::OnDocumentLoaded, [&]( const Event* ) {
|
||||
|
||||
} ) );
|
||||
|
||||
listeners.push_back(
|
||||
editor->addEventListener( Event::OnDocumentClosed, [&]( const Event* event ) {
|
||||
Lock l( mDocMutex );
|
||||
const DocEvent* docEvent = static_cast<const DocEvent*>( event );
|
||||
TextDocument* doc = docEvent->getDoc();
|
||||
mDocs.erase( doc );
|
||||
} ) );
|
||||
|
||||
listeners.push_back(
|
||||
editor->addEventListener( Event::OnDocumentChanged, [&, editor]( const Event* ) {
|
||||
TextDocument* oldDoc = mEditorDocs[editor];
|
||||
TextDocument* newDoc = editor->getDocumentRef().get();
|
||||
Lock l( mDocMutex );
|
||||
mDocs.erase( oldDoc );
|
||||
mEditorDocs[editor] = newDoc;
|
||||
} ) );
|
||||
|
||||
listeners.push_back(
|
||||
editor->addEventListener( Event::OnCursorPosChange, [&, editor]( const Event* ) {} ) );
|
||||
|
||||
listeners.push_back(
|
||||
editor->addEventListener( Event::OnDocumentSyntaxDefinitionChange, [&]( const Event* ev ) {
|
||||
// const DocSyntaxDefEvent* event = static_cast<const DocSyntaxDefEvent*>( ev );
|
||||
} ) );
|
||||
|
||||
mEditors.insert( { editor, listeners } );
|
||||
mDocs.insert( editor->getDocumentRef().get() );
|
||||
mEditorDocs[editor] = editor->getDocumentRef().get();
|
||||
}
|
||||
|
||||
void LSPPlugin::onUnregister( UICodeEditor* editor ) {
|
||||
if ( mClosing )
|
||||
return;
|
||||
Lock l( mDocMutex );
|
||||
TextDocument* doc = mEditorDocs[editor];
|
||||
auto cbs = mEditors[editor];
|
||||
for ( auto listener : cbs )
|
||||
editor->removeEventListener( listener );
|
||||
mEditors.erase( editor );
|
||||
mEditorDocs.erase( editor );
|
||||
for ( auto editor : mEditorDocs )
|
||||
if ( editor.second == doc )
|
||||
return;
|
||||
mDocs.erase( doc );
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef ECODE_LSPPLUGIN_HPP
|
||||
#define ECODE_LSPPLUGIN_HPP
|
||||
|
||||
#include "../pluginmanager.hpp"
|
||||
#include "lspclientmanager.hpp"
|
||||
#include <eepp/config.hpp>
|
||||
#include <eepp/system/clock.hpp>
|
||||
#include <eepp/system/mutex.hpp>
|
||||
#include <eepp/system/sys.hpp>
|
||||
#include <eepp/system/threadpool.hpp>
|
||||
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
|
||||
#include <eepp/ui/uicodeeditor.hpp>
|
||||
#include <set>
|
||||
using namespace EE;
|
||||
using namespace EE::System;
|
||||
using namespace EE::UI;
|
||||
|
||||
namespace ecode {
|
||||
|
||||
struct LSP {
|
||||
std::string name;
|
||||
std::string language;
|
||||
const SyntaxDefinition* langDefinition;
|
||||
std::vector<SyntaxPattern> filePatterns;
|
||||
std::string command;
|
||||
std::string url;
|
||||
std::vector<std::string> rootIndicationFileName;
|
||||
};
|
||||
|
||||
class LSPPlugin : public UICodeEditorPlugin {
|
||||
public:
|
||||
static PluginDefinition Definition() {
|
||||
return {
|
||||
"lsp", "LSP Client", "Language Server Protocol Client.", LSPPlugin::New, { 0, 1, 0 } };
|
||||
}
|
||||
|
||||
static UICodeEditorPlugin* New( const PluginManager* pluginManager );
|
||||
|
||||
virtual ~LSPPlugin();
|
||||
|
||||
std::string getId() { return Definition().id; }
|
||||
|
||||
std::string getTitle() { return Definition().name; }
|
||||
|
||||
std::string getDescription() { return Definition().description; }
|
||||
|
||||
bool isReady() const { return true; }
|
||||
|
||||
void onRegister( UICodeEditor* );
|
||||
|
||||
void onUnregister( UICodeEditor* );
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ThreadPool> mPool;
|
||||
Clock mClock;
|
||||
Mutex mDocMutex;
|
||||
std::unordered_map<UICodeEditor*, std::vector<Uint32>> mEditors;
|
||||
std::set<TextDocument*> mDocs;
|
||||
std::unordered_map<UICodeEditor*, TextDocument*> mEditorDocs;
|
||||
LSPClientManager mClientManager;
|
||||
std::string mConfigPath;
|
||||
bool mClosing{ false };
|
||||
bool mReady{ false };
|
||||
|
||||
LSPPlugin( const PluginManager* pluginManager );
|
||||
|
||||
void load( const PluginManager* pluginManager );
|
||||
|
||||
void loadLSPConfig( const std::string& path );
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
#endif // ECODE_LSPPLUGIN_HPP
|
||||
@@ -133,7 +133,7 @@ UIPushButton* UITreeViewCellGlobalSearch::updateText( const std::string& text )
|
||||
ProjectSearch::ResultData* res =
|
||||
(ProjectSearch::ResultData*)getCurIndex().parent().internalData();
|
||||
|
||||
auto styleDef = SyntaxDefinitionManager::instance()->getStyleByExtension( res->file );
|
||||
auto styleDef = SyntaxDefinitionManager::instance()->getByExtension( res->file );
|
||||
|
||||
Uint32 from = text.find_first_not_of( ' ' );
|
||||
Uint32 to = from;
|
||||
|
||||
Reference in New Issue
Block a user