mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-06-02 19:46:29 +03:00
ecode: Fix in tooltip. Added static Text::wrapText. Fix export of syntax definitions.
eepp: Started working on a Git plugin.
This commit is contained in:
250
src/tools/ecode/plugins/git/gitplugin.cpp
Normal file
250
src/tools/ecode/plugins/git/gitplugin.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
#include "gitplugin.hpp"
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/scopedop.hpp>
|
||||
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
|
||||
#include <eepp/ui/uipopupmenu.hpp>
|
||||
#include <eepp/ui/uitooltip.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using namespace EE::UI::Doc;
|
||||
|
||||
using json = nlohmann::json;
|
||||
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
|
||||
#define GIT_THREADED 1
|
||||
#else
|
||||
#define GIT_THREADED 0
|
||||
#endif
|
||||
|
||||
namespace ecode {
|
||||
|
||||
UICodeEditorPlugin* GitPlugin::New( PluginManager* pluginManager ) {
|
||||
return eeNew( GitPlugin, ( pluginManager, false ) );
|
||||
}
|
||||
|
||||
UICodeEditorPlugin* GitPlugin::NewSync( PluginManager* pluginManager ) {
|
||||
return eeNew( GitPlugin, ( pluginManager, true ) );
|
||||
}
|
||||
|
||||
GitPlugin::GitPlugin( PluginManager* pluginManager, bool sync ) : PluginBase( pluginManager ) {
|
||||
if ( sync ) {
|
||||
load( pluginManager );
|
||||
} else {
|
||||
#if defined( GIT_THREADED ) && GIT_THREADED == 1
|
||||
mThreadPool->run( [&, pluginManager] { load( pluginManager ); } );
|
||||
#else
|
||||
load( pluginManager );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
GitPlugin::~GitPlugin() {
|
||||
mShuttingDown = true;
|
||||
}
|
||||
|
||||
void GitPlugin::load( PluginManager* pluginManager ) {
|
||||
AtomicBoolScopedOp loading( mLoading, true );
|
||||
pluginManager->subscribeMessages( this,
|
||||
[this]( const auto& notification ) -> PluginRequestHandle {
|
||||
return processMessage( notification );
|
||||
} );
|
||||
|
||||
std::string path = pluginManager->getPluginsPath() + "git.json";
|
||||
if ( FileSystem::fileExists( path ) ||
|
||||
FileSystem::fileWrite( path, "{\n \"config\":{},\n \"keybindings\":{}\n}\n" ) ) {
|
||||
mConfigPath = path;
|
||||
}
|
||||
std::string data;
|
||||
if ( !FileSystem::fileGet( path, data ) )
|
||||
return;
|
||||
mConfigHash = String::hash( data );
|
||||
|
||||
json j;
|
||||
try {
|
||||
j = json::parse( data, nullptr, true, true );
|
||||
} catch ( const json::exception& e ) {
|
||||
Log::error( "GitPlugin::load - Error parsing config from path %s, error: %s, config "
|
||||
"file content:\n%s",
|
||||
path.c_str(), e.what(), data.c_str() );
|
||||
// Recreate it
|
||||
j = json::parse( "{\n \"config\":{},\n \"keybindings\":{},\n}\n", nullptr, true, true );
|
||||
}
|
||||
|
||||
bool updateConfigFile = false;
|
||||
|
||||
if ( j.contains( "config" ) ) {
|
||||
auto& config = j["config"];
|
||||
|
||||
if ( config.contains( "statusbar_display_branch" ) )
|
||||
mStatusBarDisplayBranch = config.value( "statusbar_display_branch", true );
|
||||
else {
|
||||
config["statusbar_display_branch"] = mStatusBarDisplayBranch;
|
||||
updateConfigFile = true;
|
||||
}
|
||||
|
||||
if ( config.contains( "statusbar_display_modifications" ) )
|
||||
mStatusBarDisplayModifications =
|
||||
config.value( "statusbar_display_modifications", true );
|
||||
else {
|
||||
config["statusbar_display_modifications"] = mStatusBarDisplayModifications;
|
||||
updateConfigFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( updateConfigFile ) {
|
||||
std::string newData = j.dump( 2 );
|
||||
if ( newData != data ) {
|
||||
FileSystem::fileWrite( path, newData );
|
||||
mConfigHash = String::hash( newData );
|
||||
}
|
||||
}
|
||||
|
||||
mGit = std::make_unique<Git>( "", pluginManager->getWorkspaceFolder() );
|
||||
mGitFound = !mGit->getGitPath().empty();
|
||||
|
||||
subscribeFileSystemListener();
|
||||
mReady = true;
|
||||
fireReadyCbs();
|
||||
setReady();
|
||||
}
|
||||
|
||||
PluginRequestHandle GitPlugin::processMessage( const PluginMessage& msg ) {
|
||||
switch ( msg.type ) {
|
||||
case PluginMessageType::WorkspaceFolderChanged: {
|
||||
mGit->setProjectPath( msg.asJSON()["folder"] );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return PluginRequestHandle::empty();
|
||||
}
|
||||
|
||||
void GitPlugin::onFileSystemEvent( const FileEvent& ev, const FileInfo& file ) {
|
||||
PluginBase::onFileSystemEvent( ev, file );
|
||||
|
||||
if ( mShuttingDown || isLoading() )
|
||||
return;
|
||||
}
|
||||
|
||||
void GitPlugin::displayTooltip( UICodeEditor* editor, const Git::BlameData& blame,
|
||||
const Vector2f& position ) {
|
||||
// HACK: Gets the old font style to restore it when the tooltip is hidden
|
||||
UITooltip* tooltip = editor->createTooltip();
|
||||
if ( tooltip == nullptr )
|
||||
return;
|
||||
|
||||
String str(
|
||||
blame.error.empty()
|
||||
? String::format( "%s: %s\n%s: %s (%s)\n%s: %s\n\n%s",
|
||||
i18n( "commit", "Commit" ).toUtf8().c_str(), blame.commitHash.c_str(),
|
||||
i18n( "author", "Author" ).toUtf8().c_str(), blame.author.c_str(),
|
||||
blame.authorEmail.c_str(), i18n( "date", "Date" ).toUtf8().c_str(),
|
||||
blame.date.c_str(), blame.commitMessage.c_str() )
|
||||
: blame.error );
|
||||
|
||||
Text::wrapText( str, PixelDensity::dpToPx( 400 ), tooltip->getFontStyleConfig(),
|
||||
editor->getTabWidth() );
|
||||
|
||||
editor->setTooltipText( str );
|
||||
|
||||
mTooltipInfoShowing = true;
|
||||
mOldTextStyle = tooltip->getFontStyle();
|
||||
mOldTextAlign = tooltip->getHorizontalAlign();
|
||||
mOldDontAutoHideOnMouseMove = tooltip->dontAutoHideOnMouseMove();
|
||||
mOldUsingCustomStyling = tooltip->getUsingCustomStyling();
|
||||
tooltip->setHorizontalAlign( UI_HALIGN_LEFT );
|
||||
tooltip->setPixelsPosition( tooltip->getTooltipPosition( position ) );
|
||||
tooltip->setDontAutoHideOnMouseMove( false );
|
||||
tooltip->setUsingCustomStyling( true );
|
||||
|
||||
// const auto& syntaxDef = SyntaxDefinitionManager::instance()->getByLSPName( "markdown" );
|
||||
|
||||
// SyntaxTokenizer::tokenizeText( syntaxDef, editor->getColorScheme(), *tooltip->getTextCache(), 0,
|
||||
// 0xFFFFFFFF, true, "\n\t " );
|
||||
|
||||
// tooltip->notifyTextChangedFromTextCache();
|
||||
|
||||
if ( editor->hasFocus() && !tooltip->isVisible() )
|
||||
tooltip->show();
|
||||
}
|
||||
|
||||
void GitPlugin::hideTooltip( UICodeEditor* editor ) {
|
||||
mTooltipInfoShowing = false;
|
||||
UITooltip* tooltip = nullptr;
|
||||
if ( editor && ( tooltip = editor->getTooltip() ) && tooltip->isVisible() ) {
|
||||
editor->setTooltipText( "" );
|
||||
tooltip->hide();
|
||||
// Restore old tooltip state
|
||||
tooltip->setFontStyle( mOldTextStyle );
|
||||
tooltip->setHorizontalAlign( mOldTextAlign );
|
||||
tooltip->setUsingCustomStyling( mOldUsingCustomStyling );
|
||||
tooltip->setDontAutoHideOnMouseMove( mOldDontAutoHideOnMouseMove );
|
||||
}
|
||||
}
|
||||
|
||||
void GitPlugin::onRegisterListeners( UICodeEditor* editor, std::vector<Uint32>& listeners ) {
|
||||
listeners.push_back(
|
||||
editor->addEventListener( Event::OnCursorPosChange, [this, editor]( const Event* ) {
|
||||
if ( mTooltipInfoShowing )
|
||||
hideTooltip( editor );
|
||||
} ) );
|
||||
}
|
||||
|
||||
void GitPlugin::blame( UICodeEditor* editor ) {
|
||||
if ( !mGitFound ) {
|
||||
editor->setTooltipText(
|
||||
i18n( "git_not_found",
|
||||
"Git binary not found.\nPlease check that git is accesible via PATH" ) );
|
||||
return;
|
||||
}
|
||||
mThreadPool->run( [this, editor]() {
|
||||
auto blame = mGit->blame( editor->getDocument().getFilePath(),
|
||||
editor->getDocument().getSelection().start().line() );
|
||||
editor->runOnMainThread( [this, editor, blame] {
|
||||
displayTooltip(
|
||||
editor, blame,
|
||||
editor->getScreenPosition( editor->getDocument().getSelection().start() )
|
||||
.getPosition() );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::onRegister( UICodeEditor* editor ) {
|
||||
PluginBase::onRegister( editor );
|
||||
if ( !editor->hasDocument() )
|
||||
return;
|
||||
|
||||
auto& doc = editor->getDocument();
|
||||
doc.setCommand( "git-blame", [this]( TextDocument::Client* client ) {
|
||||
blame( static_cast<UICodeEditor*>( client ) );
|
||||
} );
|
||||
}
|
||||
|
||||
void GitPlugin::onUnregister( UICodeEditor* editor ) {
|
||||
PluginBase::onUnregister( editor );
|
||||
}
|
||||
|
||||
bool GitPlugin::onCreateContextMenu( UICodeEditor*, UIPopUpMenu* menu, const Vector2i& /*position*/,
|
||||
const Uint32& /*flags*/ ) {
|
||||
if ( !mGitFound )
|
||||
return false;
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
auto addFn = [this, menu]( const std::string& txtKey, const std::string& txtVal,
|
||||
const std::string& icon = "" ) {
|
||||
menu->add( i18n( txtKey, txtVal ),
|
||||
!icon.empty() ? mManager->getUISceneNode()->findIcon( icon )->getSize(
|
||||
PixelDensity::dpToPxI( 12 ) )
|
||||
: nullptr,
|
||||
KeyBindings::keybindFormat( mKeyBindings[txtKey] ) )
|
||||
->setId( txtKey );
|
||||
};
|
||||
|
||||
addFn( "git-blame", "Git Blame" );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
Reference in New Issue
Block a user