Skip to content

Commit 70aecdd

Browse files
committed
Added support for Tab jump modes (SpartanJ/ecode#469). Including a Tab Switcher (I have no better name for the moment).
Added support to hide the Tab Bar (SpartanJ/ecode#477). Updated efsw. Updated JS, TS, C++ grammars.
1 parent b6ead5f commit 70aecdd

25 files changed

+536
-52
lines changed

bin/assets/plugins/aiassistant.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@
209209
},
210210
{
211211
"max_tokens": 128000,
212-
"name": "gpt-4o-mini",
213-
"cheapest": true
212+
"name": "gpt-4o-mini"
214213
},
215214
{
216215
"max_tokens": 200000,
@@ -229,7 +228,8 @@
229228
"name": "o3-mini"
230229
},
231230
{
232-
"name": "gpt-4.1-nano"
231+
"name": "gpt-4.1-nano",
232+
"cheapest": true
233233
},
234234
{
235235
"name": "gpt-4.1-mini"

include/eepp/ui/keyboardshortcut.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class EE_API KeyBindings {
6666

6767
void removeKeybind( const Shortcut& keys );
6868

69-
void removeKeybind(const std::string& kb );
69+
void removeKeybind( const std::string& kb );
7070

7171
bool existsKeybind( const Shortcut& keys );
7272

@@ -86,6 +86,8 @@ class EE_API KeyBindings {
8686

8787
const std::map<std::string, Uint64> getKeybindings() const;
8888

89+
Shortcut getShortcutFromCommand( const std::string& cmd ) const;
90+
8991
std::string getShortcutString( Shortcut shortcut, bool format = false ) const;
9092

9193
protected:

include/eepp/ui/models/itemlistmodel.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ template <typename T> class ItemListOwnerModel final : public Model {
109109
return std::make_shared<ItemListOwnerModel<T>>( data );
110110
}
111111

112+
explicit ItemListOwnerModel( std::vector<T>&& data ) : mData( std::move( data ) ) {}
113+
112114
explicit ItemListOwnerModel( const std::vector<T>& data ) : mData( data ) {}
113115

114116
virtual ~ItemListOwnerModel() {}

include/eepp/ui/tools/uicodeeditorsplitter.hpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ class EE_API UICodeEditorSplitter {
230230

231231
void setHideTabBarOnSingleTab( bool hideTabBarOnSingleTab );
232232

233+
void setHideTabBar( bool hideTabBar );
234+
233235
const std::vector<UITabWidget*>& getTabWidgets() const;
234236

235237
Node* getBaseLayout() const;
@@ -280,21 +282,13 @@ class EE_API UICodeEditorSplitter {
280282
} );
281283
t.setCommand( "next-tab", [this] {
282284
UITabWidget* tabWidget = tabWidgetFromWidget( mCurWidget );
283-
if ( tabWidget && tabWidget->getTabCount() > 1 ) {
284-
UITab* tab = (UITab*)mCurWidget->getData();
285-
Uint32 tabIndex = tabWidget->getTabIndex( tab );
286-
switchToTab( ( tabIndex + 1 ) % tabWidget->getTabCount() );
287-
}
285+
if ( tabWidget )
286+
tabWidget->focusNextTab();
288287
} );
289288
t.setCommand( "previous-tab", [this] {
290289
UITabWidget* tabWidget = tabWidgetFromWidget( mCurWidget );
291-
if ( tabWidget && tabWidget->getTabCount() > 1 ) {
292-
UITab* tab = (UITab*)mCurWidget->getData();
293-
Uint32 tabIndex = tabWidget->getTabIndex( tab );
294-
Int32 newTabIndex = (Int32)tabIndex - 1;
295-
switchToTab( newTabIndex < 0 ? tabWidget->getTabCount() - newTabIndex
296-
: newTabIndex );
297-
}
290+
if ( tabWidget )
291+
tabWidget->focusPreviousTab();
298292
} );
299293
for ( int i = 1; i <= 10; i++ )
300294
t.setCommand( String::format( "switch-to-tab-%d", i ),
@@ -379,6 +373,7 @@ class EE_API UICodeEditorSplitter {
379373
std::vector<UITabWidget*> mTabWidgets;
380374
Node* mBaseLayout{ nullptr };
381375
Client* mClient;
376+
bool mHideTabBar{ false };
382377
bool mHideTabBarOnSingleTab{ true };
383378
bool mFirstCodeEditor{ true };
384379
bool mVisualSplitting{ true };

include/eepp/ui/uitabwidget.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace EE { namespace UI {
1111

1212
class UIPopUpMenu;
1313
class UIScrollBar;
14+
class UIListView;
1415

1516
class EE_API TabEvent : public Event {
1617
public:
@@ -32,6 +33,17 @@ class EE_API UITabWidget : public UIWidget {
3233

3334
enum class FocusTabBehavior { Closest, FocusOrder, Default };
3435

36+
enum class TabJumpMode { Linear, Chronological };
37+
38+
static TabJumpMode tabJumpModefromString( std::string_view mode ) {
39+
return String::iequals( mode, "chronological" ) ? TabJumpMode::Chronological
40+
: TabJumpMode::Linear;
41+
}
42+
43+
static std::string tabJumpModeToString( TabJumpMode mode ) {
44+
return mode == TabJumpMode::Chronological ? "chronological" : "linear";
45+
}
46+
3547
class StyleConfig {
3648
public:
3749
Float TabSeparation = 0;
@@ -151,10 +163,14 @@ class EE_API UITabWidget : public UIWidget {
151163

152164
UITab* setTabSelected( const Uint32& tabIndex );
153165

166+
const bool& getHideTabBar() const;
167+
154168
const bool& getHideTabBarOnSingleTab() const;
155169

156170
void setHideTabBarOnSingleTab( const bool& hideTabBarOnSingleTab );
157171

172+
void setHideTabBar( const bool& hideTabBar );
173+
158174
const TabTryCloseCallback& getTabTryCloseCallback() const;
159175

160176
void setTabTryCloseCallback( const TabTryCloseCallback& tabTryCloseCallback );
@@ -195,6 +211,20 @@ class EE_API UITabWidget : public UIWidget {
195211

196212
void setSplitFunction( SplitFunctionCb cb, Float splitEdgePercent = 0.1 );
197213

214+
const std::deque<UITab*>& getFocusHistory() const { return mFocusHistory; }
215+
216+
void setEnableTabSwitcher( bool enable ) { mEnableTabSwitcher = enable; }
217+
218+
bool isTabSwitcherEnabled() const { return mEnableTabSwitcher; }
219+
220+
void focusNextTab( const std::vector<Keycode>& tabSwitcherMetaTrigger = {} );
221+
222+
void focusPreviousTab( const std::vector<Keycode>& tabSwitcherMetaTrigger = {} );
223+
224+
void setTabJumpMode( TabJumpMode mode ) { mTabJumpMode = mode; }
225+
226+
TabJumpMode getTabJumpMode() const { return mTabJumpMode; }
227+
198228
protected:
199229
friend class UITab;
200230

@@ -207,18 +237,22 @@ class EE_API UITabWidget : public UIWidget {
207237
Uint32 mTabSelectedIndex;
208238
TabTryCloseCallback mTabTryCloseCallback;
209239
bool mHideTabBarOnSingleTab{ false };
240+
bool mHideTabBar{ false };
210241
bool mAllowRearrangeTabs{ false };
211242
bool mAllowDragAndDropTabs{ false };
212243
bool mAllowSwitchTabsInEmptySpaces{ false };
213244
bool mDroppableHoveringColorWasSet{ false };
214245
bool mEnabledCreateContextMenu{ false };
246+
bool mEnableTabSwitcher{ false };
215247
Float mTabVerticalDragResistance;
216248
Color mDroppableHoveringColor{ Color::Transparent };
217249
FocusTabBehavior mFocusTabBehavior{ FocusTabBehavior::Closest };
218250
std::deque<UITab*> mFocusHistory;
219251
UIPopUpMenu* mCurrentMenu{ nullptr };
220252
SplitFunctionCb mSplitFn;
221253
Float mSplitEdgePercent{ 0.1 };
254+
UIListView* mTabSwitcher{ nullptr };
255+
TabJumpMode mTabJumpMode{ TabJumpMode::Chronological };
222256

223257
void onThemeLoaded();
224258

@@ -268,6 +302,11 @@ class EE_API UITabWidget : public UIWidget {
268302
void eraseFocusHistory( UITab* tab );
269303

270304
std::optional<SplitDirection> getDropDirection() const;
305+
306+
void createTabSwitcher( const std::vector<Keycode>& tabSwitcherMetaTrigger,
307+
bool fromPrev = false );
308+
309+
Uint32 getTabSelectedFocusHistoryIndex() const;
271310
};
272311

273312
}} // namespace EE::UI

include/eepp/window/keycodes.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,8 @@ class EE_API KeyMod {
712712

713713
static const std::map<std::string, Uint32>& getModMap();
714714

715+
static std::vector<Keycode> getKeyCodesFromModifier( Uint32 mod );
716+
715717
private:
716718
static Uint32 defaultModifier;
717719
};

src/eepp/ui/doc/languages/cpp.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ void addCPP() {
2525
{ "keyword", "keyword", "literal" } },
2626
{ { "cpp_number_parser" }, "number", "", SyntaxPatternMatchType::Parser },
2727
{ { "[%+%-=/%*%^%%<>!~|&]" }, "operator" },
28-
{ { "(if|for|while|switch|catch|sizeof|typeid|defined)\\s*(?=\\()" },
28+
{ { "(if|for|while|switch|catch|sizeof|typeid|defined|return|throw|alignof|noexcept|"
29+
"new|delete)"
30+
"\\s*(?=\\()" },
2931
{ "normal", "keyword", "keyword" },
3032
"",
3133
SyntaxPatternMatchType::RegEx },

src/eepp/ui/doc/languages/javascript.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ void addJavaScript() {
2020
"string" },
2121
{ { "js_number_parser" }, "number", "", SyntaxPatternMatchType::Parser },
2222
{ { "[%+%-=/%*%^%%<>!~|&]" }, "operator" },
23-
{ { "(if|for|while|switch|catch|with)\\s*(?=\\()" },
23+
{ { "(if|for|while|switch|catch|with|typeof|delete|void|super|await|function)\\s*(?="
24+
"\\()" },
2425
{ "normal", "keyword", "keyword" },
2526
"",
2627
SyntaxPatternMatchType::RegEx },

src/eepp/ui/doc/syntaxdefinitionmanager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class TextMateScopeMapper {
6363
{ "constant.other", "literal" },
6464
{ "constant.regexp", "string" },
6565

66+
{ "meta.import", "keyword" },
67+
{ "meta.package", "keyword" },
68+
6669
{ "comment.unused", "normal" }, // unused comments pattern
6770
{ "declaration.package", "literal" },
6871
{ "declaration.import", "literal" },

src/eepp/ui/keyboardshortcut.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ bool KeyBindings::hasCommand( const std::string& command ) {
119119
return mKeybindingsInvert.find( command ) != mKeybindingsInvert.end();
120120
}
121121

122+
KeyBindings::Shortcut KeyBindings::getShortcutFromCommand( const std::string& cmd ) const {
123+
auto it = mKeybindingsInvert.find( cmd );
124+
if ( it != mKeybindingsInvert.end() )
125+
return it->second;
126+
return {};
127+
}
128+
122129
void KeyBindings::removeCommandKeybind( const std::string& command ) {
123130
auto kbIt = mKeybindingsInvert.find( command );
124131
if ( kbIt != mKeybindingsInvert.end() ) {

src/eepp/ui/tools/uicodeeditorsplitter.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ UITabWidget* UICodeEditorSplitter::createTabWidget( Node* parent ) {
632632
tabWidget->setParent( parent );
633633
tabWidget->setTabsClosable( true );
634634
tabWidget->setHideTabBarOnSingleTab( mHideTabBarOnSingleTab );
635+
tabWidget->setHideTabBar( mHideTabBar );
635636
tabWidget->setAllowRearrangeTabs( true );
636637
tabWidget->setAllowDragAndDropTabs( true );
637638
tabWidget->setAllowSwitchTabsInEmptySpaces( true );
@@ -958,6 +959,15 @@ void UICodeEditorSplitter::setHideTabBarOnSingleTab( bool hideTabBarOnSingleTab
958959
}
959960
}
960961

962+
void UICodeEditorSplitter::setHideTabBar( bool hideTabBar ) {
963+
if ( hideTabBar != mHideTabBar ) {
964+
mHideTabBar = hideTabBar;
965+
966+
for ( auto widget : mTabWidgets )
967+
widget->setHideTabBar( hideTabBar );
968+
}
969+
}
970+
961971
const std::vector<UITabWidget*>& UICodeEditorSplitter::getTabWidgets() const {
962972
return mTabWidgets;
963973
}

src/eepp/ui/uieventdispatcher.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void UIEventDispatcher::checkTabPress( const Uint32& KeyCode, const Uint32& mod
5252
if ( mFocusNode->isWidget() && NULL != win && !mJustGainedFocus ) {
5353
if ( mod & KEYMOD_SHIFT ) {
5454
mFocusNode->asType<UIWidget>()->onFocusPrevWidget();
55-
} else {
55+
} else if ( mod == 0 ) {
5656
mFocusNode->asType<UIWidget>()->onFocusNextWidget();
5757
}
5858
}

src/eepp/ui/uiscrollablewidget.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ Rectf UIScrollableWidget::getVisibleRect() const {
203203

204204
bool UIScrollableWidget::shouldVerticalScrollBeVisible() const {
205205
Float totH = getPixelsSize().getHeight() - getPixelsPadding().Top - getPixelsPadding().Bottom -
206-
mHScroll->getPixelsSize().getHeight();
206+
( mHScrollMode == ScrollBarMode::AlwaysOff || !mHScroll->isVisible()
207+
? 0
208+
: mHScroll->getPixelsSize().getHeight() );
207209
return getContentSize().getHeight() > totH;
208210
}
209211

@@ -391,6 +393,17 @@ Uint32 UIScrollableWidget::onMessage( const NodeMessage* Msg ) {
391393
if ( moved )
392394
return 1;
393395
}
396+
case NodeMessage::FocusLoss: {
397+
if ( NULL != getEventDispatcher() ) {
398+
Node* focusNode = getEventDispatcher()->getFocusNode();
399+
400+
if ( this != focusNode && !isParentOf( focusNode ) ) {
401+
onWidgetFocusLoss();
402+
}
403+
404+
return 1;
405+
}
406+
}
394407
}
395408
return UIWidget::onMessage( Msg );
396409
}

0 commit comments

Comments
 (0)