Skip to content

Commit

Permalink
feat: Added Editor API to set the ghost text (#5036)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewnester committed Jan 24, 2023
1 parent ab4f788 commit 958d573
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ace.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,8 @@ export namespace Ace {
showComposition(position: number): void;
setCompositionText(text: string): void;
hideComposition(): void;
setGhostText(text: string, position: Point): void;
removeGhostText(): void;
setTheme(theme: string, callback?: () => void): void;
getTheme(): string;
setStyle(style: string, include?: boolean): void;
Expand Down Expand Up @@ -843,6 +845,8 @@ export namespace Ace {
removeWordLeft(): void;
removeLineToEnd(): void;
splitLine(): void;
setGhostText(text: string, position: Point): void;
removeGhostText(): void;
transposeLetters(): void;
toLowerCase(): void;
toUpperCase(): void;
Expand Down
5 changes: 5 additions & 0 deletions src/css/editor.css.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,4 +583,9 @@ styles.join("\\n")
white-space: pre;
opacity: 0.7;
margin: 0 10px;
}
.ace_ghost_text {
opacity: 0.5;
font-style: italic;
}`;
26 changes: 26 additions & 0 deletions src/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var CommandManager = require("./commands/command_manager").CommandManager;
var defaultCommands = require("./commands/default_commands").commands;
var config = require("./config");
var TokenIterator = require("./token_iterator").TokenIterator;
var LineWidgets = require("./line_widgets").LineWidgets;

var clipboard = require("./clipboard");

Expand Down Expand Up @@ -1425,6 +1426,31 @@ Editor.$uid = 0;
this.moveCursorToPosition(cursor);
};

/**
* Set the "ghost" text in provided position. "Ghost" text is a kind of
* preview text inside the editor which can be used to preview some code
* inline in the editor such as, for example, code completions.
*
* @param {String} text Text to be inserted as "ghost" text
* @param {object} position Position to insert text to
*/
this.setGhostText = function(text, position) {
if (!this.session.widgetManager) {
this.session.widgetManager = new LineWidgets(this.session);
this.session.widgetManager.attach(this);
}
this.renderer.setGhostText(text, position);
};

/**
* Removes "ghost" text currently displayed in the editor.
*/
this.removeGhostText = function() {
if (!this.session.widgetManager) return;

this.renderer.removeGhostText();
};

/**
* Transposes current line.
**/
Expand Down
7 changes: 7 additions & 0 deletions src/line_widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,15 @@ function LineWidgets(session) {
w.el = dom.createElement("div");
w.el.innerHTML = w.html;
}
if (w.text && !w.el) {
w.el = dom.createElement("div");
w.el.textContent = w.text;
}
if (w.el) {
dom.addCssClass(w.el, "ace_lineWidgetContainer");
if (w.className) {
dom.addCssClass(w.el, w.className);
}
w.el.style.position = "absolute";
w.el.style.zIndex = 5;
renderer.container.appendChild(w.el);
Expand Down
41 changes: 40 additions & 1 deletion src/virtual_renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,46 @@ var VirtualRenderer = function(container, theme) {
this.$composition = null;
this.$cursorLayer.element.style.display = "";
};


this.setGhostText = function(text, position) {
var cursor = this.session.selection.cursor;
var insertPosition = position || { row: cursor.row, column: cursor.column };

this.removeGhostText();

var textLines = text.split("\n");
this.addToken(textLines[0], "ghost_text", insertPosition.row, insertPosition.column);
this.$ghostText = {
text: text,
position: {
row: insertPosition.row,
column: insertPosition. column
}
};
if (textLines.length > 1) {
this.$ghostTextWidget = {
text: textLines.slice(1).join("\n"),
row: insertPosition.row,
column: insertPosition.column,
className: "ace_ghost_text"
};
this.session.widgetManager.addLineWidget(this.$ghostTextWidget);
}

};

this.removeGhostText = function() {
if (!this.$ghostText) return;

var position = this.$ghostText.position;
this.removeExtraToken(position.row, position.column);
if (this.$ghostTextWidget) {
this.session.widgetManager.removeLineWidget(this.$ghostTextWidget);
this.$ghostTextWidget = null;
}
this.$ghostText = null;
};

this.addToken = function(text, type, row, column) {
var session = this.session;
session.bgTokenizer.lines[row] = null;
Expand Down
29 changes: 29 additions & 0 deletions src/virtual_renderer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,35 @@ module.exports = {
];
assertCoordsColor(values, imageData.data);
},
"test ghost text": function() {
editor.session.setValue("abcdef");
editor.setGhostText("Ghost");

editor.renderer.$loop._flush();
assert.equal(editor.renderer.content.textContent, "Ghostabcdef");

editor.setGhostText("Ghost", {row: 0, column: 3});

editor.renderer.$loop._flush();
assert.equal(editor.renderer.content.textContent, "abcGhostdef");

editor.setGhostText("Ghost", {row: 0, column: 6});

editor.renderer.$loop._flush();
assert.equal(editor.renderer.content.textContent, "abcdefGhost");
},

"test multiline ghost text": function() {
editor.session.setValue("abcdef");
editor.renderer.$loop._flush();

editor.setGhostText("Ghost1\nGhost2\nGhost3", {row: 0, column: 6});

editor.renderer.$loop._flush();
assert.equal(editor.renderer.content.textContent, "abcdefGhost1");

assert.equal(editor.session.lineWidgets[0].el.textContent, "Ghost2\nGhost3");
},
"test: brackets highlighting": function (done) {
var renderer = editor.renderer;
editor.session.setValue(
Expand Down

0 comments on commit 958d573

Please sign in to comment.