From eeaa8f019c532adaca9ece702bcf47202554d823 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Wed, 14 Oct 2026 13:53:48 +0300 Subject: [PATCH] Add Caddyfile syntax highlighting --- src/.vitepress/config.js | 4 + src/.vitepress/grammars/caddyfile.LICENSE | 21 + .../grammars/caddyfile.tmLanguage.json | 376 ++++++++++++++++++ 3 files changed, 401 insertions(+) create mode 100644 src/.vitepress/grammars/caddyfile.LICENSE create mode 100644 src/.vitepress/grammars/caddyfile.tmLanguage.json diff --git a/src/.vitepress/config.js b/src/.vitepress/config.js index 36ebf9b4..f7db34dd 100644 --- a/src/.vitepress/config.js +++ b/src/.vitepress/config.js @@ -1,5 +1,8 @@ import taskLists from 'markdown-it-task-lists' +// Based on https://github.com/caddyserver/vscode-caddyfile (MIT), with fixes for placeholders, IPv6 and global options +import caddyfileGrammar from './grammars/caddyfile.tmLanguage.json' + let currentYear = new Date().getFullYear(); export default { @@ -26,6 +29,7 @@ export default { ] }, markdown: { + languages: [{...caddyfileGrammar, name: 'caddyfile', aliases: ['caddy']}], config: (md) => { md.use(taskLists) } diff --git a/src/.vitepress/grammars/caddyfile.LICENSE b/src/.vitepress/grammars/caddyfile.LICENSE new file mode 100644 index 00000000..be6374e7 --- /dev/null +++ b/src/.vitepress/grammars/caddyfile.LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Matthew Penner + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/.vitepress/grammars/caddyfile.tmLanguage.json b/src/.vitepress/grammars/caddyfile.tmLanguage.json new file mode 100644 index 00000000..50b9fd38 --- /dev/null +++ b/src/.vitepress/grammars/caddyfile.tmLanguage.json @@ -0,0 +1,376 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + + "name": "Caddyfile", + "fileTypes": ["Caddyfile"], + "scopeName": "source.Caddyfile", + + "patterns": [ + { "include": "#comments" }, + { "include": "#strings" }, + { "include": "#placeholders" }, + { "include": "#domains" }, + { "include": "#status_codes" }, + { "include": "#path" }, + { "include": "#global_options" }, + { "include": "#matchers" }, + { "include": "#directive" }, + { "include": "#site_block_common" } + ], + + "repository": { + "comments": { + "patterns": [ + { + "name": "comment.line.Caddyfile", + "match": "\\s#.*" + }, + { + "name": "comment.line.Caddyfile", + "match": "^#.*" + } + ] + }, + + "strings": { + "patterns": [ + { + "comment": "Double Quoted Strings", + "begin": "\"", + "end": "\"", + "name": "string.quoted.double.Caddyfile", + "patterns": [ + { + "name": "constant.character.escape.Caddyfile", + "match": "\\\\\"" + }, + { "include": "#placeholders" } + ] + }, + { + "comment": "Backtick Strings", + "begin": "`", + "end": "`", + "name": "string.quoted.single.Caddyfile" + } + ] + }, + + "status_codes": { + "patterns": [ + { + "name": "constant.numeric.decimal", + "match": "\\s[0-9]{3}(?!\\.)" + } + ] + }, + + "path": { + "patterns": [ + { + "name": "keyword.control.caddyfile", + "match": "(unix/)*/[a-zA-Z0-9_\\-./*]+" + }, + { + "name": "variable.other.property.caddyfile", + "match": "\\*.[a-z]{1,5}" + }, + { + "name": "variable.other.property.caddyfile", + "match": "\\*/?" + }, + { + "name": "variable.other.property.caddyfile", + "match": "\\?/" + } + ] + }, + + "domains": { + "patterns": [ + { + "comment": "Domains and URLs", + "name": "keyword.control.caddyfile", + "match": "(https?://)*[a-z0-9-\\*]*(?:\\.[a-zA-Z]{2,})+(:[0-9]+)*[^\\s,]*" + }, + { + "comment": "localhost", + "name": "keyword.control.caddyfile", + "match": "localhost(:[0-9]+)*" + }, + { + "comment": "IPv4", + "name": "keyword.control.caddyfile", + "match": "((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + }, + { + "comment": "IPv6", + "name": "keyword.control.caddyfile", + "match": "(?