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