From 7fae6fa420b5555099aacefd2e745d11f732763e Mon Sep 17 00:00:00 2001 From: mtgmonkey Date: Thu, 18 Dec 2025 22:35:32 +0100 Subject: [PATCH] add syntax --- _syntaxes/Nix.sublime-syntax | 610 +++++++++++++++++++++++++++++++++ posts/20251218-glsl-edsl-p1.md | 121 +++++++ 2 files changed, 731 insertions(+) create mode 100644 _syntaxes/Nix.sublime-syntax create mode 100644 posts/20251218-glsl-edsl-p1.md diff --git a/_syntaxes/Nix.sublime-syntax b/_syntaxes/Nix.sublime-syntax new file mode 100644 index 0000000..c9a1f4c --- /dev/null +++ b/_syntaxes/Nix.sublime-syntax @@ -0,0 +1,610 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +# 'borrowed' from Yola syntaxes on 2025 12 18 +name: Nix +file_extensions: + - nix +scope: source.nix +contexts: + main: + - include: expression + comment: + - match: '/\*([^*]|\*[^\/])*' + push: + - meta_scope: comment.block.nix + - match: \*\/ + pop: true + - include: comment-remark + - match: '\#' + push: + - meta_scope: comment.line.number-sign.nix + - match: $ + pop: true + - include: comment-remark + attribute-bind: + - include: attribute-name + - include: attribute-bind-from-equals + attribute-bind-from-equals: + - match: \= + captures: + 0: keyword.operator.bind.nix + push: + - match: \; + captures: + 0: punctuation.terminator.bind.nix + pop: true + - include: expression + attribute-inherit: + - match: \binherit\b + captures: + 0: keyword.other.inherit.nix + push: + - match: \; + captures: + 0: punctuation.terminator.inherit.nix + pop: true + - match: \( + captures: + 0: punctuation.section.function.arguments.nix + push: + - match: (?=\;) + pop: true + - match: \) + captures: + 0: punctuation.section.function.arguments.nix + push: + - match: (?=\;) + pop: true + - include: bad-reserved + - include: attribute-name-single + - include: others + - include: expression + - match: '(?=[a-zA-Z\_])' + push: + - match: (?=\;) + pop: true + - include: bad-reserved + - include: attribute-name-single + - include: others + - include: others + attribute-name: + - match: '\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*' + scope: entity.other.attribute-name.multipart.nix + - match: \. + - include: string-quoted + - include: interpolation + attribute-name-single: + - match: '\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*' + scope: entity.other.attribute-name.single.nix + attrset-contents: + - include: attribute-inherit + - include: bad-reserved + - include: attribute-bind + - include: others + attrset-definition: + - match: '(?=\{)' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - match: '(\{)' + captures: + 0: punctuation.definition.attrset.nix + push: + - match: '(\})' + captures: + 0: punctuation.definition.attrset.nix + pop: true + - include: attrset-contents + - match: '(?<=\})' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + attrset-definition-brace-opened: + - match: '(?<=\})' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + - match: (?=.?) + push: + - match: '\}' + captures: + 0: punctuation.definition.attrset.nix + pop: true + - include: attrset-contents + attrset-for-sure: + - match: (?=\brec\b) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - match: \brec\b + captures: + 0: keyword.other.nix + push: + - match: '(?=\{)' + pop: true + - include: others + - include: attrset-definition + - include: others + - match: '(?=\{\s*(\}|[^,?]*(=|;)))' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: attrset-definition + - include: others + attrset-or-function: + - match: '\{' + captures: + 0: punctuation.definition.attrset-or-function.nix + push: + - match: '(?=([\])};]|\b(else|then)\b))' + pop: true + - match: '(?=(\s*\}|\"|\binherit\b|\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*(\s*\.|\s*=[^=])|\$\{[a-zA-z0-9\_\''\-]+\}(\s*\.|\s*=[^=])))' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: attrset-definition-brace-opened + - match: '(?=(\.\.\.|\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*\s*[,?]))' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-definition-brace-opened + - include: bad-reserved + - match: '\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*' + captures: + 0: variable.parameter.function.maybe.nix + push: + - match: '(?=([\])};]|\b(else|then)\b))' + pop: true + - match: (?=\.) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: attrset-definition-brace-opened + - match: \s*(\,) + captures: + 1: keyword.operator.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-definition-brace-opened + - match: (?=\=) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: attribute-bind-from-equals + - include: attrset-definition-brace-opened + - match: (?=\?) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-parameter-default + - match: \, + captures: + 0: keyword.operator.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-definition-brace-opened + - include: others + - include: others + bad-reserved: + - match: '(?\=|\>|&&|\|\||-\>|//|\?|\+\+|-|\*|/(?=([^*]|$))|\+)' + scope: keyword.operator.nix + - include: constants + - include: bad-reserved + - include: parameter-name + - include: others + function-body: + - match: '(@\s*([a-zA-Z\_][a-zA-Z0-9\_\''\-]*)\s*)?(\:)' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression + function-body-from-colon: + - match: (\:) + captures: + 0: punctuation.definition.function.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression + function-contents: + - include: bad-reserved + - include: function-parameter + - include: others + function-definition: + - match: (?=.?) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-body-from-colon + - match: (?=.?) + push: + - match: (?=\:) + pop: true + - match: '(\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*)' + captures: + 0: variable.parameter.function.4.nix + push: + - match: (?=\:) + pop: true + - match: \@ + push: + - match: (?=\:) + pop: true + - include: function-header-until-colon-no-arg + - include: others + - include: others + - match: '(?=\{)' + push: + - match: (?=\:) + pop: true + - include: function-header-until-colon-with-arg + - include: others + function-definition-brace-opened: + - match: (?=.?) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-body-from-colon + - match: (?=.?) + push: + - match: (?=\:) + pop: true + - include: function-header-close-brace-with-arg + - match: (?=.?) + push: + - match: '(?=\})' + pop: true + - include: function-contents + - include: others + function-for-sure: + - match: '(?=(\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*\s*[:@]|\{[^}]*\}\s*:|\{[^#}"''/=]*[,\?]))' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: function-definition + function-header-close-brace-no-arg: + - match: '\}' + captures: + 0: punctuation.definition.entity.function.nix + push: + - match: (?=\:) + pop: true + - include: others + function-header-close-brace-with-arg: + - match: '\}' + captures: + 0: punctuation.definition.entity.function.nix + push: + - match: (?=\:) + pop: true + - include: function-header-terminal-arg + - include: others + function-header-open-brace: + - match: '\{' + captures: + 0: punctuation.definition.entity.function.2.nix + push: + - match: '(?=\})' + pop: true + - include: function-contents + function-header-terminal-arg: + - match: (?=@) + push: + - match: (?=\:) + pop: true + - match: \@ + push: + - match: (?=\:) + pop: true + - match: '(\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*)' + push: + - meta_scope: variable.parameter.function.3.nix + - match: (?=\:) + pop: true + - include: others + - include: others + function-header-until-colon-no-arg: + - match: '(?=\{)' + push: + - match: (?=\:) + pop: true + - include: function-header-open-brace + - include: function-header-close-brace-no-arg + function-header-until-colon-with-arg: + - match: '(?=\{)' + push: + - match: (?=\:) + pop: true + - include: function-header-open-brace + - include: function-header-close-brace-with-arg + function-parameter: + - match: (\.\.\.) + push: + - meta_scope: keyword.operator.nix + - match: '(,|(?=\}))' + pop: true + - include: others + - match: '\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*' + captures: + 0: variable.parameter.function.1.nix + push: + - match: '(,|(?=\}))' + captures: + 0: keyword.operator.nix + pop: true + - include: whitespace + - include: comment + - include: function-parameter-default + - include: expression + - include: others + function-parameter-default: + - match: \? + captures: + 0: keyword.operator.nix + push: + - match: "(?=[,}])" + pop: true + - include: expression + if: + - match: (?=\bif\b) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - match: \bif\b + captures: + 0: keyword.other.nix + push: + - match: \bth(?=en\b) + captures: + 0: keyword.other.nix + pop: true + - include: expression + - match: (?<=th)en\b + captures: + 0: keyword.other.nix + push: + - match: \bel(?=se\b) + captures: + 0: keyword.other.nix + pop: true + - include: expression + - match: (?<=el)se\b + captures: + 0: keyword.other.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + captures: + 0: keyword.other.nix + pop: true + - include: expression + illegal: + - match: . + scope: invalid.illegal + interpolation: + - match: '\$\{' + captures: + 0: punctuation.section.embedded.begin.nix + push: + - meta_scope: markup.italic + - match: '\}' + captures: + 0: punctuation.section.embedded.end.nix + pop: true + - include: expression + let: + - match: (?=\blet\b) + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - match: \blet\b + captures: + 0: keyword.other.nix + push: + - match: '(?=([\])};,]|\b(in|else|then)\b))' + pop: true + - match: '(?=\{)' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - match: '\{' + push: + - match: '\}' + pop: true + - include: attrset-contents + - match: '(^|(?<=\}))' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + - include: others + - include: attrset-contents + - include: others + - match: \bin\b + captures: + 0: keyword.other.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression + list: + - match: '\[' + captures: + 0: punctuation.definition.list.nix + push: + - match: '\]' + captures: + 0: punctuation.definition.list.nix + pop: true + - include: expression + list-and-cont: + - match: '(?=\[)' + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: list + - include: expression-cont + operator-unary: + - match: (!|-) + scope: keyword.operator.unary.nix + others: + - include: whitespace + - include: comment + - include: illegal + parameter-name: + - match: '\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*' + captures: + 0: variable.parameter.name.nix + parameter-name-and-cont: + - match: '\b[a-zA-Z\_][a-zA-Z0-9\_\''\-]*' + captures: + 0: variable.parameter.name.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + parens: + - match: \( + captures: + 0: punctuation.definition.expression.nix + push: + - match: \) + captures: + 0: punctuation.definition.expression.nix + pop: true + - include: expression + parens-and-cont: + - match: (?=\() + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: parens + - include: expression-cont + string: + - match: (?=\'\') + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - match: \'\' + captures: + 0: punctuation.definition.string.other.start.nix + push: + - meta_scope: string.quoted.other.nix + - match: \'\'(?!\$|\'|\\.) + captures: + 0: punctuation.definition.string.other.end.nix + pop: true + - match: \'\'(\$|\'|\\.) + scope: constant.character.escape.nix + - include: interpolation + - include: expression-cont + - match: (?=\") + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: string-quoted + - include: expression-cont + - match: '(~?[a-zA-Z0-9\.\_\-\+]*(\/[a-zA-Z0-9\.\_\-\+]+)+)' + captures: + 0: string.unquoted.path.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + - match: '(\<[a-zA-Z0-9\.\_\-\+]+(\/[a-zA-Z0-9\.\_\-\+]+)*\>)' + captures: + 0: string.unquoted.spath.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + - match: '([a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\'']+)' + captures: + 0: string.unquoted.url.nix + push: + - match: '(?=([\])};,]|\b(else|then)\b))' + pop: true + - include: expression-cont + string-quoted: + - match: \" + captures: + 0: punctuation.definition.string.double.start.nix + push: + - meta_scope: string.quoted.double.nix + - match: \" + captures: + 0: punctuation.definition.string.double.end.nix + pop: true + - match: \\. + scope: constant.character.escape.nix + - include: interpolation + whitespace: + - match: \s+ + with-assert: + - match: '(?=4.20.2.0 + , GLFW-b <1000 +... +``` + +--- + +``` hs +-- | src/Main.hs +module Main (main) where + +-- | windowing library +import qualified Graphics.UI.GLFW as GLFW + +-- | main +main :: IO () +main = do + -- initialize GLFW + _ <- GLFW.init + GLFW.defaultWindowHints + + -- we use GLSL version 3.3 Core here + GLFW.windowHint $ GLFW.WindowHint'ContextVersionMajor 3 + GLFW.windowHint $ GLFW.WindowHint'ContextVersionMinor 3 + GLFW.windowHint $ GLFW.WindowHint'OpenGLProfile GLFW.OpenGLProfile'Core + + -- monitor required to fullscreen at start + monitor <- GLFW.getPrimaryMonitor + + -- actually create the window + Just window <- GLFW.createWindow 256 256 "hs-glsl" monitor Nothing + GLFW.makeContextCurrent $ Just window + + -- enter loop + loop window + +-- | loop that runs every frame +loop :: GLFW.Window -> IO () +loop window = do + -- swap to next framebuffer + GLFW.swapBuffers window + + -- call next frame + loop window +``` + +Great, a fullscreen window that never closes! I'll go ahead and add a quick key callback so that pressing `esc` closes the program. + +``` +-- | src/Main.hs