[rkward/work/consolecompletion] rkward: WIP: Start merging the improved script window hinting into the console.
Thomas Friedrichsmeier
null at kde.org
Sun Jan 26 09:51:21 GMT 2020
Git commit 1af9c145e858fb4805e079c90b1702d4edcef1f5 by Thomas Friedrichsmeier.
Committed on 26/01/2020 at 09:50.
Pushed by tfry into branch 'work/consolecompletion'.
WIP: Start merging the improved script window hinting into the console.
M +5 -6 rkward/rkconsole.cpp
M +1 -2 rkward/rkconsole.h
M +5 -5 rkward/windows/rkcodecompletion.cpp
M +7 -2 rkward/windows/rkcodecompletion.h
M +0 -162 rkward/windows/rkcommandeditorwindow.cpp
M +0 -31 rkward/windows/rkcommandeditorwindow.h
https://commits.kde.org/rkward/1af9c145e858fb4805e079c90b1702d4edcef1f5
diff --git a/rkward/rkconsole.cpp b/rkward/rkconsole.cpp
index 2a37f154..b12c9f6e 100644
--- a/rkward/rkconsole.cpp
+++ b/rkward/rkconsole.cpp
@@ -2,7 +2,7 @@
rkconsole - description
-------------------
begin : Thu Aug 19 2004
- copyright : (C) 2004-2019 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2020 by Thomas Friedrichsmeier
email : thomas.friedrichsmeier at kdemail.net
***************************************************************************/
@@ -54,6 +54,7 @@
#include "rkglobals.h"
#include "rkward.h"
#include "windows/rkhelpsearchwindow.h"
+#include "windows/rkcodecompletion.h"
#include "rbackend/rkrinterface.h"
#include "rbackend/rcommand.h"
#include "settings/rksettings.h"
@@ -63,7 +64,6 @@
#include "misc/rkstandardicons.h"
#include "misc/rkstandardactions.h"
#include "core/robjectlist.h"
-#include "core/rfunctionobject.h"
#include "debug.h"
@@ -143,7 +143,7 @@ RKConsole::RKConsole (QWidget *parent, bool tool_window, const char *name) : RKM
doc->setModified (false);
- hinter = new RKFunctionArgHinter (this, view);
+ new RKCompletionManager (view);
setCaption (i18n ("R Console"));
console_part = new RKConsolePart (this);
@@ -175,7 +175,6 @@ RKConsole::RKConsole (QWidget *parent, bool tool_window, const char *name) : RKM
RKConsole::~RKConsole () {
RK_TRACE (APP);
- delete hinter;
RKSettingsModuleConsole::saveCommandHistory (commands_history.getHistory ());
}
@@ -332,8 +331,8 @@ bool RKConsole::handleKeyPress (QKeyEvent *e) {
iface->forceCompletion ();
return true;
}
-
- hinter->hideArgHint ();
+#warning TODO
+// hinter->hideArgHint ();
commands_history.append (currentEditingLine ());
submitCommand ();
return true;
diff --git a/rkward/rkconsole.h b/rkward/rkconsole.h
index 5b7f20de..d68765c7 100644
--- a/rkward/rkconsole.h
+++ b/rkward/rkconsole.h
@@ -2,7 +2,7 @@
rkconsole - description
-------------------
begin : Thu Aug 19 2004
- copyright : (C) 2004, 2006, 2007, 2010, 2011 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2020 by Thomas Friedrichsmeier
email : thomas.friedrichsmeier at kdemail.net
***************************************************************************/
@@ -130,7 +130,6 @@ friend class RKConsolePart;
RCommand *current_command;
KTextEditor::Document *doc;
KTextEditor::View *view;
- RKFunctionArgHinter *hinter;
static RKConsole *main_console;
diff --git a/rkward/windows/rkcodecompletion.cpp b/rkward/windows/rkcodecompletion.cpp
index 6db3aa4f..837a0e10 100644
--- a/rkward/windows/rkcodecompletion.cpp
+++ b/rkward/windows/rkcodecompletion.cpp
@@ -2,7 +2,7 @@
rkcodecompletion - description
-------------------
begin : Thu Feb 21 2019
- copyright : (C) 2004-2019 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2020 by Thomas Friedrichsmeier
email : thomas.friedrichsmeier at kdemail.net
***************************************************************************/
@@ -58,10 +58,11 @@ public:
//////////////////////// RKCompletionManager //////////////////////
-RKCompletionManager::RKCompletionManager (KTextEditor::View* view) : QObject (view) {
+RKCompletionManager::RKCompletionManager (KTextEditor::View* view, Mode _mode) : QObject (view) {
RK_TRACE (COMMANDEDITOR);
_view = view;
+ mode = _mode;
keep_active = false;
user_triggered = false;
ignore_next_trigger = false;
@@ -89,12 +90,11 @@ RKCompletionManager::RKCompletionManager (KTextEditor::View* view) : QObject (vi
(*it)->installEventFilter (this); // to handle Tab-key; installing on the view, alone, is not enough.
}
- // HACK: I just can't see to make the object name completion model play nice with automatic invocation.
+ // HACK: I just can't seem to make the object name completion model play nice with automatic invocation.
// However, there is no official way to invoke all registered models, manually. So we try to hack our way
// to a pointer to the default kate keyword completion model
kate_keyword_completion_model = KTextEditor::Editor::instance ()->findChild<KTextEditor::CodeCompletionModel *> ();
if (!kate_keyword_completion_model) kate_keyword_completion_model = view->findChild<KTextEditor::CodeCompletionModel *> (QString());
-
} else {
RK_ASSERT (false); // Not a katepart?
}
@@ -222,7 +222,7 @@ void RKCompletionManager::updateCallHint () {
while (potential_symbol_end < -1 && line >= 0) {
--line;
QString context_line = doc->line (line);
- if (context_line.startsWith ('>')) continue; // For console: TODO limit to console
+ if (mode == Console && !context_line.startsWith ('>')) continue; // skip output lines
full_context.prepend (context_line);
int pos = context_line.length () - 1;
diff --git a/rkward/windows/rkcodecompletion.h b/rkward/windows/rkcodecompletion.h
index c9857c6a..131480bf 100644
--- a/rkward/windows/rkcodecompletion.h
+++ b/rkward/windows/rkcodecompletion.h
@@ -2,7 +2,7 @@
rkcodecompletion - description
-------------------
begin : Thu Feb 21 2019
- copyright : (C) 2004-2019 by Thomas Friedrichsmeier
+ copyright : (C) 2004-2020 by Thomas Friedrichsmeier
email : thomas.friedrichsmeier at kdemail.net
***************************************************************************/
@@ -37,7 +37,11 @@ class RKArgumentHintModel;
class RKCompletionManager : public QObject {
Q_OBJECT
public:
- RKCompletionManager (KTextEditor::View *view);
+ enum Mode {
+ Script,
+ Console
+ };
+ RKCompletionManager (KTextEditor::View *view, Mode=Script);
~RKCompletionManager ();
QString currentCompletionWord () const;
@@ -71,6 +75,7 @@ private:
KTextEditor::View *_view;
KTextEditor::Cursor cached_position;
+ Mode mode;
KTextEditor::Range symbol_range;
KTextEditor::Cursor call_opening;
diff --git a/rkward/windows/rkcommandeditorwindow.cpp b/rkward/windows/rkcommandeditorwindow.cpp
index fe4d5091..5c9269e1 100644
--- a/rkward/windows/rkcommandeditorwindow.cpp
+++ b/rkward/windows/rkcommandeditorwindow.cpp
@@ -242,12 +242,10 @@ RKCommandEditorWindow::RKCommandEditorWindow (QWidget *parent, const QUrl _url,
// somehow the katepart loses the context menu each time it loses focus
connect (m_view, &KTextEditor::View::focusIn, this, &RKCommandEditorWindow::focusIn);
- hinter = 0;
if (use_r_highlighting) {
RKCommandHighlighter::setHighlighting (m_doc, RKCommandHighlighter::RScript);
if (flags & RKCommandEditorFlags::UseCodeHinting) {
new RKCompletionManager (m_view);
- //hinter = new RKFunctionArgHinter (this, m_view);
}
} else {
RKCommandHighlighter::setHighlighting (m_doc, RKCommandHighlighter::Automatic);
@@ -276,7 +274,6 @@ RKCommandEditorWindow::~RKCommandEditorWindow () {
m_view->writeSessionConfig (viewconf);
}
- delete hinter;
discardPreview ();
delete m_view;
QList<KTextEditor::View*> views = m_doc->views ();
@@ -1050,165 +1047,6 @@ void RKCommandEditorWindow::selectionChanged (KTextEditor::View* view) {
}
}
-//////////////////////// RKFunctionArgHinter //////////////////////////////
-
-#include <QToolTip>
-#include <QStyle>
-
-#include "../core/rfunctionobject.h"
-
-RKFunctionArgHinter::RKFunctionArgHinter (RKScriptContextProvider *provider, KTextEditor::View* view) {
- RK_TRACE (COMMANDEDITOR);
-
- RKFunctionArgHinter::provider = provider;
- RKFunctionArgHinter::view = view;
-
- const QObjectList children = view->children ();
- for (QObjectList::const_iterator it = children.constBegin(); it != children.constEnd (); ++it) {
- QObject *obj = *it;
- obj->installEventFilter (this);
- }
-
- arghints_popup = new QLabel (0, Qt::ToolTip);
- arghints_popup->setMargin (2);
- // HACK trying hard to trick the style into using the correct color
- // ... and sometimes we still get white on yellow in some styles. Sigh...
- // A simple heuristic tries to detect the worst cases of unreasonably low contrast, and forces black on light blue, then.
- QPalette p = QToolTip::palette ();
- QColor b = p.color (QPalette::Inactive, QPalette::ToolTipBase);
- QColor f = p.color (QPalette::Inactive, QPalette::ToolTipText);
- if ((qAbs (f.greenF () - b.greenF ()) + qAbs (f.redF () - b.redF ()) + qAbs (f.yellowF () - b.yellowF ())) < .6) {
- f = Qt::black;
- b = QColor (192, 219, 255);
- }
- p.setColor (QPalette::Inactive, QPalette::WindowText, f);
- p.setColor (QPalette::Inactive, QPalette::Window, b);
- p.setColor (QPalette::Inactive, QPalette::ToolTipText, f);
- p.setColor (QPalette::Inactive, QPalette::ToolTipBase, b);
- arghints_popup->setForegroundRole (QPalette::ToolTipText);
- arghints_popup->setBackgroundRole (QPalette::ToolTipBase);
- arghints_popup->setPalette (p);
- arghints_popup->setFrameStyle (QFrame::Box);
- arghints_popup->setLineWidth (1);
- arghints_popup->setWordWrap (true);
- arghints_popup->setWindowOpacity (arghints_popup->style ()->styleHint (QStyle::SH_ToolTipLabel_Opacity, 0, arghints_popup) / 255.0);
- arghints_popup->hide ();
- active = false;
-
- connect (&updater, &QTimer::timeout, this, &RKFunctionArgHinter::updateArgHintWindow);
-}
-
-RKFunctionArgHinter::~RKFunctionArgHinter () {
- RK_TRACE (COMMANDEDITOR);
- delete arghints_popup;
-}
-
-void RKFunctionArgHinter::tryArgHint () {
- RK_TRACE (COMMANDEDITOR);
-
- if (!RKSettingsModuleCommandEditor::argHintingEnabled ()) return;
-
- // do this in the next event cycle to make sure any inserted characters have truly been inserted
- QTimer::singleShot (0, this, SLOT (tryArgHintNow()));
-}
-
-void RKFunctionArgHinter::tryArgHintNow () {
- RK_TRACE (COMMANDEDITOR);
-
- // find the active opening brace
- int line_rev = -1;
- QList<int> unclosed_braces;
- QString full_context;
- while (unclosed_braces.isEmpty ()) {
- QString context_line = provider->provideContext (++line_rev);
- if (context_line.isNull ()) break;
- full_context.prepend (context_line);
- for (int i = 0; i < context_line.length (); ++i) {
- QChar c = context_line.at (i);
- if (c == '"' || c == '\'' || c == '`') { // NOTE: this algo does not produce good results on string constants spanning newlines.
- i = RKCommonFunctions::quoteEndPosition (c, context_line, i + 1);
- if (i < 0) break;
- continue;
- } else if (c == '\\') {
- ++i;
- continue;
- } else if (c == '(') {
- unclosed_braces.append (i);
- } else if (c == ')') {
- if (!unclosed_braces.isEmpty()) unclosed_braces.pop_back ();
- }
- }
- }
-
- int potential_symbol_end = unclosed_braces.isEmpty () ? -1 : unclosed_braces.last () - 1;
-
- // now find out where the symbol to the left of the opening brace ends
- // there cannot be a line-break between the opening brace, and the symbol name (or can there?), so no need to fetch further context
- while ((potential_symbol_end >= 0) && full_context.at (potential_symbol_end).isSpace ()) {
- --potential_symbol_end;
- }
- if (potential_symbol_end <= 0) {
- hideArgHint ();
- return;
- }
-
- // now identify the symbol and object (if any)
- QString effective_symbol = RKCommonFunctions::getCurrentSymbol (full_context, potential_symbol_end);
- if (effective_symbol.isEmpty ()) {
- hideArgHint ();
- return;
- }
-
- RObject *object = RObjectList::getObjectList ()->findObject (effective_symbol);
- if ((!object) || (!object->isType (RObject::Function))) {
- hideArgHint ();
- return;
- }
-
- // initialize and show popup
- arghints_popup->setText (effective_symbol + " (" + static_cast<RFunctionObject*> (object)->printArgs () + ')');
- arghints_popup->resize (arghints_popup->sizeHint () + QSize (2, 2));
- active = true;
- updater.start (50);
- updateArgHintWindow ();
-}
-
-void RKFunctionArgHinter::updateArgHintWindow () {
- RK_TRACE (COMMANDEDITOR);
-
- if (!active) return;
-
- arghints_popup->move (view->mapToGlobal (view->cursorPositionCoordinates () + QPoint (0, arghints_popup->fontMetrics ().lineSpacing () + arghints_popup->margin ()*2)));
- if (view->hasFocus ()) arghints_popup->show ();
- else arghints_popup->hide ();
-}
-
-void RKFunctionArgHinter::hideArgHint () {
- RK_TRACE (COMMANDEDITOR);
- arghints_popup->hide ();
- active = false;
- updater.stop ();
-}
-
-bool RKFunctionArgHinter::eventFilter (QObject *, QEvent *e) {
- if (e->type () == QEvent::KeyPress || e->type () == QEvent::ShortcutOverride) {
- RK_TRACE (COMMANDEDITOR); // avoid loads of empty traces, putting this here
- QKeyEvent *k = static_cast<QKeyEvent *> (e);
-
- if (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return || k->key () == Qt::Key_Up || k->key () == Qt::Key_Down || k->key () == Qt::Key_Left || k->key () == Qt::Key_Right || k->key () == Qt::Key_Home || k->key () == Qt::Key_Tab) {
- hideArgHint ();
- } else if (k->key () == Qt::Key_Backspace || k->key () == Qt::Key_Delete){
- tryArgHint ();
- } else {
- QString text = k->text ();
- if ((text == "(") || (text == ")") || (text == ",")) {
- tryArgHint ();
- }
- }
- }
-
- return false;
-}
// static
KTextEditor::Document* RKCommandHighlighter::_doc = 0;
diff --git a/rkward/windows/rkcommandeditorwindow.h b/rkward/windows/rkcommandeditorwindow.h
index 21876b55..ebe53893 100644
--- a/rkward/windows/rkcommandeditorwindow.h
+++ b/rkward/windows/rkcommandeditorwindow.h
@@ -72,36 +72,6 @@ public:
virtual void currentHelpContext (QString *symbol, QString *package) = 0;
};
-class RObject;
-/** function argument hinting for RKCommandEditorWindow and RKConsole */
-class RKFunctionArgHinter : public QObject {
- Q_OBJECT
-public:
- RKFunctionArgHinter (RKScriptContextProvider *provider, KTextEditor::View* view);
- ~RKFunctionArgHinter ();
-
- /** Try to show an arg hint now */
- void tryArgHint ();
- /** Hide the arg hint (if shown) */
- void hideArgHint ();
-public slots:
- /** Internal worker function for tryArgHint () */
- void tryArgHintNow ();
-
- void updateArgHintWindow ();
-protected:
- /** The (keypress) events of the view are filtered to determine, when to show / hide an argument hint */
- bool eventFilter (QObject *, QEvent *e) override;
-private:
- RKScriptContextProvider *provider;
- KTextEditor::View *view;
-
- /** A timer to refresh the hint window periodically. This is a bit sorry, but it's really hard to find out, when the view has been moved, or gains/loses focus. While possible, this approach uses much less code. */
- QTimer updater;
- bool active;
- QLabel *arghints_popup;
-};
-
class RKJobSequence;
class RKXMLGUIPreviewArea;
class RKPreviewManager;
@@ -207,7 +177,6 @@ private:
KTextEditor::Document *m_doc;
KTextEditor::View *m_view;
KTextEditor::MovingInterface *smart_iface;
- RKFunctionArgHinter *hinter;
void initializeActions (KActionCollection* ac);
More information about the rkward-tracker
mailing list