UICodeEditor: open context menu with the application key.

ecode: Minor LSP improvements.
This commit is contained in:
Martín Lucas Golini
2023-01-26 02:35:30 -03:00
parent 6044bb53b2
commit f12a24a96e
6 changed files with 122 additions and 62 deletions

View File

@@ -845,6 +845,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
bool gutterSpaceExists( UICodeEditorPlugin* plugin ) const;
bool topSpaceExists( UICodeEditorPlugin* plugin ) const;
bool createContextMenu();
};
}} // namespace EE::UI

View File

@@ -57,7 +57,7 @@ class EE_API UIWidget : public UINode {
void tooltipRemove();
UIWidget* setTooltipText( const String& Text );
UIWidget* setTooltipText( const String& text );
String getTooltipText();

View File

@@ -102,6 +102,7 @@ const std::map<KeyBindings::Shortcut, std::string> UICodeEditor::getDefaultKeybi
{ { KEY_UP, KEYMOD_LALT }, "add-cursor-above" },
{ { KEY_DOWN, KEYMOD_LALT }, "add-cursor-below" },
{ { KEY_ESCAPE }, "reset-cursor" },
{ { KEY_APPLICATION }, "open-context-menu" },
};
}
@@ -163,6 +164,11 @@ UICodeEditor::UICodeEditor( const bool& autoRegisterBaseCommands,
UICodeEditor( "codeeditor", autoRegisterBaseCommands, autoRegisterBaseKeybindings ) {}
UICodeEditor::~UICodeEditor() {
if ( mCurrentMenu ) {
mCurrentMenu->clearEventListener();
mCurrentMenu = nullptr;
}
for ( auto& plugin : mPlugins )
plugin->onUnregister( this );
@@ -970,6 +976,11 @@ void UICodeEditor::createDefaultContextMenuOptions( UIPopUpMenu* menu ) {
}
}
bool UICodeEditor::createContextMenu() {
Rectf pos( getScreenPosition( mDoc->getSelection().start() ) );
return onCreateContextMenu( pos.getPosition().asInt(), 0 );
}
bool UICodeEditor::onCreateContextMenu( const Vector2i& position, const Uint32& flags ) {
if ( mCurrentMenu )
return false;
@@ -991,12 +1002,13 @@ bool UICodeEditor::onCreateContextMenu( const Vector2i& position, const Uint32&
}
menu->setCloseOnHide( true );
menu->addEventListener( Event::OnItemClicked, [&]( const Event* event ) {
menu->addEventListener( Event::OnItemClicked, [&, menu]( const Event* event ) {
if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) )
return;
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
std::string txt( item->getId() );
mDoc.get()->execute( txt );
menu->hide();
} );
Vector2f pos( position.asFloat() );
@@ -1004,6 +1016,10 @@ bool UICodeEditor::onCreateContextMenu( const Vector2i& position, const Uint32&
UIMenu::findBestMenuPos( pos, menu );
menu->setPixelsPosition( pos );
menu->show();
menu->addEventListener( Event::OnMenuHide, [&]( const Event* ) {
if ( !isClosing() )
setFocus();
} );
menu->addEventListener( Event::OnClose, [&]( const Event* ) { mCurrentMenu = nullptr; } );
mCurrentMenu = menu;
return true;
@@ -2862,6 +2878,7 @@ void UICodeEditor::registerCommands() {
mDoc->setCommand( "copy-containing-folder-path", [&] { copyContainingFolderPath(); } );
mDoc->setCommand( "copy-file-path", [&] { copyFilePath(); } );
mDoc->setCommand( "find-replace", [&] { showFindReplace(); } );
mDoc->setCommand( "open-context-menu", [&] { createContextMenu(); } );
mUnlockedCmd.insert( { "copy", "select-all" } );
}

View File

@@ -357,16 +357,16 @@ Uint32 UIWidget::onMouseLeave( const Vector2i& Pos, const Uint32& Flags ) {
return UINode::onMouseLeave( Pos, Flags );
}
UIWidget* UIWidget::setTooltipText( const String& Text ) {
if ( NULL == mTooltip ) { // If the tooltip wasn't created it will avoid to create a new one if
// the string is ""
if ( Text.size() ) {
UIWidget* UIWidget::setTooltipText( const String& text ) {
// If the tooltip wasn't created it will avoid to create a new one if the string is ""
if ( NULL == mTooltip ) {
if ( !text.empty() ) {
createTooltip();
mTooltip->setText( Text );
mTooltip->setText( text );
}
} else { // but if it's created, i will allow it
mTooltip->setText( Text );
mTooltip->setText( text );
}
return this;

View File

@@ -226,8 +226,10 @@ void LSPClientPlugin::loadLSPConfig( std::vector<LSPDefinition>& lsps, const std
Time::fromString( config["server_close_after_idle_time"].get<std::string>() ) );
}
if ( mKeyBindings.empty() )
if ( mKeyBindings.empty() ) {
mKeyBindings["lsp-go-to-definition"] = "f2";
mKeyBindings["lsp-symbol-info"] = "f1";
}
if ( j.contains( "keybindings" ) ) {
auto kb = j["keybindings"];
@@ -235,8 +237,9 @@ void LSPClientPlugin::loadLSPConfig( std::vector<LSPDefinition>& lsps, const std
if ( kb.contains( key ) )
mKeyBindings[key] = kb[key];
};
auto list = { "lsp-go-to-definition", "lsp-go-to-declaration", "lsp-go-to-implementation",
"lsp-go-to-type-definition", "lsp-switch-header-source" };
auto list = { "lsp-go-to-definition", "lsp-go-to-declaration",
"lsp-go-to-implementation", "lsp-go-to-type-definition",
"lsp-switch-header-source", "lsp-symbol-info" };
for ( const auto& key : list )
bindKey( key );
}
@@ -376,11 +379,11 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) {
"textDocument/typeDefinition" );
} );
editor->getDocument().setCommand( "lsp-switch-header-source", [&, editor]() {
auto* server = mClientManager.getOneLSPClientServer( editor );
if ( server )
server->switchSourceHeader( editor->getDocument().getURI() );
} );
editor->getDocument().setCommand( "lsp-switch-header-source",
[&, editor]() { switchSourceHeader( editor ); } );
editor->getDocument().setCommand( "lsp-symbol-info",
[&, editor]() { getSymbolInfo( editor ); } );
}
std::vector<Uint32> listeners;
@@ -400,6 +403,31 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) {
mDelayedDocs[&editor->getDocument()] = editor->getDocumentRef();
}
void LSPClientPlugin::switchSourceHeader( UICodeEditor* editor ) {
auto* server = mClientManager.getOneLSPClientServer( editor );
if ( server )
server->switchSourceHeader( editor->getDocument().getURI() );
}
void LSPClientPlugin::getSymbolInfo( UICodeEditor* editor ) {
auto server = mClientManager.getOneLSPClientServer( editor );
if ( server == nullptr )
return;
server->documentHover(
editor->getDocument().getURI(), editor->getDocument().getSelection().start(),
[&, editor]( const Int64&, const LSPHover& resp ) {
if ( resp.range.isValid() && !resp.contents.empty() &&
!resp.contents[0].value.empty() ) {
editor->runOnMainThread( [editor, resp, this]() {
displayTooltip(
editor, resp,
editor->getScreenPosition( editor->getDocument().getSelection().start() )
.getPosition() );
} );
}
} );
}
void LSPClientPlugin::onUnregister( UICodeEditor* editor ) {
for ( auto& kb : mKeyBindings ) {
editor->getKeyBindings().removeCommandKeybind( kb.first );
@@ -442,6 +470,8 @@ bool LSPClientPlugin::onCreateContextMenu( UICodeEditor* editor, UIPopUpMenu* me
};
auto cap = server->getCapabilities();
addFn( "lsp-symbol-info", "Symbol Info" );
if ( cap.definitionProvider )
addFn( "lsp-go-to-definition", "Go To Definition" );
@@ -461,14 +491,15 @@ bool LSPClientPlugin::onCreateContextMenu( UICodeEditor* editor, UIPopUpMenu* me
}
void LSPClientPlugin::hideTooltip( UICodeEditor* editor ) {
if ( editor && editor->getTooltip() && editor->getTooltip()->isVisible() ) {
UITooltip* tooltip = nullptr;
if ( editor && ( tooltip = editor->getTooltip() ) && tooltip->isVisible() ) {
editor->setTooltipText( "" );
editor->getTooltip()->hide();
tooltip->hide();
// Restore old tooltip state
editor->getTooltip()->setFontStyle( mOldTextStyle );
editor->getTooltip()->setHorizontalAlign( mOldTextAlign );
editor->getTooltip()->setUsingCustomStyling( mOldUsingCustomStyling );
editor->getTooltip()->setDontAutoHideOnMouseMove( mOldDontAutoHideOnMouseMove );
tooltip->setFontStyle( mOldTextStyle );
tooltip->setHorizontalAlign( mOldTextAlign );
tooltip->setUsingCustomStyling( mOldUsingCustomStyling );
tooltip->setDontAutoHideOnMouseMove( mOldDontAutoHideOnMouseMove );
}
}
@@ -483,6 +514,45 @@ void LSPClientPlugin::tryHideTooltip( UICodeEditor* editor, const Vector2i& posi
hideTooltip( editor );
}
void LSPClientPlugin::displayTooltip( UICodeEditor* editor, const LSPHover& resp,
const Vector2f& position ) {
editor->setTooltipText( resp.contents[0].value );
// HACK: Gets the old font style to restore it when the tooltip is hidden
UITooltip* tooltip = editor->getTooltip();
if ( tooltip == nullptr )
return;
mOldTextStyle = tooltip->getFontStyle();
mOldTextAlign = tooltip->getHorizontalAlign();
mOldDontAutoHideOnMouseMove = tooltip->dontAutoHideOnMouseMove();
mOldUsingCustomStyling = tooltip->getUsingCustomStyling();
tooltip->setHorizontalAlign( UI_HALIGN_LEFT );
tooltip->setPixelsPosition( tooltip->getTooltipPosition( position ) );
tooltip->setDontAutoHideOnMouseMove( true );
tooltip->setUsingCustomStyling( true );
tooltip->setFontStyle( Text::Regular );
const auto& syntaxDef = resp.contents[0].kind == LSPMarkupKind::MarkDown
? SyntaxDefinitionManager::instance()->getByLSPName( "markdown" )
: editor->getSyntaxDefinition();
SyntaxTokenizer::tokenizeText( syntaxDef, editor->getColorScheme(), *tooltip->getTextCache() );
if ( editor->hasFocus() && !tooltip->isVisible() )
tooltip->show();
}
void LSPClientPlugin::tryDisplayTooltip( UICodeEditor* editor, const LSPHover& resp,
const Vector2i& position ) {
TextPosition startCursorPosition = editor->resolveScreenPosition( position.asFloat() );
TextPosition currentMousePosition = currentMouseTextPosition( editor );
if ( startCursorPosition != currentMousePosition ||
!( resp.range.isValid() && !resp.contents.empty() && !resp.contents[0].value.empty() &&
resp.range.contains( startCursorPosition ) ) )
return;
mCurrentHover = resp;
displayTooltip( editor, resp, position.asFloat() );
}
bool LSPClientPlugin::onMouseMove( UICodeEditor* editor, const Vector2i& position,
const Uint32& flags ) {
if ( flags != 0 ) {
@@ -502,47 +572,10 @@ bool LSPClientPlugin::onMouseMove( UICodeEditor* editor, const Vector2i& positio
server->documentHover(
editor->getDocument().getURI(), currentMouseTextPosition( editor ),
[&, editor, position]( const Int64&, const LSPHover& resp ) {
if ( resp.range.isValid() && !resp.contents.empty() ) {
if ( resp.range.isValid() && !resp.contents.empty() &&
!resp.contents[0].value.empty() ) {
editor->runOnMainThread( [editor, resp, position, this]() {
TextPosition startCursorPosition =
editor->resolveScreenPosition( position.asFloat() );
TextPosition currentMousePosition =
currentMouseTextPosition( editor );
if ( startCursorPosition != currentMousePosition )
return;
if ( resp.range.isValid() && !resp.contents.empty() &&
resp.range.contains( startCursorPosition ) ) {
mCurrentHover = resp;
editor->setTooltipText( resp.contents[0].value );
// HACK: Gets the old font style to restore it when the tooltip
// is hidden
mOldTextStyle = editor->getTooltip()->getFontStyle();
mOldTextAlign = editor->getTooltip()->getHorizontalAlign();
mOldDontAutoHideOnMouseMove =
editor->getTooltip()->dontAutoHideOnMouseMove();
mOldUsingCustomStyling =
editor->getTooltip()->getUsingCustomStyling();
editor->getTooltip()->setHorizontalAlign( UI_HALIGN_LEFT );
editor->getTooltip()->setPixelsPosition(
editor->getTooltip()->getTooltipPosition(
position.asFloat() ) );
editor->getTooltip()->setDontAutoHideOnMouseMove( true );
editor->getTooltip()->setUsingCustomStyling( true );
editor->getTooltip()->setFontStyle( Text::Regular );
const auto& syntaxDef =
resp.contents[0].kind == LSPMarkupKind::MarkDown
? SyntaxDefinitionManager::instance()->getByLSPName(
"markdown" )
: editor->getSyntaxDefinition();
SyntaxTokenizer::tokenizeText(
syntaxDef, editor->getColorScheme(),
*editor->getTooltip()->getTextCache() );
if ( editor->hasFocus() && !editor->getTooltip()->isVisible() )
editor->getTooltip()->show();
}
tryDisplayTooltip( editor, resp, position );
} );
}
} );

View File

@@ -113,6 +113,14 @@ class LSPClientPlugin : public UICodeEditorPlugin {
void tryHideTooltip( UICodeEditor* editor, const Vector2i& position );
void hideTooltip( UICodeEditor* editor );
void tryDisplayTooltip( UICodeEditor* editor, const LSPHover& resp, const Vector2i& position );
void displayTooltip( UICodeEditor* editor, const LSPHover& resp, const Vector2f& position );
void getSymbolInfo( UICodeEditor* editor );
void switchSourceHeader( UICodeEditor* editor );
};
} // namespace ecode