mirc.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. //mIRC mode by Ford_Lawnmower :: Based on Velocity mode by Steve O'Hara
  4. ;(function (mod) {
  5. if (typeof exports == 'object' && typeof module == 'object')
  6. // CommonJS
  7. mod(require('../../lib/codemirror'))
  8. else if (typeof define == 'function' && define.amd)
  9. // AMD
  10. define(['../../lib/codemirror'], mod)
  11. // Plain browser env
  12. else mod(CodeMirror)
  13. })(function (CodeMirror) {
  14. 'use strict'
  15. CodeMirror.defineMIME('text/mirc', 'mirc')
  16. CodeMirror.defineMode('mirc', function () {
  17. function parseWords(str) {
  18. var obj = {},
  19. words = str.split(' ')
  20. for (var i = 0; i < words.length; ++i) obj[words[i]] = true
  21. return obj
  22. }
  23. var specials = parseWords(
  24. '$! $$ $& $? $+ $abook $abs $active $activecid ' +
  25. '$activewid $address $addtok $agent $agentname $agentstat $agentver ' +
  26. '$alias $and $anick $ansi2mirc $aop $appactive $appstate $asc $asctime ' +
  27. '$asin $atan $avoice $away $awaymsg $awaytime $banmask $base $bfind ' +
  28. '$binoff $biton $bnick $bvar $bytes $calc $cb $cd $ceil $chan $chanmodes ' +
  29. '$chantypes $chat $chr $cid $clevel $click $cmdbox $cmdline $cnick $color ' +
  30. '$com $comcall $comchan $comerr $compact $compress $comval $cos $count ' +
  31. '$cr $crc $creq $crlf $ctime $ctimer $ctrlenter $date $day $daylight ' +
  32. '$dbuh $dbuw $dccignore $dccport $dde $ddename $debug $decode $decompress ' +
  33. '$deltok $devent $dialog $did $didreg $didtok $didwm $disk $dlevel $dll ' +
  34. '$dllcall $dname $dns $duration $ebeeps $editbox $emailaddr $encode $error ' +
  35. '$eval $event $exist $feof $ferr $fgetc $file $filename $filtered $finddir ' +
  36. '$finddirn $findfile $findfilen $findtok $fline $floor $fopen $fread $fserve ' +
  37. '$fulladdress $fulldate $fullname $fullscreen $get $getdir $getdot $gettok $gmt ' +
  38. '$group $halted $hash $height $hfind $hget $highlight $hnick $hotline ' +
  39. '$hotlinepos $ial $ialchan $ibl $idle $iel $ifmatch $ignore $iif $iil ' +
  40. '$inelipse $ini $inmidi $inpaste $inpoly $input $inrect $inroundrect ' +
  41. '$insong $instok $int $inwave $ip $isalias $isbit $isdde $isdir $isfile ' +
  42. '$isid $islower $istok $isupper $keychar $keyrpt $keyval $knick $lactive ' +
  43. '$lactivecid $lactivewid $left $len $level $lf $line $lines $link $lock ' +
  44. '$lock $locked $log $logstamp $logstampfmt $longfn $longip $lower $ltimer ' +
  45. '$maddress $mask $matchkey $matchtok $md5 $me $menu $menubar $menucontext ' +
  46. '$menutype $mid $middir $mircdir $mircexe $mircini $mklogfn $mnick $mode ' +
  47. '$modefirst $modelast $modespl $mouse $msfile $network $newnick $nick $nofile ' +
  48. '$nopath $noqt $not $notags $notify $null $numeric $numok $oline $onpoly ' +
  49. '$opnick $or $ord $os $passivedcc $pic $play $pnick $port $portable $portfree ' +
  50. '$pos $prefix $prop $protect $puttok $qt $query $rand $r $rawmsg $read $readomo ' +
  51. '$readn $regex $regml $regsub $regsubex $remove $remtok $replace $replacex ' +
  52. '$reptok $result $rgb $right $round $scid $scon $script $scriptdir $scriptline ' +
  53. '$sdir $send $server $serverip $sfile $sha1 $shortfn $show $signal $sin ' +
  54. '$site $sline $snick $snicks $snotify $sock $sockbr $sockerr $sockname ' +
  55. '$sorttok $sound $sqrt $ssl $sreq $sslready $status $strip $str $stripped ' +
  56. '$syle $submenu $switchbar $tan $target $ticks $time $timer $timestamp ' +
  57. '$timestampfmt $timezone $tip $titlebar $toolbar $treebar $trust $ulevel ' +
  58. '$ulist $upper $uptime $url $usermode $v1 $v2 $var $vcmd $vcmdstat $vcmdver ' +
  59. '$version $vnick $vol $wid $width $wildsite $wildtok $window $wrap $xor'
  60. )
  61. var keywords = parseWords(
  62. 'abook ajinvite alias aline ame amsg anick aop auser autojoin avoice ' +
  63. 'away background ban bcopy beep bread break breplace bset btrunc bunset bwrite ' +
  64. 'channel clear clearall cline clipboard close cnick color comclose comopen ' +
  65. 'comreg continue copy creq ctcpreply ctcps dcc dccserver dde ddeserver ' +
  66. 'debug dec describe dialog did didtok disable disconnect dlevel dline dll ' +
  67. 'dns dqwindow drawcopy drawdot drawfill drawline drawpic drawrect drawreplace ' +
  68. 'drawrot drawsave drawscroll drawtext ebeeps echo editbox emailaddr enable ' +
  69. 'events exit fclose filter findtext finger firewall flash flist flood flush ' +
  70. 'flushini font fopen fseek fsend fserve fullname fwrite ghide gload gmove ' +
  71. 'gopts goto gplay gpoint gqreq groups gshow gsize gstop gtalk gunload hadd ' +
  72. 'halt haltdef hdec hdel help hfree hinc hload hmake hop hsave ial ialclear ' +
  73. 'ialmark identd if ignore iline inc invite iuser join kick linesep links list ' +
  74. 'load loadbuf localinfo log mdi me menubar mkdir mnick mode msg nick noop notice ' +
  75. 'notify omsg onotice part partall pdcc perform play playctrl pop protect pvoice ' +
  76. 'qme qmsg query queryn quit raw reload remini remote remove rename renwin ' +
  77. 'reseterror resetidle return rlevel rline rmdir run ruser save savebuf saveini ' +
  78. 'say scid scon server set showmirc signam sline sockaccept sockclose socklist ' +
  79. 'socklisten sockmark sockopen sockpause sockread sockrename sockudp sockwrite ' +
  80. 'sound speak splay sreq strip switchbar timer timestamp titlebar tnick tokenize ' +
  81. 'toolbar topic tray treebar ulist unload unset unsetall updatenl url uwho ' +
  82. 'var vcadd vcmd vcrem vol while whois window winhelp write writeint if isalnum ' +
  83. 'isalpha isaop isavoice isban ischan ishop isignore isin isincs isletter islower ' +
  84. 'isnotify isnum ison isop isprotect isreg isupper isvoice iswm iswmcs ' +
  85. 'elseif else goto menu nicklist status title icon size option text edit ' +
  86. 'button check radio box scroll list combo link tab item'
  87. )
  88. var functions = parseWords('if elseif else and not or eq ne in ni for foreach while switch')
  89. var isOperatorChar = /[+\-*&%=<>!?^\/\|]/
  90. function chain(stream, state, f) {
  91. state.tokenize = f
  92. return f(stream, state)
  93. }
  94. function tokenBase(stream, state) {
  95. var beforeParams = state.beforeParams
  96. state.beforeParams = false
  97. var ch = stream.next()
  98. if (/[\[\]{}\(\),\.]/.test(ch)) {
  99. if (ch == '(' && beforeParams) state.inParams = true
  100. else if (ch == ')') state.inParams = false
  101. return null
  102. } else if (/\d/.test(ch)) {
  103. stream.eatWhile(/[\w\.]/)
  104. return 'number'
  105. } else if (ch == '\\') {
  106. stream.eat('\\')
  107. stream.eat(/./)
  108. return 'number'
  109. } else if (ch == '/' && stream.eat('*')) {
  110. return chain(stream, state, tokenComment)
  111. } else if (ch == ';' && stream.match(/ *\( *\(/)) {
  112. return chain(stream, state, tokenUnparsed)
  113. } else if (ch == ';' && !state.inParams) {
  114. stream.skipToEnd()
  115. return 'comment'
  116. } else if (ch == '"') {
  117. stream.eat(/"/)
  118. return 'keyword'
  119. } else if (ch == '$') {
  120. stream.eatWhile(/[$_a-z0-9A-Z\.:]/)
  121. if (specials && specials.propertyIsEnumerable(stream.current().toLowerCase())) {
  122. return 'keyword'
  123. } else {
  124. state.beforeParams = true
  125. return 'builtin'
  126. }
  127. } else if (ch == '%') {
  128. stream.eatWhile(/[^,\s()]/)
  129. state.beforeParams = true
  130. return 'string'
  131. } else if (isOperatorChar.test(ch)) {
  132. stream.eatWhile(isOperatorChar)
  133. return 'operator'
  134. } else {
  135. stream.eatWhile(/[\w\$_{}]/)
  136. var word = stream.current().toLowerCase()
  137. if (keywords && keywords.propertyIsEnumerable(word)) return 'keyword'
  138. if (functions && functions.propertyIsEnumerable(word)) {
  139. state.beforeParams = true
  140. return 'keyword'
  141. }
  142. return null
  143. }
  144. }
  145. function tokenComment(stream, state) {
  146. var maybeEnd = false,
  147. ch
  148. while ((ch = stream.next())) {
  149. if (ch == '/' && maybeEnd) {
  150. state.tokenize = tokenBase
  151. break
  152. }
  153. maybeEnd = ch == '*'
  154. }
  155. return 'comment'
  156. }
  157. function tokenUnparsed(stream, state) {
  158. var maybeEnd = 0,
  159. ch
  160. while ((ch = stream.next())) {
  161. if (ch == ';' && maybeEnd == 2) {
  162. state.tokenize = tokenBase
  163. break
  164. }
  165. if (ch == ')') maybeEnd++
  166. else if (ch != ' ') maybeEnd = 0
  167. }
  168. return 'meta'
  169. }
  170. return {
  171. startState: function () {
  172. return {
  173. tokenize: tokenBase,
  174. beforeParams: false,
  175. inParams: false,
  176. }
  177. },
  178. token: function (stream, state) {
  179. if (stream.eatSpace()) return null
  180. return state.tokenize(stream, state)
  181. },
  182. }
  183. })
  184. })