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/qtcassert.h>
35 
36 #include <QDebug>
37 
38 using namespace Utils;
39 
40 namespace FakeVim {
41 namespace Internal {
42 
43 #ifdef FAKEVIM_STANDALONE
FvBaseAspect()44 FvBaseAspect::FvBaseAspect()
45 {
46 }
47 
setValue(const QVariant & value)48 void FvBaseAspect::setValue(const QVariant &value)
49 {
50     m_value = value;
51 }
52 
value() const53 QVariant FvBaseAspect::value() const
54 {
55     return m_value;
56 }
57 
setDefaultValue(const QVariant & value)58 void FvBaseAspect::setDefaultValue(const QVariant &value)
59 {
60     m_defaultValue = value;
61     m_value = value;
62 }
63 
defaultValue() const64 QVariant FvBaseAspect::defaultValue() const
65 {
66     return m_defaultValue;
67 }
68 
setSettingsKey(const QString & group,const QString & key)69 void FvBaseAspect::setSettingsKey(const QString &group, const QString &key)
70 {
71     m_settingsGroup = group;
72     m_settingsKey = key;
73 }
74 
settingsKey() const75 QString FvBaseAspect::settingsKey() const
76 {
77     return m_settingsKey;
78 }
79 #endif
80 
FakeVimSettings()81 FakeVimSettings::FakeVimSettings()
82 {
83 #ifndef FAKEVIM_STANDALONE
84     setup(&useFakeVim,     false, "UseFakeVim",     {},    tr("Use FakeVim"));
85 #endif
86     // Specific FakeVim settings
87     setup(&readVimRc,      false, "ReadVimRc",      {},    tr("Read .vimrc from location:"));
88     setup(&vimRcPath,      QString(), "VimRcPath",  {},    {}); // tr("Path to .vimrc")
89     setup(&showMarks,      false, "ShowMarks",      "sm",  tr("Show position of text marks"));
90     setup(&passControlKey, false, "PassControlKey", "pck", tr("Pass control keys"));
91     setup(&passKeys,       true,  "PassKeys",       "pk",  tr("Pass keys in insert mode"));
92 
93     // Emulated Vsetting
94     setup(&startOfLine,    true,  "StartOfLine",    "sol", tr("Start of line"));
95     setup(&tabStop,        8,     "TabStop",        "ts",  tr("Tabulator size:"));
96     setup(&smartTab,       false, "SmartTab",       "sta", tr("Smart tabulators"));
97     setup(&hlSearch,       true,  "HlSearch",       "hls", tr("Highlight search results"));
98     setup(&shiftWidth,     8,     "ShiftWidth",     "sw",  tr("Shift width:"));
99     setup(&expandTab,      false, "ExpandTab",      "et",  tr("Expand tabulators"));
100     setup(&autoIndent,     false, "AutoIndent",     "ai",  tr("Automatic indentation"));
101     setup(&smartIndent,    false, "SmartIndent",    "si",  tr("Smart tabulators"));
102     setup(&incSearch,      true,  "IncSearch",      "is",  tr("Incremental search"));
103     setup(&useCoreSearch,  false, "UseCoreSearch",  "ucs", tr("Use search dialog"));
104     setup(&smartCase,      false, "SmartCase",      "scs", tr("Use smartcase"));
105     setup(&ignoreCase,     false, "IgnoreCase",     "ic",  tr("Use ignorecase"));
106     setup(&wrapScan,       true,  "WrapScan",       "ws",  tr("Use wrapscan"));
107     setup(&tildeOp,        false, "TildeOp",        "top", tr("Use tildeop"));
108     setup(&showCmd,        true,  "ShowCmd",        "sc",  tr("Show partial command"));
109     setup(&relativeNumber, false, "RelativeNumber", "rnu", tr("Show line numbers relative to cursor"));
110     setup(&blinkingCursor, false, "BlinkingCursor", "bc",  tr("Blinking cursor"));
111     setup(&scrollOff,      0,     "ScrollOff",      "so",  tr("Scroll offset:"));
112     setup(&backspace,      "indent,eol,start",
113                                   "Backspace",      "bs",  tr("Backspace:"));
114     setup(&isKeyword,      "@,48-57,_,192-255,a-z,A-Z",
115                                   "IsKeyword",      "isk", tr("Keyword characters:"));
116     setup(&clipboard,      {},    "Clipboard",      "cb",  tr(""));
117     setup(&formatOptions,  {},    "formatoptions",  "fo",  tr(""));
118 
119     // Emulated plugins
120     setup(&emulateVimCommentary, false, "commentary", {}, "vim-commentary");
121     setup(&emulateReplaceWithRegister, false, "ReplaceWithRegister", {}, "ReplaceWithRegister");
122     setup(&emulateExchange, false, "exchange", {}, "vim-exchange");
123     setup(&emulateArgTextObj, false, "argtextobj", {}, "argtextobj.vim");
124     setup(&emulateSurround, false, "surround", {}, "vim-surround");
125 
126     // Some polish
127     useFakeVim.setDisplayName(tr("Use Vim-style Editing"));
128 
129     relativeNumber.setToolTip(tr("Displays line numbers relative to the line containing "
130         "text cursor."));
131 
132     passControlKey.setToolTip(tr("Does not interpret key sequences like Ctrl-S in FakeVim "
133         "but handles them as regular shortcuts. This gives easier access to core functionality "
134         "at the price of losing some features of FakeVim."));
135 
136     passKeys.setToolTip(tr("Does not interpret some key presses in insert mode so that "
137         "code can be properly completed and expanded."));
138 
139     tabStop.setToolTip(tr("Vim tabstop option."));
140 
141 #ifndef FAKEVIM_STANDALONE
142     backspace.setDisplayStyle(FvStringAspect::LineEditDisplay);
143     isKeyword.setDisplayStyle(FvStringAspect::LineEditDisplay);
144 
145     const QString vimrcDefault = QLatin1String(HostOsInfo::isAnyUnixHost()
146                 ? "$HOME/.vimrc" : "%USERPROFILE%\\_vimrc");
147     vimRcPath.setExpectedKind(PathChooser::File);
148     vimRcPath.setToolTip(tr("Keep empty to use the default path, i.e. "
149                "%USERPROFILE%\\_vimrc on Windows, ~/.vimrc otherwise."));
150     vimRcPath.setPlaceHolderText(tr("Default: %1").arg(vimrcDefault));
151     vimRcPath.setDisplayStyle(FvStringAspect::PathChooserDisplay);
152 #endif
153 }
154 
155 FakeVimSettings::~FakeVimSettings() = default;
156 
item(const QString & name)157 FvBaseAspect *FakeVimSettings::item(const QString &name)
158 {
159     return m_nameToAspect.value(name, nullptr);
160 }
161 
trySetValue(const QString & name,const QString & value)162 QString FakeVimSettings::trySetValue(const QString &name, const QString &value)
163 {
164     FvBaseAspect *aspect = m_nameToAspect.value(name, nullptr);
165     if (!aspect)
166         return tr("Unknown option: %1").arg(name);
167     if (aspect == &tabStop || aspect == &shiftWidth) {
168         if (value.toInt() <= 0)
169             return tr("Argument must be positive: %1=%2")
170                     .arg(name).arg(value);
171     }
172     aspect->setValue(value);
173     return QString();
174 }
175 
setup(FvBaseAspect * aspect,const QVariant & value,const QString & settingsKey,const QString & shortName,const QString & labelText)176 void FakeVimSettings::setup(FvBaseAspect *aspect,
177                             const QVariant &value,
178                             const QString &settingsKey,
179                             const QString &shortName,
180                             const QString &labelText)
181 {
182     aspect->setSettingsKey("FakeVim", settingsKey);
183     aspect->setDefaultValue(value);
184 #ifndef FAKEVIM_STANDALONE
185     aspect->setLabelText(labelText);
186     aspect->setAutoApply(false);
187     registerAspect(aspect);
188 
189     if (auto boolAspect = dynamic_cast<FvBoolAspect *>(aspect))
190         boolAspect->setLabelPlacement(FvBoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
191 #else
192     Q_UNUSED(labelText)
193 #endif
194 
195     const QString longName = settingsKey.toLower();
196     if (!longName.isEmpty()) {
197         m_nameToAspect[longName] = aspect;
198         m_aspectToName[aspect] = longName;
199     }
200     if (!shortName.isEmpty())
201         m_nameToAspect[shortName] = aspect;
202 }
203 
fakeVimSettings()204 FakeVimSettings *fakeVimSettings()
205 {
206     static FakeVimSettings s;
207     return &s;
208 }
209 
210 } // namespace Internal
211 } // namespace FakeVim
212