Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Initial work on the annotation service and mark occurrences plugin
  • Loading branch information
Andrew Eisenberg authored and Andrew Eisenberg committed Mar 13, 2012
1 parent 8d428c5 commit 7ec046b
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 6 deletions.
1 change: 0 additions & 1 deletion bundles/org.eclipse.orion.client.core/web/defaults.pref
Expand Up @@ -13,6 +13,5 @@
"plugins/preferencesPlugin.html":true,
"plugins/taskPlugin.html": true,
"plugins/csslintPlugin.html": true,
"plugins/esprimaJsContentAssistPlugin.html": true
}
}
10 changes: 8 additions & 2 deletions bundles/org.eclipse.orion.client.core/web/edit/setup.js
Expand Up @@ -17,12 +17,12 @@ define(['require', 'dojo', 'orion/selection', 'orion/status', 'orion/progress',
'orion/problems', 'orion/editor/contentAssist', 'orion/editorCommands', 'orion/editor/editorFeatures', 'orion/editor/editor', 'orion/syntaxchecker',
'orion/breadcrumbs', 'orion/textview/textView', 'orion/textview/textModel',
'orion/textview/projectionTextModel', 'orion/textview/keyBinding','orion/searchAndReplace/textSearcher','orion/searchAndReplace/orionTextSearchAdaptor',
'orion/edit/dispatcher', 'orion/contentTypes', 'orion/PageUtil', 'orion/highlight',
'orion/edit/dispatcher', 'orion/contentTypes', 'orion/PageUtil', 'orion/highlight', 'orion/textview/annotationservice',
'dojo/parser', 'dojo/hash', 'dijit/layout/BorderContainer', 'dijit/layout/ContentPane', 'orion/widgets/eWebBorderContainer' ],
function(require, dojo, mSelection, mStatus, mProgress, mDialogs, mCommands, mUtil, mFavorites,
mFileClient, mOperationsClient, mSearchClient, mGlobalCommands, mOutliner, mProblems, mContentAssist, mEditorCommands, mEditorFeatures, mEditor,
mSyntaxchecker, mBreadcrumbs, mTextView, mTextModel, mProjectionTextModel, mKeyBinding, mSearcher,
mSearchAdaptor, mDispatcher, mContentTypes, PageUtil, Highlight) {
mSearchAdaptor, mDispatcher, mContentTypes, PageUtil, Highlight, mAnnotationService) {

var exports = exports || {};

Expand Down Expand Up @@ -105,6 +105,12 @@ exports.setUpEditor = function(serviceRegistry, preferences, isReadOnly){
} else {
if (!editor.getTextView()) {
editor.installTextView();

// Create the annotation service. Must wait until after text view is installed so that the
// annotation model is available
var annotationService = new mAnnotationService.AnnotationService(serviceRegistry, editor);
serviceRegistry.registerService("orion.edit.annotations", annotationService);

}
var fullPathName = fileURI;
var progressTimeout = setTimeout(function() {
Expand Down
@@ -0,0 +1,133 @@
/*******************************************************************************
* @license
* Copyright (c) 2012 Contributors
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
* License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
*
* Contributors:
* Andrew Eisenberg (vmware) - initial API and implementation
*******************************************************************************/
/*global define console */
define("markOccurrences", [], function() {
// private variable
var _annotationProvider = {
_serviceProvider : null,
setServiceProvider : function(serviceProvider) { this._serviceProvider = serviceProvider; },
modelChanged : function() {
if (this._serviceProvider) {
this._serviceProvider.dispatchEvent("registerAnnotationType", {
type: "orion.annotation.markoccurrences",
style: { "font-weight": "bold" },
rangeStyle: {styleClass: "annotationOverview currentLine"},
html: "<div class='annotationHTML currentLine'></div>",
overviewStyle: {styleClass: "annotationOverview currentLine"}
});
}
},
pushAnnotations : function(ranges) {
if (ranges && ranges.length > 0) {
console.log("All locations: " + JSON.stringify(ranges));
this._serviceProvider.dispatchEvent("addAnnotations", {
type: "orion.annotation.markoccurrences",
ranges: ranges
});
}
}
};


function isIdentifierPart(char) {
return (/\d|\w|\$|_/).exec(char) !== null;
}

function isIdentifierStart(char) {
return (/\w|\$|_/).exec(char) !== null;
}

function isIdentifier(word) {
if (!word || word.length === 0) {
return false;
}
if (!isIdentifierStart(word.charAt(0))) {
return false;
}
for (var i = 1; i < word.length; i++) {
if (!isIdentifierPart(word.charAt(0))) {
return false;
}
}
return true;
}

function findCurrentWord(start, end, buffer) {
// ensure that if caret is after last char of word, then we still see the word
start--;
while (start > 0 && isIdentifierPart(buffer.charAt(start))) {
start--;
}
if (start > 0 || !isIdentifierPart(buffer.charAt(start))) {
start++;
}
while (end < buffer.length && isIdentifierPart(buffer.charAt(end))) {
end++;
}
var word = buffer.substring(start, end);
if (isIdentifier(word)) {
return word;
} else {
return null;
}
}


function findLocations(buffer, toFind) {
if (!toFind) {
return [];
}
var lastIndex = -1,
result = [];
while (true) {
lastIndex = buffer.indexOf(toFind, lastIndex + 1);

if (lastIndex === -1) {
break;
}

// must check the boundary of the word before choosing it
var prevChar = buffer.charAt(lastIndex - 1);
var nextChar = buffer.charAt(lastIndex + toFind.length);
if (!isIdentifierPart(prevChar) && !isIdentifierPart(nextChar)) {
result.push({
start: lastIndex,
end: lastIndex + toFind.length,
title: "Occurrence of '" + toFind + "'"
});
}
}
return result;
}

return {
markOccurrences: {
onModelChanging: function(e) {
_annotationProvider.modelChanged();
},
onSelection: function(e) {
if (e.text) {
var current = findCurrentWord(e.newValue.start, e.newValue.end, e.text);
if (current) {
console.log("Current selection: " + current);
} else {
console.log("Identifier is not selected");
}
var ranges = findLocations(e.text, current);
_annotationProvider.pushAnnotations(ranges);
}
}
},

annotationProvider : _annotationProvider
};
});
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta name="copyright" content="Copyright (c) VMware Corporation and others 2012.">
<title>Esprima Content Assist</title>
<script type="text/javascript" src="http://orion.eclipse.org/orion/plugin.js"></script>
<script type="text/javascript" src="http://orion.eclipse.org/requirejs/require.js"></script>
<script type="text/javascript" src="markOccurrences.js"></script>
<script>
/*global eclipse require console */
require(["markOccurrences"], function(markOccurrencesPlugin) {
var provider = new eclipse.PluginProvider();
provider.registerServiceProvider("orion.edit.model", markOccurrencesPlugin.markOccurrences,
{
types: ["Selection", "ModelChanging"],
contentType: ["text.javascript"]
});

var serviceProvider =
provider.registerServiceProvider("orion.edit.annotations",
markOccurrencesPlugin.annotationProvider, { });

markOccurrencesPlugin.annotationProvider.setServiceProvider(serviceProvider);

provider.connect();
});
</script>
</head>
<body>
<p>A plugin that highlights all occurrences of the selected word in the current editor.</p>
</body>
</html>
Expand Up @@ -6,6 +6,7 @@
<script type="text/javascript" src="../orion/plugin.js"></script>
<script type="text/javascript" src="../../org.dojotoolkit/dojo/dojo.js.uncompressed.js"></script>
<script>
/*global eclipse window dojo */
window.onload = function() {
var provider = new eclipse.PluginProvider();

Expand All @@ -17,7 +18,7 @@
}

var temp = document.createElement('a');
temp.href = "../task"
temp.href = "../task";
var base = makeParentRelative(temp.href);

// testing that command service handles image-less actions properly
Expand All @@ -30,7 +31,7 @@
},
content: options,
handleAs: "json",
timeout: options.Longpolling == true? 70000: 15000
timeout: options.Longpolling === true? 70000: 15000
});
},
getOperation: function(taskLocation){
Expand Down
Expand Up @@ -328,6 +328,12 @@ define("orion/editor/editor", ['i18n!orion/editor/nls/messages', 'orion/textview
getAnnotationModel : function() {
return this._annotationModel;
},

addAnnotationType : function(type) {
this._annotationStyler.addAnnotationType(type);
this._overviewRuler.addAnnotationType(type);
this._annotationRuler.addAnnotationType(type);
},

/**
* Helper for finding occurrences of str in the editor contents.
Expand Down
@@ -0,0 +1,53 @@
/*******************************************************************************
* @license
* Copyright (c) 2012 VMware and others.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution
* License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html).
*
* Contributors:
* Andrew Eisenberg (VMware) - initial API and implementation
******************************************************************************/

/*global define */

define('orion/textview/annotationservice', ['orion/textview/annotations', 'dojo'], function(mAnnotations, dojo) {
return { AnnotationService : function(serviceRegistry, editor) {
this._annotationModel = editor.getAnnotationModel();
this._annotationTypes = {};
this.registerAnnotationType = function(event) {
this._annotationTypes[event.type] = function() {
this.type = event.type;
this.title = event.title;
this.style = event.style;
this.html = event.html;
this.overviewStyle = event.overviewStyle;
this.rangeStyle = event.rangeStyle;
};
editor.addAnnotationType(event.type);
};

this.addAnnotations = function(event) {
var Annotation = this._annotationTypes[event.type];
if (Annotation) {
this._annotationModel.removeAnnotations(event.type);
for (var i = 0; i < event.ranges.length; i++) {
var annotation = new Annotation();
for (var prop in event.ranges[i]) {
if (event.ranges[i].hasOwnProperty(prop)) {
annotation[prop] = event.ranges[i][prop];
}
}
this._annotationModel.addAnnotation(annotation);
}
}
};

var annotationsService = serviceRegistry.getService("orion.edit.annotations");
if (annotationsService) {
annotationsService.addEventListener("registerAnnotationType", dojo.hitch(this, "registerAnnotationType"));
annotationsService.addEventListener("addAnnotations", dojo.hitch(this, "addAnnotations"));
}
} };
});
Expand Up @@ -4891,7 +4891,8 @@ define("orion/textview/textView", ['orion/textview/textModel', 'orion/textview/k
var e = {
type: "Selection",
oldValue: {start:oldSelection.start, end:oldSelection.end},
newValue: {start:selection.start, end:selection.end}
newValue: {start:selection.start, end:selection.end},
text: this._model.getText()
};
this.onSelection(e);
}
Expand Down

0 comments on commit 7ec046b

Please sign in to comment.