<commit_before>module('lively.ide.WindowNavigation').requires('lively.morphic.Widgets', 'lively.morphic.Events', 'lively.ide.tools.SelectionNarrowing').toRun(function() {

Object.subclass('lively.ide.WindowNavigation.WindowManager',
'initialzing', {
    initialize: function(containerMorph) {
        this.root = containerMorph;
    }
},
'accessing', {
    getWindows: function() {
        return this.root.submorphs.select(function(ea) { return ea.isWindow; });
    },
    findWindow: function(func) { return this.getWindows().detect(func); },
    makeWindowActive: function(win) {
        win && win.comeForward();
    },
    showWindow: function(win) {
        if (!win) return;
        if (this.showWindowCaller && this.showWindowTarget === win) return;
        if (this.showWindowCaller) { Global.clearInterval(this.showWindowCaller); delete this.showWindowCaller; }
        this.showWindowTarget = win;
        var self = this;
        this.showWindowCaller = (function() {
            if (this.showWindowTarget) this.showWindowTarget.show();
        }).bind(this).delay(0.8);
    },

    resetList: function(windowLister) {
        this.showWindowTarget = null;
        if (this.showWindowCaller) { Global.clearInterval(this.showWindowCaller); delete this.showWindowCaller; }
        windowLister.deactivate();
    },
    resetListAndRevertActiveWindow: function(windowLister) {
        if (this.currentWindow) this.currentWindow.comeForward();
        this.resetList(windowLister);
    }
},
'morphic switcher', {
    startWindowSelection: function() {
        var winMgr = this,
            windows = this.getWindows().reverse(),
            topMostWin = windows[0],
            firstIsActive = lively.morphic.Morph.focusedMorph().ownerChain().include(topMostWin);
        lively.ide.tools.SelectionNarrowing.getNarrower({
            name: 'lively.ide.WindowNavigation.NarrowingList',
            setup: function(narrower) {
                lively.bindings.connect(narrower, 'confirmedSelection', winMgr, 'makeWindowActive');
                lively.bindings.connect(narrower, 'selection', winMgr, 'showWindow');
                lively.bindings.connect(narrower, 'confirmedSelection', winMgr, 'resetList', {converter: function() { return this.sourceObj; }});
                lively.bindings.connect(narrower, 'escapePressed', winMgr, 'resetListAndRevertActiveWindow');
            },
            spec: {
                prompt: "select window: ",
                preselect: firstIsActive ? 1 : 0,
                maxItems: 20,
                candidates: windows.map(function(ea, i) {
                    return {isListItem: true, string: (i+1) + ' - ' + ea.getTitle(), value: ea}; })
            }
        })
        return this;
    }

});
<commit_msg>ide: window switcher allows closing windows with alt-2<commit_after>module('lively.ide.WindowNavigation').requires('lively.morphic.Widgets', 'lively.morphic.Events', 'lively.ide.tools.SelectionNarrowing').toRun(function() {

Object.subclass('lively.ide.WindowNavigation.WindowManager',
'initialzing', {
    initialize: function(containerMorph) {
        this.root = containerMorph;
    }
},
'accessing', {
    getWindows: function() {
        return this.root.submorphs.select(function(ea) { return ea.isWindow; });
    },
    findWindow: function(func) { return this.getWindows().detect(func); },
    makeWindowActive: function(win) {
        win && win.comeForward();
    },
    showWindow: function(win) {
        if (!win) return;
        if (this.showWindowCaller && this.showWindowTarget === win) return;
        if (this.showWindowCaller) { Global.clearInterval(this.showWindowCaller); delete this.showWindowCaller; }
        this.showWindowTarget = win;
        var self = this;
        this.showWindowCaller = (function() {
            if (this.showWindowTarget) this.showWindowTarget.show();
        }).bind(this).delay(0.8);
    },

    resetList: function(windowLister) {
        this.showWindowTarget = null;
        if (this.showWindowCaller) { Global.clearInterval(this.showWindowCaller); delete this.showWindowCaller; }
        windowLister.deactivate();
    },
    resetListAndRevertActiveWindow: function(windowLister) {
        if (this.currentWindow) this.currentWindow.comeForward();
        this.resetList(windowLister);
    }
},
'morphic switcher', {
    startWindowSelection: function() {
        var winMgr = this, windows = this.getWindows().reverse(), topMostWin = windows[0],
            firstIsActive = lively.morphic.Morph.focusedMorph().ownerChain().include(topMostWin);
        function windowList() {
            return winMgr.getWindows().reverse().map(function(ea, i) {
                return {isListItem: true, string: (i+1) + ' - ' + ea.getTitle(), value: ea}; })
        }
        var narrower = lively.ide.tools.SelectionNarrowing.getNarrower({
            name: 'lively.ide.WindowNavigation.NarrowingList',
            setup: function(narrower) {
                lively.bindings.connect(narrower, 'selection', winMgr, 'showWindow');
                lively.bindings.connect(narrower, 'escapePressed', winMgr, 'resetListAndRevertActiveWindow');
            },
            spec: {
                prompt: "select window: ",
                preselect: firstIsActive ? 1 : 0,
                maxItems: 20,
                candidates: windowList(),
                actions: [
                    {name: 'come forward', exec: function(candidate) { winMgr.makeWindowActive(candidate); winMgr.resetList(narrower); }},
                    {name: 'close', exec: function(candidate) { candidate.initiateShutdown(); narrower.state.allCandidates = windowList(); narrower.filter(narrower.getInput()); }}]
            }
        });
        return this;
    }

});

{'fraction_non_alphanumeric': 0.13356521739130434, 'fraction_numerical': 0.002956521739130435, 'mean_word_length': 2.798546895640687, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1767614', 'n_tokens_mistral': 1699, 'n_tokens_neox': 1659, 'n_words': 271}