Commit d6919b15 authored by hluk's avatar hluk Committed by hjk
Browse files

FakeVim: Support for relative line numbering



Settable using 'relativenumber' and 'rnu' options.

Change-Id: Idb5aa9669bdfa157d6bb6b517a09d63e8f511b95
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent c63ccc90
......@@ -198,6 +198,7 @@ FakeVimSettings *theFakeVimSettings()
createAction(s, ConfigWrapScan, true, _("WrapScan"), _("ws"));
createAction(s, ConfigTildeOp, false, _("TildeOp"), _("top"));
createAction(s, ConfigShowCmd, true, _("ShowCmd"), _("sc"));
createAction(s, ConfigRelativeNumber, false, _("RelativeNumber"),_("rnu"));
createAction(s, ConfigScrollOff, 0, _("ScrollOff"), _("so"));
createAction(s, ConfigBackspace, _("indent,eol,start"), _("ConfigBackspace"), _("bs"));
createAction(s, ConfigIsKeyword, _("@,48-57,_,192-255,a-z,A-Z"), _("IsKeyword"), _("isk"));
......
......@@ -98,7 +98,8 @@ enum FakeVimSettingsCode
ConfigPassKeys,
ConfigClipboard,
ConfigShowCmd,
ConfigScrollOff
ConfigScrollOff,
ConfigRelativeNumber
};
class FakeVimSettings : public QObject
......
......@@ -137,6 +137,16 @@
</property>
</widget>
</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>
</item>
<item>
......@@ -372,6 +382,7 @@
<tabstop>checkBoxWrapScan</tabstop>
<tabstop>checkBoxShowMarks</tabstop>
<tabstop>checkBoxPassControlKey</tabstop>
<tabstop>checkBoxRelativeNumber</tabstop>
<tabstop>spinBoxShiftWidth</tabstop>
<tabstop>spinBoxTabStop</tabstop>
<tabstop>spinBoxScrollOff</tabstop>
......
......@@ -86,8 +86,10 @@
#include <QFileDialog>
#include <QtPlugin>
#include <QObject>
#include <QPainter>
#include <QPointer>
#include <QSettings>
#include <QScrollBar>
#include <QStackedWidget>
#include <QTextStream>
......@@ -231,6 +233,127 @@ private:
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
......@@ -334,6 +457,9 @@ QWidget *FakeVimOptionPage::widget()
m_group.insert(theFakeVimSetting(ConfigShowCmd),
m_ui.checkBoxShowCmd);
m_group.insert(theFakeVimSetting(ConfigRelativeNumber),
m_ui.checkBoxRelativeNumber);
connect(m_ui.pushButtonCopyTextEditorSettings, SIGNAL(clicked()),
SLOT(copyTextEditorSettings()));
connect(m_ui.pushButtonSetQtStyle, SIGNAL(clicked()),
......@@ -901,6 +1027,7 @@ private slots:
void maybeReadVimRc();
void setBlockSelection(bool);
void hasBlockSelection(bool*);
void setShowRelativeLineNumbers(const QVariant &value);
void resetCommandBuffer();
void showCommandBuffer(const QString &contents, int cursorPos, int anchorPos,
......@@ -923,6 +1050,8 @@ private slots:
void switchToFile(int n);
int currentFile() const;
void createRelativeNumberWidget(IEditor *editor);
signals:
void delayedQuitRequested(bool forced, Core::IEditor *editor);
void delayedQuitAllRequested(bool forced);
......@@ -1104,6 +1233,8 @@ bool FakeVimPluginPrivate::initialize()
this, SLOT(maybeReadVimRc()));
connect(theFakeVimSetting(ConfigVimRcPath), SIGNAL(valueChanged(QVariant)),
this, SLOT(maybeReadVimRc()));
connect(theFakeVimSetting(ConfigRelativeNumber), SIGNAL(valueChanged(QVariant)),
this, SLOT(setShowRelativeLineNumbers(QVariant)));
// Delayed operations.
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 userCommandMapGroup[] = "FakeVimUserCommand";
......@@ -1673,6 +1813,9 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor)
resetCommandBuffer();
handler->setupWidget();
}
if (theFakeVimSetting(ConfigRelativeNumber)->value().toBool())
createRelativeNumberWidget(editor);
}
void FakeVimPluginPrivate::editorAboutToClose(IEditor *editor)
......@@ -1746,6 +1889,14 @@ void FakeVimPluginPrivate::hasBlockSelection(bool *on)
*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)
{
FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment