|
1 |
| -// issues: nested multiline comments |
2 |
| -Prism.languages.swift = Prism.languages.extend('clike', { |
3 |
| - 'string': { |
4 |
| - pattern: /("|')(?:\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[^(])|(?!\1)[^\\\r\n])*\1/, |
5 |
| - greedy: true, |
6 |
| - inside: { |
7 |
| - 'interpolation': { |
8 |
| - pattern: /\\\((?:[^()]|\([^)]+\))+\)/, |
9 |
| - inside: { |
10 |
| - delimiter: { |
11 |
| - pattern: /^\\\(|\)$/, |
12 |
| - alias: 'variable' |
13 |
| - } |
14 |
| - // See rest below |
15 |
| - } |
| 1 | +Prism.languages.swift = { |
| 2 | + 'comment': { |
| 3 | + // Nested comments are supported up to 2 levels |
| 4 | + pattern: /(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/, |
| 5 | + lookbehind: true, |
| 6 | + greedy: true |
| 7 | + }, |
| 8 | + 'string-literal': [ |
| 9 | + // https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html |
| 10 | + { |
| 11 | + pattern: RegExp( |
| 12 | + /(^|[^"#])/.source |
| 13 | + + '(?:' |
| 14 | + // single-line string |
| 15 | + + /"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source |
| 16 | + + '|' |
| 17 | + // multi-line string |
| 18 | + + /"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source |
| 19 | + + ')' |
| 20 | + + /(?!["#])/.source |
| 21 | + ), |
| 22 | + lookbehind: true, |
| 23 | + greedy: true, |
| 24 | + inside: { |
| 25 | + 'interpolation': { |
| 26 | + pattern: /(\\\()(?:[^()]|\([^()]*\))*(?=\))/, |
| 27 | + lookbehind: true, |
| 28 | + inside: null // see below |
| 29 | + }, |
| 30 | + 'interpolation-punctuation': { |
| 31 | + pattern: /^\)|\\\($/, |
| 32 | + alias: 'punctuation' |
| 33 | + }, |
| 34 | + 'punctuation': /\\(?=[\r\n])/, |
| 35 | + 'string': /[\s\S]+/ |
| 36 | + } |
| 37 | + }, |
| 38 | + { |
| 39 | + pattern: RegExp( |
| 40 | + /(^|[^"#])(#+)/.source |
| 41 | + + '(?:' |
| 42 | + // single-line string |
| 43 | + + /"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source |
| 44 | + + '|' |
| 45 | + // multi-line string |
| 46 | + + /"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source |
| 47 | + + ')' |
| 48 | + + '\\2' |
| 49 | + ), |
| 50 | + lookbehind: true, |
| 51 | + greedy: true, |
| 52 | + inside: { |
| 53 | + 'interpolation': { |
| 54 | + pattern: /(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/, |
| 55 | + lookbehind: true, |
| 56 | + inside: null // see below |
| 57 | + }, |
| 58 | + 'interpolation-punctuation': { |
| 59 | + pattern: /^\)|\\#+\($/, |
| 60 | + alias: 'punctuation' |
| 61 | + }, |
| 62 | + 'string': /[\s\S]+/ |
16 | 63 | }
|
| 64 | + }, |
| 65 | + ], |
| 66 | + |
| 67 | + 'directive': { |
| 68 | + // directives with conditions |
| 69 | + pattern: RegExp( |
| 70 | + /#/.source |
| 71 | + + '(?:' |
| 72 | + + ( |
| 73 | + /(?:elseif|if)\b/.source |
| 74 | + + '(?:[ \t]*' |
| 75 | + // This regex is a little complex. It's equivalent to this: |
| 76 | + // (?:![ \t]*)?(?:\b\w+\b(?:[ \t]*<round>)?|<round>)(?:[ \t]*(?:&&|\|\|))? |
| 77 | + // where <round> is a general parentheses expression. |
| 78 | + + /(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source |
| 79 | + + ')+' |
| 80 | + ) |
| 81 | + + '|' |
| 82 | + + /(?:else|endif)\b/.source |
| 83 | + + ')' |
| 84 | + ), |
| 85 | + alias: 'property', |
| 86 | + inside: { |
| 87 | + 'directive-name': /^#\w+/, |
| 88 | + 'boolean': /\b(?:true|false)\b/, |
| 89 | + 'number': /\b\d+(?:\.\d+)*\b/, |
| 90 | + 'operator': /!|&&|\|\||[<>]=?/, |
| 91 | + 'punctuation': /[(),]/ |
17 | 92 | }
|
18 | 93 | },
|
19 |
| - 'keyword': /\b(?:actor|as|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic(?:Type)?|else|enum|extension|fallthrough|final|for|func|get|guard|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonisolated|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|Self|set|some|static|struct|subscript|super|switch|throws?|try|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|__(?:COLUMN__|FILE__|FUNCTION__|LINE__))\b/, |
| 94 | + 'literal': { |
| 95 | + pattern: /#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/, |
| 96 | + alias: 'constant' |
| 97 | + }, |
| 98 | + 'other-directive': { |
| 99 | + pattern: /#\w+\b/, |
| 100 | + alias: 'property' |
| 101 | + }, |
| 102 | + |
| 103 | + 'attribute': { |
| 104 | + pattern: /@\w+/, |
| 105 | + alias: 'atrule' |
| 106 | + }, |
| 107 | + |
| 108 | + 'function-definition': { |
| 109 | + pattern: /(\bfunc\s+)\w+/, |
| 110 | + lookbehind: true, |
| 111 | + alias: 'function' |
| 112 | + }, |
| 113 | + 'label': { |
| 114 | + // https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html#ID141 |
| 115 | + pattern: /\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/, |
| 116 | + lookbehind: true, |
| 117 | + alias: 'important' |
| 118 | + }, |
| 119 | + |
| 120 | + 'keyword': /\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/, |
| 121 | + 'boolean': /\b(?:true|false)\b/, |
| 122 | + 'nil': { |
| 123 | + pattern: /\bnil\b/, |
| 124 | + alias: 'constant' |
| 125 | + }, |
| 126 | + |
| 127 | + 'short-argument': /\$\d+\b/, |
| 128 | + 'omit': { |
| 129 | + pattern: /\b_\b/, |
| 130 | + alias: 'keyword' |
| 131 | + }, |
20 | 132 | 'number': /\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,
|
21 |
| - 'constant': /\b(?:nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/, |
22 |
| - 'atrule': /@\b(?:IB(?:Outlet|Designable|Action|Inspectable)|class_protocol|exported|globalActor|MainActor|noreturn|NS(?:Copying|Managed)|objc|propertyWrapper|UIApplicationMain|auto_closure)\b/, |
23 |
| - 'builtin': /\b(?:[A-Z]\S+|abs|advance|alignof(?:Value)?|assert|contains|count(?:Elements)?|debugPrint(?:ln)?|distance|drop(?:First|Last)|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lexicographicalCompare|map|max(?:Element)?|min(?:Element)?|numericCast|overlaps|partition|print(?:ln)?|reduce|reflect|reverse|sizeof(?:Value)?|sort(?:ed)?|split|startsWith|stride(?:of(?:Value)?)?|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|with(?:ExtendedLifetime|Unsafe(?:MutablePointers?|Pointers?)|VaList))\b/ |
| 133 | + |
| 134 | + // A class name must start with an upper-case letter and be either 1 letter long or contain a lower-case letter. |
| 135 | + 'class-name': /\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/, |
| 136 | + 'function': /\b[a-z_]\w*(?=\s*\()/i, |
| 137 | + 'constant': /\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/, |
| 138 | + |
| 139 | + // Operators are generic in Swift. Developers can even create new operators (e.g. +++). |
| 140 | + // https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html#ID481 |
| 141 | + // This regex only supports ASCII operators. |
| 142 | + 'operator': /[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/, |
| 143 | + 'punctuation': /[{}[\]();,.:\\]/ |
| 144 | +}; |
| 145 | + |
| 146 | +Prism.languages.swift['string-literal'].forEach(function (rule) { |
| 147 | + rule.inside['interpolation'].inside = Prism.languages.swift; |
24 | 148 | });
|
25 |
| -Prism.languages.swift['string'].inside['interpolation'].inside.rest = Prism.languages.swift; |
|
0 commit comments