Skip to content

Commit 4212ee1

Browse files
committed
Add Improved GuiTabline
Uses new Neovim API: neovim/neovim#12481 Adds QTabBars for both vim-tabs and vim-buffers. Also includes general UI improvements: - Tab close buttons - Tab filetype icons
1 parent d6e8c18 commit 4212ee1

File tree

10 files changed

+614
-211
lines changed

10 files changed

+614
-211
lines changed

src/gui/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ add_library(neovim-qt-gui
4747
popupmenumodel.cpp
4848
scrollbar.cpp
4949
shell.cpp
50+
tabline.cpp
5051
treeview.cpp
5152
${SRCS_PLATFORM}
5253
${NEOVIM_RCC_SOURCES})

src/gui/mainwindow.cpp

Lines changed: 10 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ static QString DefaultWindowTitle() noexcept
1313
return "Neovim";
1414
}
1515

16-
MainWindow::MainWindow(NeovimConnector* c, QWidget* parent)
17-
: QMainWindow(parent)
16+
MainWindow::MainWindow(NeovimConnector* c, QWidget* parent) noexcept
17+
: QMainWindow{ parent }
18+
, m_tabline{ *c, this }
1819
, m_defaultFont{ font() }
1920
, m_defaultPalette{ palette() }
2021
{
@@ -42,24 +43,7 @@ void MainWindow::init(NeovimConnector *c)
4243

4344
m_shell = new Shell(c);
4445

45-
m_tabline_bar = addToolBar("tabline");
46-
m_tabline_bar->setObjectName("tabline");
47-
m_tabline_bar->setAllowedAreas(Qt::TopToolBarArea);
48-
m_tabline_bar->setMovable(false);
49-
m_tabline_bar->setFloatable(false);
50-
// Avoid margins around the tabbar
51-
m_tabline_bar->layout()->setContentsMargins(0, 0, 0, 0);
52-
53-
m_tabline = new QTabBar(m_tabline_bar);
54-
m_tabline->setDrawBase(false);
55-
m_tabline->setExpanding(false);
56-
m_tabline->setDocumentMode(true);
57-
m_tabline->setFocusPolicy(Qt::NoFocus);
58-
connect(m_tabline, &QTabBar::currentChanged,
59-
this, &MainWindow::changeTab);
60-
61-
m_tabline_bar->addWidget(m_tabline);
62-
m_tabline_bar->setVisible(m_shell->GetShellOptions().IsTablineEnabled());
46+
addToolBar(&m_tabline);
6347

6448
// Context menu and actions for right-click
6549
m_contextMenu = new QMenu();
@@ -123,12 +107,6 @@ void MainWindow::init(NeovimConnector *c)
123107
this, &MainWindow::neovimError);
124108
connect(m_shell, &Shell::neovimIsUnsupported,
125109
this, &MainWindow::neovimIsUnsupported);
126-
connect(m_shell, &Shell::neovimExtTablineSet,
127-
this, &MainWindow::extTablineSet);
128-
connect(m_shell, &Shell::neovimTablineUpdate,
129-
this, &MainWindow::neovimTablineUpdate);
130-
connect(m_shell, &Shell::neovimShowtablineSet,
131-
this, &MainWindow::neovimShowtablineSet);
132110
connect(m_shell, &Shell::neovimShowContextMenu,
133111
this, &MainWindow::neovimShowContextMenu);
134112
connect(m_actCut, &QAction::triggered,
@@ -331,95 +309,18 @@ void MainWindow::handleNeovimAttachment(bool attached)
331309
{
332310
emit neovimAttachmentChanged(attached);
333311

334-
if (attached) {
335-
if (isWindow() && m_shell != NULL) {
336-
m_shell->updateGuiWindowState(windowState());
337-
}
338-
} else {
339-
m_tabline->deleteLater();
340-
m_tabline_bar->deleteLater();
341-
}
342-
}
343-
344-
Shell* MainWindow::shell()
345-
{
346-
return m_shell;
347-
}
348-
349-
void MainWindow::extTablineSet(bool val)
350-
{
351-
ShellOptions& shellOptions{ m_shell->GetShellOptions() };
352-
353-
// We can ignore events where the value does not change.
354-
if (val == shellOptions.IsTablineEnabled()) {
312+
if (!attached) {
355313
return;
356314
}
357315

358-
shellOptions.SetIsTablineEnabled(val);
359-
m_nvim->api0()->vim_command("silent! redraw!");
360-
m_tabline_bar->setVisible(val);
361-
}
362-
363-
void MainWindow::neovimShowtablineSet(int val)
364-
{
365-
m_shell->GetShellOptions().SetOptionShowTabline(val);
316+
if (m_shell && isWindow()) {
317+
m_shell->updateGuiWindowState(windowState());
318+
}
366319
}
367320

368-
void MainWindow::neovimTablineUpdate(int64_t curtab, QList<Tab> tabs)
321+
Shell* MainWindow::shell()
369322
{
370-
if (!m_shell->GetShellOptions().IsTablineEnabled()) {
371-
return;
372-
}
373-
374-
// remove extra tabs
375-
for (int index=tabs.size(); index<m_tabline->count(); index++) {
376-
m_tabline->removeTab(index);
377-
}
378-
379-
for (int index=0; index<tabs.size(); index++) {
380-
// Escape & in tab name otherwise it will be interpreted as
381-
// a keyboard shortcut (#357) - escaping is done using &&
382-
QString text = tabs[index].name;
383-
text.replace("&", "&&");
384-
385-
if (m_tabline->count() <= index) {
386-
m_tabline->addTab(text);
387-
} else {
388-
m_tabline->setTabText(index, text);
389-
}
390-
391-
m_tabline->setTabToolTip(index, text);
392-
m_tabline->setTabData(index, QVariant::fromValue(tabs[index].tab));
393-
394-
if (curtab == tabs[index].tab) {
395-
m_tabline->setCurrentIndex(index);
396-
}
397-
}
398-
399-
Q_ASSERT(tabs.size() == m_tabline->count());
400-
401-
switch(m_shell->GetShellOptions().GetOptionShowTabline())
402-
{
403-
// Never show tabline
404-
case 0:
405-
m_tabline_bar->setVisible(false);
406-
break;
407-
408-
// Show tabline for two or more tabs.
409-
case 1:
410-
m_tabline_bar->setVisible(tabs.size() >= 2);
411-
break;
412-
413-
// Always show tabline
414-
case 2:
415-
m_tabline_bar->setVisible(true);
416-
break;
417-
418-
// Fallback: show tabline for two or more tabs
419-
default:
420-
m_tabline_bar->setVisible(tabs.size() >= 2);
421-
break;
422-
}
323+
return m_shell;
423324
}
424325

425326
void MainWindow::neovimShowContextMenu()
@@ -447,20 +348,6 @@ void MainWindow::neovimSendSelectAll()
447348
m_nvim->api0()->vim_command("normal! ggVG");
448349
}
449350

450-
void MainWindow::changeTab(int index)
451-
{
452-
if (!m_shell->GetShellOptions().IsTablineEnabled()) {
453-
return;
454-
}
455-
456-
if (m_nvim->api2() == NULL) {
457-
return;
458-
}
459-
460-
int64_t tab = m_tabline->tabData(index).toInt();
461-
m_nvim->api2()->nvim_set_current_tabpage(tab);
462-
}
463-
464351
void MainWindow::saveWindowGeometry()
465352
{
466353
QSettings settings{ "window-geometry" };

src/gui/mainwindow.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
#ifndef NEOVIM_QT_MAINWINDOW
2-
#define NEOVIM_QT_MAINWINDOW
1+
#pragma once
32

43
#include <QMainWindow>
54
#include <QPalette>
65
#include <QSplitter>
7-
#include <QCloseEvent>
86
#include <QStackedWidget>
97
#include <QTabBar>
108

119
#include "errorwidget.h"
1210
#include "neovimconnector.h"
1311
#include "scrollbar.h"
1412
#include "shell.h"
13+
#include "tabline.h"
1514
#include "treeview.h"
1615

1716
namespace NeovimQt {
@@ -27,7 +26,7 @@ class MainWindow: public QMainWindow
2726
FullScreen,
2827
};
2928

30-
MainWindow(NeovimConnector *, QWidget *parent=0);
29+
MainWindow(NeovimConnector* c, QWidget* parent = nullptr) noexcept;
3130

3231
bool isNeovimAttached() const noexcept { return m_shell && m_shell->isNeovimAttached(); }
3332

@@ -60,15 +59,11 @@ private slots:
6059
void showIfDelayed();
6160
void handleNeovimAttachment(bool);
6261
void neovimIsUnsupported();
63-
void neovimShowtablineSet(int);
64-
void neovimTablineUpdate(int64_t curtab, QList<NeovimQt::Tab> tabs);
6562
void neovimShowContextMenu();
6663
void neovimSendCut();
6764
void neovimSendCopy();
6865
void neovimSendPaste();
6966
void neovimSendSelectAll();
70-
void extTablineSet(bool);
71-
void changeTab(int index);
7267
void saveWindowGeometry();
7368

7469
// GuiAdaptive Color/Font/Style Slots
@@ -87,8 +82,6 @@ private slots:
8782
Shell* m_shell{ nullptr };
8883
DelayedShow m_delayedShow{ DelayedShow::Disabled };
8984
QStackedWidget m_stack;
90-
QTabBar* m_tabline{ nullptr };
91-
QToolBar* m_tabline_bar{ nullptr };
9285

9386
bool m_neovim_requested_close{ false };
9487
QMenu* m_contextMenu{ nullptr };
@@ -97,6 +90,7 @@ private slots:
9790
QAction* m_actPaste{ nullptr };
9891
QAction* m_actSelectAll{ nullptr };
9992
ScrollBar* m_scrollbar{ nullptr };
93+
Tabline m_tabline;
10094
int m_exitStatus{ 0 };
10195

10296
// GuiAdaptive Color/Font/Style
@@ -111,6 +105,4 @@ private slots:
111105
void updateAdaptiveFont() noexcept;
112106
};
113107

114-
} // Namespace
115-
116-
#endif
108+
} // namespace NeovimQt

src/gui/shell.cpp

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -562,30 +562,8 @@ void Shell::handleRedraw(const QByteArray& name, const QVariantList& opargs)
562562
handleBusy(true);
563563
} else if (name == "busy_stop"){
564564
handleBusy(false);
565-
} else if (name == "tabline_update") {
566-
if (opargs.size() < 2 || !opargs.at(0).canConvert<int64_t>()) {
567-
qWarning() << "Unexpected argument for tabline_update:" << opargs;
568-
return;
569-
}
570-
int64_t curtab = opargs.at(0).toInt();
571-
QList<Tab> tabs;
572-
foreach(const QVariant& tabv, opargs.at(1).toList()) {
573-
QVariantMap tab = tabv.toMap();
574-
575-
if (!tab.contains("tab") || !tab.contains("name")) {
576-
qWarning() << "Unexpected tab value in tabline_update:" << tab;
577-
}
578-
579-
int64_t num = tab.value("tab").toInt();
580-
QString name = tab.value("name").toString();
581-
tabs.append(Tab(num, name));
582-
}
583-
584-
emit neovimTablineUpdate(curtab, tabs);
585565
} else if (name == "option_set") {
586-
if (2 <= opargs.size()) {
587-
handleSetOption(opargs.at(0).toString(), opargs.at(1));
588-
}
566+
handleSetOption(opargs);
589567
} else if (name == "suspend") {
590568
if (isWindow()) {
591569
setWindowState(windowState() | Qt::WindowMinimized);
@@ -942,18 +920,22 @@ void Shell::handleExtGuiOption(const QString& name, const QVariant& value)
942920
}
943921
}
944922

945-
void Shell::handleSetOption(const QString& name, const QVariant& value)
923+
void Shell::handleSetOption(const QVariantList& opargs)
946924
{
925+
if (opargs.size() < 2 || !opargs.at(0).canConvert<QString>()) {
926+
qWarning() << "Unexpected arguments for option_set:" << opargs;
927+
return;
928+
}
929+
930+
const QString name{ opargs.at(0).toString() };
931+
const QVariant& value{ opargs.at(1) };
932+
947933
if (name == "guifont") {
948934
setGuiFont(value.toString(), false /*force*/);
949935
} else if (name == "guifontwide") {
950936
handleGuiFontWide(value);
951937
} else if (name == "linespace") {
952938
handleLineSpace(value);
953-
} else if (name == "showtabline") {
954-
emit neovimShowtablineSet(value.toString().toInt());
955-
} else if (name == "ext_tabline") {
956-
emit neovimExtTablineSet(value.toBool());
957939
} else {
958940
// Uncomment for writing new event handling code.
959941
// qDebug() << "Received unknown option" << name << value;

src/gui/shell.h

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
#ifndef NEOVIM_QT_SHELL
2-
#define NEOVIM_QT_SHELL
3-
4-
#include <QWidget>
5-
#include <QVariantList>
6-
#include <QFont>
1+
#pragma once
72
#include <QBackingStore>
3+
#include <QFont>
84
#include <QLabel>
9-
#include <QTimer>
10-
#include <QUrl>
115
#include <QList>
126
#include <QMap>
137
#include <QMenu>
8+
#include <QTimer>
9+
#include <QUrl>
10+
#include <QVariantList>
11+
#include <QWidget>
1412

1513
#include "neovimconnector.h"
1614
#include "popupmenu.h"
@@ -19,20 +17,10 @@
1917
#include "shellwidget/cursor.h"
2018
#include "shellwidget/highlight.h"
2119
#include "shellwidget/shellwidget.h"
20+
#include "tab.h"
2221

2322
namespace NeovimQt {
2423

25-
class Tab {
26-
public:
27-
Tab(int64_t id, QString name) {
28-
this->tab = id;
29-
this->name = name;
30-
}
31-
/// The tab handle, a unique tab identifier
32-
int64_t tab;
33-
QString name;
34-
};
35-
3624
class Shell: public ShellWidget
3725
{
3826
Q_OBJECT
@@ -95,11 +83,6 @@ class Shell: public ShellWidget
9583
void neovimGuiCloseRequest(int status = 0);
9684
/// This signal is emmited if the running neovim version is unsupported by the GUI
9785
void neovimIsUnsupported();
98-
void neovimExtTablineSet(bool);
99-
/// The tabline needs updating. curtab is the handle of the current tab (not its index)
100-
/// as seen in Tab::tab.
101-
void neovimTablineUpdate(int64_t curtab, QList<NeovimQt::Tab> tabs);
102-
void neovimShowtablineSet(int);
10386
void neovimShowContextMenu();
10487
void colorsChanged();
10588

@@ -159,7 +142,7 @@ protected slots:
159142
virtual void handleSetTitle(const QVariantList& opargs);
160143
virtual void handleSetScrollRegion(const QVariantList& opargs);
161144
virtual void handleBusy(bool);
162-
virtual void handleSetOption(const QString& name, const QVariant& value);
145+
virtual void handleSetOption(const QVariantList& opargs);
163146
void handleExtGuiOption(const QString& name, const QVariant& value);
164147
virtual void handlePopupMenuShow(const QVariantList& opargs);
165148
virtual void handlePopupMenuSelect(const QVariantList& opargs);
@@ -288,5 +271,4 @@ template <class T>
288271
}
289272
}
290273

291-
} // Namespace
292-
#endif
274+
} // namespace NeovimQtj

0 commit comments

Comments
 (0)