1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "fakevimactions.h"
27 #include "fakevimhandler.h"
28 
29 // Please do not add any direct dependencies to other Qt Creator code  here.
30 // Instead emit signals and let the FakeVimPlugin channel the information to
31 // Qt Creator. The idea is to keep this file here in a "clean" state that
32 // allows easy reuse with any QTextEdit or QPlainTextEdit derived class.
33 
34 #include <utils/layoutbuilder.h>
35 #include <utils/qtcassert.h>
36 
37 #include <QDebug>
38 
39 using namespace Utils;
40 
41 namespace FakeVim {
42 namespace Internal {
43 
44 #ifdef FAKEVIM_STANDALONE
FvBaseAspect()45 FvBaseAspect::FvBaseAspect()
46 {
47 }
48 
setValue(const QVariant & value)49 void FvBaseAspect::setValue(const QVariant &value)
50 {
51     m_value = value;
52 }
53 
value() const54 QVariant FvBaseAspect::value() const
55 {
56     return m_value;
57 }
58 
setDefaultValue(const QVariant & value)59 void FvBaseAspect::setDefaultValue(const QVariant &value)
60 {
61     m_defaultValue = value;
62     m_value = value;
63 }
64 
defaultValue() const65 QVariant FvBaseAspect::defaultValue() const
66 {
67     return m_defaultValue;
68 }
69 
setSettingsKey(const QString & group,const QString & key)70 void FvBaseAspect::setSettingsKey(const QString &group, const QString &key)
71 {
72     m_settingsGroup = group;
73     m_settingsKey = key;
74 }
75 
settingsKey() const76 QString FvBaseAspect::settingsKey() const
77 {
78     return m_settingsKey;
79 }
80 
81 // unused but kept for compile
setAutoApply(bool)82 void setAutoApply(bool ) {}
83 #endif
84 
FakeVimSettings()85 FakeVimSettings::FakeVimSettings()
86 {
87     setAutoApply(false);
88 
89 #ifndef FAKEVIM_STANDALONE
90     setup(&useFakeVim,     false, "UseFakeVim",     {},    tr("Use FakeVim"));
91 #endif
92     // Specific FakeVim settings
93     setup(&readVimRc,      false, "ReadVimRc",      {},    tr("Read .vimrc from location:"));
94     setup(&vimRcPath,      QString(), "VimRcPath",  {},    {}); // tr("Path to .vimrc")
95     setup(&showMarks,      false, "ShowMarks",      "sm",  tr("Show position of text marks"));
96     setup(&passControlKey, false, "PassControlKey", "pck", tr("Pass control keys"));
97     setup(&passKeys,       true,  "PassKeys",       "pk",  tr("Pass keys in insert mode"));
98 
99     // Emulated Vsetting
100     setup(&startOfLine,    true,  "StartOfLine",    "sol", tr("Start of line"));
101     setup(&tabStop,        8,     "TabStop",        "ts",  tr("Tabulator size:"));
102     setup(&smartTab,       false, "SmartTab",       "sta", tr("Smart tabulators"));
103     setup(&hlSearch,       true,  "HlSearch",       "hls", tr("Highlight search results"));
104     setup(&shiftWidth,     8,     "ShiftWidth",     "sw",  tr("Shift width:"));
105     setup(&expandTab,      false, "ExpandTab",      "et",  tr("Expand tabulators"));
106     setup(&autoIndent,     false, "AutoIndent",     "ai",  tr("Automatic indentation"));
107     setup(&smartIndent,    false, "SmartIndent",    "si",  tr("Smart tabulators"));
108     setup(&incSearch,      true,  "IncSearch",      "is",  tr("Incremental search"));
109     setup(&useCoreSearch,  false, "UseCoreSearch",  "ucs", tr("Use search dialog"));
110     setup(&smartCase,      false, "SmartCase",      "scs", tr("Use smartcase"));
111     setup(&ignoreCase,     false, "IgnoreCase",     "ic",  tr("Use ignorecase"));
112     setup(&wrapScan,       true,  "WrapScan",       "ws",  tr("Use wrapscan"));
113     setup(&tildeOp,        false, "TildeOp",        "top", tr("Use tildeop"));
114     setup(&showCmd,        true,  "ShowCmd",        "sc",  tr("Show partial command"));
115     setup(&relativeNumber, false, "RelativeNumber", "rnu", tr("Show line numbers relative to cursor"));
116     setup(&blinkingCursor, false, "BlinkingCursor", "bc",  tr("Blinking cursor"));
117     setup(&scrollOff,      0,     "ScrollOff",      "so",  tr("Scroll offset:"));
118     setup(&backspace,      "indent,eol,start",
119                                   "Backspace",      "bs",  tr("Backspace:"));
120     setup(&isKeyword,      "@,48-57,_,192-255,a-z,A-Z",
121                                   "IsKeyword",      "isk", tr("Keyword characters:"));
122     setup(&clipboard,      {},    "Clipboard",      "cb",  tr(""));
123     setup(&formatOptions,  {},    "formatoptions",  "fo",  tr(""));
124 
125     // Emulated plugins
126     setup(&emulateVimCommentary, false, "commentary", {}, "vim-commentary");
127     setup(&emulateReplaceWithRegister, false, "ReplaceWithRegister", {}, "ReplaceWithRegister");
128     setup(&emulateExchange, false, "exchange", {}, "vim-exchange");
129     setup(&emulateArgTextObj, false, "argtextobj", {}, "argtextobj.vim");
130     setup(&emulateSurround, false, "surround", {}, "vim-surround");
131 
132     // Some polish
133     useFakeVim.setDisplayName(tr("Use Vim-style Editing"));
134 
135     relativeNumber.setToolTip(tr("Displays line numbers relative to the line containing "
136         "text cursor."));
137 
138     passControlKey.setToolTip(tr("Does not interpret key sequences like Ctrl-S in FakeVim "
139         "but handles them as regular shortcuts. This gives easier access to core functionality "
140         "at the price of losing some features of FakeVim."));
141 
142     passKeys.setToolTip(tr("Does not interpret some key presses in insert mode so that "
143         "code can be properly completed and expanded."));
144 
145     tabStop.setToolTip(tr("Vim tabstop option."));
146 
147 #ifndef FAKEVIM_STANDALONE
148     backspace.setDisplayStyle(FvStringAspect::LineEditDisplay);
149     isKeyword.setDisplayStyle(FvStringAspect::LineEditDisplay);
150 
151     const QString vimrcDefault = QLatin1String(HostOsInfo::isAnyUnixHost()
152                 ? "$HOME/.vimrc" : "%USERPROFILE%\\_vimrc");
153     vimRcPath.setExpectedKind(PathChooser::File);
154     vimRcPath.setToolTip(tr("Keep empty to use the default path, i.e. "
155                "%USERPROFILE%\\_vimrc on Windows, ~/.vimrc otherwise."));
156     vimRcPath.setPlaceHolderText(tr("Default: %1").arg(vimrcDefault));
157     vimRcPath.setDisplayStyle(FvStringAspect::PathChooserDisplay);
158 #endif
159 }
160 
161 FakeVimSettings::~FakeVimSettings() = default;
162 
item(const QString & name)163 FvBaseAspect *FakeVimSettings::item(const QString &name)
164 {
165     return m_nameToAspect.value(name, nullptr);
166 }
167 
trySetValue(const QString & name,const QString & value)168 QString FakeVimSettings::trySetValue(const QString &name, const QString &value)
169 {
170     FvBaseAspect *aspect = m_nameToAspect.value(name, nullptr);
171     if (!aspect)
172         return tr("Unknown option: %1").arg(name);
173     if (aspect == &tabStop || aspect == &shiftWidth) {
174         if (value.toInt() <= 0)
175             return tr("Argument must be positive: %1=%2")
176                     .arg(name).arg(value);
177     }
178     aspect->setValue(value);
179     return QString();
180 }
181 
setup(FvBaseAspect * aspect,const QVariant & value,const QString & settingsKey,const QString & shortName,const QString & labelText)182 void FakeVimSettings::setup(FvBaseAspect *aspect,
183                             const QVariant &value,
184                             const QString &settingsKey,
185                             const QString &shortName,
186                             const QString &labelText)
187 {
188     aspect->setSettingsKey("FakeVim", settingsKey);
189     aspect->setDefaultValue(value);
190 #ifndef FAKEVIM_STANDALONE
191     aspect->setLabelText(labelText);
192     aspect->setAutoApply(false);
193     registerAspect(aspect);
194 
195     if (auto boolAspect = dynamic_cast<FvBoolAspect *>(aspect))
196         boolAspect->setLabelPlacement(FvBoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
197 #else
198     Q_UNUSED(labelText)
199 #endif
200 
201     const QString longName = settingsKey.toLower();
202     if (!longName.isEmpty()) {
203         m_nameToAspect[longName] = aspect;
204         m_aspectToName[aspect] = longName;
205     }
206     if (!shortName.isEmpty())
207         m_nameToAspect[shortName] = aspect;
208 }
209 
fakeVimSettings()210 FakeVimSettings *fakeVimSettings()
211 {
212     static FakeVimSettings s;
213     return &s;
214 }
215 
216 } // namespace Internal
217 } // namespace FakeVim
218