mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-25 23:57:53 +03:00
UITab: Implemented proper support for max/min width and height.
UICodeEditor::getLineHeight() now uses the font height. ecode: Fixes for Formatter and Linter plugins.
This commit is contained in:
@@ -31,8 +31,8 @@ class EE_API UITabWidget : public UIWidget {
|
||||
Uint32 MaxTextLength = 100;
|
||||
Float TabHeight = 0;
|
||||
Uint32 TabTextAlign = ( UI_HALIGN_CENTER | UI_VALIGN_CENTER );
|
||||
Float MinTabWidth = 32;
|
||||
Float MaxTabWidth = 300;
|
||||
std::string MinTabWidth = "32dp";
|
||||
std::string MaxTabWidth = "300dp";
|
||||
bool TabsClosable = false;
|
||||
bool TabsEdgesDiffSkins = false; //! Indicates if the edge tabs ( the left and right
|
||||
//! border tab ) are different from the central tabs.
|
||||
@@ -91,13 +91,13 @@ class EE_API UITabWidget : public UIWidget {
|
||||
|
||||
void setMaxTextLength( const Uint32& maxTextLength );
|
||||
|
||||
Float getMinTabWidth() const;
|
||||
std::string getMinTabWidth() const;
|
||||
|
||||
void setMinTabWidth( const Float& minTabWidth );
|
||||
void setMinTabWidth( const std::string& minTabWidth );
|
||||
|
||||
Float getMaxTabWidth() const;
|
||||
std::string getMaxTabWidth() const;
|
||||
|
||||
void setMaxTabWidth( const Float& maxTabWidth );
|
||||
void setMaxTabWidth( const std::string& maxTabWidth );
|
||||
|
||||
bool getTabsClosable() const;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class EE_API UITextView : public UIWidget {
|
||||
|
||||
virtual void onSizeChange();
|
||||
|
||||
virtual void autoShrink();
|
||||
virtual void autoWrap();
|
||||
|
||||
virtual void onAutoSize();
|
||||
|
||||
|
||||
@@ -239,9 +239,9 @@ class EE_API UIWidget : public UINode {
|
||||
|
||||
void createTooltip();
|
||||
|
||||
Sizef getCurrentMinSize();
|
||||
Sizef getMinSize();
|
||||
|
||||
Sizef getCurrentMaxSize();
|
||||
Sizef getMaxSize();
|
||||
|
||||
bool isTabStop() const;
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ class EE_API Engine {
|
||||
public:
|
||||
~Engine();
|
||||
|
||||
static bool isEngineRunning();
|
||||
|
||||
/** Creates a new window. */
|
||||
EE::Window::Window* createWindow( WindowSettings Settings,
|
||||
ContextSettings Context = ContextSettings() );
|
||||
|
||||
+1
-1
@@ -1184,7 +1184,7 @@ solution "eepp"
|
||||
set_kind()
|
||||
language "C++"
|
||||
files { "src/tools/eterm/**.cpp" }
|
||||
if os.is("linux") then
|
||||
if os.is_real("linux") then
|
||||
links { "util" }
|
||||
end
|
||||
if os.is("haiku") then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 7.0.2, 2022-06-28T21:06:48. -->
|
||||
<!-- Written by QtCreator 7.0.2, 2022-07-01T23:51:49. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
@@ -109,7 +109,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">20</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
@@ -1203,6 +1203,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">ecode-debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||
<value type="QString" key="RunConfiguration.Arguments">"/home/downloads/Reporte de facturacion de 01-06-2022 a 30-06-2022.csv"</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
|
||||
@@ -1125,6 +1125,7 @@
|
||||
../../src/tools/ecode/projectdirectorytree.hpp
|
||||
../../src/tools/ecode/projectsearch.cpp
|
||||
../../src/tools/ecode/projectsearch.hpp
|
||||
../../src/tools/ecode/scopedop.hpp
|
||||
../../src/tools/ecode/uicodeeditorsplitter.cpp
|
||||
../../src/tools/ecode/uicodeeditorsplitter.hpp
|
||||
../../src/tools/ecode/uitreeviewglobalsearch.cpp
|
||||
|
||||
@@ -2033,7 +2033,7 @@ Int64 UICodeEditor::getColFromXOffset( Int64 lineNumber, const Float& x ) const
|
||||
}
|
||||
|
||||
Float UICodeEditor::getLineHeight() const {
|
||||
return mFont->getLineSpacing( getCharacterSize() );
|
||||
return mFont->getFontHeight( getCharacterSize() );
|
||||
}
|
||||
|
||||
Float UICodeEditor::getCharacterSize() const {
|
||||
|
||||
@@ -188,13 +188,13 @@ void UISplitter::updateFromDrag() {
|
||||
mSplitter->setEnabled( mSplitter->isVisible() );
|
||||
|
||||
if ( UIOrientation::Horizontal == mOrientation ) {
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getCurrentMinSize().getWidth() : 0.f;
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getMinSize().getWidth() : 0.f;
|
||||
|
||||
if ( mSplitter->getPosition().x < mPadding.Left + fMinSize ) {
|
||||
mSplitter->setPosition( mPadding.Left + fMinSize, mSplitter->getPosition().y );
|
||||
}
|
||||
|
||||
Float lMinSize = mLastWidget ? mLastWidget->getCurrentMinSize().getWidth() : 0.f;
|
||||
Float lMinSize = mLastWidget ? mLastWidget->getMinSize().getWidth() : 0.f;
|
||||
|
||||
if ( mSplitter->getPosition().x + mSplitter->getSize().getWidth() >
|
||||
mDpSize.getWidth() - mPadding.Right - lMinSize ) {
|
||||
@@ -206,13 +206,13 @@ void UISplitter::updateFromDrag() {
|
||||
mSplitter->setPixelsSize( mSplitter->getPixelsSize().getWidth(),
|
||||
mSize.getHeight() - mPaddingPx.Top - mPaddingPx.Bottom );
|
||||
} else {
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getCurrentMinSize().getHeight() : 0.f;
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getMinSize().getHeight() : 0.f;
|
||||
|
||||
if ( mSplitter->getPosition().y < mPadding.Top + fMinSize ) {
|
||||
mSplitter->setPosition( mSplitter->getPosition().x, mPadding.Top + fMinSize );
|
||||
}
|
||||
|
||||
Float lMinSize = mLastWidget ? mLastWidget->getCurrentMinSize().getHeight() : 0.f;
|
||||
Float lMinSize = mLastWidget ? mLastWidget->getMinSize().getHeight() : 0.f;
|
||||
|
||||
if ( mSplitter->getPosition().y + mSplitter->getSize().getHeight() >
|
||||
mDpSize.getHeight() - mPadding.Bottom - lMinSize ) {
|
||||
@@ -346,7 +346,7 @@ void UISplitter::updateLayout() {
|
||||
mFirstWidget->setPixelsPosition( mPaddingPx.Left, mPaddingPx.Top );
|
||||
|
||||
if ( UIOrientation::Horizontal == mOrientation ) {
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getCurrentMinSize().getWidth() : 0.f;
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getMinSize().getWidth() : 0.f;
|
||||
|
||||
firstSplit = eemax( firstSplit, fMinSize );
|
||||
secondSplit = totalSpace - firstSplit;
|
||||
@@ -361,7 +361,7 @@ void UISplitter::updateLayout() {
|
||||
mSize.getHeight() - mPaddingPx.Top - mPaddingPx.Bottom );
|
||||
} else {
|
||||
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getCurrentMinSize().getHeight() : 0.f;
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getMinSize().getHeight() : 0.f;
|
||||
|
||||
firstSplit = eemax( firstSplit, fMinSize );
|
||||
secondSplit = totalSpace - firstSplit;
|
||||
|
||||
+15
-4
@@ -229,8 +229,7 @@ void UITab::onAutoSize() {
|
||||
}
|
||||
|
||||
if ( mFlags & UI_AUTO_SIZE ) {
|
||||
Float w =
|
||||
mTextBox->getSize().getWidth() +
|
||||
Float nonTextW =
|
||||
( NULL != mIcon ? mIcon->getSize().getWidth() + mIcon->getLayoutMargin().Left +
|
||||
mIcon->getLayoutMargin().Right
|
||||
: 0 ) +
|
||||
@@ -239,10 +238,17 @@ void UITab::onAutoSize() {
|
||||
mCloseButton->getLayoutMargin().Right
|
||||
: 0 ) +
|
||||
getSkinSize().getWidth();
|
||||
Float textW = mTextBox->getSize().getWidth();
|
||||
Float w = textW + nonTextW;
|
||||
|
||||
if ( NULL != tTabW ) {
|
||||
w = eemax( w, tTabW->getMinTabWidth() );
|
||||
w = eemin( w, tTabW->getMaxTabWidth() );
|
||||
if ( !mMinWidthEq.empty() )
|
||||
w = eemax( w, getMinSize().getWidth() );
|
||||
if ( !mMaxWidthEq.empty() )
|
||||
w = eemin( w, getMaxSize().getWidth() );
|
||||
|
||||
if ( textW > w - nonTextW )
|
||||
getTextBox()->setMaxWidthEq( String::format( "%.0fdp", w - nonTextW ) );
|
||||
}
|
||||
|
||||
setInternalWidth( w );
|
||||
@@ -251,6 +257,9 @@ void UITab::onAutoSize() {
|
||||
if ( NULL != getTabWidget() )
|
||||
getTabWidget()->orderTabs();
|
||||
}
|
||||
|
||||
if ( getTextBox()->getTextWidth() > getTextBox()->getSize().getWidth() )
|
||||
getTextBox()->setHorizontalAlign( UI_HALIGN_LEFT );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,6 +355,8 @@ void UITab::updateTab() {
|
||||
UITabWidget* tTabW = getTabWidget();
|
||||
|
||||
if ( NULL != tTabW ) {
|
||||
setMinWidthEq( tTabW->getMinTabWidth() );
|
||||
setMaxWidthEq( tTabW->getMaxTabWidth() );
|
||||
if ( mText.size() > tTabW->getMaxTextLength() ) {
|
||||
UIPushButton::setText( mText.substr( 0, tTabW->getMaxTextLength() ) );
|
||||
} else {
|
||||
|
||||
@@ -149,9 +149,9 @@ std::string UITabWidget::getPropertyString( const PropertyDefinition* propertyDe
|
||||
case PropertyId::MaxTextLength:
|
||||
return String::toString( getMaxTextLength() );
|
||||
case PropertyId::MinTabWidth:
|
||||
return String::fromFloat( getMinTabWidth(), "dp" );
|
||||
return getMinTabWidth();
|
||||
case PropertyId::MaxTabWidth:
|
||||
return String::fromFloat( getMaxTabWidth(), "dp" );
|
||||
return getMaxTabWidth();
|
||||
case PropertyId::TabClosable:
|
||||
return getTabsClosable() ? "true" : "false";
|
||||
case PropertyId::TabsEdgesDiffSkin:
|
||||
@@ -221,10 +221,10 @@ bool UITabWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
setMaxTextLength( attribute.asUint( 1 ) );
|
||||
break;
|
||||
case PropertyId::MinTabWidth:
|
||||
setMinTabWidth( attribute.asDpDimension( this, "1" ) );
|
||||
setMinTabWidth( attribute.asString() );
|
||||
break;
|
||||
case PropertyId::MaxTabWidth:
|
||||
setMaxTabWidth( attribute.asDpDimension( this ) );
|
||||
setMaxTabWidth( attribute.asString() );
|
||||
break;
|
||||
case PropertyId::TabClosable:
|
||||
setTabsClosable( attribute.asBool() );
|
||||
@@ -281,11 +281,11 @@ void UITabWidget::setMaxTextLength( const Uint32& maxTextLength ) {
|
||||
}
|
||||
}
|
||||
|
||||
Float UITabWidget::getMinTabWidth() const {
|
||||
std::string UITabWidget::getMinTabWidth() const {
|
||||
return mStyleConfig.MinTabWidth;
|
||||
}
|
||||
|
||||
void UITabWidget::setMinTabWidth( const Float& minTabWidth ) {
|
||||
void UITabWidget::setMinTabWidth( const std::string& minTabWidth ) {
|
||||
if ( minTabWidth != mStyleConfig.MinTabWidth ) {
|
||||
mStyleConfig.MinTabWidth = minTabWidth;
|
||||
updateTabs();
|
||||
@@ -293,11 +293,11 @@ void UITabWidget::setMinTabWidth( const Float& minTabWidth ) {
|
||||
}
|
||||
}
|
||||
|
||||
Float UITabWidget::getMaxTabWidth() const {
|
||||
std::string UITabWidget::getMaxTabWidth() const {
|
||||
return mStyleConfig.MaxTabWidth;
|
||||
}
|
||||
|
||||
void UITabWidget::setMaxTabWidth( const Float& maxTabWidth ) {
|
||||
void UITabWidget::setMaxTabWidth( const std::string& maxTabWidth ) {
|
||||
if ( maxTabWidth != mStyleConfig.MaxTabWidth ) {
|
||||
mStyleConfig.MaxTabWidth = maxTabWidth;
|
||||
updateTabs();
|
||||
|
||||
@@ -265,7 +265,7 @@ UITextView* UITextView::setSelectionBackColor( const Color& color ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
void UITextView::autoShrink() {
|
||||
void UITextView::autoWrap() {
|
||||
if ( mFlags & UI_WORD_WRAP ) {
|
||||
wrapText( mSize.getWidth() );
|
||||
}
|
||||
@@ -286,13 +286,25 @@ void UITextView::onAutoSize() {
|
||||
}
|
||||
|
||||
if ( mWidthPolicy == SizePolicy::WrapContent ) {
|
||||
setInternalPixelsWidth( (int)mTextCache->getTextWidth() + mPaddingPx.Left +
|
||||
mPaddingPx.Right );
|
||||
Float totW = (int)mTextCache->getTextWidth() + mPaddingPx.Left + mPaddingPx.Right;
|
||||
if ( !getMaxWidthEq().empty() ) {
|
||||
Float oldW = totW;
|
||||
totW = eemin( totW, getMaxSize().getWidth() );
|
||||
if ( oldW != totW )
|
||||
clipEnable();
|
||||
}
|
||||
setInternalPixelsWidth( totW );
|
||||
}
|
||||
|
||||
if ( mHeightPolicy == SizePolicy::WrapContent ) {
|
||||
setInternalPixelsHeight( (int)mTextCache->getTextHeight() + mPaddingPx.Top +
|
||||
mPaddingPx.Bottom );
|
||||
Float totH = (int)mTextCache->getTextHeight() + mPaddingPx.Top + mPaddingPx.Bottom;
|
||||
if ( !getMaxHeightEq().empty() ) {
|
||||
Float oldH = totH;
|
||||
totH = eemin( totH, getMaxSize().getHeight() );
|
||||
if ( oldH != totH )
|
||||
clipEnable();
|
||||
}
|
||||
setInternalPixelsHeight( totH );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,7 +605,7 @@ void UITextView::recalculate() {
|
||||
mFontLineCenter = eefloor(
|
||||
(Float)( ( mTextCache->getFont()->getLineSpacing( fontHeight ) - fontHeight ) / 2 ) );
|
||||
|
||||
autoShrink();
|
||||
autoWrap();
|
||||
onAutoSize();
|
||||
alignFix();
|
||||
resetSelCache();
|
||||
@@ -641,7 +653,7 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
if ( flags & UI_WORD_WRAP ) {
|
||||
mFlags |= UI_WORD_WRAP;
|
||||
flags &= ~UI_WORD_WRAP;
|
||||
autoShrink();
|
||||
autoWrap();
|
||||
}
|
||||
|
||||
setFontStyle( flags );
|
||||
@@ -652,7 +664,7 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
mFlags |= UI_WORD_WRAP;
|
||||
else
|
||||
mFlags &= ~UI_WORD_WRAP;
|
||||
autoShrink();
|
||||
autoWrap();
|
||||
break;
|
||||
case PropertyId::TextStrokeWidth:
|
||||
setOutlineThickness( lengthFromValue( attribute ) );
|
||||
|
||||
@@ -415,7 +415,7 @@ Node* UIWidget::setSize( const Sizef& size ) {
|
||||
return UINode::setSize( s );
|
||||
}
|
||||
|
||||
Sizef UIWidget::getCurrentMinSize() {
|
||||
Sizef UIWidget::getMinSize() {
|
||||
Sizef s;
|
||||
|
||||
if ( s.x < mMinSize.x )
|
||||
@@ -438,19 +438,19 @@ Sizef UIWidget::getCurrentMinSize() {
|
||||
return s;
|
||||
}
|
||||
|
||||
Sizef UIWidget::getCurrentMaxSize() {
|
||||
Sizef UIWidget::getMaxSize() {
|
||||
Sizef s;
|
||||
|
||||
if ( !mMaxWidthEq.empty() ) {
|
||||
Float length =
|
||||
lengthFromValueAsDp( mMaxWidthEq, CSS::PropertyRelativeTarget::ContainingBlockWidth );
|
||||
s.x = eemin( s.x, length );
|
||||
s.x = eemax( s.x, length );
|
||||
}
|
||||
|
||||
if ( !mMaxHeightEq.empty() ) {
|
||||
Float length =
|
||||
lengthFromValueAsDp( mMaxHeightEq, CSS::PropertyRelativeTarget::ContainingBlockHeight );
|
||||
s.y = eemin( s.y, length );
|
||||
s.y = eemax( s.y, length );
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
@@ -220,6 +220,10 @@ Uint32 Engine::getWindowCount() const {
|
||||
return mWindows.size();
|
||||
}
|
||||
|
||||
bool Engine::isEngineRunning() {
|
||||
return existsSingleton() && Engine::instance()->isRunning();
|
||||
}
|
||||
|
||||
bool Engine::isRunning() const {
|
||||
return NULL != mWindow;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "formatterplugin.hpp"
|
||||
#include "../../scopedop.hpp"
|
||||
#include "../../thirdparty/json.hpp"
|
||||
#include "../../thirdparty/subprocess.h"
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <eepp/system/lock.hpp>
|
||||
#include <eepp/system/luapattern.hpp>
|
||||
#include <random>
|
||||
|
||||
@@ -27,7 +29,13 @@ FormatterPlugin::FormatterPlugin( const std::string& formattersPath,
|
||||
}
|
||||
|
||||
FormatterPlugin::~FormatterPlugin() {
|
||||
mClosing = true;
|
||||
mShuttingDown = true;
|
||||
|
||||
if ( mWorkersCount != 0 ) {
|
||||
std::unique_lock<std::mutex> lock( mWorkMutex );
|
||||
mWorkerCondition.wait( lock, [&]() { return mWorkersCount <= 0; } );
|
||||
}
|
||||
|
||||
for ( auto editor : mEditors )
|
||||
editor->unregisterPlugin( this );
|
||||
}
|
||||
@@ -49,7 +57,7 @@ void FormatterPlugin::onRegister( UICodeEditor* editor ) {
|
||||
}
|
||||
|
||||
void FormatterPlugin::onUnregister( UICodeEditor* editor ) {
|
||||
if ( mClosing )
|
||||
if ( mShuttingDown )
|
||||
return;
|
||||
mEditors.erase( editor );
|
||||
}
|
||||
@@ -98,6 +106,16 @@ void FormatterPlugin::load( const std::string& formatterPath ) {
|
||||
}
|
||||
|
||||
void FormatterPlugin::formatDoc( UICodeEditor* editor ) {
|
||||
ScopedOp op(
|
||||
[&]() {
|
||||
mWorkMutex.lock();
|
||||
mWorkersCount++;
|
||||
},
|
||||
[&]() {
|
||||
mWorkersCount--;
|
||||
mWorkMutex.unlock();
|
||||
mWorkerCondition.notify_all();
|
||||
} );
|
||||
if ( !mReady )
|
||||
return;
|
||||
|
||||
@@ -152,8 +170,8 @@ void FormatterPlugin::runFormatter( UICodeEditor* editor, const Formatter& forma
|
||||
const std::string& path ) {
|
||||
|
||||
std::string cmd( formatter.command );
|
||||
String::replaceAll( cmd, "$FILENAME", path );
|
||||
std::vector<std::string> cmdArr = String::split( cmd, ' ' );
|
||||
String::replaceAll( cmd, "$FILENAME", "\"" + path + "\"" );
|
||||
std::vector<std::string> cmdArr = String::split( cmd, " " );
|
||||
std::vector<const char*> strings;
|
||||
for ( size_t i = 0; i < cmdArr.size(); ++i )
|
||||
strings.push_back( cmdArr[i].c_str() );
|
||||
@@ -168,13 +186,14 @@ void FormatterPlugin::runFormatter( UICodeEditor* editor, const Formatter& forma
|
||||
std::string buffer( 1024, '\0' );
|
||||
std::string data;
|
||||
unsigned bytesRead = 0;
|
||||
int returnCode;
|
||||
do {
|
||||
bytesRead = subprocess_read_stdout( &subprocess, &buffer[0], buffer.size() );
|
||||
data += buffer.substr( 0, bytesRead );
|
||||
} while ( bytesRead != 0 );
|
||||
} while ( bytesRead != 0 && subprocess_alive( &subprocess ) && !mShuttingDown );
|
||||
|
||||
int ret;
|
||||
subprocess_join( &subprocess, &ret );
|
||||
if ( subprocess_alive( &subprocess ) && !mShuttingDown )
|
||||
subprocess_join( &subprocess, &returnCode );
|
||||
subprocess_destroy( &subprocess );
|
||||
// Log::info( "Formatter result:\n%s", data.c_str() );
|
||||
|
||||
@@ -209,4 +228,4 @@ FormatterPlugin::Formatter FormatterPlugin::supportsFormatter( std::shared_ptr<T
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ecode
|
||||
|
||||
@@ -42,9 +42,12 @@ class FormatterPlugin : public UICodeEditorPlugin {
|
||||
std::shared_ptr<ThreadPool> mPool;
|
||||
std::vector<Formatter> mFormatters;
|
||||
std::set<UICodeEditor*> mEditors;
|
||||
std::mutex mWorkMutex;
|
||||
std::condition_variable mWorkerCondition;
|
||||
Int32 mWorkersCount{ 0 };
|
||||
|
||||
bool mAutoFormatOnSave{ false };
|
||||
bool mClosing{ false };
|
||||
bool mShuttingDown{ false };
|
||||
bool mReady{ false };
|
||||
|
||||
void load( const std::string& formatterPath );
|
||||
@@ -56,6 +59,6 @@ class FormatterPlugin : public UICodeEditorPlugin {
|
||||
FormatterPlugin::Formatter supportsFormatter( std::shared_ptr<TextDocument> doc );
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ecode
|
||||
|
||||
#endif // ECODE_FORMATTERPLUGIN_HPP
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "linterplugin.hpp"
|
||||
#include "../../scopedop.hpp"
|
||||
#include "../../thirdparty/json.hpp"
|
||||
#include "../../thirdparty/subprocess.h"
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/text.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <eepp/system/lock.hpp>
|
||||
#include <eepp/system/luapattern.hpp>
|
||||
#include <eepp/ui/uitooltip.hpp>
|
||||
#include <random>
|
||||
@@ -29,7 +31,13 @@ LinterPlugin::LinterPlugin( const std::string& lintersPath, std::shared_ptr<Thre
|
||||
}
|
||||
|
||||
LinterPlugin::~LinterPlugin() {
|
||||
mClosing = true;
|
||||
mShuttingDown = true;
|
||||
|
||||
if ( mWorkersCount != 0 ) {
|
||||
std::unique_lock<std::mutex> lock( mWorkMutex );
|
||||
mWorkerCondition.wait( lock, [&]() { return mWorkersCount <= 0; } );
|
||||
}
|
||||
|
||||
for ( const auto& editor : mEditors ) {
|
||||
for ( auto listener : editor.second )
|
||||
editor.first->removeEventListener( listener );
|
||||
@@ -155,7 +163,7 @@ void LinterPlugin::onRegister( UICodeEditor* editor ) {
|
||||
}
|
||||
|
||||
void LinterPlugin::onUnregister( UICodeEditor* editor ) {
|
||||
if ( mClosing )
|
||||
if ( mShuttingDown )
|
||||
return;
|
||||
Lock l( mDocMutex );
|
||||
TextDocument* doc = mEditorDocs[editor];
|
||||
@@ -193,11 +201,22 @@ void LinterPlugin::setDelayTime( const Time& delayTime ) {
|
||||
}
|
||||
|
||||
void LinterPlugin::lintDoc( std::shared_ptr<TextDocument> doc ) {
|
||||
ScopedOp op(
|
||||
[&]() {
|
||||
mWorkMutex.lock();
|
||||
mWorkersCount++;
|
||||
},
|
||||
[&]() {
|
||||
mWorkersCount--;
|
||||
mWorkMutex.unlock();
|
||||
mWorkerCondition.notify_all();
|
||||
} );
|
||||
if ( !mReady )
|
||||
return;
|
||||
auto linter = supportsLinter( doc );
|
||||
if ( linter.command.empty() )
|
||||
return;
|
||||
|
||||
IOStreamString fileString;
|
||||
if ( doc->isDirty() || !doc->hasFilepath() ) {
|
||||
std::string tmpPath;
|
||||
@@ -230,8 +249,8 @@ void LinterPlugin::runLinter( std::shared_ptr<TextDocument> doc, const Linter& l
|
||||
const std::string& path ) {
|
||||
Clock clock;
|
||||
std::string cmd( linter.command );
|
||||
String::replaceAll( cmd, "$FILENAME", path );
|
||||
std::vector<std::string> cmdArr = String::split( cmd, ' ' );
|
||||
String::replaceAll( cmd, "$FILENAME", "\"" + path + "\"" );
|
||||
std::vector<std::string> cmdArr = String::split( cmd, " " );
|
||||
std::vector<const char*> strings;
|
||||
for ( size_t i = 0; i < cmdArr.size(); ++i )
|
||||
strings.push_back( cmdArr[i].c_str() );
|
||||
@@ -246,13 +265,14 @@ void LinterPlugin::runLinter( std::shared_ptr<TextDocument> doc, const Linter& l
|
||||
std::string buffer( 1024, '\0' );
|
||||
std::string data;
|
||||
unsigned bytesRead = 0;
|
||||
int returnCode;
|
||||
do {
|
||||
bytesRead = subprocess_read_stdout( &subprocess, &buffer[0], buffer.size() );
|
||||
data += buffer.substr( 0, bytesRead );
|
||||
} while ( bytesRead != 0 );
|
||||
} while ( bytesRead != 0 && subprocess_alive( &subprocess ) && !mShuttingDown );
|
||||
|
||||
int returnCode;
|
||||
subprocess_join( &subprocess, &returnCode );
|
||||
if ( subprocess_alive( &subprocess ) && !mShuttingDown )
|
||||
subprocess_join( &subprocess, &returnCode );
|
||||
subprocess_destroy( &subprocess );
|
||||
|
||||
if ( linter.hasNoErrorsExitCode && linter.noErrorsExitCode == returnCode ) {
|
||||
@@ -500,4 +520,4 @@ void LinterPlugin::invalidateEditors( TextDocument* doc ) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ecode
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <eepp/system/mutex.hpp>
|
||||
#include <eepp/system/threadpool.hpp>
|
||||
#include <eepp/ui/uicodeeditor.hpp>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
using namespace EE;
|
||||
using namespace EE::System;
|
||||
@@ -81,9 +82,12 @@ class LinterPlugin : public UICodeEditorPlugin {
|
||||
Time mDelayTime{ Seconds( 0.5f ) };
|
||||
Mutex mDocMutex;
|
||||
Mutex mMatchesMutex;
|
||||
std::mutex mWorkMutex;
|
||||
std::condition_variable mWorkerCondition;
|
||||
Int32 mWorkersCount{ 0 };
|
||||
|
||||
bool mReady{ false };
|
||||
bool mClosing{ false };
|
||||
bool mShuttingDown{ false };
|
||||
|
||||
void load( const std::string& lintersPath );
|
||||
|
||||
@@ -103,6 +107,6 @@ class LinterPlugin : public UICodeEditorPlugin {
|
||||
std::string getMatchString( const LinterType& type );
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ecode
|
||||
|
||||
#endif // ECODE_LINTERPLUGIN_HPP
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef ECODE_SCOPEDOP_HPP
|
||||
#define ECODE_SCOPEDOP_HPP
|
||||
|
||||
#include <functional>
|
||||
|
||||
class ScopedOp {
|
||||
public:
|
||||
ScopedOp( std::function<void()> startOp,
|
||||
std::function<void()> endOp = std::function<void()>() ) :
|
||||
mEndOp( endOp ) {
|
||||
if ( startOp )
|
||||
startOp();
|
||||
}
|
||||
|
||||
~ScopedOp() {
|
||||
if ( mEndOp )
|
||||
mEndOp();
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> mEndOp;
|
||||
};
|
||||
|
||||
#endif // SCOPEDOP_HPP
|
||||
+5
-7
@@ -432,7 +432,7 @@ int subprocess_create_named_pipe_helper(void **rd, void **wr) {
|
||||
pipeTypeByte | pipeWait, 1, 4096, 4096, SUBPROCESS_NULL,
|
||||
SUBPROCESS_PTR_CAST(LPSECURITY_ATTRIBUTES, &saAttr));
|
||||
|
||||
if (invalidHandleValue == rd) {
|
||||
if (invalidHandleValue == *rd) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ int subprocess_create_named_pipe_helper(void **rd, void **wr) {
|
||||
SUBPROCESS_PTR_CAST(LPSECURITY_ATTRIBUTES, &saAttr),
|
||||
openExisting, fileAttributeNormal, SUBPROCESS_NULL);
|
||||
|
||||
if (invalidHandleValue == wr) {
|
||||
if (invalidHandleValue == *wr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -740,10 +740,7 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
int stdoutfd[2];
|
||||
int stderrfd[2];
|
||||
pid_t child;
|
||||
extern char **environ;
|
||||
char *const empty_environment[1] = {SUBPROCESS_NULL};
|
||||
posix_spawn_file_actions_t actions;
|
||||
char *const *used_environment;
|
||||
|
||||
if (subprocess_option_inherit_environment ==
|
||||
(options & subprocess_option_inherit_environment)) {
|
||||
@@ -767,9 +764,10 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !defined(NO_POSIX_SPAWN)
|
||||
extern char **environ;
|
||||
posix_spawn_file_actions_t actions;
|
||||
char *const *used_environment;
|
||||
|
||||
if (environment) {
|
||||
#ifdef __clang__
|
||||
|
||||
Reference in New Issue
Block a user