branch: elpa/systemd commit e3855752415b37b7baaac9b98c4cad81f2296fef Author: Mark Oteiza <mvote...@udel.edu> Commit: Mark Oteiza <mvote...@udel.edu>
initial company support for directives --- systemd-company.el | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++ systemd.el | 8 ++++ 2 files changed, 135 insertions(+) diff --git a/systemd-company.el b/systemd-company.el new file mode 100644 index 0000000..938f752 --- /dev/null +++ b/systemd-company.el @@ -0,0 +1,127 @@ +;;; systemd-company.el --- company backend for systemd unit directives + +;; Copyright (C) 2015 Mark Oteiza <mvote...@udel.edu> + +;; Author: Mark Oteiza <mvote...@udel.edu> + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 3 +;; of the License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(declare-function company-mode "company") +(declare-function company-begin-backend "company") +(declare-function company-grab-symbol "company") + +(defconst systemd-company-directives + ;; TODO: keep a script of sorts for generating this list. systemd + ;; source has a python script in tools/ for parsing the + ;; documentation xml for the unit directives. + ;; + ;; forcer on freenode threw together a curl monstrosity for achieving + ;; the same: + ;; curl -s http://www.freedesktop.org/software/systemd/man/systemd.directives.html | tr -d '\n' | sed 's/>/>\n/g' | sed -ne '/Unit directives/,/Options on the kernel/p' | sed -ne 's/.*<dt id="\([^-][^"]*\)=">.*/\1/p' + '("Accept" "AccuracySec" "After" "Alias" "AllowIsolate" "Also" + "AppArmorProfile" "AssertACPower" "AssertArchitecture" + "AssertCapability" "AssertDirectoryNotEmpty" "AssertFileIsExecutable" + "AssertFileNotEmpty" "AssertFirstBoot" "AssertHost" + "AssertKernelCommandLine" "AssertNeedsUpdate" "AssertPathExists" + "AssertPathExistsGlob" "AssertPathIsDirectory" "AssertPathIsMountPoint" + "AssertPathIsReadWrite" "AssertPathIsSymbolicLink" "AssertSecurity" + "AssertVirtualization" "Backlog" "Before" "BindIPv6Only" "BindToDevice" + "BindsTo" "BlockIOAccounting" "BlockIODeviceWeight" "BlockIOReadBandwidth" + "BlockIOWeight" "BlockIOWriteBandwidth" "Broadcast" "BusName" + "BusPolicy" "CPUAccounting" "CPUAffinity" "CPUQuota" + "CPUSchedulingPolicy" "CPUSchedulingPriority" "CPUSchedulingResetOnFork" + "CPUShares" "Capabilities" "CapabilityBoundingSet" "ConditionACPower" + "ConditionArchitecture" "ConditionCapability" + "ConditionDirectoryNotEmpty" "ConditionFileIsExecutable" + "ConditionFileNotEmpty" "ConditionFirstBoot" "ConditionHost" + "ConditionKernelCommandLine" "ConditionNeedsUpdate" + "ConditionPathExists" "ConditionPathExistsGlob" + "ConditionPathIsDirectory" "ConditionPathIsMountPoint" + "ConditionPathIsReadWrite" "ConditionPathIsSymbolicLink" + "ConditionSecurity" "ConditionVirtualization" "Conflicts" + "DefaultDependencies" "DefaultInstance" "DeferAcceptSec" "Delegate" + "Description" "DeviceAllow" "DevicePolicy" "DirectoryMode" + "DirectoryNotEmpty" "Documentation" "Environment" "EnvironmentFile" + "ExecReload" "ExecStart" "ExecStartPost" "ExecStartPre" "ExecStop" + "ExecStopPost" "ExecStopPre" "FailureAction" "FileDescriptorStoreMax" + "FreeBind" "Group" "GuessMainPID" "IOSchedulingClass" + "IOSchedulingPriority" "IPTOS" "IPTTL" "IgnoreOnIsolate" + "IgnoreOnSnapshot" "IgnoreSIGPIPE" "InaccessibleDirectories" + "JobTimeoutAction" "JobTimeoutRebootArgument" + "JobTimeoutSec" "JoinsNamespaceOf" "KeepAlive" "KeepAliveIntervalSec" + "KeepAliveProbes" "KeepAliveTimeSec" "KillMode" "KillSignal" + "LimitAS" "LimitCORE" "LimitCPU" "LimitDATA" "LimitFSIZE" "LimitLOCKS" + "LimitMEMLOCK" "LimitMSGQUEUE" "LimitNICE" "LimitNOFILE" "LimitNPROC" + "LimitRSS" "LimitRTPRIO" "LimitRTTIME" "LimitSIGPENDING" "LimitSTACK" + "ListenDatagram" "ListenFIFO" "ListenMessageQueue" "ListenNetlink" + "ListenSequentialPacket" "ListenSpecial" "ListenStream" "MakeDirectory" + "Mark" "MaxConnections" "MemoryAccounting" "MemoryLimit" + "MessageQueueMaxMessages" "MessageQueueMessageSize" "MountFlags" + "Nice" "NoDelay" "NoNewPrivileges" "NonBlocking" "NotifyAccess" + "OOMScoreAdjust" "OnActiveSec" "OnBootSec" "OnCalendar" "OnFailure" + "OnFailureJobMode" "OnStartupSec" "OnUnitActiveSec" "OnUnitInactiveSec" + "Options" "PAMName" "PIDFile" "PartOf" "PassCredentials" "PassSecurity" + "PathChanged" "PathExists" "PathExistsGlob" "PathModified" + "PermissionsStartOnly" "Persistent" "Personality" "PipeSize" "Priority" + "PrivateDevices" "PrivateNetwork" "PrivateTmp" "PropagatesReloadTo" + "ProtectHome" "ProtectSystem" "ReadOnlyDirectories" "ReadWriteDirectories" + "RebootArgument" "ReceiveBuffer" "RefuseManualStart" "RefuseManualStop" + "ReloadPropagatedFrom" "RemainAfterExit" "RemoveOnStop" "RequiredBy" + "Requires" "RequiresMountsFor" "RequiresOverridable" "Requisite" + "RequisiteOverridable" "Restart" "RestartForceExitStatus" + "RestartPreventExitStatus" "RestartSec" "RestrictAddressFamilies" + "ReusePort" "RootDirectory" "RootDirectoryStartOnly" "RuntimeDirectory" + "RuntimeDirectoryMode" "SELinuxContext" "SELinuxContextFromNet" + "SecureBits" "SendBuffer" "SendSIGHUP" "SendSIGKILL" "Service" "Slice" + "SloppyOptions" "SmackLabel" "SmackLabelIPIn" "SmackLabelIPOut" + "SmackProcessLabel" "SocketGroup" "SocketMode" "SocketUser" "Sockets" + "SourcePath" "StandardError" "StandardInput" "StandardOutput" + "StartLimitAction" "StartLimitBurst" "StartLimitInterval" + "StartupBlockIOWeight" "StartupCPUShares" "StopWhenUnneeded" + "SuccessExitStatus" "SupplementaryGroups" "Symlinks" "SyslogFacility" + "SyslogIdentifier" "SyslogLevel" "SyslogLevelPrefix" + "SystemCallArchitectures" "SystemCallErrorNumber" "SystemCallFilter" + "TCPCongestion" "TTYPath" "TTYReset" "TTYVHangup" "TTYVTDisallocate" + "TimeoutSec" "TimeoutStartSec" "TimeoutStopSec" "TimerSlackNSec" + "Transparent" "Type" "UMask" "Unit" "User" "UtmpIdentifier" + "WakeSystem" "WantedBy" "Wants" "WatchdogSec" "What" "Where" + "WorkingDirectory") + "Configuration directives for systemd 218.") + +(defun systemd-company--setup (enable) + (when (fboundp 'systemd-company--setup-company) + (systemd-company--setup-company enable))) + +(with-eval-after-load "company" + (defun systemd-company-backend (command &optional arg &rest ignored) + (interactive (list 'interactive)) + (cl-case command + (interactive (company-begin-backend 'systemd-company-backend)) + (prefix (and (eq major-mode 'systemd-mode) + (company-grab-symbol))) + (candidates + (cl-remove-if-not (lambda (c) (string-prefix-p arg c)) + systemd-company-directives)))) + (defun systemd-company--setup-company (enable) + (when enable + (add-to-list (make-local-variable 'company-backends) 'systemd-company-backend)) + (company-mode (if enable 1 -1)))) + +(provide 'systemd-company) + +;;; systemd-company.el ends here diff --git a/systemd.el b/systemd.el index 9d499c9..83b3e86 100644 --- a/systemd.el +++ b/systemd.el @@ -33,6 +33,8 @@ (require 'thingatpt) (require 'url-parse) +(require 'systemd-company) + (defgroup systemd () "Major mode for editing systemd units." :link '(url-link "http://www.freedesktop.org/wiki/Software/systemd/") @@ -51,6 +53,11 @@ (string :tag "Semicolon" ";")) :group 'systemd) +(defcustom systemd-use-company-p t + "Whether to use `company-mode' for completion, if available." + :type 'boolean + :group 'systemd) + (defvar systemd-font-lock-keywords `(("^\\([#;]\\(.*\\)\\)$" (1 'font-lock-comment-delimiter-face) @@ -148,6 +155,7 @@ at mode initialization. Key bindings: \\{systemd-mode-map}" + (systemd-company--setup systemd-use-company-p) (setq-local comment-start systemd-comment-start) (setq-local font-lock-defaults '(systemd-font-lock-keywords)))