diff --git a/ace-modes.d.ts b/ace-modes.d.ts index 8a7f1899075..f2da9f47c56 100644 --- a/ace-modes.d.ts +++ b/ace-modes.d.ts @@ -118,6 +118,14 @@ declare module "ace-code/src/mode/autohotkey" { export const Mode: new () => import(".").Ace.SyntaxMode; } +declare module "ace-code/src/mode/basic_highlight_rules" { + export const BasicHighlightRules: new () => import(".").Ace.HighlightRules; +} + +declare module "ace-code/src/mode/basic" { + export const Mode: new () => import(".").Ace.SyntaxMode; +} + declare module "ace-code/src/mode/batchfile_highlight_rules" { export const BatchFileHighlightRules: new () => import(".").Ace.HighlightRules; } @@ -424,6 +432,10 @@ declare module "ace-code/src/mode/folding/asciidoc" { export const FoldMode: new () => import(".").Ace.Folding; } +declare module "ace-code/src/mode/folding/basic" { + export const FoldMode: new () => import(".").Ace.Folding; +} + declare module "ace-code/src/mode/folding/c9search" { export const FoldMode: new () => import(".").Ace.Folding; } diff --git a/demo/kitchen-sink/docs/basic.bas b/demo/kitchen-sink/docs/basic.bas new file mode 100644 index 00000000000..830fc5ea74c --- /dev/null +++ b/demo/kitchen-sink/docs/basic.bas @@ -0,0 +1,43 @@ +120 OPEN"R" #1 "INVEN.DAT",39 +125 FIELD#1,1 AS F$,30 AS D$, 2 AS Q$,2 AS R$,4 AS PH +130 PRINT:PRINT "FUNCTIONS:":PRINT +135 PRINT 1,"INITIALIZE FILE" +140 PRINT 2 "CREATE A NEW ENTRY" +150 PRINT 3,"DISPLAY INVENTORY FOR ONE PART" +160 PRINT 4 "ADD TO STOCK" +170 PRINT 5,"SUBTRACT FROM STOCK" +180 PRINT 6,"DISPLAY ALL ITEMS BELOW REORDER LEVEL" +220 PRINT:PRINT:INPUT"FUNCTION";FUNCTION +225 IF (FUNCTION<1)OR(FUNCTION>6) THEN PRINT "BAD FUNCTION NUMBER":GOTO 130 +230 ON FUNCTION GOSUB 900,250,390,480,560,680 +240 GOTO 220 +560 REM REMOVE FROM STOCK +570 GOSUB 840 +580 IF ASC(F$)=255 THEN PRINT "NULL ENTRY":RETURN +590 PRINT DH +600 INPUT "QUANTITY TO SUBTRACT";S% +610 Q%=CVI(Q$) +620 IF (Q%-S%)<0 THEN PRINT "ONIY";Q%; "IN STOCK":GOTO 600 +630 Q%=Q%-S% +640 IF Q%=100) THEN PRINT "BAD PART NUMBER": GOTO 840 ELSE GET#1 J>ART%:RETURN +END +REM INITIALIZE FILE +INPUT "ARE YOU SURE";B$:IF B$<="Y" THEN RETURN +LSET F$=CHR$(255) +FOR O=1 TO 100 +PUT#1J +NEXT I +RETURN diff --git a/src/ext/modelist.js b/src/ext/modelist.js index 791174fe07d..6a1f0a474f6 100644 --- a/src/ext/modelist.js +++ b/src/ext/modelist.js @@ -68,6 +68,7 @@ var supportedModes = { Astro: ["astro"], AutoHotKey: ["ahk"], BatchFile: ["bat|cmd"], + Basic: ["bas|bak"], BibTeX: ["bib"], C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"], C9Search: ["c9search_results"], diff --git a/src/mode/_test/tokens_basic.json b/src/mode/_test/tokens_basic.json new file mode 100644 index 00000000000..8cbe53e6f47 --- /dev/null +++ b/src/mode/_test/tokens_basic.json @@ -0,0 +1,531 @@ +[[ + "start", + ["constant.numeric","120"], + ["text"," "], + ["entity.name","OPEN"], + ["string","\"R\""], + ["text"," #"], + ["constant.numeric","1"], + ["text"," "], + ["string","\"INVEN.DAT\""], + ["punctiation",","], + ["constant.numeric","39"] +],[ + "start", + ["constant.numeric","125"], + ["text"," "], + ["entity.name","FIELD"], + ["text","#"], + ["constant.numeric","1"], + ["punctiation",","], + ["constant.numeric","1"], + ["text"," "], + ["identifier","AS"], + ["text"," "], + ["identifier","F"], + ["text","$"], + ["punctiation",","], + ["constant.numeric","30"], + ["text"," "], + ["identifier","AS"], + ["text"," "], + ["identifier","D"], + ["text","$"], + ["punctiation",","], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["identifier","AS"], + ["text"," "], + ["identifier","Q"], + ["text","$"], + ["punctiation",","], + ["constant.numeric","2"], + ["text"," "], + ["identifier","AS"], + ["text"," "], + ["identifier","R"], + ["text","$"], + ["punctiation",","], + ["constant.numeric","4"], + ["text"," "], + ["identifier","AS"], + ["text"," "], + ["identifier","PH"] +],[ + "start", + ["constant.numeric","130"], + ["text"," "], + ["entity.name","PRINT"], + ["text",":"], + ["entity.name","PRINT"], + ["text"," "], + ["string","\"FUNCTIONS:\""], + ["text",":"], + ["entity.name","PRINT"] +],[ + "start", + ["constant.numeric","135"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["constant.numeric","1"], + ["punctiation",","], + ["string","\"INITIALIZE FILE\""] +],[ + "start", + ["constant.numeric","140"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["constant.numeric","2"], + ["text"," "], + ["string","\"CREATE A NEW ENTRY\""] +],[ + "start", + ["constant.numeric","150"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["constant.numeric","3"], + ["punctiation",","], + ["string","\"DISPLAY INVENTORY FOR ONE PART\""] +],[ + "start", + ["constant.numeric","160"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["constant.numeric","4"], + ["text"," "], + ["string","\"ADD TO STOCK\""] +],[ + "start", + ["constant.numeric","170"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["constant.numeric","5"], + ["punctiation",","], + ["string","\"SUBTRACT FROM STOCK\""] +],[ + "start", + ["constant.numeric","180"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["constant.numeric","6"], + ["punctiation",","], + ["string","\"DISPLAY ALL ITEMS BELOW REORDER LEVEL\""] +],[ + "start", + ["constant.numeric","220"], + ["text"," "], + ["entity.name","PRINT"], + ["text",":"], + ["entity.name","PRINT"], + ["text",":"], + ["entity.name","INPUT"], + ["string","\"FUNCTION\""], + ["punctiation",";"], + ["identifier","FUNCTION"] +],[ + "start", + ["constant.numeric","225"], + ["text"," "], + ["keyword.control","IF"], + ["text"," "], + ["paren.lparen","("], + ["identifier","FUNCTION"], + ["keyword.operator","<"], + ["constant.numeric","1"], + ["paren.rparen",")"], + ["keyword.operator","OR"], + ["paren.lparen","("], + ["identifier","FUNCTION"], + ["keyword.operator",">"], + ["constant.numeric","6"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["string","\"BAD FUNCTION NUMBER\""], + ["text",":"], + ["keyword.control","GOTO"], + ["text"," "], + ["constant.numeric","130"] +],[ + "start", + ["constant.numeric","230"], + ["text"," "], + ["keyword.control","ON"], + ["text"," "], + ["identifier","FUNCTION"], + ["text"," "], + ["keyword.control","GOSUB"], + ["text"," "], + ["constant.numeric","900"], + ["punctiation",","], + ["constant.numeric","250"], + ["punctiation",","], + ["constant.numeric","390"], + ["punctiation",","], + ["constant.numeric","480"], + ["punctiation",","], + ["constant.numeric","560"], + ["punctiation",","], + ["constant.numeric","680"] +],[ + "start", + ["constant.numeric","240"], + ["text"," "], + ["keyword.control","GOTO"], + ["text"," "], + ["constant.numeric","220"] +],[ + "start", + ["constant.numeric","560"], + ["text"," "], + ["comment","REM REMOVE FROM STOCK"] +],[ + "start", + ["constant.numeric","570"], + ["text"," "], + ["keyword.control","GOSUB"], + ["text"," "], + ["constant.numeric","840"] +],[ + "start", + ["constant.numeric","580"], + ["text"," "], + ["keyword.control","IF"], + ["text"," "], + ["support.function","ASC"], + ["paren.lparen","("], + ["identifier","F"], + ["text","$"], + ["paren.rparen",")"], + ["keyword.operator","="], + ["constant.numeric","255"], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["string","\"NULL ENTRY\""], + ["text",":"], + ["keyword.control","RETURN"] +],[ + "start", + ["constant.numeric","590"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["identifier","DH"] +],[ + "start", + ["constant.numeric","600"], + ["text"," "], + ["entity.name","INPUT"], + ["text"," "], + ["string","\"QUANTITY TO SUBTRACT\""], + ["punctiation",";"], + ["identifier","S"], + ["text","%"] +],[ + "start", + ["constant.numeric","610"], + ["text"," "], + ["variable","Q%"], + ["keyword.operator","="], + ["support.function","CVI"], + ["paren.lparen","("], + ["identifier","Q"], + ["text","$"], + ["paren.rparen",")"] +],[ + "start", + ["constant.numeric","620"], + ["text"," "], + ["keyword.control","IF"], + ["text"," "], + ["paren.lparen","("], + ["identifier","Q"], + ["text","%"], + ["keyword.operator","-"], + ["identifier","S"], + ["text","%"], + ["paren.rparen",")"], + ["keyword.operator","<"], + ["constant.numeric","0"], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["string","\"ONIY\""], + ["punctiation",";"], + ["identifier","Q"], + ["text","%"], + ["punctiation",";"], + ["text"," "], + ["string","\"IN STOCK\""], + ["text",":"], + ["keyword.control","GOTO"], + ["text"," "], + ["constant.numeric","600"] +],[ + "start", + ["constant.numeric","630"], + ["text"," "], + ["variable","Q%"], + ["keyword.operator","="], + ["identifier","Q"], + ["text","%"], + ["keyword.operator","-"], + ["identifier","S"], + ["text","%"] +],[ + "start", + ["constant.numeric","640"], + ["text"," "], + ["keyword.control","IF"], + ["text"," "], + ["variable","Q%"], + ["keyword.operator","=<"], + ["identifier","CVT"], + ["paren.lparen","("], + ["identifier","R"], + ["text","$"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["string","\"QUANTITY NOW\""], + ["punctiation",";"], + ["identifier","Q"], + ["text","%"], + ["punctiation",";"] +],[ + "start", + ["constant.numeric","44"], + ["text"," "], + ["identifier","REORDER"], + ["text"," "], + ["identifier","LEVEL"], + ["text","\""], + ["punctiation",";"], + ["support.function","CVI"], + ["paren.lparen","("], + ["identifier","RH"], + ["paren.rparen",")"] +],[ + "start", + ["entity.name","LSET"], + ["text"," "], + ["variable","Q$"], + ["keyword.operator","="], + ["identifier","MKU"], + ["paren.lparen","("], + ["identifier","Q"], + ["text","%"], + ["paren.rparen",")"] +],[ + "start", + ["entity.name","PUT"], + ["text","#"], + ["constant.numeric","1"], + ["punctiation",","], + ["identifier","PART"], + ["text","%"] +],[ + "start", + ["keyword.control","RETURN"] +],[ + "start", + ["identifier","DISPLAY"], + ["text"," "], + ["identifier","ITEMS"], + ["text"," "], + ["identifier","BELOW"], + ["text"," "], + ["identifier","REORDER"], + ["text"," "], + ["identifier","LEVEL"] +],[ + "start", + ["keyword.control","FOR"], + ["text"," "], + ["constant.numeric","1"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["text"," "], + ["keyword.control","TO"], + ["text"," "], + ["constant.numeric","100"] +],[ + "start", + ["entity.name","GET"], + ["text","#"], + ["constant.numeric","1"], + ["identifier","J"] +],[ + "start", + ["keyword.control","IF"], + ["text"," "], + ["identifier","OVI"], + ["paren.lparen","("], + ["identifier","tzH"], + ["paren.rparen",")"], + ["identifier","OVI"], + ["paren.lparen","("], + ["identifier","RH"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["identifier","Dtz"], + ["punctiation",";"], + ["string","\" QUANTITY\""], + ["punctiation",";"] +],[ + "start", + ["identifier","OVI"], + ["paren.lparen","("], + ["identifier","Qtz"], + ["paren.rparen",")"], + ["text"," "], + ["support.function","TAB"], + ["paren.lparen","("], + ["constant.numeric","50"], + ["paren.rparen",")"], + ["text"," "], + ["string","\"REORDER LEVEL\""], + ["punctiation",";"], + ["support.function","CVI"], + ["paren.lparen","("], + ["identifier","R"], + ["text","$"], + ["paren.rparen",")"] +],[ + "start", + ["keyword.control","NEXT"], + ["text"," "], + ["identifier","I"] +],[ + "start", + ["keyword.control","RETURN"] +],[ + "start", + ["entity.name","INPUT"], + ["text"," "], + ["string","\"PART NUMBER\""], + ["punctiation",";"], + ["identifier","PART"], + ["text","%"] +],[ + "start", + ["keyword.control","IF"], + ["paren.lparen","("], + ["identifier","PART"], + ["text","%"], + ["keyword.operator","<"], + ["constant.numeric","1"], + ["paren.rparen",")"], + ["keyword.operator","OR"], + ["paren.lparen","("], + ["identifier","PART"], + ["text","%"], + ["keyword.operator",">"], + ["constant.numeric","100"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["entity.name","PRINT"], + ["text"," "], + ["string","\"BAD PART NUMBER\""], + ["text",": "], + ["keyword.control","GOTO"], + ["text"," "], + ["constant.numeric","840"], + ["text"," "], + ["keyword.control","ELSE"], + ["text"," "], + ["entity.name","GET"], + ["text","#"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","J"], + ["keyword.operator",">"], + ["identifier","ART"], + ["text","%:"], + ["keyword.control","RETURN"] +],[ + "start", + ["entity.name","END"] +],[ + "start", + ["comment","REM INITIALIZE FILE"] +],[ + "start", + ["entity.name","INPUT"], + ["text"," "], + ["string","\"ARE YOU SURE\""], + ["punctiation",";"], + ["identifier","B"], + ["text","$:"], + ["keyword.control","IF"], + ["text"," "], + ["identifier","B"], + ["text","$"], + ["keyword.operator","<="], + ["string","\"Y\""], + ["text"," "], + ["keyword.control","THEN"], + ["text"," "], + ["keyword.control","RETURN"] +],[ + "start", + ["entity.name","LSET"], + ["text"," "], + ["variable","F$"], + ["keyword.operator","="], + ["support.function","CHR$"], + ["paren.lparen","("], + ["constant.numeric","255"], + ["paren.rparen",")"] +],[ + "start", + ["keyword.control","FOR"], + ["text"," "], + ["variable","O"], + ["keyword.operator","="], + ["constant.numeric","1"], + ["text"," "], + ["keyword.control","TO"], + ["text"," "], + ["constant.numeric","100"] +],[ + "start", + ["entity.name","PUT"], + ["text","#"], + ["constant.numeric","1"], + ["identifier","J"] +],[ + "start", + ["keyword.control","NEXT"], + ["text"," "], + ["identifier","I"] +],[ + "start", + ["keyword.control","RETURN"] +],[ + "start" +]] \ No newline at end of file diff --git a/src/mode/basic.js b/src/mode/basic.js new file mode 100644 index 00000000000..e3c26e9c9c0 --- /dev/null +++ b/src/mode/basic.js @@ -0,0 +1,40 @@ +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var BasicHighlightRules = require("./basic_highlight_rules").BasicHighlightRules; +var FoldMode = require("./folding/basic").FoldMode; + +var Mode = function() { + this.HighlightRules = BasicHighlightRules; + this.foldingRules = new FoldMode(); + this.$behaviour = this.$defaultBehaviour; + this.indentKeywords = this.foldingRules.indentKeywords; +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = ["REM"]; + + this.getMatching = function(session, row, column, tokenRange) { + if (row == undefined) { + var pos = session.selection.lead; + column = pos.column; + row = pos.row; + } + if (tokenRange == undefined) + tokenRange = true; + + var startToken = session.getTokenAt(row, column); + if (startToken) { + var val = startToken.value.toLowerCase(); + if (val in this.indentKeywords) + return this.foldingRules.basicBlock(session, row, column, tokenRange); + } + }; + + this.$id = "ace/mode/basic"; +}).call(Mode.prototype); + +exports.Mode = Mode; diff --git a/src/mode/basic_highlight_rules.js b/src/mode/basic_highlight_rules.js new file mode 100644 index 00000000000..6bc0477cd0a --- /dev/null +++ b/src/mode/basic_highlight_rules.js @@ -0,0 +1,67 @@ +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var BasicHighlightRules = function () { + + var keywordMapper = this.createKeywordMapper({ + "keyword.control": "FOR|TO|NEXT|GOSUB|RETURN|IF|THEN|ELSE|GOTO|ON|WHILE|WEND|TRON|TROFF", + "entity.name": "Auto|Call|Chain|Clear|Close|Common|Cont|Data|MERGE|ALL|Delete|DIM|EDIT|END|ERASE|ERROR|FIELD|" + + "GET|INPUT|KILL|LET|LIST|LLIST|LOAD|LSET|RSET|MERGE|NEW|NULL|OPEN|OUT|POKE|PRINT|PUT|RANDOMIZE|READ|" + + "RENUM|RESTORE|RESUME|RUN|SAVE|STOP|SWAP|WAIT|WIDTH", + "keyword.operator": "Mod|And|Not|Or|Xor|Eqv|Imp", + "support.function": "ABS|ASC|ATN|CDBL|CINT|COS|CSNG|CVI|CVS|CVD|EOF|EXP|FIX|FRE|INP|INSTR|INT|LEN|LOC|LOG|LPOS|" + + "PEEK|POS|RND|SGN|SIN|SPC|SQR|TAB|TAN|USR|VAL|VARPTR" + }, "identifier", true); + + this.$rules = { + "start": [ + { + token: "string", + regex: /"(?:\\.|[^"\\])*"/ + }, + { + token: "support.function", + regex: /(HEX|CHR|INPUT|LEFT|MID|MKI|MKS|MKD|OCT|RIGHT|SPACE|STR|STRING)\$/ + }, { + token: "entity.name", + regex: /(?:DEF\s(?:SEG|USR|FN[a-zA-Z]+)|LINE\sINPUT|L?PRINT#?(?:\sUSING)?|MID\$|ON\sERROR\sGOTO|OPTION\sBASE|WRITE#?|DATE\$|INKEY\$|TIME\$)/ + }, { + token: "variable", + regex: /[a-zA-Z][a-zA-Z0-9_]{0,38}[$%!#]?(?=\s*=)/ + }, { + token: "keyword.operator", + regex: /\\|=|\^|\*|\/|\+|\-|<|>|-/ + }, { + token: "paren.lparen", + regex: /[([]/ + }, { + token: "paren.rparen", + regex: /[\)\]]/ + }, { + token: "constant.numeric", + regex: /[+-]?\d+(\.\d+)?([ED][+-]?\d+)?(?:[!#])?/ + }, { + token: "constant.numeric", //hexal, octal + regex: /&[HO]?[0-9A-F]+/ + }, { + token: "comment", + regex: /REM\s+.*$/ + }, { + regex: "\\w+", + token: keywordMapper + },{ + token: "punctiation", + regex: /[,;]/ + + } + ] + + }; + this.normalizeRules(); +}; + +oop.inherits(BasicHighlightRules, TextHighlightRules); + +exports.BasicHighlightRules = BasicHighlightRules; diff --git a/src/mode/folding/basic.js b/src/mode/folding/basic.js new file mode 100644 index 00000000000..62efe5215fe --- /dev/null +++ b/src/mode/folding/basic.js @@ -0,0 +1,116 @@ +"use strict"; + +var oop = require("../../lib/oop"); +var BaseFoldMode = require("./fold_mode").FoldMode; +var Range = require("../../range").Range; +var TokenIterator = require("../../token_iterator").TokenIterator; + + +var FoldMode = exports.FoldMode = function() {}; + +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + this.indentKeywords = { + "tron": 1, + "while": 1, + "for": 1, + "troff": -1, + "wend": -1, + "next": -1 + }; + + this.foldingStartMarker = /(?:\s|^)(tron|while|for)\b/i; + this.foldingStopMarker = /(?:\b)(troff|next|wend)\b/i; + + this.getFoldWidgetRange = function (session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + if (isStart || isEnd) { + var match = (isEnd) ? this.foldingStopMarker.exec(line) : this.foldingStartMarker.exec(line); + var keyword = match && match[1].toLowerCase(); + if (keyword) { + var type = session.getTokenAt(row, match.index + 2).type; + if (type === "keyword.control") + return this.basicBlock(session, row, match.index + 2); + } + } + }; + + + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + var isStart = this.foldingStartMarker.test(line); + var isEnd = this.foldingStopMarker.test(line); + if (isStart && !isEnd) { + var match = this.foldingStartMarker.exec(line); + var keyword = match && match[1].toLowerCase(); + if (keyword) { + var type = session.getTokenAt(row, match.index + 2).type; + if (type == "keyword.control") { + return "start"; + } + } + } + if (foldStyle != "markbeginend" || !isEnd || isStart && isEnd) + return ""; + + var match = line.match(this.foldingStopMarker); + var keyword = match && match[1].toLowerCase(); + if (this.indentKeywords[keyword]) { + if (session.getTokenAt(row, match.index + 2).type === "keyword.control") + return "end"; + } + + return ""; + }; + + this.basicBlock = function(session, row, column, tokenRange) { + var stream = new TokenIterator(session, row, column); + + var token = stream.getCurrentToken(); + if (!token || token.type != "keyword.control") + return; + + var val = token.value.toLowerCase(); + var stack = [val]; + var dir = this.indentKeywords[val]; + + if (!dir) + return; + + var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length; + var startRow = row; + + stream.step = dir === -1 ? stream.stepBackward : stream.stepForward; + while(token = stream.step()) { + val = token.value.toLowerCase(); + if (token.type !== "keyword.control" || !this.indentKeywords[val]) + continue; + var level = dir * this.indentKeywords[val]; + + if (level > 0) { + stack.unshift(val); + } else if (level <= 0) { + stack.shift(); + } + if (stack.length === 0) { + break; + } + } + + if (!token) + return null; + + if (tokenRange) + return stream.getCurrentTokenRange(); + + var row = stream.getCurrentTokenRow(); + if (dir === -1) + return new Range(row, session.getLine(row).length, startRow, startColumn); + else + return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn()); + }; + +}).call(FoldMode.prototype); diff --git a/src/mode/folding/basic_test.js b/src/mode/folding/basic_test.js new file mode 100644 index 00000000000..a1fd2475c7f --- /dev/null +++ b/src/mode/folding/basic_test.js @@ -0,0 +1,97 @@ +if (typeof process !== "undefined") + require("amd-loader"); + +"use strict"; + +var BasicMode = require("../basic").Mode; +var EditSession = require("../../edit_session").EditSession; +var assert = require("../../test/assertions"); + +module.exports = { + setUp: function() { + this.mode = new BasicMode(); + }, + + "test: ms-basic mode folding with markbeginend": function() { + var session = new EditSession([ + '10 INPUT"HOW MANY DIGITS";N', + '20 T=TIME', + '30 L=INT(10*N/3)+1:DIM A(L)', + '40 Z$="000000":T$="999999"', + '50 FOR I=1TOL:A(I)=2:NEXT', + '60 M=0:P=0', + '70 FOR J=1TON:Q=0:K=2*L+1', + '80 FOR I=L TO 1 STEP -1', + 'WHILE FLIPS', + 'FLIPS=0', + 'FOR I=1 TO J-1', + 'IF A$(I)>A$(I+1) THEN', + 'SWAP A$(I),', + 'A$(I+1):FLIPS=1', + 'NEXT I', + 'WEND', + '90 K=K-2:X=10*A(I)+Q*I', + '100 Q=INT(X/K):A(I)=X-Q*K', + '110 NEXT', + '120 Y=INT(Q/10):A(1)=Q-10*Y:Q=Y', + '130 IF Q=9 THEN M=M+1:GOTO170', + '140 IF Q>9 THEN PRINT CHR$(49+P);LEFT$(Z$,M);:GOTO170', + '150 PRINT CHR$(48+P);LEFT$(T$,M);', + '160 P=Q:M=0', + '170 NEXT', + '180 PRINT CHR$(48+P):PRINT (TIME-T)/59.98' + ]); + + session.setFoldStyle("markbeginend"); + session.setMode(this.mode); + + // Assert fold widgets at the start of foldable regions + assert.equal(session.getFoldWidget(6), "start"); // Line 6: FOR J=1TON + assert.equal(session.getFoldWidget(7), "start"); // Line 7: FOR I=L TO 1 STEP -1 + assert.equal(session.getFoldWidget(8), "start"); // Line 8: WHILE FLIPS + assert.equal(session.getFoldWidget(10), "start"); // Line10: FOR I=1 TO J-1 + + // Assert fold widgets at the end of foldable regions + assert.equal(session.getFoldWidget(14), "end"); // Line14: NEXT I + assert.equal(session.getFoldWidget(15), "end"); // Line15: WEND + assert.equal(session.getFoldWidget(18), "end"); // Line18: 110 NEXT + assert.equal(session.getFoldWidget(24), "end"); // Line24: 170 NEXT + + // Lines without fold widgets + for (var i = 0; i < session.getLength(); i++) { + if ([0, 1, 2, 3, 4, 6, 7, 8, 10, 14, 15, 18, 24].indexOf(i) === -1) { + assert.equal(session.getFoldWidget(i), ""); + } + } + + // Check folding ranges from start lines + var range; + range = session.getFoldWidgetRange(6); + assert.range(range, 6, 25, 24, 4); + + range = session.getFoldWidgetRange(7); + assert.range(range, 7, 23, 18, 4); + + range = session.getFoldWidgetRange(8); + assert.range(range, 8, 11, 15, 0); + + range = session.getFoldWidgetRange(10); + assert.range(range, 10, 14, 14, 0); + + // Check folding ranges from end lines + range = session.getFoldWidgetRange(14); + assert.range(range, 10, 14, 14, 0); + + range = session.getFoldWidgetRange(15); + assert.range(range, 8, 11, 15, 0); + + range = session.getFoldWidgetRange(18); + assert.range(range, 7, 23, 18, 4); + + range = session.getFoldWidgetRange(24); + assert.range(range, 6, 25, 24, 4); + } +}; + +if (typeof module !== "undefined" && module === require.main) + require("asyncjs").test.testcase(module.exports).exec();