G-Code.sublime-syntax 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. %YAML 1.2
  2. ---
  3. #
  4. # G-Code (RepRap, not ISO-6983)
  5. # Author: @thinkyhead
  6. #
  7. # RapRap G-Code is very simple.
  8. #
  9. # TODO: Lines that start with N get a different context, accepting a checksum.
  10. #
  11. name: G-Code (RepRap)
  12. file_extensions:
  13. - [ g, gco, gcode ]
  14. scope: source.gcode
  15. variables:
  16. decimal: '[+-]?\d+(\.\d*)?'
  17. contexts:
  18. prototype:
  19. - match: \s+
  20. - include: mixin_comment
  21. - match: $
  22. pop: true
  23. main:
  24. - meta_scope: line.gcode
  25. - match: '([Nn]\s*(\d+))'
  26. captures:
  27. 1: entity.nword.gcode
  28. 2: constant.numeric.line-number.gcode
  29. - match: ()
  30. set: gcode_command
  31. # G, M, or T command
  32. gcode_command:
  33. - meta_content_scope: ctx.command.gcode
  34. # M20 S2 P/path/to/file/name.gco
  35. - match: ([Mm](20))\s*((S)(2)\s*(P))
  36. captures:
  37. 1: entity.command.gcode markup.bold.gcode
  38. 2: constant.numeric.command.gcode
  39. 3: ctx.params.gcode
  40. 4: keyword.param.gcode
  41. 5: constant.numeric.param.gcode
  42. 6: keyword.param.gcode
  43. set: gcode_string_arg
  44. # M117 or M118 - Commands taking a string
  45. - match: ([Mm]\s*(11[78]))\b
  46. captures:
  47. 1: entity.command.gcode markup.bold.gcode
  48. 2: constant.numeric.command.gcode
  49. set: gcode_string_arg
  50. # Other commands, followed by data
  51. - match: ([GMTgmt]\s*(\d+)((\.)(\d+))?)
  52. captures:
  53. 1: entity.command.gcode markup.bold.gcode
  54. 2: constant.numeric.command.gcode
  55. 4: entity.separator.subcode
  56. 5: constant.numeric.subcode
  57. set: gcode_params
  58. - match: ()
  59. set: syntax_error
  60. # Parameters of a command
  61. gcode_params:
  62. - meta_content_scope: ctx.params.gcode
  63. # M32 [S<pos>] [P<bool>] !/path/file.gco#
  64. - match: \!
  65. scope: punctuation.string.path.open.gcode
  66. push: gcode_path_arg
  67. # asterisk starts a checksum
  68. - match: \*
  69. scope: punctuation.marker.checksum.gcode
  70. set: gcode_checksum
  71. # parameter and single-quoted value
  72. - match: ([A-Za-z])\s*(')
  73. captures:
  74. 1: keyword.param.gcode
  75. 2: punctuation.quote.single.open.gcode
  76. push: gcode_string_arg_quoted_single
  77. # parameter and double-quoted value
  78. - match: ([A-Za-z])\s*(")
  79. captures:
  80. 1: keyword.param.gcode
  81. 2: punctuation.quote.double.open.gcode
  82. push: gcode_string_arg_quoted_double
  83. # parameter and list of values
  84. - match: ([Ee])\s*(({{decimal}}\s*:\s*)+{{decimal}})
  85. captures:
  86. 1: keyword.param.gcode
  87. 2: constant.numeric.param.gcode
  88. # parameter and numeric value
  89. - match: ([A-Za-z])\s*({{decimal}})
  90. captures:
  91. 1: keyword.param.gcode
  92. 2: constant.numeric.param.gcode
  93. # parameter with no value
  94. - match: '[A-Za-z]'
  95. scope: keyword.param.gcode
  96. set: gcode_params
  97. - match: ()
  98. set: syntax_error
  99. gcode_string_arg_quoted_single:
  100. - meta_content_scope: string.quoted.single.gcode
  101. - match: ([^'\\]+)
  102. - match: (\\)
  103. scope: punctuation.string.escape.gcode
  104. push: escape_char
  105. - match: (')
  106. scope: punctuation.quote.single.close.gcode
  107. pop: true
  108. - match: ()
  109. set: syntax_error
  110. gcode_string_arg_quoted_double:
  111. - meta_content_scope: string.quoted.double.gcode
  112. - match: ([^"\\]+)
  113. - match: (\\)
  114. scope: punctuation.string.escape.gcode
  115. push: escape_char
  116. - match: (")
  117. scope: punctuation.quote.double.close.gcode
  118. pop: true
  119. - match: ()
  120. set: syntax_error
  121. gcode_string_arg:
  122. - meta_content_scope: ctx.string.gcode
  123. - match: ([^;]+)
  124. scope: string.unquoted.gcode
  125. escape_char:
  126. - meta_scope: string.escape.gcode punctuation.string.escape.gcode
  127. - match: '.'
  128. pop: true
  129. gcode_path_arg:
  130. - meta_content_scope: string.unquoted.path.gcode
  131. - match: (#)
  132. scope: punctuation.string.path.close.gcode
  133. pop: true
  134. gcode_checksum:
  135. - meta_content_scope: constant.numeric.checksum.gcode
  136. - meta_include_prototype: false
  137. - match: \d+
  138. - match: ( *)$
  139. pop: true
  140. - include: mixin_comment
  141. - match: ()
  142. set: syntax_error
  143. # Done interpreting to the end of the line
  144. gcode_line_done:
  145. - match: \s*$
  146. pop: true
  147. # Comments begin with a ';' and finish at the end of the line.
  148. mixin_comment:
  149. - match: ^\s*;
  150. scope: punctuation.comment.line.start
  151. set: gcode_comment
  152. - match: \s*;
  153. scope: punctuation.comment.eol.start
  154. set: gcode_comment
  155. - match: \s*\(
  156. scope: punctuation.paren.comment.open
  157. push: gcode_comment_paren
  158. # Comment to end of line.
  159. gcode_comment:
  160. - meta_content_scope: comment.gcode
  161. - match: \s*$
  162. pop: true
  163. gcode_comment_paren:
  164. - meta_content_scope: paren.comment.gcode
  165. - match: '[^)]+'
  166. - match: '[)]'
  167. scope: punctuation.paren.comment.close
  168. pop: true
  169. - match: \s*$
  170. pop: true
  171. # Everything after this point is broken by a syntax error
  172. syntax_error:
  173. - meta_scope: invalid.error.syntax.gcode
  174. - match: .*$
  175. pop: true