Skip to content

Commit 1aad193

Browse files
author
quinox
committed
Generate vim syntax based on the documentation
1 parent 195653b commit 1aad193

File tree

5 files changed

+251
-12
lines changed

5 files changed

+251
-12
lines changed

man/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
TARGETS := flashmq.1 flashmq.conf.5 flashmq.1.html flashmq.conf.5.html
1+
TARGETS := flashmq.1 flashmq.conf.5 flashmq.1.html flashmq.conf.5.html flashmq.vim
22

33
all: $(TARGETS)
44

@@ -29,3 +29,6 @@ clean:
2929

3030
%.html: docbook5-to-html5/docbook5-to-html5.xsl %.dbk5
3131
xsltproc $^ > $@
32+
33+
%.vim:
34+
vim/syntax.generate vim/syntax.template.vim flashmq.conf.5.dbk5 > $@

man/flashmq.conf.5.dbk5

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@
575575
Listen parameters can only be used within <literal>listen { }</literal> blocks.
576576
</para>
577577
<variablelist>
578-
<varlistentry xml:id="port">
578+
<varlistentry xml:id="listen__port">
579579
<term><option>port</option></term>
580580
<listitem>
581581
<para>
@@ -605,7 +605,7 @@
605605
</itemizedlist>
606606
</listitem>
607607
</varlistentry>
608-
<varlistentry xml:id="protocol">
608+
<varlistentry xml:id="listen__protocol">
609609
<term><option>protocol</option></term>
610610
<listitem>
611611
<para>
@@ -621,7 +621,7 @@
621621
</para>
622622
</listitem>
623623
</varlistentry>
624-
<varlistentry xml:id="inet_protocol">
624+
<varlistentry xml:id="listen__inet_protocol">
625625
<term><option>inet_protocol</option></term>
626626
<listitem>
627627
<para>
@@ -643,31 +643,31 @@
643643
</para>
644644
</listitem>
645645
</varlistentry>
646-
<varlistentry xml:id="inet4_bind_address">
646+
<varlistentry xml:id="listen__inet4_bind_address">
647647
<term><option>inet4_bind_address</option> <replaceable>inet4address</replaceable></term>
648648
<listitem>
649649
<para>
650650
Default: 0.0.0.0
651651
</para>
652652
</listitem>
653653
</varlistentry>
654-
<varlistentry xml:id="inet6_bind_address">
654+
<varlistentry xml:id="listen__inet6_bind_address">
655655
<term><option>inet6_bind_address</option> <replaceable>inet6address</replaceable></term>
656656
<listitem>
657657
<para>
658658
Default: ::0
659659
</para>
660660
</listitem>
661661
</varlistentry>
662-
<varlistentry xml:id="fullchain">
662+
<varlistentry xml:id="listen__fullchain">
663663
<term><option>fullchain</option> <replaceable>/foobar/server.crt</replaceable></term>
664664
<listitem>
665665
<para>
666666
Specifying a chain makes the listener SSL, and also requires the <option>privkey</option> to be set.
667667
</para>
668668
</listitem>
669669
</varlistentry>
670-
<varlistentry xml:id="privkey">
670+
<varlistentry xml:id="listen__privkey">
671671
<term><option>privkey</option> <replaceable>/foobar/server.key</replaceable></term>
672672
<listitem>
673673
<para>
@@ -676,7 +676,7 @@
676676
</listitem>
677677
</varlistentry>
678678

679-
<varlistentry xml:id="client_verification_ca_file">
679+
<varlistentry xml:id="listen__client_verification_ca_file">
680680
<term><option>client_verification_ca_file</option> <replaceable>/foobar/client_authority.crt</replaceable></term>
681681
<listitem>
682682
<para>
@@ -688,7 +688,7 @@
688688
</listitem>
689689
</varlistentry>
690690

691-
<varlistentry xml:id="client_verification_ca_dir">
691+
<varlistentry xml:id="listen__client_verification_ca_dir">
692692
<term><option>client_verification_ca_dir</option> <replaceable>/foobar/dir_with_certificates</replaceable></term>
693693
<listitem>
694694
<para>
@@ -703,7 +703,7 @@
703703
</listitem>
704704
</varlistentry>
705705

706-
<varlistentry xml:id="client_verification_still_do_authn">
706+
<varlistentry xml:id="listen__client_verification_still_do_authn">
707707
<term><option>client_verification_still_do_authn</option> <replaceable>true/false</replaceable></term>
708708
<listitem>
709709
<para>
@@ -721,7 +721,7 @@
721721
</listitem>
722722
</varlistentry>
723723

724-
<varlistentry xml:id="haproxy">
724+
<varlistentry xml:id="listen__haproxy">
725725
<term><option>haproxy</option> <replaceable>true/false</replaceable></term>
726726
<listitem>
727727
<para>

man/flashmq.vim

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
" Vim syntax file
2+
" Language: FlashMQ configuration file
3+
4+
"
5+
" Goals:
6+
"
7+
" Make incorrect / unknown options stand out. Special attention is given to
8+
" also have this work correctly for blocks, E.G., the toplevel directive
9+
" `log_file` is colored in a global scope but not when it's used inside a
10+
" `listen` block
11+
"
12+
" https://vimdoc.sourceforge.net/htmldoc/syntax.html
13+
"
14+
" TODO:
15+
" - Test number of arguments, specifically: most options take 1 argument, but
16+
" fe. bridge__subscribe takes an optional second argument
17+
" - Deal with quoted options?
18+
"
19+
20+
if exists("b:current_syntax")
21+
finish
22+
endif
23+
let b:current_syntax = "flashmq"
24+
25+
syn region fmqComment display oneline start='^\s*#' end='$'
26+
27+
" We "render" fmqWrongBlock as Error (which makes it red), but then also use
28+
" transparent which makes it be the color of the parent, so it all becomes a
29+
" neutral color.
30+
" Without the transparent+Error trick you would see fmqTopLevelDirective
31+
" highlighted inside blocks which is undesirable: you can't specify `log_file`
32+
" inside a `listen` block, so it shouldn't get colorized.
33+
"
34+
" Real blocks (like `listen` and `bridge`) are defined later and thus get a
35+
" higher priority, and will replace this match.
36+
syn region fmqWrongBlock start=+^.*{+ end=+}+ transparent contains=NONE,fmqComment
37+
38+
hi link fmqComment Comment
39+
hi link fmqWrongBlock Error
40+
hi link fmqTopLevelDirective Type
41+
42+
" The rest of this file has been dynamically generated
43+
"
44+
" Local scopes
45+
"
46+
47+
syn match fmqTopLevelDirective "^\s*allow_anonymous\s"
48+
syn match fmqTopLevelDirective "^\s*allow_unsafe_clientid_chars\s"
49+
syn match fmqTopLevelDirective "^\s*allow_unsafe_username_chars\s"
50+
syn match fmq_bridge_Directive "^\s*address\s" contained
51+
syn match fmq_bridge_Directive "^\s*bridge_protocol_bit\s" contained
52+
syn match fmq_bridge_Directive "^\s*ca_dir\s" contained
53+
syn match fmq_bridge_Directive "^\s*ca_file\s" contained
54+
syn match fmq_bridge_Directive "^\s*clientid_prefix\s" contained
55+
syn match fmq_bridge_Directive "^\s*inet_protocol\s" contained
56+
syn match fmq_bridge_Directive "^\s*keepalive\s" contained
57+
syn match fmq_bridge_Directive "^\s*local_clean_start\s" contained
58+
syn match fmq_bridge_Directive "^\s*local_session_expiry_interval\s" contained
59+
syn match fmq_bridge_Directive "^\s*local_username\s" contained
60+
syn match fmq_bridge_Directive "^\s*max_incoming_topic_aliases\s" contained
61+
syn match fmq_bridge_Directive "^\s*max_outgoing_topic_aliases\s" contained
62+
syn match fmq_bridge_Directive "^\s*port\s" contained
63+
syn match fmq_bridge_Directive "^\s*protocol_version\s" contained
64+
syn match fmq_bridge_Directive "^\s*publish\s" contained
65+
syn match fmq_bridge_Directive "^\s*remote_clean_start\s" contained
66+
syn match fmq_bridge_Directive "^\s*remote_password\s" contained
67+
syn match fmq_bridge_Directive "^\s*remote_retain_available\s" contained
68+
syn match fmq_bridge_Directive "^\s*remote_session_expiry_interval\s" contained
69+
syn match fmq_bridge_Directive "^\s*remote_username\s" contained
70+
syn match fmq_bridge_Directive "^\s*subscribe\s" contained
71+
syn match fmq_bridge_Directive "^\s*tls\s" contained
72+
syn match fmq_bridge_Directive "^\s*use_saved_clientid\s" contained
73+
syn match fmqTopLevelDirective "^\s*client_initial_buffer_size\s"
74+
syn match fmqTopLevelDirective "^\s*client_max_write_buffer_size\s"
75+
syn match fmqTopLevelDirective "^\s*expire_retained_messages_after_seconds\s"
76+
syn match fmqTopLevelDirective "^\s*expire_sessions_after_seconds\s"
77+
syn match fmqTopLevelDirective "^\s*include_dir\s"
78+
syn match fmq_listen_Directive "^\s*allow_anonymous\s" contained
79+
syn match fmq_listen_Directive "^\s*client_verification_ca_dir\s" contained
80+
syn match fmq_listen_Directive "^\s*client_verification_ca_file\s" contained
81+
syn match fmq_listen_Directive "^\s*client_verification_still_do_authn\s" contained
82+
syn match fmq_listen_Directive "^\s*fullchain\s" contained
83+
syn match fmq_listen_Directive "^\s*haproxy\s" contained
84+
syn match fmq_listen_Directive "^\s*inet4_bind_address\s" contained
85+
syn match fmq_listen_Directive "^\s*inet6_bind_address\s" contained
86+
syn match fmq_listen_Directive "^\s*inet_protocol\s" contained
87+
syn match fmq_listen_Directive "^\s*port\s" contained
88+
syn match fmq_listen_Directive "^\s*privkey\s" contained
89+
syn match fmq_listen_Directive "^\s*protocol\s" contained
90+
syn match fmqTopLevelDirective "^\s*log_debug\s"
91+
syn match fmqTopLevelDirective "^\s*log_file\s"
92+
syn match fmqTopLevelDirective "^\s*log_level\s"
93+
syn match fmqTopLevelDirective "^\s*log_subscriptions\s"
94+
syn match fmqTopLevelDirective "^\s*max_event_loop_drift\s"
95+
syn match fmqTopLevelDirective "^\s*max_incoming_topic_alias_value\s"
96+
syn match fmqTopLevelDirective "^\s*max_outgoing_topic_alias_value\s"
97+
syn match fmqTopLevelDirective "^\s*max_packet_size\s"
98+
syn match fmqTopLevelDirective "^\s*minimum_wildcard_subscription_depth\s"
99+
syn match fmqTopLevelDirective "^\s*mosquitto_acl_file\s"
100+
syn match fmqTopLevelDirective "^\s*mosquitto_password_file\s"
101+
syn match fmqTopLevelDirective "^\s*overload_mode\s"
102+
syn match fmqTopLevelDirective "^\s*plugin\s"
103+
syn match fmqTopLevelDirective "^\s*plugin_opt_\s"
104+
syn match fmqTopLevelDirective "^\s*plugin_serialize_auth_checks\s"
105+
syn match fmqTopLevelDirective "^\s*plugin_serialize_init\s"
106+
syn match fmqTopLevelDirective "^\s*plugin_timer_period\s"
107+
syn match fmqTopLevelDirective "^\s*quiet\s"
108+
syn match fmqTopLevelDirective "^\s*retained_messages_delivery_limit\s"
109+
syn match fmqTopLevelDirective "^\s*retained_messages_mode\s"
110+
syn match fmqTopLevelDirective "^\s*retained_messages_node_limit\s"
111+
syn match fmqTopLevelDirective "^\s*rlimit_nofile\s"
112+
syn match fmqTopLevelDirective "^\s*shared_subscription_targeting\s"
113+
syn match fmqTopLevelDirective "^\s*storage_dir\s"
114+
syn match fmqTopLevelDirective "^\s*thread_count\s"
115+
syn match fmqTopLevelDirective "^\s*websocket_set_real_ip_from\s"
116+
syn match fmqTopLevelDirective "^\s*wildcard_subscription_deny_mode\s"
117+
syn match fmqTopLevelDirective "^\s*wills_enabled\s"
118+
syn match fmqTopLevelDirective "^\s*zero_byte_username_is_anonymous\s"
119+
120+
"
121+
" Global scopes
122+
"
123+
124+
syn region fmq_bridge_InnerBlock start="{" end="}" contains=fmq_bridge_Directive,fmqComment
125+
syn region fmq_bridge_Block start="^bridge\s" end="$" contains=fmq_bridge_InnerBlock
126+
hi link fmq_bridge_Directive Type
127+
hi link fmq_bridge_Block Statement
128+
129+
syn region fmq_listen_InnerBlock start="{" end="}" contains=fmq_listen_Directive,fmqComment
130+
syn region fmq_listen_Block start="^listen\s" end="$" contains=fmq_listen_InnerBlock
131+
hi link fmq_listen_Directive Type
132+
hi link fmq_listen_Block Statement
133+

man/vim/syntax.generate

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
set -eu
3+
4+
die() {
5+
>&2 echo "Fatal error: $*"
6+
exit 9
7+
}
8+
9+
[[ $# -eq 2 ]] || die "Expected 2 arguments, got $#: $*
10+
Usage: [ template file ] [ .dbk5 file ]"
11+
12+
template="$1"
13+
dbk5="$2"
14+
15+
cat "$template"
16+
17+
# Finding config options
18+
xmlnames=$(sed -n '/^\s*<varlistentry xml:id="\([^ "]*\)">.*/ { s//\1/; p }' "$dbk5" | sort)
19+
readarray -t all_config_names <<< "$xmlnames"
20+
21+
# This will contain listen, bridge etc.
22+
declare -a GLOBAL_SCOPES=()
23+
24+
echo "\""
25+
echo "\" Local scopes"
26+
echo "\""
27+
echo ""
28+
29+
for configname in "${all_config_names[@]}"
30+
do
31+
if [[ "$configname" == *"__"* ]];
32+
then
33+
# this is a nested option like bridge__address
34+
scope=${configname%__*} # bridge
35+
localname=${configname#*__} # address
36+
echo "syn match fmq_${scope}_Directive \"^\s*$localname\s\" contained"
37+
GLOBAL_SCOPES+=($scope)
38+
39+
else
40+
# this is a global option like log_file
41+
echo "syn match fmqTopLevelDirective \"^\s*$configname\s\""
42+
fi
43+
done
44+
45+
readarray -t unique_global_scopes <<< $(echo "${GLOBAL_SCOPES[*]}" | sed 's/ /\n/g' | sort | uniq)
46+
47+
echo ""
48+
echo "\""
49+
echo "\" Global scopes"
50+
echo "\""
51+
echo ""
52+
53+
for scope in "${unique_global_scopes[@]}"
54+
do
55+
echo "syn region fmq_${scope}_InnerBlock start=\"{\" end=\"}\" contains=fmq_${scope}_Directive,fmqComment"
56+
echo "syn region fmq_${scope}_Block start=\"^$scope\s\" end=\"$\" contains=fmq_${scope}_InnerBlock"
57+
echo "hi link fmq_${scope}_Directive Type"
58+
echo "hi link fmq_${scope}_Block Statement"
59+
echo ""
60+
done
61+

man/vim/syntax.template.vim

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
" Vim syntax file
2+
" Language: FlashMQ configuration file
3+
4+
"
5+
" Goals:
6+
"
7+
" Make incorrect / unknown options stand out. Special attention is given to
8+
" also have this work correctly for blocks, E.G., the toplevel directive
9+
" `log_file` is colored in a global scope but not when it's used inside a
10+
" `listen` block
11+
"
12+
" https://vimdoc.sourceforge.net/htmldoc/syntax.html
13+
"
14+
" TODO:
15+
" - Test number of arguments, specifically: most options take 1 argument, but
16+
" fe. bridge__subscribe takes an optional second argument
17+
" - Deal with quoted options?
18+
"
19+
20+
if exists("b:current_syntax")
21+
finish
22+
endif
23+
let b:current_syntax = "flashmq"
24+
25+
syn region fmqComment display oneline start='^\s*#' end='$'
26+
27+
" We "render" fmqWrongBlock as Error (which makes it red), but then also use
28+
" transparent which makes it be the color of the parent, so it all becomes a
29+
" neutral color.
30+
" Without the transparent+Error trick you would see fmqTopLevelDirective
31+
" highlighted inside blocks which is undesirable: you can't specify `log_file`
32+
" inside a `listen` block, so it shouldn't get colorized.
33+
"
34+
" Real blocks (like `listen` and `bridge`) are defined later and thus get a
35+
" higher priority, and will replace this match.
36+
syn region fmqWrongBlock start=+^.*{+ end=+}+ transparent contains=NONE,fmqComment
37+
38+
hi link fmqComment Comment
39+
hi link fmqWrongBlock Error
40+
hi link fmqTopLevelDirective Type
41+
42+
" The rest of this file has been dynamically generated

0 commit comments

Comments
 (0)