Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: dart/site/try/src/editor.dart

Issue 197923002: Mock up code completion. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: dart/site/try/src/editor.dart
diff --git a/dart/site/try/src/editor.dart b/dart/site/try/src/editor.dart
index 885295de9c167a69860620832964cdb048f71f0c..47fa0df7a5dc79b9b978bc9d4c2e24fedbe97221 100644
--- a/dart/site/try/src/editor.dart
+++ b/dart/site/try/src/editor.dart
@@ -6,6 +6,12 @@ library trydart.editor;
import 'dart:html';
+import 'dart:async' show
+ Timer;
+
+import 'dart:convert' show
+ JSON;
+
import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart'
show
EOF_TOKEN,
@@ -19,6 +25,7 @@ import 'compilation.dart' show
scheduleCompilation;
import 'ui.dart' show
+ applyingSettings,
currentTheme,
hackDiv,
inputPre,
@@ -26,6 +33,7 @@ import 'ui.dart' show
outputDiv;
import 'decoration.dart' show
+ CodeCompletionDecoration,
Decoration,
DiagnosticDecoration,
error,
@@ -34,7 +42,17 @@ import 'decoration.dart' show
const String INDENT = '\u{a0}\u{a0}';
+Set<String> seenIdentifiers;
+
onKeyUp(KeyboardEvent e) {
+ scheduleCodeCompletion();
+
+ if (e.keyCode == 40 && activeCompletion != null) {
+ e.preventDefault();
+ print('${e.keyCode}: ${e}');
+ return;
+ }
+
if (e.keyCode == 13) {
e.preventDefault();
Selection selection = window.getSelection();
@@ -51,16 +69,94 @@ onKeyUp(KeyboardEvent e) {
hackDiv = newDiv;
}
+Timer codeCompletionTimer;
+
+void scheduleCodeCompletion() {
+ if (applyingSettings) return;
+ if (codeCompletionTimer != null) {
+ codeCompletionTimer.cancel();
+ codeCompletionTimer = null;
+ }
+ codeCompletionTimer =
+ new Timer(const Duration(milliseconds: 1), displayCodeCompletion);
+}
+
+var activeCompletion;
+
+void displayCodeCompletion() {
+ if (activeCompletion != null) {
+ activeCompletion.classes.remove('active');
+ activeCompletion = null;
+ }
+ Selection selection = window.getSelection();
+ if (!selection.isCollapsed) return;
+ var anchorNode = selection.anchorNode;
+ if (!inputPre.contains(anchorNode)) return;
+ int anchorOffset = selection.anchorOffset;
+ int type = anchorNode.nodeType;
+ if (type != Node.TEXT_NODE) return;
+ Text text = anchorNode;
+ var parent = text.parent;
+ if (parent is! Element) return;
+ parent.classes.add('active');
+ var ui = parent.query('.dart-code-completion');
+ if (ui == null) return;
+ activeCompletion = parent;
+ observer.disconnect();
+ ui.nodes.clear();
+ String prefix = text.data.substring(0, anchorOffset).trim();
+ if (!prefix.isEmpty) {
+ String encodedArg0 = Uri.encodeComponent('"$prefix"');
+ String mindQuery =
+ 'http://dart-mind.appspot.com/rpc'
+ '?action=GetExportingPubCompletions'
+ '&arg0=$encodedArg0';
+ HttpRequest request = new HttpRequest();
+ request.open('GET', mindQuery, async: false);
+ try {
+ List<String> response = <String>[];
+ var sw = new Stopwatch();
+ if (false) {
+ sw.start();
+ request.send();
+ sw.stop();
+ if (request.status == 200) {
+ response = JSON.decode(request.responseText);
+ }
+ } else {
+ sw.start();
+ response =
+ seenIdentifiers.where(
+ (String identifier) => identifier != prefix && identifier.startsWith(prefix))
kasperl 2014/03/13 07:39:58 Long line.
+ .toList(growable: false)
+ ..sort();
kasperl 2014/03/13 07:39:58 I think I'd prefer to not use .. for this. It's a
+ sw.stop();
+ }
+ response.forEach((String completion) {
+ ui.appendHtml('$completion<br>');
+ });
+ ui.appendHtml('${sw.elapsedMilliseconds}ms<br>');
+ } catch (e) {
+ window.console.dir(e);
+ }
+ }
+ observer.observe(inputPre, childList: true, characterData: true, subtree: true);
kasperl 2014/03/13 07:39:58 Long line.
+}
+
bool isMalformedInput = false;
String currentSource = "";
// TODO(ahe): This method should be cleaned up. It is too large.
onMutation(List<MutationRecord> mutations, MutationObserver observer) {
- scheduleCompilation();
+ // scheduleCompilation();
- for (Element element in inputPre.queryAll('a[class="diagnostic"]>span')) {
+ for (Element element in inputPre.queryAll('a.diagnostic>span')) {
+ element.remove();
+ }
+ for (Element element in inputPre.queryAll('.dart-code-completion')) {
element.remove();
}
+
// Discard clean-up mutations.
observer.takeRecords();
@@ -181,6 +277,7 @@ onMutation(List<MutationRecord> mutations, MutationObserver observer) {
Token token = new StringScanner(
new StringSourceFile('', text), includeComments: true).tokenize();
int offset = 0;
+ seenIdentifiers = new Set<String>();
for (;token.kind != EOF_TOKEN; token = token.next) {
Decoration decoration = getDecoration(token);
if (decoration == null) continue;
@@ -213,6 +310,14 @@ onMutation(List<MutationRecord> mutations, MutationObserver observer) {
window.localStorage['currentSource'] = currentSource;
+ if (activeCompletion != null) {
+ if (codeCompletionTimer != null) {
+ codeCompletionTimer.cancel();
+ codeCompletionTimer = null;
+ }
+ displayCodeCompletion();
+ }
+
// Discard highlighting mutations.
observer.takeRecords();
}
@@ -295,7 +400,12 @@ Decoration getDecoration(Token token) {
String tokenValue = token.value;
String tokenInfo = token.info.value;
if (tokenInfo == 'string') return currentTheme.string;
- // if (tokenInfo == 'identifier') return identifier;
+ if (tokenInfo == 'identifier') {
+ seenIdentifiers.add(tokenValue);
+
+ print(seenIdentifiers);
+ return CodeCompletionDecoration.from(currentTheme.foreground);
+ }
if (tokenInfo == 'keyword') return currentTheme.keyword;
if (tokenInfo == 'comment') return currentTheme.singleLineComment;
if (tokenInfo == 'malformed input') {

Powered by Google App Engine
This is Rietveld 408576698