Ace: Mueva los puntos de interrupción a medida que cambia el código.

Creado en 6 mar. 2013  ·  4Comentarios  ·  Fuente: ajaxorg/ace

Para resumir: sería genial si los puntos de interrupción se movieran a medida que cambia el código.

En más detalles: sería genial tener identificadores de línea que persistan para las líneas. Esta característica parece ser algo central para la experiencia de edición, y tanto los puntos de interrupción como los mensajes de error deben estar vinculados a los identificadores de línea.

Comentario más útil

Encontré una solución, pero solo funciona en mi caso porque solo permito un punto de interrupción a la vez. Con alguna mejora puede caber también para el caso general.
Utilicé el detector de cambios en la instancia del editor y verifiqué la cantidad de líneas modificadas por la acción que activó el evento. Si son más de uno estamos en el caso de que se añadan o eliminen uno o más renglones. El parámetro de acción del evento nos ayuda a entender en qué caso nos encontramos.
Para ver si tengo que mover los puntos de interrupción, verifico si está entre la fila inicial y final de la modificación. Si está en este rango, tengo que moverme.

El código (escrito rápidamente) es el siguiente:

aceEditor.on("change", function (e) {
                var breakpointsArray = aceEditor.session.getBreakpoints();
                if(Object.keys(aceEditor.session.getBreakpoints()).length>0){
                    if(e.lines.length>1){
                        var breakpoint = parseInt(Object.keys(breakpointsArray)[0]);
                        var lines = e.lines.length -1;
                        var start = e.start.row;
                        var end = e.end.row;
                        if(e.action==='insert'){
                            console.log('new lines',breakpoint, start , end );
                            if(breakpoint>start ){
                                console.log('breakpoint forward');
                                aceEditor.session.clearBreakpoint(breakpoint);
                                aceEditor.session.setBreakpoint(breakpoint + lines);
                            }
                        } else if(e.action==='remove'){
                            console.log('removed lines',breakpoint, start , end);
                            if(breakpoint>start && breakpoint<end ){
                                console.log('breakpoint remove');
                                aceEditor.session.clearBreakpoint(breakpoint);
                            }
                            if(breakpoint>=end ){
                                console.log('breakpoint behind');
                                aceEditor.session.clearBreakpoint(breakpoint);
                                aceEditor.session.setBreakpoint(breakpoint - lines);
                            }
                        }
                    }
                }
            });

¡Espero haber ayudado a alguien!

Todos 4 comentarios

En cloud9 usamos change listener para actualizar los puntos de interrupción en una matriz separada https://github.com/ajaxorg/cloud9/blob/master/plugins-client/ext.debugger/breakpoints.js#L170

Dado que Ace usa una matriz de cadenas, no estoy seguro de cómo implementar mejor los identificadores de línea, ya sea una matriz completa de objetos sincronizados con las líneas, o usar rangos similares al manejo de líneas de plegado en edit_session. La parte complicada es el manejo de las líneas que se dividen o fusionan, ya que los diferentes tipos de anotaciones de línea necesitan un comportamiento diferente.

Creo que su solución para los puntos de interrupción funcionaría bien para las anotaciones.

La parte complicada es el manejo de las líneas que se dividen o fusionan, ya que los diferentes tipos de anotaciones de línea necesitan un comportamiento diferente.

Hmm... No puedo inventar un solo ejemplo. Te agradecería que compartieras algunos :)

Encontré una solución, pero solo funciona en mi caso porque solo permito un punto de interrupción a la vez. Con alguna mejora puede caber también para el caso general.
Utilicé el detector de cambios en la instancia del editor y verifiqué la cantidad de líneas modificadas por la acción que activó el evento. Si son más de uno estamos en el caso de que se añadan o eliminen uno o más renglones. El parámetro de acción del evento nos ayuda a entender en qué caso nos encontramos.
Para ver si tengo que mover los puntos de interrupción, verifico si está entre la fila inicial y final de la modificación. Si está en este rango, tengo que moverme.

El código (escrito rápidamente) es el siguiente:

aceEditor.on("change", function (e) {
                var breakpointsArray = aceEditor.session.getBreakpoints();
                if(Object.keys(aceEditor.session.getBreakpoints()).length>0){
                    if(e.lines.length>1){
                        var breakpoint = parseInt(Object.keys(breakpointsArray)[0]);
                        var lines = e.lines.length -1;
                        var start = e.start.row;
                        var end = e.end.row;
                        if(e.action==='insert'){
                            console.log('new lines',breakpoint, start , end );
                            if(breakpoint>start ){
                                console.log('breakpoint forward');
                                aceEditor.session.clearBreakpoint(breakpoint);
                                aceEditor.session.setBreakpoint(breakpoint + lines);
                            }
                        } else if(e.action==='remove'){
                            console.log('removed lines',breakpoint, start , end);
                            if(breakpoint>start && breakpoint<end ){
                                console.log('breakpoint remove');
                                aceEditor.session.clearBreakpoint(breakpoint);
                            }
                            if(breakpoint>=end ){
                                console.log('breakpoint behind');
                                aceEditor.session.clearBreakpoint(breakpoint);
                                aceEditor.session.setBreakpoint(breakpoint - lines);
                            }
                        }
                    }
                }
            });

¡Espero haber ayudado a alguien!

Modifiqué la solución anterior de alessandrocaprarelli para que funcione en múltiples puntos de interrupción, puede ser útil para otros:

editor.on("change", function (e) {
    if (e.lines.length > 1 && (e.action==='insert' || e.action==='remove')){
        const breakpointsArrayOld = editor.session.getBreakpoints();
        let breakpointsArrayNew = [];

        const amountOfLinesAffected = e.lines.length - 1;
        const startRow = e.start.row;
        const endRow = e.end.row;

        for (const key of Object.keys(breakpointsArrayOld)) {
            let breakpointRow = parseInt(key)

            if (e.action==='insert') {  // new lines
                if (breakpointRow > startRow ){
                    // breakpoint forward
                    breakpointsArrayNew[breakpointRow + amountOfLinesAffected] = "ace_breakpoint"
                }
                else {
                    // unaffected by insert
                    breakpointsArrayNew[breakpointRow] = "ace_breakpoint"
                }
            }
            else if (e.action==='remove') {  // removed lines
                if (breakpointRow > startRow && breakpointRow <= endRow ){
                    // breakpoint removed
                }
                else if (breakpointRow >= endRow ){
                    // breakpoint behind
                    breakpointsArrayNew[breakpointRow - amountOfLinesAffected] = "ace_breakpoint"
                }
                else {
                    // unaffected by remove
                    breakpointsArrayNew[breakpointRow] = "ace_breakpoint"
                }
            }
        }

        // remove all old breakpoints
        for (const key of Object.keys(breakpointsArrayOld)) {
            let breakpointRow = parseInt(key)
            editor.session.clearBreakpoint(breakpointRow);
        }

        // add all new breakpoints
        for (const key of Object.keys(breakpointsArrayNew)) {
            let breakpointRow = parseInt(key)
            editor.session.setBreakpoint(breakpointRow);
        }
    }
})
¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

velara3 picture velara3  ·  5Comentarios

xfix picture xfix  ·  5Comentarios

ketysek picture ketysek  ·  3Comentarios

akosyakov picture akosyakov  ·  3Comentarios

dimroc picture dimroc  ·  6Comentarios