Ace: Mova os pontos de interrupção à medida que o código muda.

Criado em 6 mar. 2013  ·  4Comentários  ·  Fonte: ajaxorg/ace

Para encurtar a história: seria ótimo se os pontos de interrupção se movessem à medida que o código mudasse.

Em mais detalhes: seria ótimo ter identificadores de linha que persistem para as linhas. Esse recurso parece ser um pouco essencial para a experiência de edição, e os pontos de interrupção e as mensagens de erro devem ser vinculados aos identificadores de linha.

Comentários muito úteis

Encontrei uma solução, mas funciona apenas no meu caso porque permito apenas um ponto de interrupção por vez. Com alguma melhora pode caber também para o caso geral.
Eu usei o ouvinte on change na instância do editor e verifiquei o número de linhas que são modificadas pela ação que disparou o evento. Se forem mais de uma, estamos no caso em que uma ou mais linhas são adicionadas ou removidas. O parâmetro de ação do evento nos ajuda a entender em que caso estamos.
Para ver se tenho que mover o(s) breakpoint(s) verifico se está entre a linha inicial e final da modificação. Se estiver nessa faixa eu tenho que me mover.

O código (escrito rapidamente) é o seguinte:

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 ter ajudado alguém!

Todos 4 comentários

No cloud9, usamos change listener para atualizar pontos de interrupção em uma matriz separada https://github.com/ajaxorg/cloud9/blob/master/plugins-client/ext.debugger/breakpoints.js#L170

Como ace usa array de strings, não tenho certeza de como implementar melhor os identificadores de linha, seja um array completo de objetos mantidos em sincronia com as linhas ou use intervalos semelhantes ao manuseio de linhas de dobra em edit_session. A parte complicada é o manuseio de linhas que estão sendo divididas ou mescladas, pois diferentes tipos de anotações de linha precisam de comportamento diferente.

Acredito que sua solução para pontos de interrupção funcionaria bem para anotações.

A parte complicada é o manuseio de linhas que estão sendo divididas ou mescladas, pois diferentes tipos de anotações de linha precisam de comportamento diferente.

Hmm.. Não consigo inventar um único exemplo. Agradeceria se compartilhasse alguns :)

Encontrei uma solução, mas funciona apenas no meu caso porque permito apenas um ponto de interrupção por vez. Com alguma melhora pode caber também para o caso geral.
Eu usei o ouvinte on change na instância do editor e verifiquei o número de linhas que são modificadas pela ação que disparou o evento. Se forem mais de uma, estamos no caso em que uma ou mais linhas são adicionadas ou removidas. O parâmetro de ação do evento nos ajuda a entender em que caso estamos.
Para ver se tenho que mover o(s) breakpoint(s) verifico se está entre a linha inicial e final da modificação. Se estiver nessa faixa eu tenho que me mover.

O código (escrito rapidamente) é o seguinte:

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 ter ajudado alguém!

Modifiquei a solução de alessandrocaprarelli acima para funcionar em vários pontos de interrupção, pode ser útil para outros:

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);
        }
    }
})
Esta página foi útil?
0 / 5 - 0 avaliações