forked from qt-creator/qt-creator
FakeVim: Support for relative line numbering
Settable using 'relativenumber' and 'rnu' options. Change-Id: Idb5aa9669bdfa157d6bb6b517a09d63e8f511b95 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -198,6 +198,7 @@ FakeVimSettings *theFakeVimSettings()
|
|||||||
createAction(s, ConfigWrapScan, true, _("WrapScan"), _("ws"));
|
createAction(s, ConfigWrapScan, true, _("WrapScan"), _("ws"));
|
||||||
createAction(s, ConfigTildeOp, false, _("TildeOp"), _("top"));
|
createAction(s, ConfigTildeOp, false, _("TildeOp"), _("top"));
|
||||||
createAction(s, ConfigShowCmd, true, _("ShowCmd"), _("sc"));
|
createAction(s, ConfigShowCmd, true, _("ShowCmd"), _("sc"));
|
||||||
|
createAction(s, ConfigRelativeNumber, false, _("RelativeNumber"),_("rnu"));
|
||||||
createAction(s, ConfigScrollOff, 0, _("ScrollOff"), _("so"));
|
createAction(s, ConfigScrollOff, 0, _("ScrollOff"), _("so"));
|
||||||
createAction(s, ConfigBackspace, _("indent,eol,start"), _("ConfigBackspace"), _("bs"));
|
createAction(s, ConfigBackspace, _("indent,eol,start"), _("ConfigBackspace"), _("bs"));
|
||||||
createAction(s, ConfigIsKeyword, _("@,48-57,_,192-255,a-z,A-Z"), _("IsKeyword"), _("isk"));
|
createAction(s, ConfigIsKeyword, _("@,48-57,_,192-255,a-z,A-Z"), _("IsKeyword"), _("isk"));
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ enum FakeVimSettingsCode
|
|||||||
ConfigPassKeys,
|
ConfigPassKeys,
|
||||||
ConfigClipboard,
|
ConfigClipboard,
|
||||||
ConfigShowCmd,
|
ConfigShowCmd,
|
||||||
ConfigScrollOff
|
ConfigScrollOff,
|
||||||
|
ConfigRelativeNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
class FakeVimSettings : public QObject
|
class FakeVimSettings : public QObject
|
||||||
|
|||||||
@@ -137,6 +137,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkBoxRelativeNumber">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Display line numbers relative to the line containing text cursor.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Show line numbers relative to cursor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -372,6 +382,7 @@
|
|||||||
<tabstop>checkBoxWrapScan</tabstop>
|
<tabstop>checkBoxWrapScan</tabstop>
|
||||||
<tabstop>checkBoxShowMarks</tabstop>
|
<tabstop>checkBoxShowMarks</tabstop>
|
||||||
<tabstop>checkBoxPassControlKey</tabstop>
|
<tabstop>checkBoxPassControlKey</tabstop>
|
||||||
|
<tabstop>checkBoxRelativeNumber</tabstop>
|
||||||
<tabstop>spinBoxShiftWidth</tabstop>
|
<tabstop>spinBoxShiftWidth</tabstop>
|
||||||
<tabstop>spinBoxTabStop</tabstop>
|
<tabstop>spinBoxTabStop</tabstop>
|
||||||
<tabstop>spinBoxScrollOff</tabstop>
|
<tabstop>spinBoxScrollOff</tabstop>
|
||||||
|
|||||||
@@ -86,8 +86,10 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QPainter>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QScrollBar>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
@@ -231,6 +233,127 @@ private:
|
|||||||
int m_lastMessageLevel;
|
int m_lastMessageLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RelativeNumbersColumn : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RelativeNumbersColumn(BaseTextEditorWidget *baseTextEditor)
|
||||||
|
: QWidget(baseTextEditor)
|
||||||
|
, m_currentPos(0)
|
||||||
|
, m_lineSpacing(0)
|
||||||
|
, m_editor(baseTextEditor)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||||
|
|
||||||
|
m_timerUpdate.setSingleShot(true);
|
||||||
|
m_timerUpdate.setInterval(0);
|
||||||
|
connect(&m_timerUpdate, SIGNAL(timeout()), SLOT(followEditorLayout()));
|
||||||
|
updateOnSignal(m_editor, SIGNAL(cursorPositionChanged()));
|
||||||
|
updateOnSignal(m_editor->verticalScrollBar(), SIGNAL(valueChanged(int)));
|
||||||
|
updateOnSignal(m_editor->document(), SIGNAL(contentsChanged()));
|
||||||
|
updateOnSignal(TextEditorSettings::instance(),
|
||||||
|
SIGNAL(displaySettingsChanged(TextEditor::DisplaySettings)));
|
||||||
|
|
||||||
|
m_editor->installEventFilter(this);
|
||||||
|
|
||||||
|
followEditorLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
QTextCursor firstVisibleCursor = m_editor->cursorForPosition(QPoint(0, 0));
|
||||||
|
QTextBlock firstVisibleBlock = firstVisibleCursor.block();
|
||||||
|
if (firstVisibleCursor.positionInBlock() > 0) {
|
||||||
|
firstVisibleBlock = firstVisibleBlock.next();
|
||||||
|
firstVisibleCursor.setPosition(firstVisibleBlock.position());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find relative number for the first visible line.
|
||||||
|
QTextBlock block = m_editor->textCursor().block();
|
||||||
|
bool forward = firstVisibleBlock.blockNumber() > block.blockNumber();
|
||||||
|
int n = 0;
|
||||||
|
while (block.isValid() && block != firstVisibleBlock) {
|
||||||
|
block = forward ? block.next() : block.previous();
|
||||||
|
if (block.isVisible())
|
||||||
|
n += forward ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy colors from extra area palette.
|
||||||
|
QPainter p(this);
|
||||||
|
QPalette pal = m_editor->extraArea()->palette();
|
||||||
|
const QColor fg = pal.color(QPalette::Dark);
|
||||||
|
const QColor bg = pal.color(QPalette::Background);
|
||||||
|
p.setPen(fg);
|
||||||
|
|
||||||
|
// Draw relative line numbers.
|
||||||
|
QRect rect(0, m_editor->cursorRect(firstVisibleCursor).y(), width(), m_lineSpacing);
|
||||||
|
bool hideLineNumbers = m_editor->lineNumbersVisible();
|
||||||
|
while (block.isValid()) {
|
||||||
|
if (block.isVisible()) {
|
||||||
|
if (n != 0 && rect.intersects(event->rect())) {
|
||||||
|
const int line = qAbs(n);
|
||||||
|
const QString number = QString::number(line);
|
||||||
|
if (hideLineNumbers)
|
||||||
|
p.fillRect(rect, bg);
|
||||||
|
if (hideLineNumbers || line < 100)
|
||||||
|
p.drawText(rect, Qt::AlignRight | Qt::AlignVCenter, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.translate(0, m_lineSpacing * block.lineCount());
|
||||||
|
if (rect.y() > height())
|
||||||
|
break;
|
||||||
|
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = block.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eventFilter(QObject *, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::Resize || event->type() == QEvent::Move)
|
||||||
|
m_timerUpdate.start();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void followEditorLayout()
|
||||||
|
{
|
||||||
|
QTextCursor tc = m_editor->textCursor();
|
||||||
|
m_currentPos = tc.position();
|
||||||
|
m_lineSpacing = m_editor->cursorRect(tc).height();
|
||||||
|
setFont(m_editor->extraArea()->font());
|
||||||
|
|
||||||
|
// Follow geometry of normal line numbers if visible,
|
||||||
|
// otherwise follow geometry of marks (breakpoints etc.).
|
||||||
|
QRect rect = m_editor->extraArea()->geometry().adjusted(0, 0, -3, 0);
|
||||||
|
bool marksVisible = m_editor->marksVisible();
|
||||||
|
bool lineNumbersVisible = m_editor->lineNumbersVisible();
|
||||||
|
bool foldMarksVisible = m_editor->codeFoldingVisible();
|
||||||
|
if (marksVisible && lineNumbersVisible)
|
||||||
|
rect.setLeft(m_lineSpacing);
|
||||||
|
if (foldMarksVisible && (marksVisible || lineNumbersVisible))
|
||||||
|
rect.setRight(rect.right() - (m_lineSpacing + m_lineSpacing % 2));
|
||||||
|
setGeometry(rect);
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateOnSignal(QObject *object, const char *signal)
|
||||||
|
{
|
||||||
|
connect(object, signal, &m_timerUpdate, SLOT(start()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_currentPos;
|
||||||
|
int m_lineSpacing;
|
||||||
|
BaseTextEditorWidget *m_editor;
|
||||||
|
QTimer m_timerUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// FakeVimOptionPage
|
// FakeVimOptionPage
|
||||||
@@ -334,6 +457,9 @@ QWidget *FakeVimOptionPage::widget()
|
|||||||
m_group.insert(theFakeVimSetting(ConfigShowCmd),
|
m_group.insert(theFakeVimSetting(ConfigShowCmd),
|
||||||
m_ui.checkBoxShowCmd);
|
m_ui.checkBoxShowCmd);
|
||||||
|
|
||||||
|
m_group.insert(theFakeVimSetting(ConfigRelativeNumber),
|
||||||
|
m_ui.checkBoxRelativeNumber);
|
||||||
|
|
||||||
connect(m_ui.pushButtonCopyTextEditorSettings, SIGNAL(clicked()),
|
connect(m_ui.pushButtonCopyTextEditorSettings, SIGNAL(clicked()),
|
||||||
SLOT(copyTextEditorSettings()));
|
SLOT(copyTextEditorSettings()));
|
||||||
connect(m_ui.pushButtonSetQtStyle, SIGNAL(clicked()),
|
connect(m_ui.pushButtonSetQtStyle, SIGNAL(clicked()),
|
||||||
@@ -901,6 +1027,7 @@ private slots:
|
|||||||
void maybeReadVimRc();
|
void maybeReadVimRc();
|
||||||
void setBlockSelection(bool);
|
void setBlockSelection(bool);
|
||||||
void hasBlockSelection(bool*);
|
void hasBlockSelection(bool*);
|
||||||
|
void setShowRelativeLineNumbers(const QVariant &value);
|
||||||
|
|
||||||
void resetCommandBuffer();
|
void resetCommandBuffer();
|
||||||
void showCommandBuffer(const QString &contents, int cursorPos, int anchorPos,
|
void showCommandBuffer(const QString &contents, int cursorPos, int anchorPos,
|
||||||
@@ -923,6 +1050,8 @@ private slots:
|
|||||||
void switchToFile(int n);
|
void switchToFile(int n);
|
||||||
int currentFile() const;
|
int currentFile() const;
|
||||||
|
|
||||||
|
void createRelativeNumberWidget(IEditor *editor);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void delayedQuitRequested(bool forced, Core::IEditor *editor);
|
void delayedQuitRequested(bool forced, Core::IEditor *editor);
|
||||||
void delayedQuitAllRequested(bool forced);
|
void delayedQuitAllRequested(bool forced);
|
||||||
@@ -1104,6 +1233,8 @@ bool FakeVimPluginPrivate::initialize()
|
|||||||
this, SLOT(maybeReadVimRc()));
|
this, SLOT(maybeReadVimRc()));
|
||||||
connect(theFakeVimSetting(ConfigVimRcPath), SIGNAL(valueChanged(QVariant)),
|
connect(theFakeVimSetting(ConfigVimRcPath), SIGNAL(valueChanged(QVariant)),
|
||||||
this, SLOT(maybeReadVimRc()));
|
this, SLOT(maybeReadVimRc()));
|
||||||
|
connect(theFakeVimSetting(ConfigRelativeNumber), SIGNAL(valueChanged(QVariant)),
|
||||||
|
this, SLOT(setShowRelativeLineNumbers(QVariant)));
|
||||||
|
|
||||||
// Delayed operations.
|
// Delayed operations.
|
||||||
connect(this, SIGNAL(delayedQuitRequested(bool,Core::IEditor*)),
|
connect(this, SIGNAL(delayedQuitRequested(bool,Core::IEditor*)),
|
||||||
@@ -1143,6 +1274,15 @@ void FakeVimPluginPrivate::userActionTriggered()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimPluginPrivate::createRelativeNumberWidget(IEditor *editor)
|
||||||
|
{
|
||||||
|
if (BaseTextEditorWidget *textEditor = qobject_cast<BaseTextEditorWidget *>(editor->widget())) {
|
||||||
|
RelativeNumbersColumn *relativeNumbers = new RelativeNumbersColumn(textEditor);
|
||||||
|
connect(theFakeVimSetting(ConfigRelativeNumber), SIGNAL(valueChanged(QVariant)),
|
||||||
|
relativeNumbers, SLOT(deleteLater()));
|
||||||
|
relativeNumbers->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char exCommandMapGroup[] = "FakeVimExCommand";
|
const char exCommandMapGroup[] = "FakeVimExCommand";
|
||||||
const char userCommandMapGroup[] = "FakeVimUserCommand";
|
const char userCommandMapGroup[] = "FakeVimUserCommand";
|
||||||
@@ -1673,6 +1813,9 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
|
|||||||
resetCommandBuffer();
|
resetCommandBuffer();
|
||||||
handler->setupWidget();
|
handler->setupWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theFakeVimSetting(ConfigRelativeNumber)->value().toBool())
|
||||||
|
createRelativeNumberWidget(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeVimPluginPrivate::editorAboutToClose(IEditor *editor)
|
void FakeVimPluginPrivate::editorAboutToClose(IEditor *editor)
|
||||||
@@ -1746,6 +1889,14 @@ void FakeVimPluginPrivate::hasBlockSelection(bool *on)
|
|||||||
*on = bt->hasBlockSelection();
|
*on = bt->hasBlockSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FakeVimPluginPrivate::setShowRelativeLineNumbers(const QVariant &value)
|
||||||
|
{
|
||||||
|
if (value.toBool()) {
|
||||||
|
foreach (IEditor *editor, m_editorToHandler.keys())
|
||||||
|
createRelativeNumberWidget(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FakeVimPluginPrivate::checkForElectricCharacter(bool *result, QChar c)
|
void FakeVimPluginPrivate::checkForElectricCharacter(bool *result, QChar c)
|
||||||
{
|
{
|
||||||
FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
|
FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
|
||||||
|
|||||||
Reference in New Issue
Block a user