My Emacs config, and other editor settings
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

272 lines
8.8 KiB

;; *****************************************************************************
;;
;; jam-mode.el
;; Font-lock support for Jam files
;;
;; Copyright (C) 2003, 2004, Rob Walker <address@hidden>
;; http://www.tenfoot.org.uk/emacs/
;; 12 May 2004 - 0.3 - Fix keyword quoting, XEmacs support
;; 22 Mar 2003 - 0.2 - Autoload
;; 04 Mar 2003 - 0.1 - Added imenu support and basic indentation
;;
;; Copyright (C) 2000, Eric Scouten
;; Started Sat, 05 Aug 2000
;;
;; *****************************************************************************
;;
;; This 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.
;;
;; jam-mode.el 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 GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;
;; *****************************************************************************
;;
;; To add font-lock support for Jam files, simply add the line
;; (require 'jam-mode) to your .emacs file. Make sure generic-mode.el
;; is visible in your load-path as well.
;;
;; *****************************************************************************
;; Generic-mode is a meta-mode which can be used to define small modes
;; which provide basic comment and font-lock support. Jam-mode depends
;; on
;; this mode.
;; generic.el for GNU emacs, generic-mode.el for XEmacs
(if (string-match "XEmacs\\|Lucid" emacs-version)
(require 'generic-mode)
(require 'generic))
(defun jam-mode-quote-keywords (keywords)
"Returns a list of expressions that match each element in KEYWORDS.
For generic-mode, each element is quoted. For generic, each element is
unchanged."
(if (featurep 'generic-mode)
(mapcar 'regexp-quote keywords)
keywords))
;;;###autoload
(define-generic-mode 'jam-mode
; Jam comments always start with '#'
(list ?# )
; Jam keywords (defined later)
nil
; Extra stuff to colorize
(list
; Jam keywords
(generic-make-keywords-list
(list "actions" "bind" "case" "default" "else" "existing" "for" "if"
"ignore" "in" "include" "local" "on" "piecemeal" "quietly" "rule"
"switch"
"together" "updated")
'font-lock-keyword-face)
; Jam built-in variables
(generic-make-keywords-list
(list
"JAMDATE" "JAMSHELL" "JAMUNAME" "JAMVERSION" "MAC" "NT" "OS" "OS2"
"OSPLAT" "OSVER" "UNIX" "VMS")
'font-lock-constant-face)
; Jam built-in targets
(generic-make-keywords-list
(list
"ALWAYS" "DEPENDS" "ECHO" "INCLUDES" "LEAVES" "LOCATE" "NOCARE"
"NOTFILE" "NOUPDATE" "SEARCH" "TEMPORARY")
'font-lock-builtin-face)
; Jam built-in targets (warnings)
(generic-make-keywords-list
(list
"EXIT")
'font-lock-warning-face)
; Jambase rules
(generic-make-keywords-list
(jam-mode-quote-keywords
(list
"Archive" "As" "Bulk" "Cc" "CcMv" "C++" "Chgrp" "Chmod"
"Chown" "Clean" "CreLib"
"Depends" "File" "Fortran" "GenFile" "GenFile1" "HardLink"
"HdrRule" "Install" "InstallBin" "InstallFile"
"InstallInto" "InstallLib" "InstallMan"
"InstallShell" "Lex" "Library" "LibraryFromObjects" "Link"
"LinkLibraries"
"Main" "MainFromObjects" "MakeLocate" "MkDir" "MkDir1"
"Object" "ObjectC++Flags"
"ObjectCcFlags" "ObjectHdrs" "Objects" "Ranlib" "RmTemps"
"Setuid" "SubDir"
"SubDirC++Flags" "SubDirCcFlags" "SubDirHdrs" "SubInclude"
"Shell" "Undefines"
"UserObject" "Yacc" "Yacc1" "BULK" "FILE" "HDRRULE"
"INSTALL" "INSTALLBIN" "INSTALLLIB"
"INSTALLMAN" "LIBRARY" "LIBS" "LINK" "MAIN" "SETUID"
"SHELL" "UNDEFINES"
"addDirName" "makeCommon" "makeDirName" "makeGrist"
"makeGristedName" "makeRelPath"
"makeString" "makeSubDir" "makeSuffixed" "unmakeDir"))
'font-lock-function-name-face)
; Jambase built-in targets
(generic-make-keywords-list
(list
"all" "clean" "dirs" "exe" "files" "first" "install" "lib" "obj"
"shell" "uninstall")
'font-lock-builtin-face)
; Jambase built-in variables
(generic-make-keywords-list
(jam-mode-quote-keywords
(list
"ALL_LOCATE_TARGET" "AR" "ARFLAGS" "AS" "ASFLAGS" "AWK"
"BCCROOT" "BINDIR" "CC" "CCFLAGS"
"C++" "C++FLAGS" "CHMOD" "CP" "CRELIB" "CW" "CWGUSI"
"CWMAC" "CWMSL" "DOT" "DOTDOT"
"EXEMODE" "FILEMODE" "FORTRAN" "FORTRANFLAGS" "GROUP"
"HDRGRIST" "HDRPATTERN" "HDRRULE"
"HDRS" "HDRSCAN" "HDRSEARCH" "INSTALL" "JAMFILE" "JAMRULES"
"LEX" "LIBDIR" "LINK"
"LINKFLAGS" "LINKLIBS" "LOCATE_SOURCE" "LOCATE_TARGET" "LN"
"MACINC" "MANDIR" "MKDIR"
"MODE" "MSLIB" "MSLINK" "MSIMPLIB" "MSRC" "MSVC" "MSVCNT"
"MV" "NEEDLIBS" "NOARSCAN"
"OSFULL" "OPTIM" "OWNER" "RANLIB" "RCP" "RELOCATE" "RM"
"RSH" "RUNVMS" "SEARCH_SOURCE"
"SED" "SHELLHEADER" "SHELLMODE" "SLASH" "SLASHINC"
"SOURCE_GRIST" "STDHDRS" "STDLIBPATH"
"SUBDIR" "SUBDIRASFLAGS" "SUBDIRC++FLAGS" "SUBDIRCCFLAGS"
"SUBDIRHDRS" "SUBDIR_TOKENS"
"SUFEXE" "SUFLIB" "SUFOBJ" "UNDEFFLAG" "UNDEFS" "WATCOM"
"YACC" "YACCFLAGS" "YACCFILES"))
'font-lock-function-name-face)
; Jam variable references $(foo)
'("$(\\([^ :\\[()\t\r\n]+\\)[)\\[:]" 1 font-lock-variable-name-face))
; Apply this mode to all files called Jamfile, Jamrules or Jambase
(list "\\(Jamfile\\|Jamrules\\|Jambase\\)\\'")
; Attach setup function so we can modify syntax table.
(list 'jam-mode-setup-function)
; Brief description
"Generic mode for Jam rules files")
(defun jam-mode-setup-function ()
(modify-syntax-entry ?_ "w")
(modify-syntax-entry ?. "w")
(modify-syntax-entry ?/ "w")
(modify-syntax-entry ?+ "w")
(modify-syntax-entry ?# "<")
(modify-syntax-entry ?\n ">")
(setq imenu-generic-expression
'(("Rules" "^rule\\s-+\\([A-Za-z0-9_]+\\)" 1)
("Actions" "^actions\\s-+\\([A-Za-z0-9_]+\\)" 1)))
(imenu-add-to-menubar "Jam")
(make-local-variable 'indent-line-function)
(setq indent-line-function 'jam-indent-line)
(run-hooks 'jam-mode-hook)
)
(defvar jam-mode-hook nil)
(defvar jam-indent-size 2
"Amount to indent by in jam-mode")
(defvar jam-case-align-to-colon t
"Whether to align case statements to the colons")
(defun jam-indent-line (&optional whole-exp)
"Indent current line"
(interactive)
(let ((indent (jam-indent-level))
(pos (- (point-max) (point))) beg)
(beginning-of-line)
(setq beg (point))
(skip-chars-forward " \t")
(if (zerop (- indent (current-column)))
nil
(delete-region beg (point))
(indent-to indent))
(if (> (- (point-max) pos) (point))
(goto-char (- (point-max) pos)))
))
(defun jam-goto-block-start ()
"Goto the start of the block containing point (or beginning of buffer if not in a block)"
(let ((l 1))
(while (and (not (bobp)) (> l 0))
(skip-chars-backward "^{}")
(unless (bobp)
(backward-char)
(setq l (cond
((eq (char-after) ?{) (1- l))
((eq (char-after) ?}) (1+ l))
)))
)
(bobp))
)
(defun jam-indent-level ()
(save-excursion
(let ((p (point))
ind
(is-block-start nil)
(is-block-end nil)
(is-case nil)
(is-switch nil)
switch-ind)
;; see what's on this line
(beginning-of-line)
(setq is-block-end (looking-at "^[^{\n]*}\\s-*$"))
(setq is-block-start (looking-at ".*{\\s-*$"))
(setq is-case (looking-at "\\s-*case.*:"))
;; goto start of current block (0 if at top level)
(if (jam-goto-block-start)
(setq ind 0)
(setq ind (+ (current-indentation) jam-indent-size)))
;; increase indent in switch statements (not cases)
(setq is-switch (re-search-backward "^\\s-*switch" (- (point)
100) t))
(when (and is-switch (not (or is-block-end is-case)))
(goto-char p)
(setq ind (if (and jam-case-align-to-colon
(re-search-backward
"^\\s-*case.*?\\(:\\)"))
(+ (- (match-beginning 1) (match-beginning 0))
jam-indent-size)
(+ ind jam-indent-size)))
)
;; indentation of this line is jam-indent-size more than that of the
;; previous block
(cond (is-block-start ind)
(is-block-end (- ind jam-indent-size))
(is-case ind)
(t ind)
)
)))
(provide 'jam-mode)
;; jam-mode.el ends here