File indexing completed on 2024-04-14 03:55:29
0001 /* 0002 SPDX-FileCopyrightText: 2003-2005 Anders Lund <anders@alweb.dk> 0003 SPDX-FileCopyrightText: 2001-2010 Christoph Cullmann <cullmann@kde.org> 0004 SPDX-FileCopyrightText: 2001 Charles Samuels <charles@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "katecmds.h" 0010 0011 #include "kateautoindent.h" 0012 #include "katecmd.h" 0013 #include "katedocument.h" 0014 #include "katepartdebug.h" 0015 #include "katerenderer.h" 0016 #include "katesyntaxmanager.h" 0017 #include "kateview.h" 0018 0019 #include <KLocalizedString> 0020 0021 #include <QDateTime> 0022 #include <QRegularExpression> 0023 0024 // BEGIN CoreCommands 0025 KateCommands::CoreCommands *KateCommands::CoreCommands::m_instance = nullptr; 0026 0027 // this returns whether the string s could be converted to 0028 // a bool value, one of on|off|1|0|true|false. the argument val is 0029 // set to the extracted value in case of success 0030 static bool getBoolArg(const QString &t, bool *val) 0031 { 0032 bool res(false); 0033 QString s = t.toLower(); 0034 res = (s == QLatin1String("on") || s == QLatin1String("1") || s == QLatin1String("true")); 0035 if (res) { 0036 *val = true; 0037 return true; 0038 } 0039 res = (s == QLatin1String("off") || s == QLatin1String("0") || s == QLatin1String("false")); 0040 if (res) { 0041 *val = false; 0042 return true; 0043 } 0044 return false; 0045 } 0046 0047 bool KateCommands::CoreCommands::help(KTextEditor::View *, const QString &cmd, QString &msg) 0048 { 0049 QString realcmd = cmd.trimmed(); 0050 if (realcmd == QLatin1String("indent")) { 0051 msg = i18n( 0052 "<p>indent</p>" 0053 "<p>Indents the selected lines or the current line</p>"); 0054 return true; 0055 } else if (realcmd == QLatin1String("unindent")) { 0056 msg = i18n( 0057 "<p>unindent</p>" 0058 "<p>Unindents the selected lines or current line.</p>"); 0059 return true; 0060 } else if (realcmd == QLatin1String("cleanindent")) { 0061 msg = i18n( 0062 "<p>cleanindent</p>" 0063 "<p>Cleans up the indentation of the selected lines or current line according to the indentation settings in the document. </p>"); 0064 return true; 0065 } else if (realcmd == QLatin1String("comment")) { 0066 msg = i18n( 0067 "<p>comment</p>" 0068 "<p>Inserts comment markers to make the selection or selected lines or current line a comment according to the text format as defined by the " 0069 "syntax highlight definition for the document.</p>"); 0070 return true; 0071 } else if (realcmd == QLatin1String("uncomment")) { 0072 msg = i18n( 0073 "<p>uncomment</p>" 0074 "<p>Removes comment markers from the selection or selected lines or current line according to the text format as defined by the syntax highlight " 0075 "definition for the document.</p>"); 0076 return true; 0077 } else if (realcmd == QLatin1String("goto")) { 0078 msg = i18n( 0079 "<p>goto <b>line number</b></p>" 0080 "<p>This command navigates to the specified line number.</p>"); 0081 return true; 0082 } else if (realcmd == QLatin1String("set-indent-pasted-text")) { 0083 msg = i18n( 0084 "<p>set-indent-pasted-text <b>enable</b></p>" 0085 "<p>If enabled, indentation of text pasted from the clipboard is adjusted using the current indenter.</p>" 0086 "<p>Possible true values: 1 on true<br/>" 0087 "possible false values: 0 off false</p>"); 0088 return true; 0089 } else if (realcmd == QLatin1String("kill-line")) { 0090 msg = i18n("Deletes the current line."); 0091 return true; 0092 } else if (realcmd == QLatin1String("set-tab-width")) { 0093 msg = i18n( 0094 "<p>set-tab-width <b>width</b></p>" 0095 "<p>Sets the tab width to the number <b>width</b></p>"); 0096 return true; 0097 } else if (realcmd == QLatin1String("set-replace-tab")) { 0098 msg = i18n( 0099 "<p>set-replace-tab <b>enable</b></p>" 0100 "<p>If enabled, tabs are replaced with spaces as you type.</p>" 0101 "<p>Possible true values: 1 on true<br/>" 0102 "possible false values: 0 off false</p>"); 0103 return true; 0104 } else if (realcmd == QLatin1String("set-show-tabs")) { 0105 msg = i18n( 0106 "<p>set-show-tabs <b>enable</b></p>" 0107 "<p>If enabled, TAB characters and trailing whitespace will be visualized by a small dot.</p>" 0108 "<p>Possible true values: 1 on true<br/>" 0109 "possible false values: 0 off false</p>"); 0110 return true; 0111 } else if (realcmd == QLatin1String("set-remove-trailing-spaces")) { 0112 msg = i18n( 0113 "<p>set-remove-trailing-spaces <b>mode</b></p>" 0114 "<p>Removes the trailing spaces in the document depending on the <b>mode</b>.</p>" 0115 "<p>Possible values:" 0116 "<ul>" 0117 "<li><b>none</b>: never remove trailing spaces.</li>" 0118 "<li><b>modified</b>: remove trailing spaces only of modified lines.</li>" 0119 "<li><b>all</b>: remove trailing spaces in the entire document.</li>" 0120 "</ul></p>"); 0121 return true; 0122 } else if (realcmd == QLatin1String("set-indent-width")) { 0123 msg = i18n( 0124 "<p>set-indent-width <b>width</b></p>" 0125 "<p>Sets the indentation width to the number <b>width</b>. Used only if you are indenting with spaces.</p>"); 0126 return true; 0127 } else if (realcmd == QLatin1String("set-indent-mode")) { 0128 msg = i18n( 0129 "<p>set-indent-mode <b>mode</b></p>" 0130 "<p>The mode parameter is a value as seen in the Tools - Indentation menu</p>"); 0131 return true; 0132 } else if (realcmd == QLatin1String("set-auto-indent")) { 0133 msg = i18n( 0134 "<p>set-auto-indent <b>enable</b></p>" 0135 "<p>Enable or disable autoindentation.</p>" 0136 "<p>possible true values: 1 on true<br/>" 0137 "possible false values: 0 off false</p>"); 0138 return true; 0139 } else if (realcmd == QLatin1String("set-line-numbers")) { 0140 msg = i18n( 0141 "<p>set-line-numbers <b>enable</b></p>" 0142 "<p>Sets the visibility of the line numbers pane.</p>" 0143 "<p> possible true values: 1 on true<br/>" 0144 "possible false values: 0 off false</p>"); 0145 return true; 0146 } else if (realcmd == QLatin1String("set-folding-markers")) { 0147 msg = i18n( 0148 "<p>set-folding-markers <b>enable</b></p>" 0149 "<p>Sets the visibility of the folding markers pane.</p>" 0150 "<p> possible true values: 1 on true<br/>" 0151 "possible false values: 0 off false</p>"); 0152 return true; 0153 } else if (realcmd == QLatin1String("set-icon-border")) { 0154 msg = i18n( 0155 "<p>set-icon-border <b>enable</b></p>" 0156 "<p>Sets the visibility of the icon border.</p>" 0157 "<p> possible true values: 1 on true<br/>" 0158 "possible false values: 0 off false</p>"); 0159 return true; 0160 } else if (realcmd == QLatin1String("set-word-wrap")) { 0161 msg = i18n( 0162 "<p>set-word-wrap <b>enable</b></p>" 0163 "<p>Enables dynamic word wrap according to <b>enable</b></p>" 0164 "<p> possible true values: 1 on true<br/>" 0165 "possible false values: 0 off false</p>"); 0166 return true; 0167 } else if (realcmd == QLatin1String("set-word-wrap-column")) { 0168 msg = i18n( 0169 "<p>set-word-wrap-column <b>width</b></p>" 0170 "<p>Sets the line width for hard wrapping to <b>width</b>. This is used if you are having your text wrapped automatically.</p>"); 0171 return true; 0172 } else if (realcmd == QLatin1String("set-replace-tabs-save")) { 0173 msg = i18n( 0174 "<p>set-replace-tabs-save <b>enable</b></p>" 0175 "<p>When enabled, tabs will be replaced with whitespace whenever the document is saved.</p>" 0176 "<p> possible true values: 1 on true<br/>" 0177 "possible false values: 0 off false</p>"); 0178 return true; 0179 } else if (realcmd == QLatin1String("set-highlight")) { 0180 msg = i18n( 0181 "<p>set-highlight <b>highlight</b></p>" 0182 "<p>Sets the syntax highlighting system for the document. The argument must be a valid highlight name, as seen in the Tools → Highlighting menu. " 0183 "This command provides an autocompletion list for its argument.</p>"); 0184 return true; 0185 } else if (realcmd == QLatin1String("set-mode")) { 0186 msg = i18n( 0187 "<p>set-mode <b>mode</b></p>" 0188 "<p>Sets the mode as seen in Tools - Mode</p>"); 0189 return true; 0190 } else if (realcmd == QLatin1String("set-show-indent")) { 0191 msg = i18n( 0192 "<p>set-show-indent <b>enable</b></p>" 0193 "<p>If enabled, indentation will be visualized by a vertical dotted line.</p>" 0194 "<p> possible true values: 1 on true<br/>" 0195 "possible false values: 0 off false</p>"); 0196 return true; 0197 } else if (realcmd == QLatin1String("print")) { 0198 msg = i18n("<p>Open the Print dialog to print the current document.</p>"); 0199 return true; 0200 } else { 0201 return false; 0202 } 0203 } 0204 0205 bool KateCommands::CoreCommands::exec(KTextEditor::View *view, const QString &_cmd, QString &errorMsg, const KTextEditor::Range &range) 0206 { 0207 #define KCC_ERR(s) \ 0208 { \ 0209 errorMsg = s; \ 0210 return false; \ 0211 } 0212 // cast it hardcore, we know that it is really a kateview :) 0213 KTextEditor::ViewPrivate *v = static_cast<KTextEditor::ViewPrivate *>(view); 0214 0215 if (!v) { 0216 KCC_ERR(i18n("Could not access view")); 0217 } 0218 0219 // create a list of args 0220 QStringList args(_cmd.split(QRegularExpression(QStringLiteral("\\s+")), Qt::SkipEmptyParts)); 0221 QString cmd(args.takeFirst()); 0222 0223 // ALL commands that takes no arguments. 0224 if (cmd == QLatin1String("indent")) { 0225 if (range.isValid()) { 0226 v->doc()->editStart(); 0227 for (int line = range.start().line(); line <= range.end().line(); line++) { 0228 v->doc()->indent(KTextEditor::Range(line, 0, line, 0), 1); 0229 } 0230 v->doc()->editEnd(); 0231 } else { 0232 v->indent(); 0233 } 0234 return true; 0235 } else if (cmd == QLatin1String("unindent")) { 0236 if (range.isValid()) { 0237 v->doc()->editStart(); 0238 for (int line = range.start().line(); line <= range.end().line(); line++) { 0239 v->doc()->indent(KTextEditor::Range(line, 0, line, 0), -1); 0240 } 0241 v->doc()->editEnd(); 0242 } else { 0243 v->unIndent(); 0244 } 0245 return true; 0246 } else if (cmd == QLatin1String("cleanindent")) { 0247 if (range.isValid()) { 0248 v->doc()->editStart(); 0249 for (int line = range.start().line(); line <= range.end().line(); line++) { 0250 v->doc()->indent(KTextEditor::Range(line, 0, line, 0), 0); 0251 } 0252 v->doc()->editEnd(); 0253 } else { 0254 v->cleanIndent(); 0255 } 0256 return true; 0257 } else if (cmd == QLatin1String("fold")) { 0258 return (v->textFolding().newFoldingRange(range.isValid() ? range : v->selectionRange(), Kate::TextFolding::Persistent | Kate::TextFolding::Folded) 0259 != -1); 0260 } else if (cmd == QLatin1String("tfold")) { 0261 return (v->textFolding().newFoldingRange(range.isValid() ? range : v->selectionRange(), Kate::TextFolding::Folded) != -1); 0262 } else if (cmd == QLatin1String("unfold")) { 0263 QList<QPair<qint64, Kate::TextFolding::FoldingRangeFlags>> startingRanges = v->textFolding().foldingRangesStartingOnLine(v->cursorPosition().line()); 0264 bool unfolded = false; 0265 for (int i = 0; i < startingRanges.size(); ++i) { 0266 if (startingRanges[i].second & Kate::TextFolding::Folded) { 0267 unfolded = v->textFolding().unfoldRange(startingRanges[i].first) || unfolded; 0268 } 0269 } 0270 return unfolded; 0271 } else if (cmd == QLatin1String("comment")) { 0272 if (range.isValid()) { 0273 v->doc()->editStart(); 0274 for (int line = range.start().line(); line <= range.end().line(); line++) { 0275 v->doc()->comment(v, line, 0, KTextEditor::DocumentPrivate::Comment); 0276 } 0277 v->doc()->editEnd(); 0278 } else { 0279 v->comment(); 0280 } 0281 return true; 0282 } else if (cmd == QLatin1String("uncomment")) { 0283 if (range.isValid()) { 0284 v->doc()->editStart(); 0285 for (int line = range.start().line(); line <= range.end().line(); line++) { 0286 v->doc()->comment(v, line, 0, KTextEditor::DocumentPrivate::UnComment); 0287 } 0288 v->doc()->editEnd(); 0289 } else { 0290 v->uncomment(); 0291 } 0292 return true; 0293 } else if (cmd == QLatin1String("kill-line")) { 0294 if (range.isValid()) { 0295 v->doc()->editStart(); 0296 for (int line = range.start().line(); line <= range.end().line(); line++) { 0297 v->doc()->removeLine(range.start().line()); 0298 } 0299 v->doc()->editEnd(); 0300 } else { 0301 v->killLine(); 0302 } 0303 return true; 0304 } else if (cmd == QLatin1String("print")) { 0305 v->print(); 0306 return true; 0307 } 0308 0309 // ALL commands that take a string argument 0310 else if (cmd == QLatin1String("set-indent-mode") || cmd == QLatin1String("set-highlight") || cmd == QLatin1String("set-mode")) { 0311 // need at least one item, otherwise args.first() crashes 0312 if (args.isEmpty()) { 0313 KCC_ERR(i18n("Missing argument. Usage: %1 <value>", cmd)); 0314 } 0315 0316 if (cmd == QLatin1String("set-indent-mode")) { 0317 v->doc()->config()->setIndentationMode(args.join(QLatin1Char(' '))); 0318 v->doc()->rememberUserDidSetIndentationMode(); 0319 return true; 0320 } else if (cmd == QLatin1String("set-highlight")) { 0321 if (v->doc()->setHighlightingMode(args.join(QLatin1Char(' ')))) { 0322 static_cast<KTextEditor::DocumentPrivate *>(v->doc())->setDontChangeHlOnSave(); 0323 return true; 0324 } 0325 0326 KCC_ERR(i18n("No such highlighting '%1'", args.first())); 0327 } else if (cmd == QLatin1String("set-mode")) { 0328 if (v->doc()->setMode(args.first())) { 0329 return true; 0330 } 0331 0332 KCC_ERR(i18n("No such mode '%1'", args.first())); 0333 } 0334 } 0335 // ALL commands that takes exactly one integer argument. 0336 else if (cmd == QLatin1String("set-tab-width") || cmd == QLatin1String("set-indent-width") || cmd == QLatin1String("set-word-wrap-column") 0337 || cmd == QLatin1String("goto")) { 0338 // find a integer value > 0 0339 if (args.isEmpty()) { 0340 KCC_ERR(i18n("Missing argument. Usage: %1 <value>", cmd)); 0341 } 0342 bool ok; 0343 int val(args.first().toInt(&ok, 10)); // use base 10 even if the string starts with '0' 0344 if (!ok) 0345 KCC_ERR(i18n("Failed to convert argument '%1' to integer.", args.first())); 0346 0347 if (cmd == QLatin1String("set-tab-width")) { 0348 if (val < 1) { 0349 KCC_ERR(i18n("Width must be at least 1.")); 0350 } 0351 v->doc()->config()->setTabWidth(val); 0352 } else if (cmd == QLatin1String("set-indent-width")) { 0353 if (val < 1) { 0354 KCC_ERR(i18n("Width must be at least 1.")); 0355 } 0356 v->doc()->config()->setIndentationWidth(val); 0357 } else if (cmd == QLatin1String("set-word-wrap-column")) { 0358 if (val < 2) { 0359 KCC_ERR(i18n("Column must be at least 1.")); 0360 } 0361 v->doc()->setWordWrapAt(val); 0362 } else if (cmd == QLatin1String("goto")) { 0363 if (args.first().at(0) == QLatin1Char('-') || args.first().at(0) == QLatin1Char('+')) { 0364 // if the number starts with a minus or plus sign, add/subtract the number 0365 val = v->cursorPosition().line() + val; 0366 } else { 0367 val--; // convert given line number to the internal representation of line numbers 0368 } 0369 0370 // constrain cursor to the range [0, number of lines] 0371 if (val < 0) { 0372 val = 0; 0373 } else if (val > v->doc()->lines() - 1) { 0374 val = v->doc()->lines() - 1; 0375 } 0376 0377 v->setCursorPosition(KTextEditor::Cursor(val, 0)); 0378 return true; 0379 } 0380 return true; 0381 } 0382 0383 // ALL commands that takes 1 boolean argument. 0384 else if (cmd == QLatin1String("set-icon-border") || cmd == QLatin1String("set-folding-markers") || cmd == QLatin1String("set-indent-pasted-text") 0385 || cmd == QLatin1String("set-line-numbers") || cmd == QLatin1String("set-replace-tabs") || cmd == QLatin1String("set-show-tabs") 0386 || cmd == QLatin1String("set-word-wrap") || cmd == QLatin1String("set-wrap-cursor") || cmd == QLatin1String("set-replace-tabs-save") 0387 || cmd == QLatin1String("set-show-indent")) { 0388 if (args.isEmpty()) { 0389 KCC_ERR(i18n("Usage: %1 on|off|1|0|true|false", cmd)); 0390 } 0391 bool enable = false; 0392 KateDocumentConfig *const config = v->doc()->config(); 0393 if (getBoolArg(args.first(), &enable)) { 0394 if (cmd == QLatin1String("set-icon-border")) { 0395 v->setIconBorder(enable); 0396 } else if (cmd == QLatin1String("set-folding-markers")) { 0397 v->setFoldingMarkersOn(enable); 0398 } else if (cmd == QLatin1String("set-line-numbers")) { 0399 v->setLineNumbersOn(enable); 0400 } else if (cmd == QLatin1String("set-show-indent")) { 0401 v->renderer()->setShowIndentLines(enable); 0402 } else if (cmd == QLatin1String("set-indent-pasted-text")) { 0403 config->setIndentPastedText(enable); 0404 } else if (cmd == QLatin1String("set-replace-tabs")) { 0405 config->setReplaceTabsDyn(enable); 0406 } else if (cmd == QLatin1String("set-show-tabs")) { 0407 config->setShowTabs(enable); 0408 } else if (cmd == QLatin1String("set-show-trailing-spaces")) { 0409 config->setShowSpaces(enable ? KateDocumentConfig::Trailing : KateDocumentConfig::None); 0410 } else if (cmd == QLatin1String("set-word-wrap")) { 0411 v->doc()->setWordWrap(enable); 0412 } 0413 0414 return true; 0415 } else 0416 KCC_ERR(i18n("Bad argument '%1'. Usage: %2 on|off|1|0|true|false", args.first(), cmd)); 0417 } else if (cmd == QLatin1String("set-remove-trailing-spaces")) { 0418 // need at least one item, otherwise args.first() crashes 0419 if (args.count() != 1) { 0420 KCC_ERR(i18n("Usage: set-remove-trailing-spaces 0|-|none or 1|+|mod|modified or 2|*|all")); 0421 } 0422 0423 QString tmp = args.first().toLower().trimmed(); 0424 if (tmp == QLatin1String("1") || tmp == QLatin1String("modified") || tmp == QLatin1String("mod") || tmp == QLatin1String("+")) { 0425 v->doc()->config()->setRemoveSpaces(1); 0426 } else if (tmp == QLatin1String("2") || tmp == QLatin1String("all") || tmp == QLatin1String("*")) { 0427 v->doc()->config()->setRemoveSpaces(2); 0428 } else { 0429 v->doc()->config()->setRemoveSpaces(0); 0430 } 0431 } 0432 0433 // unlikely.. 0434 KCC_ERR(i18n("Unknown command '%1'", cmd)); 0435 } 0436 0437 bool KateCommands::CoreCommands::supportsRange(const QString &range) 0438 { 0439 static QStringList l; 0440 0441 if (l.isEmpty()) { 0442 l << QStringLiteral("indent") << QStringLiteral("unindent") << QStringLiteral("cleanindent") << QStringLiteral("comment") << QStringLiteral("uncomment") 0443 << QStringLiteral("kill-line") << QStringLiteral("fold") << QStringLiteral("tfold"); 0444 } 0445 0446 return l.contains(range); 0447 } 0448 0449 KCompletion *KateCommands::CoreCommands::completionObject(KTextEditor::View *view, const QString &cmd) 0450 { 0451 Q_UNUSED(view) 0452 0453 if (cmd == QLatin1String("set-highlight")) { 0454 QStringList l; 0455 l.reserve(KateHlManager::self()->modeList().size()); 0456 const auto modeList = KateHlManager::self()->modeList(); 0457 for (const auto &hl : modeList) { 0458 l << hl.name(); 0459 } 0460 0461 KateCmdShellCompletion *co = new KateCmdShellCompletion(); 0462 co->setItems(l); 0463 co->setIgnoreCase(true); 0464 return co; 0465 } else if (cmd == QLatin1String("set-remove-trailing-spaces")) { 0466 QStringList l; 0467 l << QStringLiteral("none") << QStringLiteral("modified") << QStringLiteral("all"); 0468 0469 KateCmdShellCompletion *co = new KateCmdShellCompletion(); 0470 co->setItems(l); 0471 co->setIgnoreCase(true); 0472 return co; 0473 } else if (cmd == QLatin1String("set-indent-mode")) { 0474 QStringList l = KateAutoIndent::listIdentifiers(); 0475 KateCmdShellCompletion *co = new KateCmdShellCompletion(); 0476 co->setItems(l); 0477 co->setIgnoreCase(true); 0478 return co; 0479 } 0480 0481 return nullptr; 0482 } 0483 // END CoreCommands 0484 0485 // BEGIN Character 0486 KateCommands::Character *KateCommands::Character::m_instance = nullptr; 0487 0488 bool KateCommands::Character::help(class KTextEditor::View *, const QString &cmd, QString &msg) 0489 { 0490 if (cmd.trimmed() == QLatin1String("char")) { 0491 msg = i18n( 0492 "<p> char <b>identifier</b> </p>" 0493 "<p>This command allows you to insert literal characters by their numerical identifier, in decimal, octal or hexadecimal form.</p>" 0494 "<p>Examples:<ul>" 0495 "<li>char <b>234</b></li>" 0496 "<li>char <b>0x1234</b></li>" 0497 "</ul></p>"); 0498 return true; 0499 } 0500 return false; 0501 } 0502 0503 bool KateCommands::Character::exec(KTextEditor::View *view, const QString &_cmd, QString &, const KTextEditor::Range &) 0504 { 0505 QString cmd = _cmd; 0506 0507 // hex, octal, base 9+1 0508 static const QRegularExpression num(QStringLiteral("^char *(0?x[0-9A-Fa-f]{1,4}|0[0-7]{1,6}|[0-9]{1,5})$")); 0509 const QRegularExpressionMatch match = num.match(cmd); 0510 if (!match.hasMatch()) { 0511 return false; 0512 } 0513 0514 cmd = match.captured(1); 0515 0516 // identify the base 0517 0518 unsigned short int number = 0; 0519 int base = 10; 0520 if (cmd.startsWith(QLatin1Char('x'))) { 0521 cmd.remove(0, 1); 0522 base = 16; 0523 } else if (cmd.startsWith(QLatin1String("0x"))) { 0524 cmd.remove(0, 2); 0525 base = 16; 0526 } else if (cmd[0] == QLatin1Char('0')) { 0527 base = 8; 0528 } 0529 bool ok; 0530 number = cmd.toUShort(&ok, base); 0531 if (!ok || number == 0) { 0532 return false; 0533 } 0534 if (number <= 255) { 0535 char buf[2]; 0536 buf[0] = (char)number; 0537 buf[1] = 0; 0538 0539 view->document()->insertText(view->cursorPosition(), QString::fromLatin1(buf)); 0540 } else { 0541 // do the unicode thing 0542 QChar c(number); 0543 0544 view->document()->insertText(view->cursorPosition(), QString(&c, 1)); 0545 } 0546 0547 return true; 0548 } 0549 0550 // END Character 0551 0552 // BEGIN Date 0553 KateCommands::Date *KateCommands::Date::m_instance = nullptr; 0554 0555 bool KateCommands::Date::help(class KTextEditor::View *, const QString &cmd, QString &msg) 0556 { 0557 if (cmd.trimmed() == QLatin1String("date")) { 0558 msg = i18n( 0559 "<p>date or date <b>format</b></p>" 0560 "<p>Inserts a date/time string as defined by the specified format, or the format yyyy-MM-dd hh:mm:ss if none is specified.</p>" 0561 "<p>Possible format specifiers are:" 0562 "<table>" 0563 "<tr><td>d</td><td>The day as number without a leading zero (1-31).</td></tr>" 0564 "<tr><td>dd</td><td>The day as number with a leading zero (01-31).</td></tr>" 0565 "<tr><td>ddd</td><td>The abbreviated localized day name (e.g. 'Mon'..'Sun').</td></tr>" 0566 "<tr><td>dddd</td><td>The long localized day name (e.g. 'Monday'..'Sunday').</td></tr>" 0567 "<tr><td>M</td><td>The month as number without a leading zero (1-12).</td></tr>" 0568 "<tr><td>MM</td><td>The month as number with a leading zero (01-12).</td></tr>" 0569 "<tr><td>MMM</td><td>The abbreviated localized month name (e.g. 'Jan'..'Dec').</td></tr>" 0570 "<tr><td>yy</td><td>The year as two digit number (00-99).</td></tr>" 0571 "<tr><td>yyyy</td><td>The year as four digit number (1752-8000).</td></tr>" 0572 "<tr><td>h</td><td>The hour without a leading zero (0..23 or 1..12 if AM/PM display).</td></tr>" 0573 "<tr><td>hh</td><td>The hour with a leading zero (00..23 or 01..12 if AM/PM display).</td></tr>" 0574 "<tr><td>m</td><td>The minute without a leading zero (0..59).</td></tr>" 0575 "<tr><td>mm</td><td>The minute with a leading zero (00..59).</td></tr>" 0576 "<tr><td>s</td><td>The second without a leading zero (0..59).</td></tr>" 0577 "<tr><td>ss</td><td>The second with a leading zero (00..59).</td></tr>" 0578 "<tr><td>z</td><td>The milliseconds without leading zeroes (0..999).</td></tr>" 0579 "<tr><td>zzz</td><td>The milliseconds with leading zeroes (000..999).</td></tr>" 0580 "<tr><td>AP</td><td>Use AM/PM display. AP will be replaced by either \"AM\" or \"PM\".</td></tr>" 0581 "<tr><td>ap</td><td>Use am/pm display. ap will be replaced by either \"am\" or \"pm\".</td></tr>" 0582 "</table></p>"); 0583 return true; 0584 } 0585 return false; 0586 } 0587 0588 bool KateCommands::Date::exec(KTextEditor::View *view, const QString &cmd, QString &, const KTextEditor::Range &) 0589 { 0590 if (!cmd.startsWith(QLatin1String("date"))) { 0591 return false; 0592 } 0593 0594 if (QDateTime::currentDateTime().toString(cmd.mid(5, cmd.length() - 5)).length() > 0) { 0595 view->document()->insertText(view->cursorPosition(), QDateTime::currentDateTime().toString(cmd.mid(5, cmd.length() - 5))); 0596 } else { 0597 view->document()->insertText(view->cursorPosition(), QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd hh:mm:ss"))); 0598 } 0599 0600 return true; 0601 } 0602 0603 // END Date