;;; apache-mode.el --- major mode for editing Apache configuration files ;; Copyright (c) 2004, 2005 Karl Chen ;; Copyright (c) 1999 Jonathan Marten ;; Author: Karl Chen ;; Keywords: languages, faces ;; Last edit: 2005-01-06 ;; Version: 2.0 $Id: apache-mode.el 8264 2005-06-29 23:34:41Z quarl $ ;; apache-mode.el 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 2, or (at your option) any later ;; version. ;; ;; It 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 your copy of Emacs; see the file COPYING. If not, write to the Free ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ;; 02111-1307, USA. ;;; Commentary: ;; ;; (autoload 'apache-mode "apache-mode" nil t) ;; (add-to-list 'auto-mode-alist '("\\.htaccess\\'" . apache-mode)) ;; (add-to-list 'auto-mode-alist '("httpd\\.conf\\'" . apache-mode)) ;; (add-to-list 'auto-mode-alist '("srm\\.conf\\'" . apache-mode)) ;; (add-to-list 'auto-mode-alist '("access\\.conf\\'" . apache-mode)) ;; (add-to-list 'auto-mode-alist '("sites-\\(available\\|enabled\\)/" . apache-mode)) ;; ;;; History: ;; 1999-10 Jonathan Marten ;; initial version ;; 2004-09-12 Karl Chen ;; rewrote pretty much everything using define-derived-mode; added support ;; for Apache 2.x; fixed highlighting in GNU Emacs; created indentation ;; function ;; ;; 2005-06-29 Kumar Appaiah ;; use syntax table instead of font-lock-keywords to highlight comments. ;; ;; 2015-08-23 David Maus ;; update list of directives for Apache 2.4 ;;; Code: ;; Requires (require 'regexp-opt) (defvar apache-indent-level 4 "*Number of spaces to indent per level") (defvar apache-mode-syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?_ "_" table) (modify-syntax-entry ?- "_" table) (modify-syntax-entry ?( "()" table) (modify-syntax-entry ?) ")(" table) (modify-syntax-entry ?< "(>" table) (modify-syntax-entry ?> ")<" table) (modify-syntax-entry ?\" "\"" table) (modify-syntax-entry ?, "." table) (modify-syntax-entry ?# "<" table) (modify-syntax-entry ?\n ">#" table) table)) ;;;###autoload (define-derived-mode apache-mode fundamental-mode "Apache" "Major mode for editing Apache configuration files." (set (make-local-variable 'comment-start) "# ") (set (make-local-variable 'comment-start-skip) "#\\W*") (set (make-local-variable 'comment-column) 48) (set (make-local-variable 'indent-line-function) 'apache-indent-line) (set (make-local-variable 'font-lock-defaults) '(apache-font-lock-keywords nil t ((?_ . "w") (?- . "w")) beginning-of-line))) ;; Font lock (defconst apache-font-lock-keywords (purecopy (list ;; see syntax table for comment highlighting ;; (list "^[ \t]*#.*" 0 'font-lock-comment-face t) (list (concat ; sections "^[ \t]*") 1 'font-lock-function-name-face) (list (concat ; directives "^[ \t]*" (regexp-opt ' ( "AcceptFilter" "AcceptPathInfo" "AccessFileName" "Action" "AddAlt" "AddAltByEncoding" "AddAltByType" "AddCharset" "AddDefaultCharset" "AddDescription" "AddEncoding" "AddHandler" "AddIcon" "AddIconByEncoding" "AddIconByType" "AddInputFilter" "AddLanguage" "AddModuleInfo" "AddOutputFilter" "AddOutputFilterByType" "AddType" "Alias" "AliasMatch" "Allow" "AllowCONNECT" "AllowEncodedSlashes" "AllowMethods" "AllowOverride" "AllowOverrideList" "Anonymous" "Anonymous_LogEmail" "Anonymous_MustGiveEmail" "Anonymous_NoUserID" "Anonymous_VerifyEmail" "AsyncRequestWorkerFactor" "AuthBasicAuthoritative" "AuthBasicFake" "AuthBasicProvider" "AuthBasicUseDigestAlgorithm" "AuthDBDUserPWQuery" "AuthDBDUserRealmQuery" "AuthDBMGroupFile" "AuthDBMType" "AuthDBMUserFile" "AuthDigestAlgorithm" "AuthDigestDomain" "AuthDigestNonceLifetime" "AuthDigestProvider" "AuthDigestQop" "AuthDigestShmemSize" "AuthFormAuthoritative" "AuthFormBody" "AuthFormDisableNoStore" "AuthFormFakeBasicAuth" "AuthFormLocation" "AuthFormLoginRequiredLocation" "AuthFormLoginSuccessLocation" "AuthFormLogoutLocation" "AuthFormMethod" "AuthFormMimetype" "AuthFormPassword" "AuthFormProvider" "AuthFormSitePassphrase" "AuthFormSize" "AuthFormUsername" "AuthGroupFile" "AuthLDAPAuthorizePrefix" "AuthLDAPBindAuthoritative" "AuthLDAPBindDN" "AuthLDAPBindPassword" "AuthLDAPCharsetConfig" "AuthLDAPCompareAsUser" "AuthLDAPCompareDNOnServer" "AuthLDAPDereferenceAliases" "AuthLDAPGroupAttribute" "AuthLDAPGroupAttributeIsDN" "AuthLDAPInitialBindAsUser" "AuthLDAPInitialBindPattern" "AuthLDAPMaxSubGroupDepth" "AuthLDAPRemoteUserAttribute" "AuthLDAPRemoteUserIsDN" "AuthLDAPSearchAsUser" "AuthLDAPSubGroupAttribute" "AuthLDAPSubGroupClass" "AuthLDAPUrl" "AuthMerging" "AuthName" "AuthnCacheContext" "AuthnCacheEnable" "AuthnCacheProvideFor" "AuthnCacheSOCache" "AuthnCacheTimeout" "AuthnzFcgiCheckAuthnProvider" "AuthnzFcgiDefineProvider" "AuthType" "AuthUserFile" "AuthzDBDLoginToReferer" "AuthzDBDQuery" "AuthzDBDRedirectQuery" "AuthzDBMType" "AuthzSendForbiddenOnFailure" "BalancerGrowth" "BalancerInherit" "BalancerMember" "BalancerPersist" "BrowserMatch" "BrowserMatchNoCase" "BufferedLogs" "BufferSize" "CacheDefaultExpire" "CacheDetailHeader" "CacheDirLength" "CacheDirLevels" "CacheDisable" "CacheEnable" "CacheFile" "CacheHeader" "CacheIgnoreCacheControl" "CacheIgnoreHeaders" "CacheIgnoreNoLastMod" "CacheIgnoreQueryString" "CacheIgnoreURLSessionIdentifiers" "CacheKeyBaseURL" "CacheLastModifiedFactor" "CacheLock" "CacheLockMaxAge" "CacheLockPath" "CacheMaxExpire" "CacheMaxFileSize" "CacheMinExpire" "CacheMinFileSize" "CacheNegotiatedDocs" "CacheQuickHandler" "CacheReadSize" "CacheReadTime" "CacheRoot" "CacheSocache" "CacheSocacheMaxSize" "CacheSocacheMaxTime" "CacheSocacheMinTime" "CacheSocacheReadSize" "CacheSocacheReadTime" "CacheStaleOnError" "CacheStoreExpired" "CacheStoreNoStore" "CacheStorePrivate" "CGIDScriptTimeout" "CGIMapExtension" "CGIPassAuth" "CharsetDefault" "CharsetOptions" "CharsetSourceEnc" "CheckCaseOnly" "CheckSpelling" "ChrootDir" "ContentDigest" "CookieDomain" "CookieExpires" "CookieName" "CookieStyle" "CookieTracking" "CoreDumpDirectory" "CustomLog" "Dav" "DavDepthInfinity" "DavGenericLockDB" "DavLockDB" "DavMinTimeout" "DBDExptime" "DBDInitSQL" "DBDKeep" "DBDMax" "DBDMin" "DBDParams" "DBDPersist" "DBDPrepareSQL" "DBDriver" "DefaultIcon" "DefaultLanguage" "DefaultRuntimeDir" "DefaultType" "Define" "DeflateBufferSize" "DeflateCompressionLevel" "DeflateFilterNote" "DeflateInflateLimitRequestBody" "DeflateInflateRatioBurst" "DeflateInflateRatioLimit" "DeflateMemLevel" "DeflateWindowSize" "Deny" "DirectoryCheckHandler" "DirectoryIndex" "DirectoryIndexRedirect" "DirectorySlash" "DocumentRoot" "DTracePrivileges" "DumpIOInput" "DumpIOOutput" "EnableExceptionHook" "EnableMMAP" "EnableSendfile" "Error" "ErrorDocument" "ErrorLog" "ErrorLogFormat" "Example" "ExpiresActive" "ExpiresByType" "ExpiresDefault" "ExtendedStatus" "ExtFilterDefine" "ExtFilterOptions" "FallbackResource" "FileETag" "FilterChain" "FilterDeclare" "FilterProtocol" "FilterProvider" "FilterTrace" "ForceLanguagePriority" "ForceType" "ForensicLog" "GprofDir" "GracefulShutdownTimeout" "Group" "Header" "HeaderName" "HeartbeatAddress" "HeartbeatListen" "HeartbeatMaxServers" "HeartbeatStorage" "HeartbeatStorage" "HostnameLookups" "IdentityCheck" "IdentityCheckTimeout" "ImapBase" "ImapDefault" "ImapMenu" "Include" "IncludeOptional" "IndexHeadInsert" "IndexIgnore" "IndexIgnoreReset" "IndexOptions" "IndexOrderDefault" "IndexStyleSheet" "InputSed" "ISAPIAppendLogToErrors" "ISAPIAppendLogToQuery" "ISAPICacheFile" "ISAPIFakeAsync" "ISAPILogNotSupported" "ISAPIReadAheadBuffer" "KeepAlive" "KeepAliveTimeout" "KeptBodySize" "LanguagePriority" "LDAPCacheEntries" "LDAPCacheTTL" "LDAPConnectionPoolTTL" "LDAPConnectionTimeout" "LDAPLibraryDebug" "LDAPOpCacheEntries" "LDAPOpCacheTTL" "LDAPReferralHopLimit" "LDAPReferrals" "LDAPRetries" "LDAPRetryDelay" "LDAPSharedCacheFile" "LDAPSharedCacheSize" "LDAPTimeout" "LDAPTrustedClientCert" "LDAPTrustedGlobalCert" "LDAPTrustedMode" "LDAPVerifyServerCert" "LimitInternalRecursion" "LimitRequestBody" "LimitRequestFields" "LimitRequestFieldSize" "LimitRequestLine" "LimitXMLRequestBody" "Listen" "ListenBackLog" "LoadFile" "LoadModule" "LogFormat" "LogIOTrackTTFB" "LogLevel" "LogMessage" "LuaAuthzProvider" "LuaCodeCache" "LuaHookAccessChecker" "LuaHookAuthChecker" "LuaHookCheckUserID" "LuaHookFixups" "LuaHookInsertFilter" "LuaHookLog" "LuaHookMapToStorage" "LuaHookTranslateName" "LuaHookTypeChecker" "LuaInherit" "LuaInputFilter" "LuaMapHandler" "LuaOutputFilter" "LuaPackageCPath" "LuaPackagePath" "LuaQuickHandler" "LuaRoot" "LuaScope" "MaxConnectionsPerChild" "MaxKeepAliveRequests" "MaxMemFree" "MaxRangeOverlaps" "MaxRangeReversals" "MaxRanges" "MaxRequestWorkers" "MaxSpareServers" "MaxSpareThreads" "MaxThreads" "MergeTrailers" "MetaDir" "MetaFiles" "MetaSuffix" "MimeMagicFile" "MinSpareServers" "MinSpareThreads" "MMapFile" "ModemStandard" "ModMimeUsePathInfo" "MultiviewsMatch" "Mutex" "NameVirtualHost" "NoProxy" "NWSSLTrustedCerts" "NWSSLUpgradeable" "Options" "Order" "OutputSed" "PassEnv" "PidFile" "PrivilegesMode" "Protocol" "ProtocolEcho" "ProxyAddHeaders" "ProxyBadHeader" "ProxyBlock" "ProxyDomain" "ProxyErrorOverride" "ProxyExpressDBMFile" "ProxyExpressDBMType" "ProxyExpressEnable" "ProxyFtpDirCharset" "ProxyFtpEscapeWildcards" "ProxyFtpListOnWildcard" "ProxyHTMLBufSize" "ProxyHTMLCharsetOut" "ProxyHTMLDocType" "ProxyHTMLEnable" "ProxyHTMLEvents" "ProxyHTMLExtended" "ProxyHTMLFixups" "ProxyHTMLInterp" "ProxyHTMLLinks" "ProxyHTMLMeta" "ProxyHTMLStripComments" "ProxyHTMLURLMap" "ProxyIOBufferSize" "ProxyMaxForwards" "ProxyPass" "ProxyPassInherit" "ProxyPassInterpolateEnv" "ProxyPassMatch" "ProxyPassReverse" "ProxyPassReverseCookieDomain" "ProxyPassReverseCookiePath" "ProxyPreserveHost" "ProxyReceiveBufferSize" "ProxyRemote" "ProxyRemoteMatch" "ProxyRequests" "ProxySCGIInternalRedirect" "ProxySCGISendfile" "ProxySet" "ProxySourceAddress" "ProxyStatus" "ProxyTimeout" "ProxyVia" "ReadmeName" "ReceiveBufferSize" "Redirect" "RedirectMatch" "RedirectPermanent" "RedirectTemp" "ReflectorHeader" "RemoteIPHeader" "RemoteIPInternalProxy" "RemoteIPInternalProxyList" "RemoteIPProxiesHeader" "RemoteIPTrustedProxy" "RemoteIPTrustedProxyList" "RemoveCharset" "RemoveEncoding" "RemoveHandler" "RemoveInputFilter" "RemoveLanguage" "RemoveOutputFilter" "RemoveType" "RequestHeader" "RequestReadTimeout" "Require" "RewriteBase" "RewriteCond" "RewriteEngine" "RewriteMap" "RewriteOptions" "RewriteRule" "RLimitCPU" "RLimitMEM" "RLimitNPROC" "Satisfy" "ScoreBoardFile" "Script" "ScriptAlias" "ScriptAliasMatch" "ScriptInterpreterSource" "ScriptLog" "ScriptLogBuffer" "ScriptLogLength" "ScriptSock" "SecureListen" "SeeRequestTail" "SendBufferSize" "ServerAdmin" "ServerAlias" "ServerLimit" "ServerName" "ServerPath" "ServerRoot" "ServerSignature" "ServerTokens" "Session" "SessionCookieName" "SessionCookieName2" "SessionCookieRemove" "SessionCryptoCipher" "SessionCryptoDriver" "SessionCryptoPassphrase" "SessionCryptoPassphraseFile" "SessionDBDCookieName" "SessionDBDCookieName2" "SessionDBDCookieRemove" "SessionDBDDeleteLabel" "SessionDBDInsertLabel" "SessionDBDPerUser" "SessionDBDSelectLabel" "SessionDBDUpdateLabel" "SessionEnv" "SessionExclude" "SessionHeader" "SessionInclude" "SessionMaxAge" "SetEnv" "SetEnvIf" "SetEnvIfExpr" "SetEnvIfNoCase" "SetHandler" "SetInputFilter" "SetOutputFilter" "SSIEndTag" "SSIErrorMsg" "SSIETag" "SSILastModified" "SSILegacyExprParser" "SSIStartTag" "SSITimeFormat" "SSIUndefinedEcho" "SSLCACertificateFile" "SSLCACertificatePath" "SSLCADNRequestFile" "SSLCADNRequestPath" "SSLCARevocationCheck" "SSLCARevocationFile" "SSLCARevocationPath" "SSLCertificateChainFile" "SSLCertificateFile" "SSLCertificateKeyFile" "SSLCipherSuite" "SSLCompression" "SSLCryptoDevice" "SSLEngine" "SSLFIPS" "SSLHonorCipherOrder" "SSLInsecureRenegotiation" "SSLOCSPDefaultResponder" "SSLOCSPEnable" "SSLOCSPOverrideResponder" "SSLOCSPResponderTimeout" "SSLOCSPResponseMaxAge" "SSLOCSPResponseTimeSkew" "SSLOCSPUseRequestNonce" "SSLOpenSSLConfCmd" "SSLOptions" "SSLPassPhraseDialog" "SSLProtocol" "SSLProxyCACertificateFile" "SSLProxyCACertificatePath" "SSLProxyCARevocationCheck" "SSLProxyCARevocationFile" "SSLProxyCARevocationPath" "SSLProxyCheckPeerCN" "SSLProxyCheckPeerExpire" "SSLProxyCheckPeerName" "SSLProxyCipherSuite" "SSLProxyEngine" "SSLProxyMachineCertificateChainFile" "SSLProxyMachineCertificateFile" "SSLProxyMachineCertificatePath" "SSLProxyProtocol" "SSLProxyVerify" "SSLProxyVerifyDepth" "SSLRandomSeed" "SSLRenegBufferSize" "SSLRequire" "SSLRequireSSL" "SSLSessionCache" "SSLSessionCacheTimeout" "SSLSessionTicketKeyFile" "SSLSessionTickets" "SSLSRPUnknownUserSeed" "SSLSRPVerifierFile" "SSLStaplingCache" "SSLStaplingErrorCacheTimeout" "SSLStaplingFakeTryLater" "SSLStaplingForceURL" "SSLStaplingResponderTimeout" "SSLStaplingResponseMaxAge" "SSLStaplingResponseTimeSkew" "SSLStaplingReturnResponderErrors" "SSLStaplingStandardCacheTimeout" "SSLStrictSNIVHostCheck" "SSLUserName" "SSLUseStapling" "SSLVerifyClient" "SSLVerifyDepth" "StartServers" "StartThreads" "Substitute" "SubstituteMaxLineLength" "Suexec" "SuexecUserGroup" "ThreadLimit" "ThreadsPerChild" "ThreadStackSize" "TimeOut" "TraceEnable" "TransferLog" "TypesConfig" "UnDefine" "UndefMacro" "UnsetEnv" "Use" "UseCanonicalName" "UseCanonicalPhysicalPort" "User" "UserDir" "VHostCGIMode" "VHostCGIPrivs" "VHostGroup" "VHostPrivs" "VHostSecure" "VHostUser" "VirtualDocumentRoot" "VirtualDocumentRootIP" "VirtualScriptAlias" "VirtualScriptAliasIP" "WatchdogInterval" "XBitHack" "xml2EncAlias" "xml2EncDefault" "xml2StartParse" ) 'words)) 1 'font-lock-keyword-face) (list ; values (regexp-opt ' ( "All" "AuthConfig" "Basic" "CONNECT" "DELETE" "Digest" "ExecCGI" "FancyIndexing" "FileInfo" "FollowSymLinks" "Full" "GET" "IconsAreLinks" "Includes" "IncludesNOEXEC" "Indexes" "Limit" "Minimal" "MultiViews" "None" "OPTIONS" "OS" "Options" "Options" "POST" "PUT" "ScanHTMLTitles" "SuppressDescription" "SuppressLastModified" "SuppressSize" "SymLinksIfOwnerMatch" "URL" "add" "allow" "any" "append" "deny" "double" "downgrade-1.0" "email" "env" "error" "force-response-1.0" "formatted" "from" "full" "gone" "group" "inetd" "inherit" "map" "mutual-failure" "nocontent" "nokeepalive" "none" "off" "on" "permanent" "referer" "seeother" "semi-formatted" "set" "standalone" "temporary" "unformatted" "unset" "user" "valid-user" ) 'words) 1 'font-lock-type-face))) "Expressions to highlight in Apache config buffers.") (defun apache-indent-line () "Indent current line of Apache code." (interactive) (let ((savep (> (current-column) (current-indentation))) (indent (max (apache-calculate-indentation) 0))) (if savep (save-excursion (indent-line-to indent)) (indent-line-to indent)))) (defun apache-previous-indentation () ;; Return the previous (non-empty/comment) indentation. Doesn't save ;; position. (let (indent) (while (and (null indent) (zerop (forward-line -1))) (unless (looking-at "[ \t]*\\(#\\|$\\)") (setq indent (current-indentation)))) (or indent 0))) (defun apache-calculate-indentation () ;; Return the amount the current line should be indented. (save-excursion (forward-line 0) (if (bobp) 0 (let ((ends-section-p (looking-at "[ \t]*