Vim "center after search" and "hard line wrap" (overleaf)

173 views
Skip to first unread message

Nick

unread,
Jul 22, 2021, 8:51:17 AM7/22/21
to Ajax.org Cloud9 Editor (Ace)
Hi,

When I perform a search in vim using 

/uniqueexamplekeyword <enter>

I do not automatically move to the location where my cursor so I have to follow each search by

zz

Can this be automated using TamperMonkey somehow? 

Also, when I am editing a long line of text in vim, I use the key combination 

gq <enter>

which hard wraps the line of text (based on :set textwidth=80)

Is there a way I can use TamperMonkey to get this key combination to work?  
When writing latex I use this key combination a lot so that I can navigate through 
the text more efficiently.

Best,
Nick

Harutyun Amirjanyan

unread,
Jul 23, 2021, 5:17:58 PM7/23/21
to ace-d...@googlegroups.com
Hi,
the first issue appears to be a bug, and unfortunately there doesn't seem to be any easy way to intercept it from TamperMonkey, but it will be fixed in the next version

for gq the following can be a good place to start, but the real gq in vim behaves somewhat differently with the way it handles comments and syntax 
let me know if it works for you and if you think we should add it to the ace by default.

vimKeyboard = require("ace/keyboard/vim")

vimKeyboard.handler.defaultKeymap.push({
    keys: 'gq',
    type: 'operator',
    operator: 'hardWrap'
})
vimKeyboard.Vim.defineOperator("hardWrap", function(cm, operatorArgs, ranges, oldAnchor, newHead) {
    var anchor = ranges[0].anchor.line;
    var head = ranges[0].head.line;
    if (anchor < head) {
        hardWrap(cm.ace, anchor, head);
    } else {
        hardWrap(cm.ace, head, anchor);
    }
    return cm.getCursor()
})

var {Range} = require("ace/range")
editor.setOption("printMarginColumn", 40)

function hardWrap(editor, startRow, endRow) {
    var max = editor.getOption("printMarginColumn")
   
    var row = startRow;
    while (row < endRow) {
        // debugger
        var line = editor.session.getLine(row)
        console.log(line, row, endRow, session.getLength())
        if (line.length > max) {
            var space = findSpace(line, max, 5);
            if (space) {
                editor.session.replace(new Range(row,space.start,row,space.end), "\n")
            }
            endRow++
        } else if (/\S/.test(line)) {
            var nextLine = session.getLine(row + 1)
            if (nextLine && /\S/.test(nextLine)) {
                var trimmedLine = line.replace(/\s+$/, "")
                var trimmedNextLine = nextLine.replace(/^\s+/, "")
                var mergedLine = trimmedLine + " " + trimmedNextLine;

                var space = findSpace(mergedLine, max, 5);
                if (space && space.start > trimmedLine.length || mergedLine.length < max) {
                    var replaceRange = new Range(row,trimmedLine.length,row + 1,nextLine.length - trimmedNextLine.length)
                    editor.session.replace(replaceRange, " ")
                    row--
                    endRow--
                }
            }
        }
        row++
    }

    function findSpace(line, max, min) {
        if (line.length < max)
            return;
        var before = line.slice(0, max)
        var after = line.slice(max)
        var spaceAfter = /^(?:(\s+)|(\S+)(\s+))/.exec(after)
        var spaceBefore = /(?:(\s+)|(\s+)(\S+))$/.exec(before)
        var start = 0
        var end = 0
        if (spaceBefore && !spaceBefore[2]) {
            start = max - spaceBefore[1].length
            end = max
        }
        if (spaceAfter && !spaceAfter[2]) {
            if (!start)
                start = max
            end = max + spaceAfter[1].length
        }
        if (start) {
            return {
                start: start,
                end: end
            }
        }
        if (spaceBefore && spaceBefore[2] && spaceBefore.index > min) {
            return {
                start: spaceBefore.index,
                end: spaceBefore.index + spaceAfter[3].length
            }
        }

    }

}




Nicholas Marshall

unread,
Jul 27, 2021, 12:38:47 PM7/27/21
to ace-d...@googlegroups.com
Thank you for the detailed response. 

I had some trouble getting the code you shared to work in Tampermonkey since I am not very familiar with javascript, but I understood the main idea. I think it would be great if some version of gq hardwrapping was added to ace!

Here is the simplified version of your code that I got to work in TamperMonkey in case it helps others

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.overleaf.com/*
// @icon         https://www.google.com/s2/favicons?domain=overleaf.com
// @grant        none
// ==/UserScript==
(function() {
    'use strict';
     var myconfig = false
     let editor = document.querySelector(".ace_editor").env.editor
     //editor.setOption('showGutter', false);
     editor.renderer.on('afterRender', function() {
            if (myconfig == false){
            editor.getSession().setMode("ace/mode/text");
            editor.setTheme('ace/theme/terminal')
            const vimKeyboard = window.ace.require("ace/keyboard/vim")
            vimKeyboard.Vim.map("jj", "<Esc>", "insert")
            editor.setKeyboardHandler(vimKeyboard.handler)

            vimKeyboard.handler.defaultKeymap.push({
                    keys: 'gq',
                    type: 'operator',
                    operator: 'hardWrap'
            })
            vimKeyboard.Vim.defineOperator("hardWrap", function(cm, operatorArgs, ranges, oldAnchor, newHead) {
                //console.log("start hardWrap")

                var anchor = ranges[0].anchor.line;
                var head = ranges[0].head.line;
                hardWrap(editor, anchor, head);
                })
            //console.log("my config was applied")
            myconfig=true
            }
    });
})();

function hardWrap(editor, startRow, endRow) {
    var textwidth = 80
    var targetrow = startRow
    var session = editor.getSession()
    var line = session.getLine(targetrow)
    var N = line.lenth
    var count = 0;
    //console.log(line)
    var newtext = ""
    while (line.length > textwidth){
        var cut = line.slice(0,textwidth).lastIndexOf(" ");
        if (cut==-1){
            break
        }
        newtext = newtext + line.slice(0,cut) + "\n"
        count = count + 1
        line = line.slice(cut+1,line.length)
    }
    newtext = newtext + line

    session.replace(new ace.Range(targetrow, 0, targetrow, N), newtext);
    editor.moveCursorTo(startRow+count+1,0);
}

--
You received this message because you are subscribed to a topic in the Google Groups "Ajax.org Cloud9 Editor (Ace)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ace-discuss/I6jXl4j8h8k/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ace-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ace-discuss/CAB9zvNJgZ78k1JJ-V2%2B7_iSzjrWajtLBzNASaAEUaHh0UV%3DqOg%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages