Skip to content

Commit 371d3b4

Browse files
authored
feat(packages/emacs): add support for emacs major mode and vim syntax for dotprompt (#409)
1 parent 13917de commit 371d3b4

File tree

10 files changed

+391
-2
lines changed

10 files changed

+391
-2
lines changed

.release-please-config.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,26 @@
101101
"draft": false,
102102
"prerelease": false,
103103
"path": "packages/vscode/**"
104+
},
105+
"packages/vim": {
106+
"release-type": "simple",
107+
"package-name": "dotprompt-vim",
108+
"changelog-path": "CHANGELOG.md",
109+
"bump-minor-pre-major": true,
110+
"bump-patch-for-minor-pre-major": true,
111+
"draft": false,
112+
"prerelease": false,
113+
"path": "packages/vim/**"
114+
},
115+
"packages/emacs": {
116+
"release-type": "simple",
117+
"package-name": "dotprompt-emacs",
118+
"changelog-path": "CHANGELOG.md",
119+
"bump-minor-pre-major": true,
120+
"bump-patch-for-minor-pre-major": true,
121+
"draft": false,
122+
"prerelease": false,
123+
"path": "packages/emacs/**"
104124
}
105125
},
106126
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"

.release-please-manifest.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55
"go": "0.2.0",
66
"java": "0.1.0",
77
"rs": "0.1.0",
8-
"packages/vscode": "0.0.1"
8+
"packages/vscode": "0.0.1",
9+
"packages/vim": "0.1.0",
10+
"packages/emacs": "0.1.0"
911
}

packages/emacs/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Dotprompt Emacs Mode
2+
3+
Provides a major mode for editing Dotprompt (`.prompt`) files.
4+
5+
## Installation
6+
7+
### Manual
8+
9+
1. Copy `dotprompt-mode.el` to your load path (e.g., `~/.emacs.d/lisp/`).
10+
2. Add the following to your init file:
11+
12+
```elisp
13+
(add-to-list 'load-path "~/.emacs.d/lisp/")
14+
(require 'dotprompt-mode)
15+
```
16+
17+
## Features
18+
19+
- Syntax highlighting for:
20+
- Dotprompt markers (`<<<dotprompt:...>>>`)
21+
- Handlebars helpers (`if`, `unless`, `each`)
22+
- Dotprompt custom helpers (`json`, `role`, `history`)
23+
- Partials (`{{> ... }}`)
24+
- Auto-detection of `.prompt` files.

packages/emacs/dotprompt-mode.el

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
;;; dotprompt-mode.el --- Major mode for Dotprompt files -*- lexical-binding: t; -*-
2+
3+
;; Copyright 2026 Google LLC
4+
;;
5+
;; Licensed under the Apache License, Version 2.0 (the "License");
6+
;; you may not use this file except in compliance with the License.
7+
;; You may obtain a copy of the License at
8+
;;
9+
;; http://www.apache.org/licenses/LICENSE-2.0
10+
;;
11+
;; Unless required by applicable law or agreed to in writing, software
12+
;; distributed under the License is distributed on an "AS IS" BASIS,
13+
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
;; See the License for the specific language governing permissions and
15+
;; limitations under the License.
16+
17+
;; Author: Google
18+
;; Version: 0.1.0
19+
;; Keywords: languages, dotprompt
20+
;; URL: https://github.com/google/dotprompt
21+
22+
;;; Commentary:
23+
24+
;; Major mode for editing Dotprompt files (.prompt).
25+
;; Provides minimal syntax highlighting for markers, helpers, and partials.
26+
;; For best results with frontmatter, consider using polymode or mmm-mode.
27+
28+
;;; Code:
29+
30+
(defgroup dotprompt nil
31+
"Major mode for editing Dotprompt files."
32+
:prefix "dotprompt-"
33+
:group 'languages)
34+
35+
(defvar dotprompt-mode-hook nil
36+
"Hook run after entering `dotprompt-mode'.")
37+
38+
(defvar dotprompt-font-lock-keywords
39+
(list
40+
;; Markers <<<dotprompt:role:system>>>
41+
'("<<<dotprompt:[^>]+>>>" . font-lock-preprocessor-face)
42+
43+
;; Partials {{> partialName}}
44+
'("{{>\\s-*[a-zA-Z0-9_.-]+\\s-*\\(.*?\\)}}" . font-lock-builtin-face)
45+
46+
;; Handlebars Control Flow {{#if}} {{/if}}
47+
'("{{[#/]\\(if\\|unless\\|each\\|with\\|log\\|lookup\\|else\\)" 1 font-lock-keyword-face)
48+
49+
;; Dotprompt Helpers (distinct color)
50+
'("\\<\\(json\\|role\\|history\\|section\\|media\\|ifEquals\\|unlessEquals\\)\\>" . font-lock-function-name-face)
51+
52+
;; General tags
53+
'("{{" . font-lock-delimiter-face)
54+
'("}}" . font-lock-delimiter-face)
55+
)
56+
"Minimal highlighting for Dotprompt.")
57+
58+
;;;###autoload
59+
(define-derived-mode dotprompt-mode prog-mode "Dotprompt"
60+
"Major mode for editing Dotprompt files."
61+
62+
;; Comments
63+
(setq-local comment-start "{{! ")
64+
(setq-local comment-end " }}")
65+
66+
;; Font lock
67+
(setq-local font-lock-defaults '(dotprompt-font-lock-keywords)))
68+
69+
;;;###autoload
70+
(add-to-list 'auto-mode-alist '("\\.prompt\\'" . dotprompt-mode))
71+
72+
(provide 'dotprompt-mode)
73+
74+
;;; dotprompt-mode.el ends here

packages/vim/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Dotprompt Vim Plugin
2+
3+
Provides syntax highlighting and filetype detection for Dotprompt (`.prompt`) files.
4+
5+
## Installation
6+
7+
### Vundle
8+
```vim
9+
Plugin 'google/dotprompt', {'rtp': 'packages/vim'}
10+
```
11+
12+
### Plug
13+
```vim
14+
Plug 'google/dotprompt', {'rtp': 'packages/vim'}
15+
```
16+
17+
### Manual
18+
Copy the contents of `syntax/` and `ftdetect/` to your `~/.vim/` directory.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
" Copyright 2026 Google LLC
2+
"
3+
" Licensed under the Apache License, Version 2.0 (the "License");
4+
" you may not use this file except in compliance with the License.
5+
" You may obtain a copy of the License at
6+
"
7+
" http://www.apache.org/licenses/LICENSE-2.0
8+
"
9+
" Unless required by applicable law or agreed to in writing, software
10+
" distributed under the License is distributed on an "AS IS" BASIS,
11+
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
" See the License for the specific language governing permissions and
13+
" limitations under the License.
14+
"
15+
" SPDX-License-Identifier: Apache-2.0
16+
17+
autocmd BufNewFile,BufRead *.prompt set filetype=dotprompt

packages/vim/syntax/dotprompt.vim

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
" Copyright 2026 Google LLC
2+
"
3+
" Licensed under the Apache License, Version 2.0 (the "License");
4+
" you may not use this file except in compliance with the License.
5+
" You may obtain a copy of the License at
6+
"
7+
" http://www.apache.org/licenses/LICENSE-2.0
8+
"
9+
" Unless required by applicable law or agreed to in writing, software
10+
" distributed under the License is distributed on an "AS IS" BASIS,
11+
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
" See the License for the specific language governing permissions and
13+
" limitations under the License.
14+
"
15+
" SPDX-License-Identifier: Apache-2.0
16+
17+
" Vim syntax file
18+
" Language: Dotprompt
19+
" Maintainer: Google
20+
" License: Apache 2.0
21+
22+
if exists("b:current_syntax")
23+
finish
24+
endif
25+
26+
" Define Dotprompt specifics
27+
syntax match dotpromptMarker "<<<dotprompt:[^>]\+>>>"
28+
syntax match dotpromptPartial "{{>.\+}}"
29+
30+
" Handlebars/Dotprompt tags
31+
syntax region dotpromptTag start="{{" end="}}" contains=dotpromptKeyword,dotpromptString,dotpromptNumber,dotpromptBoolean
32+
33+
" Keywords inside tags
34+
syntax keyword dotpromptKeyword contained if unless each with log lookup else
35+
syntax keyword dotpromptKeyword contained json role history section media ifEquals unlessEquals
36+
37+
" Data types inside tags
38+
syntax region dotpromptString start=/"/ skip=/\\"/ end=/"/ contained
39+
syntax region dotpromptString start=/'/ skip=/\\'/ end=/'/ contained
40+
syntax match dotpromptNumber "\d\+" contained
41+
syntax keyword dotpromptBoolean contained true false null undefined
42+
43+
" Highlight links
44+
highlight default link dotpromptMarker PreProc
45+
highlight default link dotpromptPartial Structure
46+
highlight default link dotpromptTag Delimiter
47+
highlight default link dotpromptKeyword Keyword
48+
highlight default link dotpromptString String
49+
highlight default link dotpromptNumber Number
50+
highlight default link dotpromptBoolean Boolean
51+
52+
" Handle Frontmatter (YAML) - attempt to include standard YAML syntax
53+
let s:current_syntax = b:current_syntax
54+
unlet b:current_syntax
55+
syntax include @Yaml syntax/yaml.vim
56+
syntax region dotpromptFrontmatter start="\%^---" end="^---" contains=@Yaml keepend
57+
let b:current_syntax = s:current_syntax
58+
59+
let b:current_syntax = "dotprompt"

packages/vscode/syntaxes/dotprompt.tmLanguage.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,4 @@
129129
]
130130
}
131131
}
132-
}
132+
}

scripts/install_emacs_mode

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
# SPDX-License-Identifier: Apache-2.0
17+
18+
set -euo pipefail
19+
20+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
21+
EMACS_PKG_DIR="$REPO_ROOT/packages/emacs"
22+
23+
# Default target directory
24+
EMACS_LISP_DIR="$HOME/.emacs.d/lisp"
25+
26+
usage() {
27+
echo "Usage: $0 [options]"
28+
echo "Options:"
29+
echo " -d, --dest DIR Destination directory (default: ~/.emacs.d/lisp)"
30+
echo " -f, --force Overwrite existing files without prompting"
31+
echo " -h, --help Show this help message"
32+
exit 1
33+
}
34+
35+
# Parse arguments
36+
DEST_DIR=""
37+
FORCE=false
38+
39+
while [[ "$#" -gt 0 ]]; do
40+
case $1 in
41+
-d|--dest) DEST_DIR="$2"; shift ;;
42+
-f|--force) FORCE=true ;;
43+
-h|--help) usage ;;
44+
*) echo "Unknown parameter passed: $1"; usage ;;
45+
esac
46+
shift
47+
done
48+
49+
# Determine destination if not specified
50+
if [[ -z "$DEST_DIR" ]]; then
51+
DEST_DIR="$EMACS_LISP_DIR"
52+
fi
53+
54+
echo "Installing Dotprompt Emacs mode to: $DEST_DIR"
55+
56+
# Create directory
57+
mkdir -p "$DEST_DIR"
58+
59+
# Copy file
60+
echo "Copying dotprompt-mode.el..."
61+
if [ -f "$DEST_DIR/dotprompt-mode.el" ] && [ "$FORCE" = false ]; then
62+
read -p "File '$DEST_DIR/dotprompt-mode.el' exists. Overwrite? (y/N) " -n 1 -r
63+
echo
64+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
65+
echo "Skipping file copy."
66+
else
67+
cp "$EMACS_PKG_DIR/dotprompt-mode.el" "$DEST_DIR/"
68+
fi
69+
else
70+
cp "$EMACS_PKG_DIR/dotprompt-mode.el" "$DEST_DIR/"
71+
fi
72+
73+
echo "Installation complete!"
74+
echo ""
75+
echo "Add the following to your Emacs initialization file (~/.emacs or ~/.emacs.d/init.el):"
76+
echo ""
77+
echo "(add-to-list 'load-path \"$DEST_DIR\")"
78+
echo "(require 'dotprompt-mode)"

0 commit comments

Comments
 (0)