diff --git a/elisp/firejail-mode.el b/elisp/firejail-mode.el new file mode 100644 index 0000000..1aefc6c --- /dev/null +++ b/elisp/firejail-mode.el @@ -0,0 +1,134 @@ +;;; 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) + ("\\" nil nil (0 font-lock-keyword-face)))) + (take-none `(,(concat (regexp-opt take-none-list "^ *\\(\\?[A-Z_]+: +\\)?\ +\\(\\(ignore +\\)?\\<\\(") "\\>\\)") + (2 font-lock-keyword-face) + ("\\" nil nil (0 font-lock-keyword-face)))) + (protocol '("^ *\\(\\?A+: +\\)?\ +\\(\\(ignore +\\)?\\\\)" (2 font-lock-keyword-face) +("\\" nil nil (0 font-lock-keyword-face)) +("\\" nil nil (0 font-lock-keyword-face)) +("\\" nil nil (0 font-lock-keyword-face)) +("\\" nil nil (0 font-lock-keyword-face)) +("\\" nil nil (0 font-lock-keyword-face)) +("\\" 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_]+: +\\)?\\(\\\\)" . 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 diff --git a/init.el b/init.el index 3338645..e5cda44 100644 --- a/init.el +++ b/init.el @@ -538,6 +538,9 @@ COMMAND and COMINT are like `compile'." ;; json (use-package json-mode) +;; firejail +(require 'firejail-mode) + ;; yaml (use-package yaml-mode)