Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ajaxorg/ace
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.24.0
Choose a base ref
...
head repository: ajaxorg/ace
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.24.1
Choose a head ref
  • 5 commits
  • 8 files changed
  • 2 contributors

Commits on Aug 9, 2023

  1. Copy the full SHA
    048d404 View commit details

Commits on Aug 10, 2023

  1. Copy the full SHA
    9e5a638 View commit details
  2. remove unused base

    mkslanc committed Aug 10, 2023
    Copy the full SHA
    78d72a9 View commit details

Commits on Aug 14, 2023

  1. Merge pull request #5280 from mkslanc/fix-autocomplete-replace-range

    Fix completions replacement range calculation
    nightwing authored Aug 14, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    29be5f6 View commit details

Commits on Aug 15, 2023

  1. release v1.24.1

    nightwing committed Aug 15, 2023
    Copy the full SHA
    2ab6454 View commit details
Showing with 124 additions and 45 deletions.
  1. +2 −0 CHANGELOG.md
  2. +1 −1 build
  3. +1 −1 package.json
  4. +31 −27 src/autocomplete.js
  5. +81 −7 src/autocomplete_test.js
  6. +1 −1 src/config.js
  7. +7 −3 src/ext/inline_autocomplete.js
  8. +0 −5 src/snippets.js
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [1.24.1](https://github.com/ajaxorg/ace/compare/v1.24.0...v1.24.1) (2023-08-15)

## [1.24.0](https://github.com/ajaxorg/ace/compare/v1.23.4...v1.24.0) (2023-08-09)


2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ace-code",
"description": "Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE",
"version": "1.24.0",
"version": "1.24.1",
"homepage": "http://github.com/ajaxorg/ace",
"engines": {
"node": ">= 0.6.0"
58 changes: 31 additions & 27 deletions src/autocomplete.js
Original file line number Diff line number Diff line change
@@ -324,9 +324,9 @@ class Autocomplete {
this.updateCompletions(false, options);
}

getCompletionProvider() {
getCompletionProvider(initialPosition) {
if (!this.completionProvider)
this.completionProvider = new CompletionProvider();
this.completionProvider = new CompletionProvider(initialPosition);
return this.completionProvider;
}

@@ -370,7 +370,10 @@ class Autocomplete {
this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
this.base.$insertRight = true;
var completionOptions = { exactMatch: this.exactMatch };
this.getCompletionProvider().provideCompletions(this.editor, completionOptions, function(err, completions, finished) {
this.getCompletionProvider({
prefix,
pos
}).provideCompletions(this.editor, completionOptions, function(err, completions, finished) {
var filtered = completions.filtered;
var prefix = util.getCompletionPrefix(this.editor);

@@ -588,8 +591,12 @@ Autocomplete.startCommand = {
* This class is responsible for providing completions and inserting them to the editor
*/
class CompletionProvider {

constructor() {

/**
* @param {{pos: Position, prefix: string}} initialPosition
*/
constructor(initialPosition) {
this.initialPosition = initialPosition;
this.active = true;
}

@@ -611,20 +618,33 @@ class CompletionProvider {
// TODO add support for options.deleteSuffix
if (!this.completions)
return false;
if (this.completions.filterText) {

var replaceBefore = this.completions.filterText.length;
var replaceAfter = 0;
if (data.range && data.range.start.row === data.range.end.row) {
replaceBefore -= this.initialPosition.prefix.length;
replaceBefore += this.initialPosition.pos.column - data.range.start.column;
replaceAfter += data.range.end.column - this.initialPosition.pos.column;
}

if (replaceBefore || replaceAfter) {
var ranges;
if (editor.selection.getAllRanges) {
ranges = editor.selection.getAllRanges();
} else {
}
else {
ranges = [editor.getSelectionRange()];
}
for (var i = 0, range; range = ranges[i]; i++) {
range.start.column -= this.completions.filterText.length;
range.start.column -= replaceBefore;
range.end.column += replaceAfter;
editor.session.remove(range);
}
}
if (data.snippet)
snippetManager.insertSnippet(editor, data.snippet, {range: data.range});

if (data.snippet) {
snippetManager.insertSnippet(editor, data.snippet);
}
else {
this.$insertString(editor, data);
}
@@ -639,23 +659,7 @@ class CompletionProvider {

$insertString(editor, data) {
var text = data.value || data;
if (data.range) {
if (editor.inVirtualSelectionMode) {
return editor.session.replace(data.range, text);
}
editor.forEachSelection(() => {
var range = editor.getSelectionRange();
if (data.range.compareRange(range) === 0) {
editor.session.replace(data.range, text);
}
else {
editor.insert(text);
}
}, null, {keepOrder: true});
}
else {
editor.execCommand("insertstring", text);
}
editor.execCommand("insertstring", text);
}

gatherCompletions(editor, callback) {
88 changes: 81 additions & 7 deletions src/autocomplete_test.js
Original file line number Diff line number Diff line change
@@ -32,6 +32,13 @@ function initEditor(value) {
return editor;
}

function afterRenderCheck(popup, callback) {
popup.renderer.on("afterRender", function wait() {
popup.renderer.off("afterRender", wait);
callback();
});
}

module.exports = {
tearDown: function() {
if (editor) {
@@ -95,7 +102,7 @@ module.exports = {
snippet: "will: $1",
meta: "snippet",
command: "startAutocomplete",
range: new Range(0, 4, 0, 6)
range: new Range(0, 4, 0, 7)
}, {
caption: "here",
value: "-here",
@@ -110,28 +117,93 @@ module.exports = {
editor.moveCursorTo(0, 6);
sendKey("w");
var popup = editor.completer.popup;
check(function () {
afterRenderCheck(popup, function () {
assert.equal(popup.data.length, 1);
editor.onCommandKey(null, 0, 13);
assert.equal(popup.data.length, 2);
assert.equal(editor.getValue(), "goodwill: ");
check(function () {
afterRenderCheck(popup, function () {
editor.onCommandKey(null, 0, 13);
assert.equal(editor.getValue(), "goodwill-here");
editor.destroy();
editor.container.remove();
done();
});
});
},
"test: correct completion replacement range when completion prefix has more than one letter": function (done) {
var editor = initEditor("<");

editor.completers = [
{
getCompletions: function (editor, session, pos, prefix, callback) {
var completions = [
{
caption: "div",
value: "div",
range: new Range(0, 1, 0, 3)
}, {
caption: "dialog",
value: "dialog",
range: new Range(0, 1, 0, 3)
}
];
callback(null, completions);
}
}
];

editor.moveCursorTo(0, 1);
sendKey("di");
var popup = editor.completer.popup;
check(function () {
assert.equal(popup.data.length, 2);
editor.onCommandKey(null, 0, 13);
check(function () {
assert.equal(editor.getValue(), "<dialog");
editor.destroy();
editor.container.remove();
done();
});
});

function check(callback) {
popup = editor.completer.popup;
popup.renderer.on("afterRender", function wait() {
popup.renderer.off("afterRender", wait);
setTimeout(function wait() {
callback();
});
}, 10);
}
},
"test: symbols after selection are not removed when replacement range is present": function (done) {
var editor = initEditor("{}");
editor.completers = [
{
getCompletions: function (editor, session, pos, prefix, callback) {
var completions = [
{
caption: "apple",
snippet: "apple: $1",
meta: "snippet",
range: new Range(0, 1, 0, 2)
}, {
caption: "pineapple",
value: "pineapple",
range: new Range(0, 1, 0, 2)
}
];
callback(null, completions);
}
}
];
editor.moveCursorTo(0, 1);
sendKey("a");
var popup = editor.completer.popup;
afterRenderCheck(popup, function () {
assert.equal(popup.data.length, 2);
editor.onCommandKey(null, 0, 13);
assert.equal(editor.getValue(), "{apple: }");
done();
});
},
"test: different completers tooltips": function (done) {
var editor = initEditor("");
var firstDoc = "<b>First</b>";
@@ -183,6 +255,8 @@ module.exports = {
id: "secondCompleter"
}
];



sendKey("c");
var popup = editor.completer.popup;
2 changes: 1 addition & 1 deletion src/config.js
Original file line number Diff line number Diff line change
@@ -168,6 +168,6 @@ var reportErrorIfPathIsNotConfigured = function() {
}
};

exports.version = "1.24.0";
exports.version = "1.24.1";


10 changes: 7 additions & 3 deletions src/ext/inline_autocomplete.js
Original file line number Diff line number Diff line change
@@ -165,9 +165,9 @@ class InlineAutocomplete {
}
}

getCompletionProvider() {
getCompletionProvider(initialPosition) {
if (!this.completionProvider)
this.completionProvider = new CompletionProvider();
this.completionProvider = new CompletionProvider(initialPosition);
return this.completionProvider;
}

@@ -219,7 +219,11 @@ class InlineAutocomplete {
exactMatch: true,
ignoreCaption: true
};
this.getCompletionProvider().provideCompletions(this.editor, options, function(err, completions, finished) {
this.getCompletionProvider({
prefix,
base: this.base,
pos
}).provideCompletions(this.editor, options, function(err, completions, finished) {
var filtered = completions.filtered;
var prefix = util.getCompletionPrefix(this.editor);

5 changes: 0 additions & 5 deletions src/snippets.js
Original file line number Diff line number Diff line change
@@ -356,9 +356,6 @@ class SnippetManager {
var processedSnippet = processSnippetText.call(this, editor, snippetText, options);

var range = editor.getSelectionRange();
if (options.range && options.range.compareRange(range) === 0) {
range = options.range;
}
var end = editor.session.replace(range, processedSnippet.text);

var tabstopManager = new TabstopManager(editor);
@@ -368,8 +365,6 @@ class SnippetManager {

insertSnippet(editor, snippetText, options={}) {
var self = this;
if (options.range && !(options.range instanceof Range))
options.range = Range.fromPoints(options.range.start, options.range.end);

if (editor.inVirtualSelectionMode)
return self.insertSnippetForSelection(editor, snippetText, options);