如何使用 ACE 编辑器突出显示代码?
Posted
技术标签:
【中文标题】如何使用 ACE 编辑器突出显示代码?【英文标题】:How can I highlight code with ACE editor? 【发布时间】:2012-02-08 13:54:00 【问题描述】:我想用语法高亮显示十几个小的 sn-ps 代码,然后通过单击它们使它们可使用 ACE Editor 进行编辑,因为我认为这比为每个代码设置完整的编辑器要快得多。我看到有一个simple command for setting up an ACE editor:
<div id="editor">some text</div>
<script src="src/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function()
var editor = ace.edit("editor");
;
</script>
有没有一种简单的方法来调用 API 以仅突出显示文本而不设置编辑器?理想的 API 会接收一些文本并返回带有可用于突出显示的标签的 html。我知道有专门的 JavaScript 突出显示库,但我想尝试对正在显示的文本和正在编辑的文本使用相同的荧光笔。
【问题讨论】:
Ace Editor 具有只读模式,基本上只显示编辑器,但您仍然会得到完整编辑器的开销。不过,速度并不是一个大问题——更多的是编辑器的大小。我用它在一些网站上进行编辑和显示,效果很好。 @RickStrahl 我很高兴知道如何设置只读模式。因为我能找到的最接近的例子是static_highlight
,但它使用了 kitchensink 框架。我会更喜欢像editor.mode = readonly
这样的单行。
【参考方案1】:
突出显示单词:
var range = new Range(rowStart, columnStart, rowEnd, columnEnd);
var marker = editor.getSession().addMarker(range,"ace_selected_word", "text");
删除突出显示的单词:
editor.getSession().removeMarker(marker);
突出显示该行:
editor.getSession().addMarker(range,"ace_active_line","background");
【讨论】:
【参考方案2】:首先,您要将行号声明为全局变量。
var erroneousLine;
这是 highlightError 函数,它以行号 (lineNumber
) 作为其参数。这可以从错误消息或使用editor.selection.getCursor().row
获取当前行或其他内容触发。
function highlightError(lineNumber)
unhighlightError();
var Range = ace.require("ace/range").Range
erroneousLine = editor.session.addMarker(new Range(lineNumber, 0, lineNumber, 144), "errorHighlight", "fullLine");
请注意,我已经声明了errorHighlight
,这就是突出显示的方式。在您的 CSS 中放置以下内容:
.errorHighlight
position:absolute;
z-index:20;
background-color:#F4B9B7;
这个函数取消高亮已经高亮的行
function unhighlightError()
editor.getSession().removeMarker(erroneousLine);
【讨论】:
【参考方案3】:有一个服务器端版本的荧光笔(在 node.js 中运行)available,很可能很容易移植到基于 Web 的 javascript。
【讨论】:
【参考方案4】:一个想法:
function highlightSyntax(text)
var res = [];
var Tokenizer = ace.require('ace/tokenizer').Tokenizer;
var Rules = ace.require('ace/mode/sql_highlight_rules').SqlHighlightRules;
var Text = ace.require('ace/layer/text').Text;
var tok = new Tokenizer(new Rules().getRules());
var lines = text.split('\n');
lines.forEach(function(line)
var renderedTokens = [];
var tokens = tok.getLineTokens(line);
if (tokens && tokens.tokens.length)
new Text(document.createElement('div')).$renderSimpleLine(renderedTokens, tokens.tokens);
res.push('<div class="ace_line">' + renderedTokens.join('') + '</div>');
);
return '<div class="ace_editor ace-tomorrow"><div class="ace_layer" style="position: static;">' + res.join('') + '</div></div>';
此函数应在给定文本中突出显示 SQL 语法(ace-tomorrow 主题),而无需加载整个编辑器,也无需装订线。
【讨论】:
从 1.4.8 版开始仍然有效,但只需更改您要添加子元素的 HTML 元素的renderedTokens
数组。
看起来很有希望,但在最新版本的 Ace 中,我得到了 Uncaught TypeError: e.appendChild is not a function
【参考方案5】:
我认为这已经很晚了,但我仍然会写,以防它可以帮助别人。
我最终在 typescript 中创建了一个简单的函数,它可以找到要突出显示的范围的坐标并滚动到它:
highlighText(text: string)
const value = this.aceEditor.session.getValue();
const startRow = value.substr(0, value.indexOf(text)).split(/\r\n|\r|\n/).length - 1;
const startCol = this.aceEditor.session.getLine(startRow).indexOf(text);
const endRowOffset = text.split(/\r\n|\r|\n/).length;
const endRow = startRow + endRowOffset - 1;
const endCollOffset = text.split(/\r\n|\r|\n/)[endRowOffset - 1].length;
const endCol = startCol + (endCollOffset > 1 ? endCollOffset + 1 : endCollOffset);
const range = new ace.Range(startRow, startCol, endRow, endCol);
this.aceEditor.session.selection.setRange(range);
this.aceEditor.scrollToLine(startRow, true, true, () => );
【讨论】:
以上是关于如何使用 ACE 编辑器突出显示代码?的主要内容,如果未能解决你的问题,请参考以下文章