]> code.delx.au - gnu-emacs-elpa/blob - packages/systemd/systemd-mode.el
Make debbugs-newest-bugs more robust
[gnu-emacs-elpa] / packages / systemd / systemd-mode.el
1 ;;; systemd-mode.el --- Major modes for systemd unit files -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2016 Free Software Foundation, Inc.
4
5 ;; Author: Mario Lang <mlang@delysid.org>
6 ;; Keywords: files
7
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
12
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Todo:
22
23 ;; * Add support for systemd-networkd .link and .network files.
24
25 ;;; Code:
26
27 (require 'conf-mode)
28
29 (defvar systemd-unit-font-lock-keywords
30 '(;; [section]
31 ("^[ \t]*\\[\\(Unit\\|Service\\)\\]"
32 1 'font-lock-type-face)
33 ;; var=val
34 ("^[ \t]*\\(.+?\\)[ \t]*="
35 1 'font-lock-variable-name-face))
36 "Keywords to highlight in Conf mode.")
37
38 (defvar-local systemd-unit-mode-sections '("Unit" "Install"))
39
40 (defvar systemd-unit-mode-map
41 (let ((map (make-sparse-keymap)))
42 (define-key map "\t" #'completion-at-point)
43 map))
44
45 (define-derived-mode systemd-unit-mode conf-unix-mode "Systemd-Unit"
46 (conf-mode-initialize "#" systemd-unit-font-lock-keywords)
47 (add-hook 'completion-at-point-functions #'systemd-mode-completion-at-point
48 nil t)
49 (setq-local completion-ignore-case t))
50
51 ;;;###autoload
52 (define-derived-mode systemd-automount-mode systemd-unit-mode "Systemd-AutoMount"
53 "Major mode for editing systemd .automount unit files"
54 (add-to-list 'systemd-unit-mode-sections "AutoMount"))
55
56 ;;;###autoload
57 (define-derived-mode systemd-mount-mode systemd-unit-mode "Systemd-Mount"
58 "Major mode for editing systemd .mount unit files"
59 (add-to-list 'systemd-unit-mode-sections "Mount"))
60
61 ;;;###autoload
62 (define-derived-mode systemd-path-mode systemd-unit-mode "Systemd-Path"
63 "Major mode for editing systemd .path unit files"
64 (add-to-list 'systemd-unit-mode-sections "Path"))
65
66 ;;;###autoload
67 (define-derived-mode systemd-service-mode systemd-unit-mode "Systemd-Service"
68 "Major mode for editing systemd .service unit files."
69 (add-to-list 'systemd-unit-mode-sections "Service"))
70
71 ;;;###autoload
72 (define-derived-mode systemd-socket-mode systemd-unit-mode "Systemd-Socket"
73 "Major mode for editing systemd .socket unit files."
74 (add-to-list 'systemd-unit-mode-sections "Socket"))
75
76 ;;;###autoload
77 (define-derived-mode systemd-swap-mode systemd-unit-mode "Systemd-Swap"
78 "Major mode for editing systemd .swap unit files."
79 (add-to-list 'systemd-unit-mode-sections "Swap"))
80
81 ;;;###autoload
82 (define-derived-mode systemd-timer-mode systemd-unit-mode "Systemd-Timer"
83 "Major mode for editing systemd .timer unit files."
84 (add-to-list 'systemd-unit-mode-sections "Timer"))
85
86 (defvar systemd-mode-section-keywords-alist
87 '(("AutoMount"
88 "Where" "DirectoryMode" "TimeoutIdleSec")
89 ("Device")
90 ("Mount"
91 "What" "Where" "Type" "Options" "SloppyOptions" "DirectoryMode"
92 "TimeoutSec")
93 ("Path"
94 "PathExists" "PathExistsGlob" "PathChanged" "PathModified"
95 "DirectoryNotEmpty" "Unit" "MakeDirectory" "DirectoryMode")
96 ("Service"
97 "Type" "RemainAfterExit" "GuessMainPID" "PIDFile" "BusName"
98 "ExecStart" "ExecStartPre" "ExecStartPost" "ExecReload"
99 "ExecStop" "ExecStopPost" "RestartSec" "TimeoutStartSec"
100 "TimeoutStopSec" "TimeoutSec" "RuntimeMaxSec" "WatchdogSec"
101 "Restart" "SuccessExitStatus" "RestartPreventExitStatus"
102 "RestartForceExitStatus" "PermissionsStartOnly"
103 "RootDirectoryStartOnly" "NonBlocking" "NotifyAccess" "Sockets"
104 "FailureAction" "FileDescriptorStoreMax" "USBFunctionDescriptors"
105 "USBFunctionStrings")
106 ("Slice")
107 ("Socket"
108 "ListenStream" "ListenDatagram" "ListenSequentialPacket"
109 "ListenFIFO" "ListenSpecial" "ListenNetlink" "ListenMessageQueue"
110 "ListenUSBFunction" "SocketProtocol" "BindIPv6Only"
111 "Backlog" "BindToDevice" "SocketUser" "SocketGroup"
112 "SocketMode" "DirectoryMode" "Accept" "Writable" "MaxConnections"
113 "KeepAlive" "KeepAliveTimeSec" "KeepAliveIntervalSec"
114 "KeepAliveProbes" "NoDelay" "Priority" "DeferAcceptSec"
115 "ReceiveBuffer" "SendBuffer" "IPTOS" "IPTTL" "Mark" "ReusePort"
116 "SmackLabel" "SmackLabelIPIn" "SmackLabelIPOut"
117 "SELinuxContextFromNet" "PipeSize" "MessageQueueMaxMessages"
118 "MessageQueueMessageSize" "FreeBind" "Transparent" "Broadcast"
119 "PassCredentials" "PassSecurity" "TCPCongestion" "ExecStartPre"
120 "ExecStartPost" "ExecStopPre" "ExecStopPost" "TimeoutSec"
121 "Service" "RemoveOnStop" "Symlinks" "FileDescriptorName"
122 "TriggerLimitIntervalSec" "TriggerLimitBurst")
123 ("Swap"
124 "What" "Priority" "Options" "TimeoutSec")
125 ("Target")
126 ("Timer"
127 "OnActiveSec" "OnBootSec" "OnStartupSec" "OnUnitActiveSec"
128 "OnUnitInactiveSec" "OnCalendar" "AccuracySec" "RandomizedDelaySec"
129 "Unit" "Persistent" "WakeSystem" "RemainAfterElapse")
130 ("Unit"
131 "Description" "Documentation" "Requires" "Requisite" "Wants" "BindsTo"
132 "PartOf" "Conflicts" "Before" "After" "OnFailure" "PropagatesReloadTo"
133 "ReloadPropagatedFrom" "JoinsNamespaceOf" "RequiresMountsFor"
134 "OnFailureJobMode" "IgnoreOnIsolate" "StopWhenUnneeded" "RefuseManualStart"
135 "RefuseManualStop" "AllowIsolate" "DefaultDependencies"
136 "JobTimeoutSec" "JobTimeoutAction" "JobTimeoutRebootArgument"
137 "StartLimitIntervalSec" "StartLimitBurst"
138 "StartLimitAction" "RebootArgument"
139 "ConditionArchitecture" "ConditionVirtualization" "ConditionHost"
140 "ConditionKernelCommandLine" "ConditionSecurity" "ConditionCapability"
141 "ConditionACPower" "ConditionNeedsUpdate" "ConditionFirstBoot"
142 "ConditionPathExists" "ConditionPathExistsGlob" "ConditionPathIsDirectory"
143 "ConditionPathIsSymbolicLink" "ConditionPathIsMountPoint"
144 "ConditionPathIsReadWrite" "ConditionDirectoryNotEmpty"
145 "ConditionFileNotEmpty" "ConditionFileIsExecutable"
146 "AssertArchitecture" "AssertVirtualization" "AssertHost"
147 "AssertKernelCommandLine" "AssertSecurity" "AssertCapability"
148 "AssertACPower" "AssertNeedsUpdate" "AssertFirstBoot" "AssertPathExists"
149 "AssertPathExistsGlob" "AssertPathIsDirectory" "AssertPathIsSymbolicLink"
150 "AssertPathIsMountPoint" "AssertPathIsReadWrite" "AssertDirectoryNotEmpty"
151 "AssertFileNotEmpty" "AssertFileIsExecutable"
152 "SourcePath")
153 ("Install"
154 "Alias" "WantedBy" "RequiredBy" "Also" "DefaultInstance")))
155
156 (defvar systemd-mode-section-regexp "^[ \t]*\\[\\([[:alpha:]]+\\)]")
157
158 (defun systemd-mode-completion-at-point ()
159 (if (save-excursion (re-search-backward systemd-mode-section-regexp nil t))
160 (let ((section (match-string-no-properties 1)))
161 (if (member-ignore-case section systemd-unit-mode-sections)
162 (let ((keywords (cdr (assoc-string
163 section systemd-mode-section-keywords-alist t))))
164 (when keywords
165 (let ((end (point)))
166 (save-excursion
167 (skip-chars-backward "[:alpha:]")
168 (let ((start (point)))
169 (skip-chars-backward " \t")
170 (when (eq (line-beginning-position) (point))
171 (list start end (mapcar (lambda (str) (concat str "="))
172 keywords))))))))
173 (display-warning major-mode
174 (format "Unexpected section [%s]." section)
175 :warning)
176 nil))))
177
178 ;;;###autoload
179 (add-to-list 'auto-mode-alist '("\\.automount\\'" . systemd-automount-mode))
180
181 ;;;###autoload
182 (add-to-list 'auto-mode-alist '("\\.mount\\'" . systemd-mount-mode))
183
184 ;;;###autoload
185 (add-to-list 'auto-mode-alist '("\\.path\\'" . systemd-path-mode))
186
187 ;;;###autoload
188 (add-to-list 'auto-mode-alist '("\\.service\\'" . systemd-service-mode))
189
190 ;;;###autoload
191 (add-to-list 'auto-mode-alist '("\\.socket\\'" . systemd-socket-mode))
192
193 ;;;###autoload
194 (add-to-list 'auto-mode-alist '("\\.swap\\'" . systemd-swap-mode))
195
196 ;;;###autoload
197 (add-to-list 'auto-mode-alist '("\\.timer\\'" . systemd-timer-mode))
198
199 (provide 'systemd-mode)
200 ;;; systemd-mode.el ends here