mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-25 23:57:53 +03:00
ecode: Implemented workspace symbol search.
This commit is contained in:
@@ -51,11 +51,12 @@ class CommandPalette {
|
||||
|
||||
const std::shared_ptr<CommandPaletteModel>& getEditorModel() const;
|
||||
|
||||
void setCommandPaletteEditor(const std::vector<std::vector<std::string> >& commandPaletteEditor);
|
||||
void
|
||||
setCommandPaletteEditor( const std::vector<std::vector<std::string>>& commandPaletteEditor );
|
||||
|
||||
void setCurModel(const std::shared_ptr<CommandPaletteModel>& curModel);
|
||||
void setCurModel( const std::shared_ptr<CommandPaletteModel>& curModel );
|
||||
|
||||
protected:
|
||||
protected:
|
||||
mutable Mutex mMatchingMutex;
|
||||
std::shared_ptr<ThreadPool> mPool;
|
||||
std::vector<std::vector<std::string>> mCommandPalette;
|
||||
|
||||
@@ -3118,7 +3118,11 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe
|
||||
{ "symbol-constant", 0xeb5d }, { "symbol-struct", 0xea91 },
|
||||
{ "symbol-event", 0xea86 }, { "symbol-operator", 0xeb64 },
|
||||
{ "symbol-type-parameter", 0xea92 }, { "expand-all", 0xeb95 },
|
||||
{ "collapse-all", 0xeac5 },
|
||||
{ "symbol-namespace", 0xea8b }, { "symbol-package", 0xea8b },
|
||||
{ "symbol-string", 0xeb8d }, { "symbol-number", 0xea90 },
|
||||
{ "symbol-boolean", 0xea8f }, { "symbol-array", 0xea8a },
|
||||
{ "symbol-object", 0xea8b }, { "symbol-key", 0xea93 },
|
||||
{ "symbol-null", 0xea8f }, { "collapse-all", 0xeac5 },
|
||||
};
|
||||
|
||||
for ( const auto& icon : codIcons )
|
||||
|
||||
@@ -3,6 +3,77 @@
|
||||
|
||||
namespace ecode {
|
||||
|
||||
class LSPSymbolInfoModel : public Model {
|
||||
public:
|
||||
static std::shared_ptr<LSPSymbolInfoModel>
|
||||
create( UISceneNode* uiSceneNode, const std::string& query,
|
||||
const std::vector<LSPSymbolInformation>& data ) {
|
||||
return std::make_shared<LSPSymbolInfoModel>( uiSceneNode, query, data );
|
||||
}
|
||||
|
||||
explicit LSPSymbolInfoModel( UISceneNode* uiSceneNode, const std::string& query,
|
||||
const std::vector<LSPSymbolInformation>& info ) :
|
||||
mUISceneNode( uiSceneNode ), mQuery( query ), mInfo( info ) {}
|
||||
|
||||
size_t rowCount( const ModelIndex& ) const override { return mInfo.size(); };
|
||||
|
||||
size_t columnCount( const ModelIndex& ) const override { return 2; }
|
||||
|
||||
Variant data( const ModelIndex& index, ModelRole role ) const override {
|
||||
if ( index.row() >= (Int64)mInfo.size() )
|
||||
return {};
|
||||
if ( role == ModelRole::Display ) {
|
||||
switch ( index.column() ) {
|
||||
case 0:
|
||||
return Variant( mInfo[index.row()].name.c_str() );
|
||||
case 1:
|
||||
return Variant( mInfo[index.row()].url.getFSPath() );
|
||||
}
|
||||
} else if ( role == ModelRole::Icon && index.column() == 0 ) {
|
||||
return mUISceneNode->findIcon(
|
||||
LSPSymbolKindHelper::toIconString( mInfo[index.row()].kind ) );
|
||||
} else if ( role == ModelRole::Custom && index.column() == 1 ) {
|
||||
return Variant( mInfo[index.row()].range.toString() );
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void update() override { onModelUpdate(); }
|
||||
|
||||
const std::vector<LSPSymbolInformation>& getInfo() const { return mInfo; }
|
||||
|
||||
LSPSymbolInformation at( const size_t& idx ) {
|
||||
eeASSERT( idx < mInfo.size() );
|
||||
return mInfo[idx];
|
||||
}
|
||||
|
||||
const std::string& getQuery() const { return mQuery; }
|
||||
|
||||
void append( const std::vector<LSPSymbolInformation>& res ) {
|
||||
mInfo.insert( mInfo.end(), res.begin(), res.end() );
|
||||
std::sort( mInfo.begin(), mInfo.end(),
|
||||
[]( const LSPSymbolInformation& l, const LSPSymbolInformation& r ) {
|
||||
return l.score > r.score;
|
||||
} );
|
||||
onModelUpdate();
|
||||
}
|
||||
|
||||
void setQuery( const std::string& query ) {
|
||||
if ( mQuery != query ) {
|
||||
mQuery = query;
|
||||
clear();
|
||||
onModelUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void clear() { mInfo.clear(); }
|
||||
|
||||
protected:
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
std::string mQuery;
|
||||
std::vector<LSPSymbolInformation> mInfo;
|
||||
};
|
||||
|
||||
static int LOCATEBAR_MAX_VISIBLE_ITEMS = 18;
|
||||
static int LOCATEBAR_MAX_RESULTS = 100;
|
||||
|
||||
@@ -10,7 +81,11 @@ FileLocator::FileLocator( UICodeEditorSplitter* editorSplitter, UISceneNode* sce
|
||||
mSplitter( editorSplitter ),
|
||||
mUISceneNode( sceneNode ),
|
||||
mApp( app ),
|
||||
mCommandPalette( mApp->getThreadPool() ) {}
|
||||
mCommandPalette( mApp->getThreadPool() ) {
|
||||
mApp->getPluginManager()->subscribeMessages(
|
||||
"universallocator",
|
||||
[&]( const PluginMessage& msg ) -> PluginRequestHandle { return processResponse( msg ); } );
|
||||
}
|
||||
|
||||
void FileLocator::hideLocateBar() {
|
||||
mLocateBarLayout->setVisible( false );
|
||||
@@ -32,6 +107,7 @@ void FileLocator::updateFilesTable() {
|
||||
mLocateTable->setModel(
|
||||
mApp->getDirTree()->fuzzyMatchTree( mLocateInput->getText(), LOCATEBAR_MAX_RESULTS ) );
|
||||
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
|
||||
mLocateTable->scrollToTop();
|
||||
#endif
|
||||
} else {
|
||||
mLocateTable->setModel( mApp->getDirTree()->asModel( LOCATEBAR_MAX_RESULTS ) );
|
||||
@@ -56,7 +132,6 @@ void FileLocator::updateCommandPaletteTable() {
|
||||
txt.trim();
|
||||
|
||||
if ( txt.size() > 1 ) {
|
||||
|
||||
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
|
||||
mCommandPalette.asyncFuzzyMatch( txt.substr( 1 ), 1000, [&]( auto res ) {
|
||||
mUISceneNode->runOnMainThread( [&, res] {
|
||||
@@ -68,6 +143,7 @@ void FileLocator::updateCommandPaletteTable() {
|
||||
#else
|
||||
mLocateTable->setModel( mCommandPalette.fuzzyMatch( txt.substr(), 1000 ) );
|
||||
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
|
||||
mLocateTable->scrollToTop();
|
||||
#endif
|
||||
} else if ( mCommandPalette.getCurModel() ) {
|
||||
mLocateTable->setModel( mCommandPalette.getCurModel() );
|
||||
@@ -118,6 +194,8 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu
|
||||
}
|
||||
} else if ( !txt.empty() && mLocateInput->getText()[0] == '>' ) {
|
||||
showCommandPalette();
|
||||
} else if ( !txt.empty() && mLocateInput->getText()[0] == ':' ) {
|
||||
showWorkspaceSymbol();
|
||||
} else {
|
||||
showLocateTable();
|
||||
if ( !mApp->isDirTreeReady() )
|
||||
@@ -168,15 +246,30 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu
|
||||
Variant vPath( modelEvent->getModel()->data(
|
||||
modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ),
|
||||
ModelRole::Display ) );
|
||||
if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) ) {
|
||||
std::string path( vPath.asCStr() );
|
||||
if ( vPath.isValid() ) {
|
||||
std::string path( vPath.is( Variant::Type::cstr ) ? vPath.asCStr()
|
||||
: vPath.asStdString() );
|
||||
Variant rangeStr( modelEvent->getModel()->data(
|
||||
modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ),
|
||||
ModelRole::Custom ) );
|
||||
auto range = rangeStr.isValid()
|
||||
? TextRange::fromString( rangeStr.asStdString() )
|
||||
: TextRange();
|
||||
UITab* tab = mSplitter->isDocumentOpen( path, true );
|
||||
if ( !tab ) {
|
||||
FileInfo fileInfo( path );
|
||||
if ( fileInfo.exists() && fileInfo.isRegularFile() )
|
||||
mApp->loadFileFromPath( path );
|
||||
mApp->loadFileFromPath( path, true, nullptr,
|
||||
[range]( UICodeEditor* editor, auto ) {
|
||||
if ( range.isValid() )
|
||||
editor->goToLine( range.start() );
|
||||
} );
|
||||
} else {
|
||||
tab->getTabWidget()->setTabSelected( tab );
|
||||
if ( range.isValid() ) {
|
||||
UICodeEditor* editor = tab->getOwnedWidget()->asType<UICodeEditor>();
|
||||
editor->goToLine( range.start() );
|
||||
}
|
||||
}
|
||||
mLocateBarLayout->execute( "close-locatebar" );
|
||||
}
|
||||
@@ -209,7 +302,7 @@ void FileLocator::showBar() {
|
||||
mLocateTable->setVisible( true );
|
||||
const String& text = mLocateInput->getText();
|
||||
|
||||
if ( !text.empty() && text[0] == '>' ) {
|
||||
if ( !text.empty() && ( text[0] == '>' || text[0] == ':' ) ) {
|
||||
Int64 selectFrom = 1;
|
||||
if ( text.size() >= 2 && text[1] == ' ' )
|
||||
selectFrom = 2;
|
||||
@@ -228,7 +321,8 @@ void FileLocator::showBar() {
|
||||
void FileLocator::showLocateBar() {
|
||||
showBar();
|
||||
|
||||
if ( !mLocateInput->getText().empty() && mLocateInput->getText()[0] == '>' )
|
||||
if ( !mLocateInput->getText().empty() &&
|
||||
( mLocateInput->getText()[0] == '>' || mLocateInput->getText()[0] == ':' ) )
|
||||
mLocateInput->setText( "" );
|
||||
|
||||
if ( mApp->getDirTree() && !mLocateTable->getModel() ) {
|
||||
@@ -249,4 +343,59 @@ void FileLocator::showCommandPalette() {
|
||||
updateLocateBar();
|
||||
}
|
||||
|
||||
void FileLocator::showWorkspaceSymbol() {
|
||||
showBar();
|
||||
|
||||
if ( mLocateInput->getText().empty() || mLocateInput->getText()[0] != ':' )
|
||||
mLocateInput->setText( ": " );
|
||||
|
||||
requestWorkspaceSymbol();
|
||||
updateLocateBar();
|
||||
}
|
||||
|
||||
void FileLocator::requestWorkspaceSymbol() {
|
||||
if ( mLocateInput->getText().empty() )
|
||||
return;
|
||||
auto txt( mLocateInput->getText().substr( 1 ).trim() );
|
||||
if ( mWorkspaceSymbolQuery != txt.toUtf8() || mWorkspaceSymbolQuery.empty() ) {
|
||||
mWorkspaceSymbolQuery = txt.toUtf8();
|
||||
if ( mWorkspaceSymbolModel ) {
|
||||
mWorkspaceSymbolModel->setQuery( mWorkspaceSymbolQuery );
|
||||
} else {
|
||||
mWorkspaceSymbolModel =
|
||||
LSPSymbolInfoModel::create( mApp->getUISceneNode(), mWorkspaceSymbolQuery, {} );
|
||||
}
|
||||
json j = json{ json{ "query", mWorkspaceSymbolQuery } };
|
||||
mApp->getPluginManager()->sendRequest( PluginMessageType::WorkspaceSymbol,
|
||||
PluginMessageFormat::JSON, &j );
|
||||
}
|
||||
}
|
||||
|
||||
void FileLocator::updateWorkspaceSymbol( const std::vector<LSPSymbolInformation>& res ) {
|
||||
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
|
||||
mUISceneNode->runOnMainThread( [&, res] {
|
||||
if ( !mWorkspaceSymbolModel ) {
|
||||
mWorkspaceSymbolModel =
|
||||
LSPSymbolInfoModel::create( mApp->getUISceneNode(), mWorkspaceSymbolQuery, res );
|
||||
} else {
|
||||
mWorkspaceSymbolModel->append( res );
|
||||
}
|
||||
mLocateTable->setModel( mWorkspaceSymbolModel );
|
||||
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
|
||||
mLocateTable->scrollToTop();
|
||||
} );
|
||||
#else
|
||||
mLocateTable->setModel( mWorkspaceSymbolModel );
|
||||
mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) );
|
||||
mLocateTable->scrollToTop();
|
||||
#endif
|
||||
}
|
||||
|
||||
PluginRequestHandle FileLocator::processResponse( const PluginMessage& msg ) {
|
||||
if ( msg.isResponse() && msg.type == PluginMessageType::WorkspaceSymbol ) {
|
||||
updateWorkspaceSymbol( msg.asSymbolInformation() );
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
#define ECODE_FILELOCATOR_HPP
|
||||
|
||||
#include "commandpalette.hpp"
|
||||
#include "plugins/pluginmanager.hpp"
|
||||
#include "widgetcommandexecuter.hpp"
|
||||
#include <eepp/ee.hpp>
|
||||
|
||||
namespace ecode {
|
||||
|
||||
class App;
|
||||
class LSPSymbolInfoModel;
|
||||
|
||||
class FileLocator {
|
||||
public:
|
||||
@@ -29,18 +31,28 @@ class FileLocator {
|
||||
|
||||
void showLocateTable();
|
||||
|
||||
void showWorkspaceSymbol();
|
||||
|
||||
protected:
|
||||
UILocateBar* mLocateBarLayout{ nullptr };
|
||||
UITableView* mLocateTable{ nullptr };
|
||||
UITextInput* mLocateInput{ nullptr };
|
||||
UICodeEditorSplitter* mSplitter{ nullptr };
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
std::shared_ptr<LSPSymbolInfoModel> mWorkspaceSymbolModel{ nullptr };
|
||||
std::string mWorkspaceSymbolQuery;
|
||||
App* mApp{ nullptr };
|
||||
CommandPalette mCommandPalette;
|
||||
|
||||
void updateLocateBar();
|
||||
|
||||
void showBar();
|
||||
|
||||
PluginRequestHandle processResponse( const PluginMessage& msg );
|
||||
|
||||
void requestWorkspaceSymbol();
|
||||
|
||||
void updateWorkspaceSymbol( const std::vector<LSPSymbolInformation>& info );
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -248,6 +248,26 @@ PluginRequestHandle LSPClientPlugin::processDocumentFormatting( const PluginMess
|
||||
return ret;
|
||||
}
|
||||
|
||||
PluginRequestHandle LSPClientPlugin::processWorkspaceSymbol( const PluginMessage& msg ) {
|
||||
if ( !msg.isRequest() || !msg.isJSON() )
|
||||
return {};
|
||||
|
||||
auto servers = mClientManager.getAllRunningServers();
|
||||
if ( servers.empty() )
|
||||
return {};
|
||||
|
||||
for ( const auto server : servers ) {
|
||||
server->workspaceSymbol(
|
||||
msg.asJSON().value( "query", "" ),
|
||||
[&]( const PluginIDType& id, const std::vector<LSPSymbolInformation>& info ) {
|
||||
mManager->sendResponse( this, PluginMessageType::WorkspaceSymbol,
|
||||
PluginMessageFormat::SymbolInformation, &info, id );
|
||||
} );
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool LSPClientPlugin::processDocumentFormattingResponse( const URI& uri,
|
||||
std::vector<LSPTextEdit> edits ) {
|
||||
auto doc = mManager->getSplitter()->findDocFromURI( uri );
|
||||
@@ -467,6 +487,12 @@ PluginRequestHandle LSPClientPlugin::processMessage( const PluginMessage& msg )
|
||||
processCancelRequest( msg );
|
||||
break;
|
||||
}
|
||||
case PluginMessageType::WorkspaceSymbol: {
|
||||
auto ret = processWorkspaceSymbol( msg );
|
||||
if ( !ret.isEmpty() )
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,8 @@ class LSPClientPlugin : public UICodeEditorPlugin {
|
||||
|
||||
PluginRequestHandle processDocumentFormatting( const PluginMessage& msg );
|
||||
|
||||
PluginRequestHandle processWorkspaceSymbol( const PluginMessage& msg );
|
||||
|
||||
void tryHideTooltip( UICodeEditor* editor, const Vector2i& position );
|
||||
|
||||
void hideTooltip( UICodeEditor* editor );
|
||||
|
||||
@@ -48,6 +48,7 @@ static const char* MEMBER_TARGET_SELECTION_RANGE = "targetSelectionRange";
|
||||
static const char* MEMBER_PREVIOUS_RESULT_ID = "previousResultId";
|
||||
static const char* MEMBER_QUERY = "query";
|
||||
static const char* MEMBER_SUCCESS = "success";
|
||||
static const char* MEMBER_LIMIT = "limit";
|
||||
|
||||
static json newRequest( const std::string& method, const json& params = json{} ) {
|
||||
json j;
|
||||
@@ -392,24 +393,23 @@ static std::vector<LSPSymbolInformation> parseWorkspaceSymbols( const json& res
|
||||
std::vector<LSPSymbolInformation> symbols;
|
||||
symbols.reserve( res.size() );
|
||||
|
||||
std::transform(
|
||||
res.cbegin(), res.cend(), std::back_inserter( symbols ), []( const json& symbol ) {
|
||||
LSPSymbolInformation symInfo;
|
||||
std::transform( res.cbegin(), res.cend(), std::back_inserter( symbols ),
|
||||
[]( const json& symbol ) {
|
||||
LSPSymbolInformation symInfo;
|
||||
|
||||
const auto& location = symbol.at( MEMBER_LOCATION );
|
||||
const auto& mrange = symbol.contains( MEMBER_RANGE ) ? symbol.at( MEMBER_RANGE )
|
||||
: location.at( MEMBER_RANGE );
|
||||
const auto& location = symbol.at( MEMBER_LOCATION );
|
||||
const auto& mrange = location.at( MEMBER_RANGE );
|
||||
|
||||
auto containerName = symbol.value( "containerName", "" );
|
||||
if ( !containerName.empty() )
|
||||
containerName.append( "::" );
|
||||
symInfo.name = containerName + symbol.value( "name", "" );
|
||||
symInfo.kind = (LSPSymbolKind)symbol.value( MEMBER_KIND, 1 );
|
||||
symInfo.range = parseRange( mrange );
|
||||
symInfo.url = URI( location.value( MEMBER_URI, "" ) );
|
||||
symInfo.score = symbol.value( "score", 0.0 );
|
||||
return symInfo;
|
||||
} );
|
||||
auto containerName = symbol.value( "containerName", "" );
|
||||
if ( !containerName.empty() )
|
||||
containerName.append( "::" );
|
||||
symInfo.name = containerName + symbol.value( "name", "" );
|
||||
symInfo.kind = (LSPSymbolKind)symbol.value( MEMBER_KIND, 1 );
|
||||
symInfo.range = parseRange( mrange );
|
||||
symInfo.url = URI( location.value( MEMBER_URI, "" ) );
|
||||
symInfo.score = symbol.value( "score", 0.0 );
|
||||
return symInfo;
|
||||
} );
|
||||
|
||||
std::sort( symbols.begin(), symbols.end(),
|
||||
[]( const LSPSymbolInformation& l, const LSPSymbolInformation& r ) {
|
||||
@@ -1039,6 +1039,10 @@ bool LSPClientServer::registerDoc( const std::shared_ptr<TextDocument>& doc ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LSPClientServer::isRunning() {
|
||||
return mProcess.isAlive() && !mProcess.isShootingDown();
|
||||
}
|
||||
|
||||
void LSPClientServer::removeDoc( TextDocument* doc ) {
|
||||
Lock l( mClientsMutex );
|
||||
if ( mClients.erase( doc ) > 0 ) {
|
||||
@@ -1240,18 +1244,22 @@ LSPClientServer::documentSymbols( const URI& document,
|
||||
}
|
||||
|
||||
LSPClientServer::LSPRequestHandle LSPClientServer::workspaceSymbol( const std::string& querySymbol,
|
||||
const JsonReplyHandler& h ) {
|
||||
auto params = json{ { MEMBER_QUERY, querySymbol } };
|
||||
const JsonReplyHandler& h,
|
||||
const size_t& limit ) {
|
||||
auto params = json{ { MEMBER_QUERY, querySymbol }, { MEMBER_LIMIT, limit } };
|
||||
return send( newRequest( "workspace/symbol", params ), h );
|
||||
}
|
||||
|
||||
LSPClientServer::LSPRequestHandle
|
||||
LSPClientServer::workspaceSymbol( const std::string& querySymbol,
|
||||
const SymbolInformationHandler& h ) {
|
||||
return workspaceSymbol( querySymbol, [h]( const IdType& id, const json& json ) {
|
||||
if ( h )
|
||||
h( id, parseWorkspaceSymbols( json ) );
|
||||
} );
|
||||
LSPClientServer::workspaceSymbol( const std::string& querySymbol, const SymbolInformationHandler& h,
|
||||
const size_t& limit ) {
|
||||
return workspaceSymbol(
|
||||
querySymbol,
|
||||
[h]( const IdType& id, const json& json ) {
|
||||
if ( h )
|
||||
h( id, parseWorkspaceSymbols( json ) );
|
||||
},
|
||||
limit );
|
||||
}
|
||||
|
||||
void fromJson( LSPWorkDoneProgressValue& value, const json& data ) {
|
||||
|
||||
@@ -63,6 +63,8 @@ class LSPClientServer {
|
||||
|
||||
bool registerDoc( const std::shared_ptr<TextDocument>& doc );
|
||||
|
||||
bool isRunning();
|
||||
|
||||
const LSPServerCapabilities& getCapabilities() const;
|
||||
|
||||
LSPClientServerManager* getManager() const;
|
||||
@@ -161,10 +163,12 @@ class LSPClientServer {
|
||||
LSPRequestHandle documentCompletion( const URI& document, const TextPosition& pos,
|
||||
const CompletionHandler& h );
|
||||
|
||||
LSPRequestHandle workspaceSymbol( const std::string& querySymbol, const JsonReplyHandler& h );
|
||||
LSPRequestHandle workspaceSymbol( const std::string& querySymbol, const JsonReplyHandler& h,
|
||||
const size_t& limit = 100 );
|
||||
|
||||
LSPRequestHandle workspaceSymbol( const std::string& querySymbol,
|
||||
const SymbolInformationHandler& h );
|
||||
const SymbolInformationHandler& h,
|
||||
const size_t& limit = 100 );
|
||||
|
||||
LSPRequestHandle selectionRange( const URI& document,
|
||||
const std::vector<TextPosition>& positions,
|
||||
|
||||
@@ -451,4 +451,14 @@ LSPClientServerManager::getLSPClientServers( const std::string& language ) {
|
||||
return servers;
|
||||
}
|
||||
|
||||
std::vector<LSPClientServer*> LSPClientServerManager::getAllRunningServers() {
|
||||
std::vector<LSPClientServer*> servers;
|
||||
Lock l( mClientsMutex );
|
||||
for ( auto& server : mClients ) {
|
||||
if ( server.second->isRunning() )
|
||||
servers.push_back( server.second.get() );
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -44,6 +44,8 @@ class LSPClientServerManager {
|
||||
|
||||
std::vector<LSPClientServer*> getLSPClientServers( const std::string& language );
|
||||
|
||||
std::vector<LSPClientServer*> getAllRunningServers();
|
||||
|
||||
LSPClientServer* getOneLSPClientServer( UICodeEditor* editor );
|
||||
|
||||
LSPClientServer* getOneLSPClientServer( const std::shared_ptr<TextDocument>& doc );
|
||||
|
||||
@@ -244,6 +244,68 @@ enum class LSPSymbolKind {
|
||||
TypeParameter = 26,
|
||||
};
|
||||
|
||||
class LSPSymbolKindHelper {
|
||||
public:
|
||||
// TODO: Complete this list
|
||||
static std::string toIconString( const LSPSymbolKind& kind ) {
|
||||
switch ( kind ) {
|
||||
case LSPSymbolKind::Method:
|
||||
return "symbol-method";
|
||||
case LSPSymbolKind::Function:
|
||||
return "symbol-function";
|
||||
case LSPSymbolKind::Constructor:
|
||||
return "symbol-constructor";
|
||||
case LSPSymbolKind::Field:
|
||||
return "symbol-field";
|
||||
case LSPSymbolKind::Variable:
|
||||
return "symbol-variable";
|
||||
case LSPSymbolKind::Class:
|
||||
return "symbol-class";
|
||||
case LSPSymbolKind::Interface:
|
||||
return "symbol-interface";
|
||||
case LSPSymbolKind::Module:
|
||||
return "symbol-module";
|
||||
case LSPSymbolKind::Property:
|
||||
return "symbol-property";
|
||||
case LSPSymbolKind::Enum:
|
||||
return "symbol-enum";
|
||||
case LSPSymbolKind::File:
|
||||
return "symbol-file";
|
||||
case LSPSymbolKind::EnumMember:
|
||||
return "symbol-enum-member";
|
||||
case LSPSymbolKind::Constant:
|
||||
return "symbol-constant";
|
||||
case LSPSymbolKind::Struct:
|
||||
return "symbol-struct";
|
||||
case LSPSymbolKind::Event:
|
||||
return "symbol-event";
|
||||
case LSPSymbolKind::Operator:
|
||||
return "symbol-operator";
|
||||
case LSPSymbolKind::TypeParameter:
|
||||
return "symbol-type-parameter";
|
||||
case LSPSymbolKind::Namespace:
|
||||
return "symbol-namespace";
|
||||
case LSPSymbolKind::Package:
|
||||
return "symbol-package";
|
||||
case LSPSymbolKind::String:
|
||||
return "symbol-string";
|
||||
case LSPSymbolKind::Number:
|
||||
return "symbol-number";
|
||||
case LSPSymbolKind::Boolean:
|
||||
return "symbol-boolean";
|
||||
case LSPSymbolKind::Array:
|
||||
return "symbol-array";
|
||||
case LSPSymbolKind::Object:
|
||||
return "symbol-object";
|
||||
case LSPSymbolKind::Key:
|
||||
return "symbol-key";
|
||||
case LSPSymbolKind::Null:
|
||||
return "symbol-null";
|
||||
}
|
||||
return "symbol-text";
|
||||
}
|
||||
};
|
||||
|
||||
struct LSPSymbolInformation {
|
||||
LSPSymbolInformation() = default;
|
||||
LSPSymbolInformation( const std::string& _name, LSPSymbolKind _kind, TextRange _range,
|
||||
|
||||
@@ -115,6 +115,23 @@ void PluginManager::setWorkspaceFolder( const std::string& workspaceFolder ) {
|
||||
sendBroadcast( PluginMessageType::WorkspaceFolderChanged, PluginMessageFormat::JSON, &data );
|
||||
}
|
||||
|
||||
PluginRequestHandle PluginManager::sendRequest( PluginMessageType type, PluginMessageFormat format,
|
||||
const void* data ) {
|
||||
if ( mClosing )
|
||||
return PluginRequestHandle::empty();
|
||||
SubscribedPlugins subscribedPlugins;
|
||||
{
|
||||
Lock l( mSubscribedPluginsMutex );
|
||||
subscribedPlugins = mSubscribedPlugins;
|
||||
}
|
||||
for ( const auto& plugin : subscribedPlugins ) {
|
||||
auto handle = plugin.second( { type, format, data } );
|
||||
if ( !handle.isEmpty() )
|
||||
return handle;
|
||||
}
|
||||
return PluginRequestHandle::empty();
|
||||
}
|
||||
|
||||
PluginRequestHandle PluginManager::sendRequest( UICodeEditorPlugin* pluginWho,
|
||||
PluginMessageType type, PluginMessageFormat format,
|
||||
const void* data ) {
|
||||
|
||||
@@ -73,6 +73,7 @@ enum class PluginMessageType {
|
||||
SymbolReference, // Request the LSP Server to find a symbol reference in the project
|
||||
ShowMessage, // The LSP server sends a request to the client to show a message on screen
|
||||
ShowDocument, // The LSP server sends a request to the client to show a document
|
||||
WorkspaceSymbol,
|
||||
Undefined
|
||||
};
|
||||
|
||||
@@ -85,6 +86,7 @@ enum class PluginMessageFormat {
|
||||
ProjectSearchResult,
|
||||
ShowMessage,
|
||||
ShowDocument,
|
||||
SymbolInformation
|
||||
};
|
||||
|
||||
class PluginIDType {
|
||||
@@ -172,6 +174,10 @@ struct PluginMessage {
|
||||
return *static_cast<const LSPShowDocumentParams*>( data );
|
||||
}
|
||||
|
||||
const std::vector<LSPSymbolInformation>& asSymbolInformation() const {
|
||||
return *static_cast<const std::vector<LSPSymbolInformation>*>( data );
|
||||
}
|
||||
|
||||
const PluginIDType& asPluginID() const { return *static_cast<const PluginIDType*>( data ); }
|
||||
|
||||
bool isResponse() const { return -1 != responseID && 0 != responseID; }
|
||||
@@ -247,6 +253,9 @@ class PluginManager {
|
||||
|
||||
void setWorkspaceFolder( const std::string& workspaceFolder );
|
||||
|
||||
PluginRequestHandle sendRequest( PluginMessageType type, PluginMessageFormat format,
|
||||
const void* data );
|
||||
|
||||
PluginRequestHandle sendRequest( UICodeEditorPlugin* pluginWho, PluginMessageType type,
|
||||
PluginMessageFormat format, const void* data );
|
||||
|
||||
@@ -290,8 +299,6 @@ class PluginManager {
|
||||
|
||||
void setSplitter( UICodeEditorSplitter* splitter );
|
||||
|
||||
PluginRequestHandle sendRequest( const PluginMessageType& notification,
|
||||
const PluginMessageFormat& format, void* data );
|
||||
};
|
||||
|
||||
class PluginsModel : public Model {
|
||||
|
||||
@@ -45,10 +45,11 @@ class FileListModel : public Model {
|
||||
switch ( role ) {
|
||||
case ModelRole::Icon:
|
||||
return Variant( iconFor( index ) );
|
||||
default:
|
||||
case ModelRole::Display:
|
||||
return Variant( index.column() == 0 ? mNames[index.row()].c_str()
|
||||
: mFiles[index.row()].c_str() );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
Reference in New Issue
Block a user