emacs-config/elisp/firejail-mode.el

135 lines
7.0 KiB
EmacsLisp
Raw Normal View History

2023-10-13 11:41:29 -07:00
;;; firejail-mode --- Major mode for editing firejail profiles -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:
(defconst firejail-profile-font-lock-keywords
(let* ((normal '("quiet" "include" "noblacklist" "nowhitelist"
"blacklist" "blacklist-nolog" "bind" "disable-mnt"
"keep-config-pulse" "keep-dev-shm" "keep-var-tmp"
"mkdir" "mkfile" "noexec" "private" "private-bin"
"private-cache" "private-cwd" "private-dev"
"private-etc" "private-home" "private-lib"
"private-opt" "private-srv" "private-tmp"
"read-only" "read-write" "tmpfs" "tracelog"
"whitelist" "whitelist-ro" "writable-etc"
"writable-run-user" "writable-var"
"writable-var-log" "allow-debuggers" "apparmor"
"caps" "caps.keep" "caps.drop"
"memory-deny-write-execute" "nonewprivs"
"noprinters" "noroot" "restrict-namespaces"
"seccomp" "seccomp.32" "seccomp.drop"
"seccomp.32.drop" "seccomp.keep" "seccomp.32.keep"
"protocol" "xephyr-screen" "dbus-system.own"
"dbus-system.talk" "dbus-system.see"
"dbus-system.call" "dbus-system.broadcast"
"dbus-user.own" "dbus-user.talk" "dbus-user.see"
"dbus-user.call" "dbus-user.broadcast" "nodbus"
"cpu" "nice" "rlimit-as" "rlimit-cpu"
"rlimit-fsize" "rlimit-nproc" "rlimit-nofile"
"rlimit-sigpending" "timeout" "allusers" "env"
"ipc-namespace" "keep-fd" "name" "no3d"
"noautopulse" "nodvd" "nogroups" "noinput"
"nosound" "notv" "nou2f" "novideo" "machine-id"
"defaultgw" "dns" "hostname" "hosts-file" "x11"
"dbus-system" "dbus-user" "ip" "ip6" "iprange"
"mac" "mtu" "net" "netfilter" "netfilter" "netlock"
"netmask" "netns" "veth-name"
"deterministic-exit-code" "deterministic-shutdown"
"join-or-start"))
(take-all-list '("caps.drop"))
(take-none-list '("shell" "net"))
(comment-rx '("^.*\\(#.*\\)$" 1 font-lock-comment-face))
(dbus-system-user-rx '("^ *\\(\\?[A-Z_]+: +\\)?\
\\(\\(ignore +\\)?\
dbus-\\(system\\|user\\) +\\(none\\|filter\\)?\\)" . 2))
(x11-rx '("^ *\\(?:\\?[A-Z_]+: +\\)?\
\\(\\(?:ignore +\\)?x11 +\\(?:none\\|xephyr\\|xorg\\|xpra\\|xvfb\\)?\\)" . 1))
(ip-ip6-rx '("^ *\\(\\?[A-Z_]+: +\\)?\
\\(\\(ignore +\\)?ip6? +\\(none\\|dhcp\\)\\)" . 2))
(take-all `(,(concat (regexp-opt take-all-list "^ *\\(\\?[A-Z_]+: +\\)?\
\\(\\(ignore +\\)?\\<\\(") "\\>\\)")
(2 font-lock-keyword-face)
("\\<all\\>" nil nil (0 font-lock-keyword-face))))
(take-none `(,(concat (regexp-opt take-none-list "^ *\\(\\?[A-Z_]+: +\\)?\
\\(\\(ignore +\\)?\\<\\(") "\\>\\)")
(2 font-lock-keyword-face)
("\\<none\\>" nil nil (0 font-lock-keyword-face))))
(protocol '("^ *\\(\\?A+: +\\)?\
\\(\\(ignore +\\)?\\<protocol\\>\\)" (2 font-lock-keyword-face)
("\\<unix\\>" nil nil (0 font-lock-keyword-face))
("\\<inet\\>" nil nil (0 font-lock-keyword-face))
("\\<inet6\\>" nil nil (0 font-lock-keyword-face))
("\\<netlink\\>" nil nil (0 font-lock-keyword-face))
("\\<packet\\>" nil nil (0 font-lock-keyword-face))
("\\<bluetooth\\>" nil nil (0 font-lock-keyword-face))))
(variable-rx '("\\${[A-Za-z_]*}" 0 font-lock-variable-name-face))
(normal-rx `(,(concat (regexp-opt normal "^ *\\(\\?[A-Z_]+: +\\)?\
\\(\\(ignore +\\)?\\<\\(") "\\>\\)") . 2)))
(list comment-rx x11-rx ip-ip6-rx take-all take-none protocol
dbus-system-user-rx normal-rx variable-rx
'("^ *\\(\\?[A-Z_]+: +\\)?\\(\\<ignore\\>\\)" . 2)))
"Highlight keywords for `firejail-profile-mode'.")
(defvar firejail-profile-syntax-table
(let ((syn-table (make-syntax-table)))
(modify-syntax-entry ?# "<" syn-table)
(modify-syntax-entry ?\n ">" syn-table)
syn-table)
"Syntax table for `firejail-profile-mode'.")
(defconst firejail-profile--keyword-list
'("quiet" "include" "noblacklist" "nowhitelist" "blacklist"
"blacklist-nolog" "bind" "disable-mnt" "keep-config-pulse"
"keep-dev-shm" "keep-var-tmp" "mkdir" "mkfile" "noexec" "private"
"private-bin" "private-cache" "private-cwd" "private-dev"
"private-etc" "private-home" "private-lib" "private-opt"
"private-srv" "private-tmp" "read-only" "read-write" "tmpfs"
"tracelog" "whitelist" "whitelist-ro" "writable-etc"
"writable-run-user" "writable-var" "writable-var-log"
"allow-debuggers" "apparmor" "caps" "caps.keep" "caps.drop"
"memory-deny-write-execute" "nonewprivs" "noprinters" "noroot"
"restrict-namespaces" "seccomp" "seccomp.32" "seccomp.drop"
"seccomp.32.drop" "seccomp.keep" "seccomp.32.keep" "protocol"
"xephyr-screen" "dbus-system.own" "dbus-system.talk"
"dbus-system.see" "dbus-system.call" "dbus-system.broadcast"
"dbus-user.own" "dbus-user.talk" "dbus-user.see" "dbus-user.call"
"dbus-user.broadcast" "nodbus" "cpu" "nice" "rlimit-as"
"rlimit-cpu" "rlimit-fsize" "rlimit-nproc" "rlimit-nofile"
"rlimit-sigpending" "timeout" "allusers" "env" "ipc-namespace"
"keep-fd" "name" "no3d" "noautopulse" "nodvd" "nogroups" "noinput"
"nosound" "notv" "nou2f" "novideo" "machine-id" "defaultgw" "dns"
"hostname" "hosts-file" "x11" "dbus-system" "dbus-user" "ip" "ip6"
"iprange" "mac" "mtu" "net" "netfilter" "netfilter" "netlock"
"netmask" "netns" "veth-name" "deterministic-exit-code" "ignore"
"deterministic-shutdown" "join-or-start" "net" "shell" "protocol")
"List of keywords used for `firejail-profile-capf'.")
(defun firejail-profile-capf ()
"Complete the firejail profile directive at point."
(if-let ((word-bounds (bounds-of-thing-at-point 'word)))
(cl-loop for kwd in firejail-profile--keyword-list
with word-at-point = (buffer-substring-no-properties
(car word-bounds)
(cdr word-bounds))
when (string-prefix-p word-at-point kwd)
collect kwd into candidates
finally return (list (car word-bounds)
(cdr word-bounds)
candidates))
(list (point)
(point)
firejail-profile--keyword-list)))
(define-derived-mode firejail-profile-mode prog-mode "Firejail-Profile"
"Major mode for editing firejail profiles."
(add-to-list (make-local-variable 'completion-at-point-functions)
#'firejail-profile-capf)
(setq-local font-lock-defaults '(firejail-profile-font-lock-keywords))
(set-syntax-table firejail-profile-syntax-table))
(add-to-list 'auto-mode-alist
'("\\.\\(firejail\\|profile\\|local\\)$" . firejail-profile-mode))
(provide 'firejail-mode)
;;; firejail-mode.el ends here