ajaxorg / ajaxorg/ace

Range: addDynamicMarker or drawSingleLineMarker is offset incorrectly when using tabs

未關閉
#5,893 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
bug effort/medium p2
主要語言
JavaScript
星號
27.1k
分支
5.3k
PR 合併指標
30 天內沒有已合併 PR

描述

### Describe the bug

Have had no problem when using `addMarker` to select a range for highlighting code. Just switched to `addDynamicMarker` with `drawSingleLineMarker` in order to add some custom CSS coloring per highlight, when I discovered that any code which has tabs `\t` is offset by 3 characters (4 spaces - 1 for the tab char). I'm guessing this is a bug, as `addMarker` correctly identifies the position regardless of tabs or spaces, however `addDynamicMarker` with `drawSingleLineMarker` only fails with (hard) tabs. Switching to 'useSoftTabs:true' fixes the issue, but only for newly created tabs whereas the problem remains for any code written using a literal `\t`.

*** Edit: see possible solution below for temp fix...

### Expected Behavior

Correctly add a marker over the given range as `addMarker` does.

### Current Behavior

Is 3 characters offset to the left.

### Reproduction Steps

Here's a small example that demonstrates the issue:

```html


ace-dynamic-marker


#editor{
height:50vh;
font-size:12pt;
}
.marker{
position:fixed;
outline:2px solid #fff;
}

// 'addMarker' works correctly with tabs, 'addDynamicMarker' is 3 char off
if(1 == 1){
console.log('true')
}



addMarker
addDynamicMarker


let Range = ace.require('ace/range').Range;
var editor = ace.edit('editor');
editor.setTheme('ace/theme/gob');
editor.session.setMode('ace/mode/javascript');

editor.setOptions({
showPrintMargin: false,
animatedScroll: true,
displayIndentGuides: false,
useWorker: true,
showLineNumbers: false,
showGutter: false,
scrollPastEnd:1,
tabSize: 4, useSoftTabs: false,
showInvisibles:true
});

let markers = []
var stringBuilder = [];
function marker(markerType){
removeMarkers()
let hl = editor.find("true")
// console.log(hl)

let range = new Range(hl.start.row, hl.start.column, hl.end.row, hl.end.column)

if(markerType == 0){
markers.push({id:editor.session.addMarker(range, "marker", "line")})
}else{
range = range.toScreenRange(editor.session) // *** fixes tab issue!!!
markers.push(editor.session.addDynamicMarker({ update: (html, markerLayer, session, config)=>{
var extraStyle = `position:fixed;outline:2px solid magenta;`;
markerLayer.drawSingleLineMarker(html, range, "", config, 0, extraStyle);
} }, true))
}
}

function removeMarkers(){
for(let i=0; i < markers.length; i++){
editor.session.removeMarker(markers[i].id);
}
markers = [];
}

```

### Possible Solution

*** Edit: just discovered that if I use `range = range.toScreenRange(editor.session)` for the example using `addDynamicMarker`, then it's correct!! I wonder if it should be necessary to add this manually, or if the function should have this built into it?

### Additional Information/Context

As an alternative, is there a way to give custom css to an `addMarker()` call? I'm guessing not, since it doesn't have the param for `extraStyle`, however it would be great if one could also pass along custom CSS like the others.

### Ace Version / Browser / OS / Keyboard layout

1.43.4 / Google Chrome / MacOS / English US

貢獻指南

開啟貢獻指南

評估

這個 Issue 還沒有評估資料。

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。