2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2009-03-30 14:46:33 +02:00
|
|
|
|
|
|
|
|
#include "fakevimactions.h"
|
2012-05-03 10:43:04 +02:00
|
|
|
#include "fakevimhandler.h"
|
2023-01-22 19:47:45 +01:00
|
|
|
#include "fakevimtr.h"
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2010-01-29 21:33:57 +01:00
|
|
|
// Please do not add any direct dependencies to other Qt Creator code here.
|
2009-03-30 14:46:33 +02:00
|
|
|
// Instead emit signals and let the FakeVimPlugin channel the information to
|
|
|
|
|
// Qt Creator. The idea is to keep this file here in a "clean" state that
|
|
|
|
|
// allows easy reuse with any QTextEdit or QPlainTextEdit derived class.
|
|
|
|
|
|
2023-05-31 08:49:34 +02:00
|
|
|
#ifndef FAKEVIM_STANDALONE
|
|
|
|
|
#include <texteditor/icodestylepreferences.h>
|
|
|
|
|
#include <texteditor/tabsettings.h>
|
|
|
|
|
#include <texteditor/texteditorsettings.h>
|
|
|
|
|
#include <texteditor/typingsettings.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-05-24 00:40:44 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
2021-02-26 17:55:55 +01:00
|
|
|
#include <utils/layoutbuilder.h>
|
2009-03-30 14:46:33 +02:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2009-10-05 11:06:05 +02:00
|
|
|
using namespace Utils;
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2023-06-01 12:02:13 +02:00
|
|
|
namespace FakeVim::Internal {
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2021-02-26 17:55:55 +01:00
|
|
|
#ifdef FAKEVIM_STANDALONE
|
2014-01-22 19:01:07 +02:00
|
|
|
|
2023-08-24 10:15:12 +02:00
|
|
|
void FvBaseAspect::setSettingsKey(const Key &group, const Key &key)
|
2014-01-22 19:01:07 +02:00
|
|
|
{
|
2016-03-01 23:24:59 +01:00
|
|
|
m_settingsGroup = group;
|
2014-01-22 19:01:07 +02:00
|
|
|
m_settingsKey = key;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-24 10:15:12 +02:00
|
|
|
Key FvBaseAspect::settingsKey() const
|
2014-01-22 19:01:07 +02:00
|
|
|
{
|
|
|
|
|
return m_settingsKey;
|
|
|
|
|
}
|
2021-03-18 09:36:15 +01:00
|
|
|
|
|
|
|
|
// unused but kept for compile
|
|
|
|
|
void setAutoApply(bool ) {}
|
2021-02-26 17:55:55 +01:00
|
|
|
#endif
|
2014-01-22 19:01:07 +02:00
|
|
|
|
2023-05-31 08:49:34 +02:00
|
|
|
|
2023-06-01 12:02:13 +02:00
|
|
|
FakeVimSettings &settings()
|
2023-05-31 08:49:34 +02:00
|
|
|
{
|
2023-07-07 12:13:07 +02:00
|
|
|
static FakeVimSettings theSettings;
|
|
|
|
|
return theSettings;
|
2023-05-31 08:49:34 +02:00
|
|
|
}
|
|
|
|
|
|
2009-03-30 14:46:33 +02:00
|
|
|
FakeVimSettings::FakeVimSettings()
|
2016-03-01 23:24:59 +01:00
|
|
|
{
|
2023-07-12 13:35:15 +02:00
|
|
|
setAutoApply(false);
|
|
|
|
|
|
2023-01-22 19:47:45 +01:00
|
|
|
setup(&useFakeVim, false, "UseFakeVim", {}, Tr::tr("Use FakeVim"));
|
2023-05-31 08:49:34 +02:00
|
|
|
|
2021-02-26 17:55:55 +01:00
|
|
|
// Specific FakeVim settings
|
2023-01-22 19:47:45 +01:00
|
|
|
setup(&readVimRc, false, "ReadVimRc", {}, Tr::tr("Read .vimrc from location:"));
|
|
|
|
|
setup(&vimRcPath, QString(), "VimRcPath", {}, {}); // Tr::tr("Path to .vimrc")
|
|
|
|
|
setup(&showMarks, false, "ShowMarks", "sm", Tr::tr("Show position of text marks"));
|
|
|
|
|
setup(&passControlKey, false, "PassControlKey", "pck", Tr::tr("Pass control keys"));
|
|
|
|
|
setup(&passKeys, true, "PassKeys", "pk", Tr::tr("Pass keys in insert mode"));
|
2016-03-01 23:24:59 +01:00
|
|
|
|
|
|
|
|
// Emulated Vsetting
|
2023-01-22 19:47:45 +01:00
|
|
|
setup(&startOfLine, true, "StartOfLine", "sol", Tr::tr("Start of line"));
|
|
|
|
|
setup(&tabStop, 8, "TabStop", "ts", Tr::tr("Tabulator size:"));
|
|
|
|
|
setup(&smartTab, false, "SmartTab", "sta", Tr::tr("Smart tabulators"));
|
|
|
|
|
setup(&hlSearch, true, "HlSearch", "hls", Tr::tr("Highlight search results"));
|
|
|
|
|
setup(&shiftWidth, 8, "ShiftWidth", "sw", Tr::tr("Shift width:"));
|
|
|
|
|
setup(&expandTab, false, "ExpandTab", "et", Tr::tr("Expand tabulators"));
|
|
|
|
|
setup(&autoIndent, false, "AutoIndent", "ai", Tr::tr("Automatic indentation"));
|
|
|
|
|
setup(&smartIndent, false, "SmartIndent", "si", Tr::tr("Smart indentation"));
|
|
|
|
|
setup(&incSearch, true, "IncSearch", "is", Tr::tr("Incremental search"));
|
|
|
|
|
setup(&useCoreSearch, false, "UseCoreSearch", "ucs", Tr::tr("Use search dialog"));
|
|
|
|
|
setup(&smartCase, false, "SmartCase", "scs", Tr::tr("Use smartcase"));
|
|
|
|
|
setup(&ignoreCase, false, "IgnoreCase", "ic", Tr::tr("Use ignorecase"));
|
|
|
|
|
setup(&wrapScan, true, "WrapScan", "ws", Tr::tr("Use wrapscan"));
|
|
|
|
|
setup(&tildeOp, false, "TildeOp", "top", Tr::tr("Use tildeop"));
|
|
|
|
|
setup(&showCmd, true, "ShowCmd", "sc", Tr::tr("Show partial command"));
|
|
|
|
|
setup(&relativeNumber, false, "RelativeNumber", "rnu", Tr::tr("Show line numbers relative to cursor"));
|
|
|
|
|
setup(&blinkingCursor, false, "BlinkingCursor", "bc", Tr::tr("Blinking cursor"));
|
2023-07-04 08:18:23 +02:00
|
|
|
setup(&systemEncoding, false, "SystemEncoding", {}, Tr::tr("Use system encoding for :source"));
|
2023-01-22 19:47:45 +01:00
|
|
|
setup(&scrollOff, 0, "ScrollOff", "so", Tr::tr("Scroll offset:"));
|
2021-02-26 17:55:55 +01:00
|
|
|
setup(&backspace, "indent,eol,start",
|
2023-01-22 19:47:45 +01:00
|
|
|
"Backspace", "bs", Tr::tr("Backspace:"));
|
2021-02-26 17:55:55 +01:00
|
|
|
setup(&isKeyword, "@,48-57,_,192-255,a-z,A-Z",
|
2023-01-22 19:47:45 +01:00
|
|
|
"IsKeyword", "isk", Tr::tr("Keyword characters:"));
|
|
|
|
|
setup(&clipboard, {}, "Clipboard", "cb", Tr::tr(""));
|
|
|
|
|
setup(&formatOptions, {}, "formatoptions", "fo", Tr::tr(""));
|
2021-01-25 21:06:53 +01:00
|
|
|
|
|
|
|
|
// Emulated plugins
|
2021-02-26 17:55:55 +01:00
|
|
|
setup(&emulateVimCommentary, false, "commentary", {}, "vim-commentary");
|
|
|
|
|
setup(&emulateReplaceWithRegister, false, "ReplaceWithRegister", {}, "ReplaceWithRegister");
|
|
|
|
|
setup(&emulateExchange, false, "exchange", {}, "vim-exchange");
|
|
|
|
|
setup(&emulateArgTextObj, false, "argtextobj", {}, "argtextobj.vim");
|
|
|
|
|
setup(&emulateSurround, false, "surround", {}, "vim-surround");
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2021-02-26 17:55:55 +01:00
|
|
|
// Some polish
|
2023-01-22 19:47:45 +01:00
|
|
|
useFakeVim.setDisplayName(Tr::tr("Use Vim-style Editing"));
|
2010-01-29 21:33:57 +01:00
|
|
|
|
2023-01-22 19:47:45 +01:00
|
|
|
relativeNumber.setToolTip(Tr::tr("Displays line numbers relative to the line containing "
|
2021-02-26 17:55:55 +01:00
|
|
|
"text cursor."));
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2023-01-22 19:47:45 +01:00
|
|
|
passControlKey.setToolTip(Tr::tr("Does not interpret key sequences like Ctrl-S in FakeVim "
|
2021-02-26 17:55:55 +01:00
|
|
|
"but handles them as regular shortcuts. This gives easier access to core functionality "
|
|
|
|
|
"at the price of losing some features of FakeVim."));
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2023-01-22 19:47:45 +01:00
|
|
|
passKeys.setToolTip(Tr::tr("Does not interpret some key presses in insert mode so that "
|
2021-02-26 17:55:55 +01:00
|
|
|
"code can be properly completed and expanded."));
|
2010-01-29 21:33:57 +01:00
|
|
|
|
2023-01-22 19:47:45 +01:00
|
|
|
tabStop.setToolTip(Tr::tr("Vim tabstop option."));
|
2021-02-26 17:55:55 +01:00
|
|
|
|
|
|
|
|
#ifndef FAKEVIM_STANDALONE
|
|
|
|
|
backspace.setDisplayStyle(FvStringAspect::LineEditDisplay);
|
|
|
|
|
isKeyword.setDisplayStyle(FvStringAspect::LineEditDisplay);
|
|
|
|
|
|
|
|
|
|
const QString vimrcDefault = QLatin1String(HostOsInfo::isAnyUnixHost()
|
|
|
|
|
? "$HOME/.vimrc" : "%USERPROFILE%\\_vimrc");
|
|
|
|
|
vimRcPath.setExpectedKind(PathChooser::File);
|
2023-01-22 19:47:45 +01:00
|
|
|
vimRcPath.setToolTip(Tr::tr("Keep empty to use the default path, i.e. "
|
2021-02-26 17:55:55 +01:00
|
|
|
"%USERPROFILE%\\_vimrc on Windows, ~/.vimrc otherwise."));
|
2023-01-22 19:47:45 +01:00
|
|
|
vimRcPath.setPlaceHolderText(Tr::tr("Default: %1").arg(vimrcDefault));
|
2023-05-31 08:49:34 +02:00
|
|
|
|
|
|
|
|
setLayouter([this] {
|
|
|
|
|
using namespace Layouting;
|
|
|
|
|
using namespace TextEditor;
|
|
|
|
|
|
|
|
|
|
Row bools {
|
|
|
|
|
Column {
|
|
|
|
|
autoIndent,
|
|
|
|
|
smartIndent,
|
|
|
|
|
expandTab,
|
|
|
|
|
smartTab,
|
|
|
|
|
hlSearch,
|
|
|
|
|
showCmd,
|
|
|
|
|
startOfLine,
|
|
|
|
|
passKeys,
|
2023-07-04 08:18:23 +02:00
|
|
|
blinkingCursor,
|
|
|
|
|
HostOsInfo::isWindowsHost() ? LayoutItem(systemEncoding) : empty
|
2023-05-31 08:49:34 +02:00
|
|
|
},
|
|
|
|
|
Column {
|
|
|
|
|
incSearch,
|
|
|
|
|
useCoreSearch,
|
|
|
|
|
ignoreCase,
|
|
|
|
|
smartCase,
|
|
|
|
|
wrapScan,
|
|
|
|
|
showMarks,
|
|
|
|
|
passControlKey,
|
|
|
|
|
relativeNumber,
|
|
|
|
|
tildeOp
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Row ints { shiftWidth, tabStop, scrollOff, st };
|
|
|
|
|
|
|
|
|
|
vimRcPath.setEnabler(&readVimRc);
|
|
|
|
|
|
|
|
|
|
Column strings {
|
|
|
|
|
backspace,
|
|
|
|
|
isKeyword,
|
|
|
|
|
Row {readVimRc, vimRcPath}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return Column {
|
|
|
|
|
useFakeVim,
|
|
|
|
|
|
|
|
|
|
Group {
|
|
|
|
|
title(Tr::tr("Vim Behavior")),
|
|
|
|
|
Column {
|
|
|
|
|
bools,
|
|
|
|
|
ints,
|
|
|
|
|
strings
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
Group {
|
|
|
|
|
title(Tr::tr("Plugin Emulation")),
|
|
|
|
|
Column {
|
|
|
|
|
emulateVimCommentary,
|
|
|
|
|
emulateReplaceWithRegister,
|
|
|
|
|
emulateArgTextObj,
|
|
|
|
|
emulateExchange,
|
|
|
|
|
emulateSurround
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
Row {
|
|
|
|
|
PushButton {
|
|
|
|
|
text(Tr::tr("Copy Text Editor Settings")),
|
|
|
|
|
onClicked([this] {
|
|
|
|
|
TabSettings ts = TextEditorSettings::codeStyle()->tabSettings();
|
|
|
|
|
TypingSettings tps = TextEditorSettings::typingSettings();
|
|
|
|
|
expandTab.setValue(ts.m_tabPolicy != TabSettings::TabsOnlyTabPolicy);
|
|
|
|
|
tabStop.setValue(ts.m_tabSize);
|
|
|
|
|
shiftWidth.setValue(ts.m_indentSize);
|
|
|
|
|
smartTab.setValue(tps.m_smartBackspaceBehavior
|
|
|
|
|
== TypingSettings::BackspaceFollowsPreviousIndents);
|
|
|
|
|
autoIndent.setValue(true);
|
|
|
|
|
smartIndent.setValue(tps.m_autoIndent);
|
|
|
|
|
incSearch.setValue(true);
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
PushButton {
|
|
|
|
|
text(Tr::tr("Set Qt Style")),
|
|
|
|
|
onClicked([this] {
|
|
|
|
|
expandTab.setVolatileValue(true);
|
|
|
|
|
tabStop.setVolatileValue(4);
|
|
|
|
|
shiftWidth.setVolatileValue(4);
|
|
|
|
|
smartTab.setVolatileValue(true);
|
|
|
|
|
autoIndent.setVolatileValue(true);
|
|
|
|
|
smartIndent.setVolatileValue(true);
|
|
|
|
|
incSearch.setVolatileValue(true);
|
|
|
|
|
backspace.setVolatileValue(QString("indent,eol,start"));
|
|
|
|
|
passKeys.setVolatileValue(true);
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
PushButton {
|
|
|
|
|
text(Tr::tr("Set Plain Style")),
|
|
|
|
|
onClicked([this] {
|
|
|
|
|
expandTab.setVolatileValue(false);
|
|
|
|
|
tabStop.setVolatileValue(8);
|
|
|
|
|
shiftWidth.setVolatileValue(8);
|
|
|
|
|
smartTab.setVolatileValue(false);
|
|
|
|
|
autoIndent.setVolatileValue(false);
|
|
|
|
|
smartIndent.setVolatileValue(false);
|
|
|
|
|
incSearch.setVolatileValue(false);
|
|
|
|
|
backspace.setVolatileValue(QString());
|
|
|
|
|
passKeys.setVolatileValue(false);
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
st
|
|
|
|
|
},
|
|
|
|
|
st
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
readSettings();
|
|
|
|
|
|
2021-02-26 17:55:55 +01:00
|
|
|
#endif
|
2009-03-30 14:46:33 +02:00
|
|
|
}
|
|
|
|
|
|
2021-02-26 17:55:55 +01:00
|
|
|
FakeVimSettings::~FakeVimSettings() = default;
|
|
|
|
|
|
2023-08-24 10:15:12 +02:00
|
|
|
FvBaseAspect *FakeVimSettings::item(const Key &name)
|
2009-03-30 15:27:59 +02:00
|
|
|
{
|
2021-02-26 17:55:55 +01:00
|
|
|
return m_nameToAspect.value(name, nullptr);
|
2009-03-30 15:27:59 +02:00
|
|
|
}
|
|
|
|
|
|
2012-05-03 10:43:04 +02:00
|
|
|
QString FakeVimSettings::trySetValue(const QString &name, const QString &value)
|
|
|
|
|
{
|
2023-08-24 10:15:12 +02:00
|
|
|
FvBaseAspect *aspect = m_nameToAspect.value(keyFromString(name), nullptr);
|
2021-02-26 17:55:55 +01:00
|
|
|
if (!aspect)
|
2023-01-22 19:47:45 +01:00
|
|
|
return Tr::tr("Unknown option: %1").arg(name);
|
2021-02-26 17:55:55 +01:00
|
|
|
if (aspect == &tabStop || aspect == &shiftWidth) {
|
2012-05-03 10:43:04 +02:00
|
|
|
if (value.toInt() <= 0)
|
2023-01-22 19:47:45 +01:00
|
|
|
return Tr::tr("Argument must be positive: %1=%2")
|
2012-05-03 10:43:04 +02:00
|
|
|
.arg(name).arg(value);
|
|
|
|
|
}
|
2023-06-26 11:02:42 +02:00
|
|
|
aspect->setVariantValue(value);
|
2012-05-03 10:43:04 +02:00
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-26 17:55:55 +01:00
|
|
|
void FakeVimSettings::setup(FvBaseAspect *aspect,
|
|
|
|
|
const QVariant &value,
|
2023-08-23 18:18:46 +02:00
|
|
|
const Key &settingsKey,
|
2023-08-24 10:15:12 +02:00
|
|
|
const Key &shortName,
|
2021-02-26 17:55:55 +01:00
|
|
|
const QString &labelText)
|
2009-03-30 14:46:33 +02:00
|
|
|
{
|
2021-02-26 17:55:55 +01:00
|
|
|
aspect->setSettingsKey("FakeVim", settingsKey);
|
2023-06-26 11:02:42 +02:00
|
|
|
aspect->setDefaultVariantValue(value);
|
2021-02-26 17:55:55 +01:00
|
|
|
#ifndef FAKEVIM_STANDALONE
|
|
|
|
|
aspect->setLabelText(labelText);
|
|
|
|
|
aspect->setAutoApply(false);
|
|
|
|
|
registerAspect(aspect);
|
|
|
|
|
|
|
|
|
|
if (auto boolAspect = dynamic_cast<FvBoolAspect *>(aspect))
|
2023-05-23 17:49:52 +02:00
|
|
|
boolAspect->setLabelPlacement(FvBoolAspect::LabelPlacement::AtCheckBox);
|
2021-02-26 17:55:55 +01:00
|
|
|
#else
|
|
|
|
|
Q_UNUSED(labelText)
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-08-23 18:18:46 +02:00
|
|
|
const Key longName = settingsKey.toLower();
|
2021-02-26 17:55:55 +01:00
|
|
|
if (!longName.isEmpty()) {
|
|
|
|
|
m_nameToAspect[longName] = aspect;
|
|
|
|
|
m_aspectToName[aspect] = longName;
|
|
|
|
|
}
|
|
|
|
|
if (!shortName.isEmpty())
|
|
|
|
|
m_nameToAspect[shortName] = aspect;
|
2013-03-08 17:50:16 +01:00
|
|
|
}
|
2009-03-30 14:46:33 +02:00
|
|
|
|
2023-07-07 12:13:07 +02:00
|
|
|
#ifndef FAKEVIM_STANDALONE
|
|
|
|
|
|
|
|
|
|
class FakeVimSettingsPage final : public Core::IOptionsPage
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
FakeVimSettingsPage()
|
|
|
|
|
{
|
|
|
|
|
const char SETTINGS_CATEGORY[] = "D.FakeVim";
|
|
|
|
|
const char SETTINGS_ID[] = "A.FakeVim.General";
|
|
|
|
|
|
|
|
|
|
setId(SETTINGS_ID);
|
|
|
|
|
setDisplayName(Tr::tr("General"));
|
|
|
|
|
setCategory(SETTINGS_CATEGORY);
|
|
|
|
|
setDisplayCategory(Tr::tr("FakeVim"));
|
|
|
|
|
setCategoryIconPath(":/fakevim/images/settingscategory_fakevim.png");
|
|
|
|
|
setSettingsProvider([] { return &settings(); });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const FakeVimSettingsPage settingsPage;
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2023-06-01 12:02:13 +02:00
|
|
|
} // FakeVim::Internal
|