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.

273 lines
8.8 KiB

;; *****************************************************************************
;; jam-mode.el
;; Font-lock support for Jam files
;; Copyright (C) 2003, 2004, Rob Walker <address@hidden>
;; 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
;; 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
(if (featurep 'generic-mode)
(mapcar 'regexp-quote keywords)
(define-generic-mode 'jam-mode
; Jam comments always start with '#'
(list ?# )
; Jam keywords (defined later)
; Extra stuff to colorize
; Jam keywords
(list "actions" "bind" "case" "default" "else" "existing" "for" "if"
"ignore" "in" "include" "local" "on" "piecemeal" "quietly" "rule"
"together" "updated")
; Jam built-in variables
; Jam built-in targets
; Jam built-in targets (warnings)
; Jambase rules
"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"
"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"
"addDirName" "makeCommon" "makeDirName" "makeGrist"
"makeGristedName" "makeRelPath"
"makeString" "makeSubDir" "makeSuffixed" "unmakeDir"))
; Jambase built-in targets
"all" "clean" "dirs" "exe" "files" "first" "install" "lib" "obj"
"shell" "uninstall")
; Jambase built-in variables
; 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"
(let ((indent (jam-indent-level))
(pos (- (point-max) (point))) beg)
(setq beg (point))
(skip-chars-forward " \t")
(if (zerop (- indent (current-column)))
(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)
(setq l (cond
((eq (char-after) ?{) (1- l))
((eq (char-after) ?}) (1+ l))
(defun jam-indent-level ()
(let ((p (point))
(is-block-start nil)
(is-block-end nil)
(is-case nil)
(is-switch nil)
;; see what's on this 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
(+ (- (match-beginning 1) (match-beginning 0))
(+ 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