ajaxorg / ajaxorg/ace

Range: addDynamicMarker or drawSingleLineMarker is offset incorrectly when using tabs

Abierto
#5,893 1 comentario 0 reacciones 0 asignados Ver en GitHub
bug effort/medium p2
Lenguaje dominante
JavaScript
Estrellas
27.1k
Forks
5.3k
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

### 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

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.