Projekt

Obecné

Profil

Stáhnout (8.74 KB) Statistiky
| Větev: | Tag: | Revize:
1
ace.define("ace/ext/elastic_tabstops_lite",["require","exports","module","ace/editor","ace/config"], function(require, exports, module) {
2
"use strict";
3

    
4
var ElasticTabstopsLite = function(editor) {
5
    this.$editor = editor;
6
    var self = this;
7
    var changedRows = [];
8
    var recordChanges = false;
9
    this.onAfterExec = function() {
10
        recordChanges = false;
11
        self.processRows(changedRows);
12
        changedRows = [];
13
    };
14
    this.onExec = function() {
15
        recordChanges = true;
16
    };
17
    this.onChange = function(delta) {
18
        if (recordChanges) {
19
            if (changedRows.indexOf(delta.start.row) == -1)
20
                changedRows.push(delta.start.row);
21
            if (delta.end.row != delta.start.row)
22
                changedRows.push(delta.end.row);
23
        }
24
    };
25
};
26

    
27
(function() {
28
    this.processRows = function(rows) {
29
        this.$inChange = true;
30
        var checkedRows = [];
31

    
32
        for (var r = 0, rowCount = rows.length; r < rowCount; r++) {
33
            var row = rows[r];
34

    
35
            if (checkedRows.indexOf(row) > -1)
36
                continue;
37

    
38
            var cellWidthObj = this.$findCellWidthsForBlock(row);
39
            var cellWidths = this.$setBlockCellWidthsToMax(cellWidthObj.cellWidths);
40
            var rowIndex = cellWidthObj.firstRow;
41

    
42
            for (var w = 0, l = cellWidths.length; w < l; w++) {
43
                var widths = cellWidths[w];
44
                checkedRows.push(rowIndex);
45
                this.$adjustRow(rowIndex, widths);
46
                rowIndex++;
47
            }
48
        }
49
        this.$inChange = false;
50
    };
51

    
52
    this.$findCellWidthsForBlock = function(row) {
53
        var cellWidths = [], widths;
54
        var rowIter = row;
55
        while (rowIter >= 0) {
56
            widths = this.$cellWidthsForRow(rowIter);
57
            if (widths.length == 0)
58
                break;
59

    
60
            cellWidths.unshift(widths);
61
            rowIter--;
62
        }
63
        var firstRow = rowIter + 1;
64
        rowIter = row;
65
        var numRows = this.$editor.session.getLength();
66

    
67
        while (rowIter < numRows - 1) {
68
            rowIter++;
69

    
70
            widths = this.$cellWidthsForRow(rowIter);
71
            if (widths.length == 0)
72
                break;
73

    
74
            cellWidths.push(widths);
75
        }
76

    
77
        return { cellWidths: cellWidths, firstRow: firstRow };
78
    };
79

    
80
    this.$cellWidthsForRow = function(row) {
81
        var selectionColumns = this.$selectionColumnsForRow(row);
82

    
83
        var tabs = [-1].concat(this.$tabsForRow(row));
84
        var widths = tabs.map(function(el) { return 0; } ).slice(1);
85
        var line = this.$editor.session.getLine(row);
86

    
87
        for (var i = 0, len = tabs.length - 1; i < len; i++) {
88
            var leftEdge = tabs[i]+1;
89
            var rightEdge = tabs[i+1];
90

    
91
            var rightmostSelection = this.$rightmostSelectionInCell(selectionColumns, rightEdge);
92
            var cell = line.substring(leftEdge, rightEdge);
93
            widths[i] = Math.max(cell.replace(/\s+$/g,'').length, rightmostSelection - leftEdge);
94
        }
95

    
96
        return widths;
97
    };
98

    
99
    this.$selectionColumnsForRow = function(row) {
100
        var selections = [], cursor = this.$editor.getCursorPosition();
101
        if (this.$editor.session.getSelection().isEmpty()) {
102
            if (row == cursor.row)
103
                selections.push(cursor.column);
104
        }
105

    
106
        return selections;
107
    };
108

    
109
    this.$setBlockCellWidthsToMax = function(cellWidths) {
110
        var startingNewBlock = true, blockStartRow, blockEndRow, maxWidth;
111
        var columnInfo = this.$izip_longest(cellWidths);
112

    
113
        for (var c = 0, l = columnInfo.length; c < l; c++) {
114
            var column = columnInfo[c];
115
            if (!column.push) {
116
                console.error(column);
117
                continue;
118
            }
119
            column.push(NaN);
120

    
121
            for (var r = 0, s = column.length; r < s; r++) {
122
                var width = column[r];
123
                if (startingNewBlock) {
124
                    blockStartRow = r;
125
                    maxWidth = 0;
126
                    startingNewBlock = false;
127
                }
128
                if (isNaN(width)) {
129
                    blockEndRow = r;
130

    
131
                    for (var j = blockStartRow; j < blockEndRow; j++) {
132
                        cellWidths[j][c] = maxWidth;
133
                    }
134
                    startingNewBlock = true;
135
                }
136

    
137
                maxWidth = Math.max(maxWidth, width);
138
            }
139
        }
140

    
141
        return cellWidths;
142
    };
143

    
144
    this.$rightmostSelectionInCell = function(selectionColumns, cellRightEdge) {
145
        var rightmost = 0;
146

    
147
        if (selectionColumns.length) {
148
            var lengths = [];
149
            for (var s = 0, length = selectionColumns.length; s < length; s++) {
150
                if (selectionColumns[s] <= cellRightEdge)
151
                    lengths.push(s);
152
                else
153
                    lengths.push(0);
154
            }
155
            rightmost = Math.max.apply(Math, lengths);
156
        }
157

    
158
        return rightmost;
159
    };
160

    
161
    this.$tabsForRow = function(row) {
162
        var rowTabs = [], line = this.$editor.session.getLine(row),
163
            re = /\t/g, match;
164

    
165
        while ((match = re.exec(line)) != null) {
166
            rowTabs.push(match.index);
167
        }
168

    
169
        return rowTabs;
170
    };
171

    
172
    this.$adjustRow = function(row, widths) {
173
        var rowTabs = this.$tabsForRow(row);
174

    
175
        if (rowTabs.length == 0)
176
            return;
177

    
178
        var bias = 0, location = -1;
179
        var expandedSet = this.$izip(widths, rowTabs);
180

    
181
        for (var i = 0, l = expandedSet.length; i < l; i++) {
182
            var w = expandedSet[i][0], it = expandedSet[i][1];
183
            location += 1 + w;
184
            it += bias;
185
            var difference = location - it;
186

    
187
            if (difference == 0)
188
                continue;
189

    
190
            var partialLine = this.$editor.session.getLine(row).substr(0, it );
191
            var strippedPartialLine = partialLine.replace(/\s*$/g, "");
192
            var ispaces = partialLine.length - strippedPartialLine.length;
193

    
194
            if (difference > 0) {
195
                this.$editor.session.getDocument().insertInLine({row: row, column: it + 1}, Array(difference + 1).join(" ") + "\t");
196
                this.$editor.session.getDocument().removeInLine(row, it, it + 1);
197

    
198
                bias += difference;
199
            }
200

    
201
            if (difference < 0 && ispaces >= -difference) {
202
                this.$editor.session.getDocument().removeInLine(row, it + difference, it);
203
                bias += difference;
204
            }
205
        }
206
    };
207
    this.$izip_longest = function(iterables) {
208
        if (!iterables[0])
209
            return [];
210
        var longest = iterables[0].length;
211
        var iterablesLength = iterables.length;
212

    
213
        for (var i = 1; i < iterablesLength; i++) {
214
            var iLength = iterables[i].length;
215
            if (iLength > longest)
216
                longest = iLength;
217
        }
218

    
219
        var expandedSet = [];
220

    
221
        for (var l = 0; l < longest; l++) {
222
            var set = [];
223
            for (var i = 0; i < iterablesLength; i++) {
224
                if (iterables[i][l] === "")
225
                    set.push(NaN);
226
                else
227
                    set.push(iterables[i][l]);
228
            }
229

    
230
            expandedSet.push(set);
231
        }
232

    
233

    
234
        return expandedSet;
235
    };
236
    this.$izip = function(widths, tabs) {
237
        var size = widths.length >= tabs.length ? tabs.length : widths.length;
238

    
239
        var expandedSet = [];
240
        for (var i = 0; i < size; i++) {
241
            var set = [ widths[i], tabs[i] ];
242
            expandedSet.push(set);
243
        }
244
        return expandedSet;
245
    };
246

    
247
}).call(ElasticTabstopsLite.prototype);
248

    
249
exports.ElasticTabstopsLite = ElasticTabstopsLite;
250

    
251
var Editor = require("../editor").Editor;
252
require("../config").defineOptions(Editor.prototype, "editor", {
253
    useElasticTabstops: {
254
        set: function(val) {
255
            if (val) {
256
                if (!this.elasticTabstops)
257
                    this.elasticTabstops = new ElasticTabstopsLite(this);
258
                this.commands.on("afterExec", this.elasticTabstops.onAfterExec);
259
                this.commands.on("exec", this.elasticTabstops.onExec);
260
                this.on("change", this.elasticTabstops.onChange);
261
            } else if (this.elasticTabstops) {
262
                this.commands.removeListener("afterExec", this.elasticTabstops.onAfterExec);
263
                this.commands.removeListener("exec", this.elasticTabstops.onExec);
264
                this.removeListener("change", this.elasticTabstops.onChange);
265
            }
266
        }
267
    }
268
});
269

    
270
});                (function() {
271
                    ace.require(["ace/ext/elastic_tabstops_lite"], function(m) {
272
                        if (typeof module == "object" && typeof exports == "object" && module) {
273
                            module.exports = m;
274
                        }
275
                    });
276
                })();
277
            
(4-4/244)