From c89425155a0150d39de6144dfa30382c8dd91d30 Mon Sep 17 00:00:00 2001 From: Merlin Diavova Date: Mon, 8 Sep 2025 11:29:52 +0100 Subject: [PATCH] Add language_zsh syntax highlighting for Zsh - - Recognises common Zsh files like `.zshrc`, `.zshenv`, `.zprofile`, etc. --- manifest.json | 15 +++- plugins/language_zsh.lua | 170 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 plugins/language_zsh.lua diff --git a/manifest.json b/manifest.json index b6c86be1..f0b73ba2 100644 --- a/manifest.json +++ b/manifest.json @@ -166,13 +166,14 @@ "language_v": {}, "language_wren": {}, "language_yaml": {}, - "language_zig": {} + "language_zig": {}, + "language_zsh": {} }, "description": "A metapackage containing all publically accessible language syntaxes.", "id": "meta_languages", "mod_version": "3", "type": "meta", - "version": "0.1.20" + "version": "0.1.21" }, { "description": "Align multiple carets and selections *([clip](https://user-images.githubusercontent.com/2798487/165631951-532f8d24-d596-4dd0-9d21-ff53c71ed32f.mp4))*", @@ -1774,6 +1775,16 @@ ], "version": "0.2" }, + { + "description": "Syntax for Zsh shell scripting language", + "id": "language_zsh", + "mod_version": "3.1", + "path": "plugins/language_zsh.lua", + "tags": [ + "language" + ], + "version": "0.1.0" + }, { "description": "Automatically inserts indentation and closing bracket/text after newline", "id": "lfautoinsert", diff --git a/plugins/language_zsh.lua b/plugins/language_zsh.lua new file mode 100644 index 00000000..542a19c6 --- /dev/null +++ b/plugins/language_zsh.lua @@ -0,0 +1,170 @@ +-- mod-version:3.1 +local syntax = require "core.syntax" + +local hex = {pattern = "\\[xX][%da-fA-F][%da-fA-F]", type = "function"} +local backslash_escape = {pattern = "\\.", type = "function"} +local unicode = { + pattern = "\\[uU][%da-fA-F][%da-fA-F][%da-fA-F][%da-fA-F]", + type = "function" +} + +local string_interpolation_syntax = {patterns = {}, symbols = {}} + +local zsh_syntax = { + name = "Zsh", + files = { + "%.zsh$", PATHSEP .. "%.zshrc$", "%.zshenv$", "%.zprofile$", "%.zlogin$", + "%.zlogout$" + }, + headers = "^#!.*zsh%s*.*$", + comment = "#", + patterns = { + -- Comments + {pattern = "#.*", type = "comment"}, -- Strings (with interpolation) + { + pattern = {"\"", "\"", "\\"}, + type = "string", + syntax = string_interpolation_syntax + }, {pattern = {"'", "'", "\\"}, type = "string"}, { + pattern = {"`", "`", "\\"}, + type = "string", + syntax = string_interpolation_syntax + }, { + pattern = {"%$%(", "%)", "\\"}, + type = "string", + syntax = string_interpolation_syntax + }, -- Numbers + {pattern = "%f[%w_%.%/]%d[%d%.]*%f[^%w_%.]", type = "number"}, + {pattern = "0x[%da-fA-F]+", type = "number"}, + {pattern = "0[0-7]+", type = "number"}, -- Operators + {pattern = "==|!=|<=|>=|<|>", type = "operator"}, + {pattern = "[=!<>|&%[%]+:%*%-]", type = "operator"}, + {pattern = "+=", type = "operator"}, + {pattern = "[%+%-*/%%]=?", type = "operator"}, + {pattern = "&&|\\|\\||!", type = "operator"}, -- Redirection + { + pattern = "<<<|>>>|<<|>>|<|>|<>|>\\||\\|&|&>|>&|2>|2>>|2>&1", + type = "operator" + }, -- Variable expansions + {pattern = "%${.-}", type = "keyword2"}, + {pattern = "%$[%w_]+", type = "keyword2"}, + {pattern = "%$[%d@#*]", type = "keyword2"}, -- Function definitions + {pattern = "%f[%w_]function%s+[%w_]+%s*%(%)", type = "function"}, + {pattern = "%f[%w_][%w_]+%s*%(%)", type = "function"}, -- Variable assignment + {pattern = "[%a_][%w_]*%f[%+=]", type = "keyword2"}, -- Arrays + {pattern = "%b()", type = "symbol"}, -- general matching for `(...)` + -- All other words + {pattern = "[%a_][%w_%-]*", type = "symbol"} + }, + + symbols = { + ["if"] = "keyword", + ["then"] = "keyword", + ["else"] = "keyword", + ["elif"] = "keyword", + ["fi"] = "keyword", + ["for"] = "keyword", + ["while"] = "keyword", + ["until"] = "keyword", + ["do"] = "keyword", + ["done"] = "keyword", + ["in"] = "keyword", + ["case"] = "keyword", + ["esac"] = "keyword", + ["function"] = "keyword", + ["time"] = "keyword", + ["coproc"] = "keyword", + ["repeat"] = "keyword", + ["select"] = "keyword", + ["always"] = "keyword", + + -- builtins + ["alias"] = "keyword", + ["autoload"] = "keyword", + ["bg"] = "keyword", + ["bindkey"] = "keyword", + ["break"] = "keyword", + ["builtin"] = "keyword", + ["cd"] = "keyword", + ["chdir"] = "keyword", + ["command"] = "keyword", + ["compdef"] = "keyword", + ["compinit"] = "keyword", + ["continue"] = "keyword", + ["dirs"] = "keyword", + ["disable"] = "keyword", + ["disown"] = "keyword", + ["echo"] = "keyword", + ["emulate"] = "keyword", + ["enable"] = "keyword", + ["eval"] = "keyword", + ["exec"] = "keyword", + ["exit"] = "keyword", + ["fc"] = "keyword", + ["fg"] = "keyword", + ["getopts"] = "keyword", + ["hash"] = "keyword", + ["history"] = "keyword", + ["jobs"] = "keyword", + ["kill"] = "keyword", + ["let"] = "keyword", + ["limit"] = "keyword", + ["logout"] = "keyword", + ["popd"] = "keyword", + ["print"] = "keyword", + ["pushd"] = "keyword", + ["pwd"] = "keyword", + ["read"] = "keyword", + ["rehash"] = "keyword", + ["return"] = "keyword", + ["setopt"] = "keyword", + ["shift"] = "keyword", + ["source"] = "keyword", + ["suspend"] = "keyword", + ["test"] = "keyword", + ["times"] = "keyword", + ["trap"] = "keyword", + ["true"] = "literal", + ["false"] = "literal", + ["ttyctl"] = "keyword", + ["type"] = "keyword", + ["ulimit"] = "keyword", + ["umask"] = "keyword", + ["unalias"] = "keyword", + ["unfunction"] = "keyword", + ["unhash"] = "keyword", + ["unlimit"] = "keyword", + ["unset"] = "keyword", + ["unsetopt"] = "keyword", + ["vared"] = "keyword", + ["wait"] = "keyword", + ["whence"] = "keyword", + ["where"] = "keyword", + ["which"] = "keyword", + ["zcompile"] = "keyword", + ["zformat"] = "keyword", + ["zftp"] = "keyword", + ["zle"] = "keyword", + ["zmodload"] = "keyword", + ["zparseopts"] = "keyword", + ["zprof"] = "keyword", + ["zpty"] = "keyword", + ["zregexparse"] = "keyword", + ["zsocket"] = "keyword", + ["zstyle"] = "keyword", + ["ztsched"] = "keyword" + } +} + +local function merge_tables(a, b) for _, v in ipairs(b) do table.insert(a, v) end end + +merge_tables(string_interpolation_syntax.patterns, { + unicode, hex, backslash_escape, {pattern = "%$[%w_]+", type = "keyword2"}, + {pattern = "%$[@#]", type = "keyword2"}, + {pattern = "%${.-}", type = "keyword2"}, + {pattern = {"%$%(%(", "%)%)"}, type = "keyword2", syntax = zsh_syntax}, + {pattern = {"%$%(", "%)"}, type = "keyword2", syntax = zsh_syntax}, + {pattern = "[%S][%w]*", type = "string"} +}) + +syntax.add(zsh_syntax)