all repos — NoPaste @ 29b774f090102303e43cf939b38ac2083e62d9f1

Resurrected - The PussTheCat.org fork of NoPaste

scripts/CodeMirror/mode/swift/swift.js (view raw)

  1// CodeMirror, copyright (c) by Marijn Haverbeke and others
  2// Distributed under an MIT license: https://codemirror.net/LICENSE
  3
  4// Swift mode created by Michael Kaminsky https://github.com/mkaminsky11
  5
  6(function(mod) {
  7  if (typeof exports == "object" && typeof module == "object")
  8    mod(require("../../lib/codemirror"))
  9  else if (typeof define == "function" && define.amd)
 10    define(["../../lib/codemirror"], mod)
 11  else
 12    mod(CodeMirror)
 13})(function(CodeMirror) {
 14  "use strict"
 15
 16  function wordSet(words) {
 17    var set = {}
 18    for (var i = 0; i < words.length; i++) set[words[i]] = true
 19    return set
 20  }
 21
 22  var keywords = wordSet(["_","var","let","class","enum","extension","import","protocol","struct","func","typealias","associatedtype",
 23                          "open","public","internal","fileprivate","private","deinit","init","new","override","self","subscript","super",
 24                          "convenience","dynamic","final","indirect","lazy","required","static","unowned","unowned(safe)","unowned(unsafe)","weak","as","is",
 25                          "break","case","continue","default","else","fallthrough","for","guard","if","in","repeat","switch","where","while",
 26                          "defer","return","inout","mutating","nonmutating","catch","do","rethrows","throw","throws","try","didSet","get","set","willSet",
 27                          "assignment","associativity","infix","left","none","operator","postfix","precedence","precedencegroup","prefix","right",
 28                          "Any","AnyObject","Type","dynamicType","Self","Protocol","__COLUMN__","__FILE__","__FUNCTION__","__LINE__"])
 29  var definingKeywords = wordSet(["var","let","class","enum","extension","import","protocol","struct","func","typealias","associatedtype","for"])
 30  var atoms = wordSet(["true","false","nil","self","super","_"])
 31  var types = wordSet(["Array","Bool","Character","Dictionary","Double","Float","Int","Int8","Int16","Int32","Int64","Never","Optional","Set","String",
 32                       "UInt8","UInt16","UInt32","UInt64","Void"])
 33  var operators = "+-/*%=|&<>~^?!"
 34  var punc = ":;,.(){}[]"
 35  var binary = /^\-?0b[01][01_]*/
 36  var octal = /^\-?0o[0-7][0-7_]*/
 37  var hexadecimal = /^\-?0x[\dA-Fa-f][\dA-Fa-f_]*(?:(?:\.[\dA-Fa-f][\dA-Fa-f_]*)?[Pp]\-?\d[\d_]*)?/
 38  var decimal = /^\-?\d[\d_]*(?:\.\d[\d_]*)?(?:[Ee]\-?\d[\d_]*)?/
 39  var identifier = /^\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1/
 40  var property = /^\.(?:\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1)/
 41  var instruction = /^\#[A-Za-z]+/
 42  var attribute = /^@(?:\$\d+|(`?)[_A-Za-z][_A-Za-z$0-9]*\1)/
 43  //var regexp = /^\/(?!\s)(?:\/\/)?(?:\\.|[^\/])+\//
 44
 45  function tokenBase(stream, state, prev) {
 46    if (stream.sol()) state.indented = stream.indentation()
 47    if (stream.eatSpace()) return null
 48
 49    var ch = stream.peek()
 50    if (ch == "/") {
 51      if (stream.match("//")) {
 52        stream.skipToEnd()
 53        return "comment"
 54      }
 55      if (stream.match("/*")) {
 56        state.tokenize.push(tokenComment)
 57        return tokenComment(stream, state)
 58      }
 59    }
 60    if (stream.match(instruction)) return "builtin"
 61    if (stream.match(attribute)) return "attribute"
 62    if (stream.match(binary)) return "number"
 63    if (stream.match(octal)) return "number"
 64    if (stream.match(hexadecimal)) return "number"
 65    if (stream.match(decimal)) return "number"
 66    if (stream.match(property)) return "property"
 67    if (operators.indexOf(ch) > -1) {
 68      stream.next()
 69      return "operator"
 70    }
 71    if (punc.indexOf(ch) > -1) {
 72      stream.next()
 73      stream.match("..")
 74      return "punctuation"
 75    }
 76    var stringMatch
 77    if (stringMatch = stream.match(/("""|"|')/)) {
 78      var tokenize = tokenString.bind(null, stringMatch[0])
 79      state.tokenize.push(tokenize)
 80      return tokenize(stream, state)
 81    }
 82
 83    if (stream.match(identifier)) {
 84      var ident = stream.current()
 85      if (types.hasOwnProperty(ident)) return "variable-2"
 86      if (atoms.hasOwnProperty(ident)) return "atom"
 87      if (keywords.hasOwnProperty(ident)) {
 88        if (definingKeywords.hasOwnProperty(ident))
 89          state.prev = "define"
 90        return "keyword"
 91      }
 92      if (prev == "define") return "def"
 93      return "variable"
 94    }
 95
 96    stream.next()
 97    return null
 98  }
 99
100  function tokenUntilClosingParen() {
101    var depth = 0
102    return function(stream, state, prev) {
103      var inner = tokenBase(stream, state, prev)
104      if (inner == "punctuation") {
105        if (stream.current() == "(") ++depth
106        else if (stream.current() == ")") {
107          if (depth == 0) {
108            stream.backUp(1)
109            state.tokenize.pop()
110            return state.tokenize[state.tokenize.length - 1](stream, state)
111          }
112          else --depth
113        }
114      }
115      return inner
116    }
117  }
118
119  function tokenString(openQuote, stream, state) {
120    var singleLine = openQuote.length == 1
121    var ch, escaped = false
122    while (ch = stream.peek()) {
123      if (escaped) {
124        stream.next()
125        if (ch == "(") {
126          state.tokenize.push(tokenUntilClosingParen())
127          return "string"
128        }
129        escaped = false
130      } else if (stream.match(openQuote)) {
131        state.tokenize.pop()
132        return "string"
133      } else {
134        stream.next()
135        escaped = ch == "\\"
136      }
137    }
138    if (singleLine) {
139      state.tokenize.pop()
140    }
141    return "string"
142  }
143
144  function tokenComment(stream, state) {
145    var ch
146    while (true) {
147      stream.match(/^[^/*]+/, true)
148      ch = stream.next()
149      if (!ch) break
150      if (ch === "/" && stream.eat("*")) {
151        state.tokenize.push(tokenComment)
152      } else if (ch === "*" && stream.eat("/")) {
153        state.tokenize.pop()
154      }
155    }
156    return "comment"
157  }
158
159  function Context(prev, align, indented) {
160    this.prev = prev
161    this.align = align
162    this.indented = indented
163  }
164
165  function pushContext(state, stream) {
166    var align = stream.match(/^\s*($|\/[\/\*])/, false) ? null : stream.column() + 1
167    state.context = new Context(state.context, align, state.indented)
168  }
169
170  function popContext(state) {
171    if (state.context) {
172      state.indented = state.context.indented
173      state.context = state.context.prev
174    }
175  }
176
177  CodeMirror.defineMode("swift", function(config) {
178    return {
179      startState: function() {
180        return {
181          prev: null,
182          context: null,
183          indented: 0,
184          tokenize: []
185        }
186      },
187
188      token: function(stream, state) {
189        var prev = state.prev
190        state.prev = null
191        var tokenize = state.tokenize[state.tokenize.length - 1] || tokenBase
192        var style = tokenize(stream, state, prev)
193        if (!style || style == "comment") state.prev = prev
194        else if (!state.prev) state.prev = style
195
196        if (style == "punctuation") {
197          var bracket = /[\(\[\{]|([\]\)\}])/.exec(stream.current())
198          if (bracket) (bracket[1] ? popContext : pushContext)(state, stream)
199        }
200
201        return style
202      },
203
204      indent: function(state, textAfter) {
205        var cx = state.context
206        if (!cx) return 0
207        var closing = /^[\]\}\)]/.test(textAfter)
208        if (cx.align != null) return cx.align - (closing ? 1 : 0)
209        return cx.indented + (closing ? 0 : config.indentUnit)
210      },
211
212      electricInput: /^\s*[\)\}\]]$/,
213
214      lineComment: "//",
215      blockCommentStart: "/*",
216      blockCommentEnd: "*/",
217      fold: "brace",
218      closeBrackets: "()[]{}''\"\"``"
219    }
220  })
221
222  CodeMirror.defineMIME("text/x-swift","swift")
223});