summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--emacs.d/elisp/go-mode.el544
-rw-r--r--emacs.d/elisp/muttrc-mode.el1638
-rw-r--r--emacs.d/functions.el191
-rw-r--r--emacs.el235
4 files changed, 2397 insertions, 211 deletions
diff --git a/emacs.d/elisp/go-mode.el b/emacs.d/elisp/go-mode.el
new file mode 100644
index 0000000..059f783
--- /dev/null
+++ b/emacs.d/elisp/go-mode.el
@@ -0,0 +1,544 @@
+;;; go-mode.el --- Major mode for the Go programming language
+
+;;; Commentary:
+
+;; For installation instructions, see go-mode-load.el
+
+;;; To do:
+
+;; * Indentation is *almost* identical to gofmt
+;; ** We think struct literal keys are labels and outdent them
+;; ** We disagree on the indentation of function literals in arguments
+;; ** There are bugs with the close brace of struct literals
+;; * Highlight identifiers according to their syntactic context: type,
+;; variable, function call, or tag
+;; * Command for adding an import
+;; ** Check if it's already there
+;; ** Factor/unfactor the import line
+;; ** Alphabetize
+;; * Remove unused imports
+;; ** This is hard, since I have to be aware of shadowing to do it
+;; right
+;; * Format region using gofmt
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defvar go-mode-syntax-table
+ (let ((st (make-syntax-table)))
+ ;; Add _ to :word: character class
+ (modify-syntax-entry ?_ "w" st)
+
+ ;; Operators (punctuation)
+ (modify-syntax-entry ?+ "." st)
+ (modify-syntax-entry ?- "." st)
+ (modify-syntax-entry ?* "." st)
+ (modify-syntax-entry ?/ "." st)
+ (modify-syntax-entry ?% "." st)
+ (modify-syntax-entry ?& "." st)
+ (modify-syntax-entry ?| "." st)
+ (modify-syntax-entry ?^ "." st)
+ (modify-syntax-entry ?! "." st)
+ (modify-syntax-entry ?= "." st)
+ (modify-syntax-entry ?< "." st)
+ (modify-syntax-entry ?> "." st)
+
+ ;; Strings
+ (modify-syntax-entry ?\" "\"" st)
+ (modify-syntax-entry ?\' "\"" st)
+ (modify-syntax-entry ?` "\"" st)
+ (modify-syntax-entry ?\\ "\\" st)
+
+ ;; Comments
+ (modify-syntax-entry ?/ ". 124b" st)
+ (modify-syntax-entry ?* ". 23" st)
+ (modify-syntax-entry ?\n "> b" st)
+ (modify-syntax-entry ?\^m "> b" st)
+
+ st)
+ "Syntax table for Go mode.")
+
+(defvar go-mode-keywords
+ '("break" "default" "func" "interface" "select"
+ "case" "defer" "go" "map" "struct"
+ "chan" "else" "goto" "package" "switch"
+ "const" "fallthrough" "if" "range" "type"
+ "continue" "for" "import" "return" "var")
+ "All keywords in the Go language. Used for font locking and
+some syntax analysis.")
+
+(defvar go-mode-font-lock-keywords
+ (let ((builtins '("cap" "close" "closed" "len" "make" "new"
+ "panic" "panicln" "print" "println"))
+ (constants '("nil" "true" "false" "iota"))
+ (type-name "\\s *\\(?:[*(]\\s *\\)*\\(?:\\w+\\s *\\.\\s *\\)?\\(\\w+\\)")
+ )
+ `((,(regexp-opt go-mode-keywords 'words) . font-lock-keyword-face)
+ (,(regexp-opt builtins 'words) . font-lock-builtin-face)
+ (,(regexp-opt constants 'words) . font-lock-constant-face)
+ ;; Function names in declarations
+ ("\\<func\\>\\s *\\(\\w+\\)" 1 font-lock-function-name-face)
+ ;; Function names in methods are handled by function call pattern
+ ;; Function names in calls
+ ;; XXX Doesn't match if function name is surrounded by parens
+ ("\\(\\w+\\)\\s *(" 1 font-lock-function-name-face)
+ ;; Type names
+ ("\\<type\\>\\s *\\(\\w+\\)" 1 font-lock-type-face)
+ (,(concat "\\<type\\>\\s *\\w+\\s *" type-name) 1 font-lock-type-face)
+ ;; Arrays/slices/map value type
+ ;; XXX Wrong. Marks 0 in expression "foo[0] * x"
+;; (,(concat "]" type-name) 1 font-lock-type-face)
+ ;; Map key type
+ (,(concat "\\<map\\s *\\[" type-name) 1 font-lock-type-face)
+ ;; Channel value type
+ (,(concat "\\<chan\\>\\s *\\(?:<-\\)?" type-name) 1 font-lock-type-face)
+ ;; new/make type
+ (,(concat "\\<\\(?:new\\|make\\)\\>\\(?:\\s \\|)\\)*(" type-name) 1 font-lock-type-face)
+ ;; Type conversion
+ (,(concat "\\.\\s *(" type-name) 1 font-lock-type-face)
+ ;; Method receiver type
+ (,(concat "\\<func\\>\\s *(\\w+\\s +" type-name) 1 font-lock-type-face)
+ ;; Labels
+ ;; XXX Not quite right. Also marks compound literal fields.
+ ("^\\s *\\(\\w+\\)\\s *:\\(\\S.\\|$\\)" 1 font-lock-constant-face)
+ ("\\<\\(goto\\|break\\|continue\\)\\>\\s *\\(\\w+\\)" 2 font-lock-constant-face)))
+ "Basic font lock keywords for Go mode. Highlights keywords,
+built-ins, functions, and some types.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Key map
+;;
+
+(defvar go-mode-map
+ (let ((m (make-sparse-keymap)))
+ (define-key m "}" #'go-mode-insert-and-indent)
+ (define-key m ")" #'go-mode-insert-and-indent)
+ (define-key m ":" #'go-mode-delayed-electric)
+ ;; In case we get : indentation wrong, correct ourselves
+ (define-key m "=" #'go-mode-insert-and-indent)
+ m)
+ "Keymap used by Go mode to implement electric keys.")
+
+(defun go-mode-insert-and-indent (key)
+ "Invoke the global binding of KEY, then reindent the line."
+
+ (interactive (list (this-command-keys)))
+ (call-interactively (lookup-key (current-global-map) key))
+ (indent-according-to-mode))
+
+(defvar go-mode-delayed-point nil
+ "The point following the previous insertion if the insertion
+was a delayed electric key. Used to communicate between
+`go-mode-delayed-electric' and `go-mode-delayed-electric-hook'.")
+(make-variable-buffer-local 'go-mode-delayed-point)
+
+(defun go-mode-delayed-electric (p)
+ "Perform electric insertion, but delayed by one event.
+
+This inserts P into the buffer, as usual, then waits for another key.
+If that second key causes a buffer modification starting at the
+point after the insertion of P, reindents the line containing P."
+
+ (interactive "p")
+ (self-insert-command p)
+ (setq go-mode-delayed-point (point)))
+
+(defun go-mode-delayed-electric-hook (b e l)
+ "An after-change-function that implements `go-mode-delayed-electric'."
+
+ (when (and go-mode-delayed-point
+ (= go-mode-delayed-point b))
+ (save-excursion
+ (save-match-data
+ (goto-char go-mode-delayed-point)
+ (indent-according-to-mode))))
+ (setq go-mode-delayed-point nil))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Parser
+;;
+
+(defvar go-mode-mark-cs-end 1
+ "The point at which the comment/string cache ends. The buffer
+will be marked from the beginning up to this point (that is, up
+to and including character (1- go-mode-mark-cs-end)).")
+(make-variable-buffer-local 'go-mode-mark-cs-end)
+
+(defvar go-mode-mark-cs-state nil
+ "The `parse-partial-sexp' state of the comment/string parser as
+of the point `go-mode-mark-cs-end'.")
+(make-variable-buffer-local 'go-mode-mark-cs-state)
+
+(defvar go-mode-mark-nesting-end 1
+ "The point at which the nesting cache ends. The buffer will be
+marked from the beginning up to this point.")
+(make-variable-buffer-local 'go-mode-mark-nesting-end)
+
+(defun go-mode-mark-clear-cache (b e l)
+ "An after-change-function that clears the comment/string and
+nesting caches from the modified point on."
+
+ (save-restriction
+ (widen)
+ (when (< b go-mode-mark-cs-end)
+ (remove-text-properties b (min go-mode-mark-cs-end (point-max)) '(go-mode-cs nil))
+ (setq go-mode-mark-cs-end b
+ go-mode-mark-cs-state nil))
+
+ (when (< b go-mode-mark-nesting-end)
+ (remove-text-properties b (min go-mode-mark-nesting-end (point-max)) '(go-mode-nesting nil))
+ (setq go-mode-mark-nesting-end b))))
+
+(defmacro go-mode-parser (&rest body)
+ "Evaluate BODY in an environment set up for parsers that use
+text properties to mark text. This inhibits changes to the undo
+list or the buffer's modification status and inhibits calls to
+the modification hooks. It also saves the excursion and
+restriction and widens the buffer, since most parsers are
+context-sensitive."
+
+ (let ((modified-var (make-symbol "modified")))
+ `(let ((buffer-undo-list t)
+ (,modified-var (buffer-modified-p))
+ (inhibit-modification-hooks t)
+ (inhibit-read-only t))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (unwind-protect
+ (progn ,@body)
+ (set-buffer-modified-p ,modified-var)))))))
+
+(defsubst go-mode-cs (&optional pos)
+ "Return the comment/string state at point POS. If point is
+inside a comment or string (including the delimiters), this
+returns a pair (START . END) indicating the extents of the
+comment or string."
+
+ (unless pos
+ (setq pos (point)))
+ (if (= pos 1)
+ nil
+ (when (> pos go-mode-mark-cs-end)
+ (go-mode-mark-cs pos))
+ (get-text-property (- pos 1) 'go-mode-cs)))
+
+(defun go-mode-mark-cs (end)
+ "Mark comments and strings up to point END. Don't call this
+directly; use `go-mode-cs'."
+
+ (setq end (min end (point-max)))
+ (go-mode-parser
+ (let* ((pos go-mode-mark-cs-end)
+ (state (or go-mode-mark-cs-state (syntax-ppss pos))))
+ ;; Mark comments and strings
+ (when (nth 8 state)
+ ;; Get to the beginning of the comment/string
+ (setq pos (nth 8 state)
+ state nil))
+ (while (> end pos)
+ ;; Find beginning of comment/string
+ (while (and (> end pos)
+ (progn
+ (setq state (parse-partial-sexp pos end nil nil state 'syntax-table)
+ pos (point))
+ (not (nth 8 state)))))
+ ;; Find end of comment/string
+ (let ((start (nth 8 state)))
+ (when start
+ (setq state (parse-partial-sexp pos (point-max) nil nil state 'syntax-table)
+ pos (point))
+ ;; Mark comment
+ (put-text-property start (- pos 1) 'go-mode-cs (cons start pos))
+ (when nil
+ (put-text-property start (- pos 1) 'face
+ `((:background "midnight blue")))))))
+ ;; Update state
+ (setq go-mode-mark-cs-end pos
+ go-mode-mark-cs-state state))))
+
+(defsubst go-mode-nesting (&optional pos)
+ "Return the nesting at point POS. The nesting is a list
+of (START . END) pairs for all braces, parens, and brackets
+surrounding POS, starting at the inner-most nesting. START is
+the location of the open character. END is the location of the
+close character or nil if the nesting scanner has not yet
+encountered the close character."
+
+ (unless pos
+ (setq pos (point)))
+ (if (= pos 1)
+ '()
+ (when (> pos go-mode-mark-nesting-end)
+ (go-mode-mark-nesting pos))
+ (get-text-property (- pos 1) 'go-mode-nesting)))
+
+(defun go-mode-mark-nesting (pos)
+ "Mark nesting up to point END. Don't call this directly; use
+`go-mode-nesting'."
+
+ (go-mode-cs pos)
+ (go-mode-parser
+ ;; Mark depth
+ (goto-char go-mode-mark-nesting-end)
+ (let ((nesting (go-mode-nesting))
+ (last (point)))
+ (while (< last pos)
+ ;; Find the next depth-changing character
+ (skip-chars-forward "^(){}[]" pos)
+ ;; Mark everything up to this character with the current
+ ;; nesting
+ (put-text-property last (point) 'go-mode-nesting nesting)
+ (when nil
+ (let ((depth (length nesting)))
+ (put-text-property last (point) 'face
+ `((:background
+ ,(format "gray%d" (* depth 10)))))))
+ (setq last (point))
+ ;; Update nesting
+ (unless (eobp)
+ (let ((ch (unless (go-mode-cs) (char-after))))
+ (forward-char 1)
+ (case ch
+ ((?\( ?\{ ?\[)
+ (setq nesting (cons (cons (- (point) 1) nil)
+ nesting)))
+ ((?\) ?\} ?\])
+ (when nesting
+ (setcdr (car nesting) (- (point) 1))
+ (setq nesting (cdr nesting))))))))
+ ;; Update state
+ (setq go-mode-mark-nesting-end last))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Indentation
+;;
+
+(defvar go-mode-non-terminating-keywords-regexp
+ (let* ((kws go-mode-keywords)
+ (kws (remove "break" kws))
+ (kws (remove "continue" kws))
+ (kws (remove "fallthrough" kws))
+ (kws (remove "return" kws)))
+ (regexp-opt kws 'words))
+ "Regular expression matching all Go keywords that *do not*
+implicitly terminate a statement.")
+
+(defun go-mode-semicolon-p ()
+ "True iff point immediately follows either an explicit or
+implicit semicolon. Point should immediately follow the last
+token on the line."
+
+ ;; #Semicolons
+ (case (char-before)
+ ((?\;) t)
+ ;; String literal
+ ((?' ?\" ?`) t)
+ ;; One of the operators and delimiters ++, --, ), ], or }
+ ((?+) (eq (char-before (1- (point))) ?+))
+ ((?-) (eq (char-before (1- (point))) ?-))
+ ((?\) ?\] ?\}) t)
+ ;; An identifier or one of the keywords break, continue,
+ ;; fallthrough, or return or a numeric literal
+ (otherwise
+ (save-excursion
+ (when (/= (skip-chars-backward "[:word:]_") 0)
+ (not (looking-at go-mode-non-terminating-keywords-regexp)))))))
+
+(defun go-mode-indentation ()
+ "Compute the ideal indentation level of the current line.
+
+To the first order, this is the brace depth of the current line,
+plus parens that follow certain keywords. case, default, and
+labels are outdented one level, and continuation lines are
+indented one level."
+
+ (save-excursion
+ (back-to-indentation)
+ (let ((cs (go-mode-cs)))
+ ;; Treat comments and strings differently only if the beginning
+ ;; of the line is contained within them
+ (when (and cs (= (point) (car cs)))
+ (setq cs nil))
+ ;; What type of context am I in?
+ (cond
+ ((and cs (save-excursion
+ (goto-char (car cs))
+ (looking-at "\\s\"")))
+ ;; Inside a multi-line string. Don't mess with indentation.
+ nil)
+ (cs
+ ;; Inside a general comment
+ (goto-char (car cs))
+ (forward-char 1)
+ (current-column))
+ (t
+ ;; Not in a multi-line string or comment
+ (let ((indent 0)
+ (inside-indenting-paren nil))
+ ;; Count every enclosing brace, plus parens that follow
+ ;; import, const, var, or type and indent according to
+ ;; depth. This simple rule does quite well, but also has a
+ ;; very large extent. It would be better if we could mimic
+ ;; some nearby indentation.
+ (save-excursion
+ (skip-chars-forward "})")
+ (let ((first t))
+ (dolist (nest (go-mode-nesting))
+ (case (char-after (car nest))
+ ((?\{)
+ (incf indent tab-width))
+ ((?\()
+ (goto-char (car nest))
+ (forward-comment (- (buffer-size)))
+ ;; Really just want the token before
+ (when (looking-back "\\<import\\|const\\|var\\|type"
+ (max (- (point) 7) (point-min)))
+ (incf indent tab-width)
+ (when first
+ (setq inside-indenting-paren t)))))
+ (setq first nil))))
+
+ ;; case, default, and labels are outdented 1 level
+ (when (looking-at "\\<case\\>\\|\\<default\\>\\|\\w+\\s *:\\(\\S.\\|$\\)")
+ (decf indent tab-width))
+
+ ;; Continuation lines are indented 1 level
+ (forward-comment (- (buffer-size)))
+ (when (case (char-before)
+ ((nil ?\{ ?:)
+ ;; At the beginning of a block or the statement
+ ;; following a label.
+ nil)
+ ((?\()
+ ;; Usually a continuation line in an expression,
+ ;; unless this paren is part of a factored
+ ;; declaration.
+ (not inside-indenting-paren))
+ ((?,)
+ ;; Could be inside a literal. We're a little
+ ;; conservative here and consider any comma within
+ ;; curly braces (as opposed to parens) to be a
+ ;; literal separator. This will fail to recognize
+ ;; line-breaks in parallel assignments as
+ ;; continuation lines.
+ (let ((depth (go-mode-nesting)))
+ (and depth
+ (not (eq (char-after (caar depth)) ?\{)))))
+ (t
+ ;; We're in the middle of a block. Did the
+ ;; previous line end with an implicit or explicit
+ ;; semicolon?
+ (not (go-mode-semicolon-p))))
+ (incf indent tab-width))
+
+ (max indent 0)))))))
+
+(defun go-mode-indent-line ()
+ "Indent the current line according to `go-mode-indentation'."
+ (interactive)
+
+ (let ((col (go-mode-indentation)))
+ (when col
+ (let ((offset (- (current-column) (current-indentation))))
+ (indent-line-to col)
+ (when (> offset 0)
+ (forward-char offset))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Go mode
+;;
+
+;;;###autoload
+(define-derived-mode go-mode prog-mode "Go"
+ "Major mode for editing Go source text.
+
+This provides basic syntax highlighting for keywords, built-ins,
+functions, and some types. It also provides indentation that is
+\(almost) identical to gofmt."
+
+ ;; Font lock
+ (set (make-local-variable 'font-lock-defaults)
+ '(go-mode-font-lock-keywords nil nil nil nil))
+
+ ;; Remove stale text properties
+ (save-restriction
+ (widen)
+ (remove-text-properties 1 (point-max)
+ '(go-mode-cs nil go-mode-nesting nil)))
+
+ ;; Reset the syntax mark caches
+ (setq go-mode-mark-cs-end 1
+ go-mode-mark-cs-state nil
+ go-mode-mark-nesting-end 1)
+ (add-hook 'after-change-functions #'go-mode-mark-clear-cache nil t)
+
+ ;; Indentation
+ (set (make-local-variable 'indent-line-function)
+ #'go-mode-indent-line)
+ (add-hook 'after-change-functions #'go-mode-delayed-electric-hook nil t)
+
+ ;; Comments
+ (set (make-local-variable 'comment-start) "// ")
+ (set (make-local-variable 'comment-end) "")
+
+ ;; Go style
+ (setq indent-tabs-mode t))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist (cons "\\.go$" #'go-mode))
+
+(defun go-mode-reload ()
+ "Reload go-mode.el and put the current buffer into Go mode.
+Useful for development work."
+
+ (interactive)
+ (unload-feature 'go-mode)
+ (require 'go-mode)
+ (go-mode))
+
+;;;###autoload
+(defun gofmt ()
+ "Pipe the current buffer through the external tool `gofmt`.
+Replace the current buffer on success; display errors on failure."
+
+ (interactive)
+ (let ((srcbuf (current-buffer)))
+ (with-temp-buffer
+ (let ((outbuf (current-buffer))
+ (errbuf (get-buffer-create "*Gofmt Errors*"))
+ (coding-system-for-read 'utf-8) ;; use utf-8 with subprocesses
+ (coding-system-for-write 'utf-8))
+ (with-current-buffer errbuf (erase-buffer))
+ (with-current-buffer srcbuf
+ (save-restriction
+ (let (deactivate-mark)
+ (widen)
+ (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt"
+ outbuf nil errbuf))
+ ;; gofmt succeeded: replace the current buffer with outbuf,
+ ;; restore the mark and point, and discard errbuf.
+ (let ((old-mark (mark t)) (old-point (point)))
+ (erase-buffer)
+ (insert-buffer-substring outbuf)
+ (goto-char (min old-point (point-max)))
+ (if old-mark (push-mark (min old-mark (point-max)) t))
+ (kill-buffer errbuf))
+
+ ;; gofmt failed: display the errors
+ (display-buffer errbuf)))))
+
+ ;; Collapse any window opened on outbuf if shell-command-on-region
+ ;; displayed it.
+ (delete-windows-on outbuf)))))
+
+;;;###autoload
+(defun gofmt-before-save ()
+ "Add this to .emacs to run gofmt on the current buffer when saving:
+ (add-hook 'before-save-hook #'gofmt-before-save)"
+
+ (interactive)
+ (when (eq major-mode 'go-mode) (gofmt)))
+
+(provide 'go-mode)
diff --git a/emacs.d/elisp/muttrc-mode.el b/emacs.d/elisp/muttrc-mode.el
new file mode 100644
index 0000000..b3bdd2c
--- /dev/null
+++ b/emacs.d/elisp/muttrc-mode.el
@@ -0,0 +1,1638 @@
+;;; muttrc-mode.el --- Major mode to edit muttrc under Emacs
+
+;;; Copyright (C) 2000, 2001, 2002 Laurent Pelecq
+;;; Copyright (C) 2009 Kumar Appaiah
+;;;
+;;; Authors: Laurent Pelecq <laurent.pelecq@soleil.org>
+;;; Kumar Appaiah <a.kumar@alumni.iitm.ac.in>
+
+;;; 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 2, 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, write to the Free Software
+;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Supported Emacs:
+;;; ================
+;;; This mode has only been tested on Emacs 21.2. If you
+;;; encounter problems with older versions or with Xemacs, let me
+;;; know.
+
+;;; Installation:
+;;; =============
+;;; Add this lines to your .emacs:
+;;; (autoload 'muttrc-mode "muttrc-mode.el"
+;;; "Major mode to edit muttrc files" t)
+;;; (setq auto-mode-alist
+;;; (append '(("muttrc\\'" . muttrc-mode))
+;;; auto-mode-alist))
+;;; Be sure this file is in a directory that appears in the load-path.
+;;;
+;;; You mail want to use this mode for other files like the mail
+;;; aliases file. In that case just add the following lines at the end
+;;; of these files:
+;;; ### Local Variables: ***
+;;; ### mode: muttrc ***
+;;; ### End: ***
+
+;;; Customization:
+;;; ==============
+;;; Execute: M-x configure-group RET muttrc RET
+;;;
+;;; By default, help on command/variable is displayed automatically
+;;; while executing a command to modify them. Disable this feature if
+;;; you have problems with.
+
+;;; Description:
+;;; ============
+;;; This mode first goal is to provide syntax highlighting with
+;;; font-lock. The basic fontification appears on strings, comments,
+;;; command names and variables. Additional fontification for commands
+;;; arguments can be enabled through the customization buffer.
+;;;
+;;; Main commands are:
+;;; C-x c -- muttrc-insert-command
+;;; C-x s -- muttrc-set-variable
+;;; C-x S -- muttrc-unset-variable
+;;;
+;;; Type C-h m for all key bindings.
+
+;;; BUGS:
+;;; =====
+;;; - Multiline commands are not properly handled and can lead to
+;;; unexpected result.
+
+
+
+;;; Code:
+
+;;; ------------------------------------------------------------
+;;; Requirement
+;;; ------------------------------------------------------------
+
+(require 'man)
+
+(defconst muttrc-mode-version "$Revision: 1.2 $")
+
+;;; ------------------------------------------------------------
+;;; Configurable stuff
+;;; ------------------------------------------------------------
+
+(defgroup muttrc nil
+ "Muttrc editing commands for Emacs."
+ :group 'files
+ :prefix "muttrc-")
+
+(defcustom muttrc-manual-path "/usr/share/doc/mutt/manual.txt.gz"
+ "Path to the Mutt manual."
+ :type 'string
+ :group 'muttrc)
+
+(defcustom muttrc-display-help t
+ "Display help for each command/variable modification if set."
+ :type 'boolean
+ :group 'muttrc)
+
+(defcustom muttrc-folder-abbrev ?+
+ "Character used to refer to the folder directory."
+ :type '(choice (const :tag "+" ?+)
+ (const :tag "=" ?=))
+ :group 'muttrc)
+
+(defcustom muttrc-argument-faces-alist
+ '((alias . bold)
+ (address . default)
+ (face . default)
+ (color . default)
+ (command . default)
+ (path . default)
+ (function . default)
+ (header . default)
+ (hook . default)
+ (key . default)
+ (map . default)
+ (mimetype . default)
+ (object . default)
+ (regexp . default)
+ (sequence . default)
+ (string . default)
+ (hook-type . default))
+ "List of faces for the Muttrc command arguments. Standard faces are
+symbols like 'bold, 'underline, ... Muttrc files must be revisited in
+order for the modifications to take effect."
+ :type '(repeat (cons symbol symbol))
+ :group 'muttrc)
+
+;;; ------------------------------------------------------------
+;;; For backward compatibility
+;;; ------------------------------------------------------------
+
+(or (functionp 'match-string-no-properties)
+ (defalias 'match-string-no-properties 'match-string))
+
+;;; ------------------------------------------------------------
+;;; Mutt variables and commands
+;;; ------------------------------------------------------------
+
+(defconst muttrc-arg-handler-alist
+ '((alias muttrc-get-word "Alias")
+ (boolean muttrc-get-boolean "Enable")
+ (number muttrc-get-number "Number")
+ (address muttrc-get-string "Address")
+ (face muttrc-get-from-list "Face" muttrc-face-alist t)
+ (color muttrc-get-from-list "Color" muttrc-color-alist)
+ (command muttrc-get-command "Command")
+ (statement muttrc-get-statement "Command")
+ (assignment muttrc-get-assignment "Variable" t)
+ (variable muttrc-get-assignment "Variable" nil)
+ (path muttrc-get-path "Path")
+ (function muttrc-get-from-list "Function" muttrc-mutt-function-alist)
+ (header muttrc-get-from-list "Header name" muttrc-header-alist)
+ (hook-type muttrc-get-from-list "Hook" muttrc-hook-alist t)
+ (key muttrc-get-string "Key")
+ (map muttrc-get-from-list "Map" muttrc-map-alist t)
+ (mimetype muttrc-get-from-list "MIME type" muttrc-mimetype-alist)
+ (object muttrc-get-from-list "Object" muttrc-object-alist)
+ (regexp muttrc-get-string "Regular expression")
+ (sequence muttrc-get-string "Sequence")
+ (string muttrc-get-string "String")
+ (alias-sort-order muttrc-get-from-list "Sort order"
+ muttrc-alias-sort-order-alist)
+ (aux-sort-order muttrc-get-from-list "Sort order"
+ muttrc-aux-sort-order-alist)
+ (browser-sort-order muttrc-get-from-list "Sort order"
+ muttrc-browser-sort-order-alist)
+ (pgp-sort-order muttrc-get-from-list "Sort order"
+ muttrc-pgp-sort-order-alist)
+ (quadoption muttrc-get-from-list "Option" muttrc-quadoption-alist)
+ (sort-order muttrc-get-from-list "Sort order"
+ muttrc-sort-order-alist))
+ "List of handler for each type of argument. The format is:
+\(ARG-TYPE FACE HANDLER PROMPT HANDLER-ARGS\).
+The PROMPT can be overwritten by in command description.")
+
+(defconst muttrc-face-alist
+ '(("none" . 1) ("bold" . 2) ("underline" . 3)
+ ("reverse" . 4) ("standout". 5)))
+
+(defconst muttrc-color-alist
+ '(("default" . 0)
+ ("black" . 1) ("blue" . 2) ("cyan" . 3) ("green" . 4)
+ ("magenta" . 5) ("red" . 6) ("white" . 7) ("yellow" . 8)
+ ("brightdefault" . 9)
+ ("brightblack" . 10) ("brightblue" . 11) ("brightcyan" . 12)
+ ("brightgreen" . 13) ("brightmagenta" . 14) ("brightred" . 15)
+ ("brightwhite" . 16) ("brightyellow" . 17)))
+
+(defconst muttrc-object-alist
+ '(("attachment" . 0)
+ ("body" . 1)
+ ("bold" . 2)
+ ("error" . 3)
+ ("hdrdefault" . 4)
+ ("header" . 5)
+ ("index" . 6)
+ ("indicator" . 7)
+ ("markers" . 8)
+ ("message" . 9)
+ ("normal" . 10)
+ ("quoted" . 11)
+ ("search" . 12)
+ ("signature" . 13)
+ ("status" . 14)
+ ("tilde" . 15)
+ ("tree" . 16)
+ ("underline" . 17))
+ "Mutt object on which color apply.")
+
+(defconst muttrc-header-alist
+ '(("content-transfer-encoding" . 0)
+ ("content-type" . 1)
+ ("date" . 2)
+ ("from" . 3)
+ ("message-id" . 4)
+ ("mime-version" . 5)
+ ("organization" . 6)
+ ("received" . 7)
+ ("reply-to" . 8)
+ ("resent-from" . 9)
+ ("subject" . 10)
+ ("to" . 11)
+ ("x-accept-language" . 12)
+ ("x-mailer" . 13)
+ ("x-mimetrack" . 14)
+ ("x-sender" . 15)))
+
+(defconst muttrc-hook-alist
+ '(("folder-hook" . 0) ("send-hook" . 1) ("save-hook" . 2)
+ ("mbox-hook" . 3) ("fcc-hook" . 4) ("fcc-save-hook" . 5)
+ ("message-hook" . 5) ("charset-hook" . 6) ("iconv-hook" . 7)
+ ("account-hook" . 8) ("append-hook" . 9) ("close-hook" . 10)
+ ("crypt-hook" . 11) ("send2-hook" . 12) ("reply-hook" . 13)
+ ("open-hook" . 14)))
+
+(defconst muttrc-map-alist
+ '(("alias" . 0) ("attach" . 1) ("browser" . 2) ("compose" . 3)
+ ("editor" . 4) ("generic" . 5) ("index" . 6) ("pager" . 7)
+ ("pgp" . 8) ("postpone" . 9) ("query" . 10)))
+
+(defconst muttrc-mimetype-alist
+ '(("application/andrew-inset" "ez")
+ ("application/excel" "xls")
+ ("application/fractals" "fif")
+ ("application/java-archive" "jar")
+ ("application/mac-binhex40" "hqx")
+ ("application/msword" "doc" "dot")
+ ("application/octet-stream" "exe" "bin")
+ ("application/oda" "oda")
+ ("application/pdf" "pdf")
+ ("application/pdf")
+ ("application/pgp" "pgp")
+ ("application/postscript" "ai" "eps" "ps" "PS")
+ ("application/pre-encrypted" "enc")
+ ("application/rtf" "rtf")
+ ("application/vnd.lotus-wordpro" "lwp" "sam")
+ ("application/vnd.ms-access" "mdb" "mda" "mde")
+ ("application/vnd.ms-excel" "xls")
+ ("application/vnd.ms-powerpoint" "ppt" "pot" "ppa" "pps" "pwz")
+ ("application/vnd.ms-schedule" "scd" "sch" "sc2")
+ ("application/wordperfect5.1" "wpd" "wp6")
+ ("application/x-arj-compressed" "arj")
+ ("application/x-bcpio" "bcpio")
+ ("application/x-chess-pgn" "pgn")
+ ("application/x-cpio" "cpio")
+ ("application/x-csh" "csh")
+ ("application/x-debian-package" "deb")
+ ("application/x-dvi" "dvi")
+ ("application/x-fortezza-ckl" "ckl")
+ ("application/x-gtar" "gtar")
+ ("application/x-gunzip" "gz")
+ ("application/x-hdf" "hdf")
+ ("application/x-javascript" "js" "mocha")
+ ("application/x-javascript-config" "jsc")
+ ("application/x-latex" "latex")
+ ("application/x-mif" "mif")
+ ("application/x-msdos-program" "com" "exe" "bat")
+ ("application/x-netcdf" "cdf" "nc")
+ ("application/x-ns-proxy-autoconfig" "pac")
+ ("application/x-ns-proxy-autoconfig")
+ ("application/x-perl" "pl" "pm")
+ ("application/x-pkcs7-crl" "crl")
+ ("application/x-pkcs7-mime" "p7m" "p7c")
+ ("application/x-pkcs7-signature" "p7s")
+ ("application/x-rar-compressed" "rar")
+ ("application/x-sh" "sh")
+ ("application/x-shar" "shar")
+ ("application/x-stuffit" "sit")
+ ("application/x-sv4cpio" "sv4cpio")
+ ("application/x-sv4crc" "sv4crc")
+ ("application/x-tar" "tar")
+ ("application/x-tar-gz" "tgz" "tar.gz")
+ ("application/x-tcl" "tcl")
+ ("application/x-tex" "tex")
+ ("application/x-texinfo" "texi" "texinfo")
+ ("application/x-troff" "t" "tr" "roff")
+ ("application/x-troff-man" "man")
+ ("application/x-troff-me" "me")
+ ("application/x-troff-ms" "ms")
+ ("application/x-ustar" "ustar")
+ ("application/x-wais-source" "src")
+ ("application/x-zip-compressed" "zip")
+ ("audio/basic" "au" "snd")
+ ("audio/basic" "snd")
+ ("audio/midi" "mid" "midi")
+ ("audio/ulaw" "au")
+ ("audio/x-aiff" "aif" "aifc" "aiff")
+ ("audio/x-aiff" "aif" "aiff" "aifc")
+ ("audio/x-wav" "wav")
+ ("image/gif" "gif")
+ ("image/ief" "ief")
+ ("image/jpeg" "jpe" "jpeg" "jpg")
+ ("image/png" "png")
+ ("image/tiff" "tif" "tiff")
+ ("image/tiff")
+ ("image/x-MS-bmp" "bmp")
+ ("image/x-cmu-raster" "ras")
+ ("image/x-photo-cd" "pcd")
+ ("image/x-portable-anymap" "pnm")
+ ("image/x-portable-bitmap" "pbm")
+ ("image/x-portable-graymap" "pgm")
+ ("image/x-portable-pixmap" "ppm")
+ ("image/x-rgb" "rgb")
+ ("image/x-xbitmap" "xbm")
+ ("image/x-xpixmap" "xpm")
+ ("image/x-xwindowdump" "xwd")
+ ("text/html" "html" "htm" "shtml")
+ ("text/plain" "txt" "text")
+ ("text/richtext" "rtx")
+ ("text/tab-separated-values" "tsv")
+ ("text/x-setext" "etx")
+ ("text/x-vcard" "vcf")
+ ("text/x-vcard")
+ ("video/dl" "dl")
+ ("video/fli" "fli")
+ ("video/gl" "gl")
+ ("video/mpeg" "mpeg" "mpg" "mpe" "mpv" "vbs" "mpegv")
+ ("video/quicktime" "qt" "mov" "moov")
+ ("video/x-msvideo" "avi")
+ ("video/x-sgi-movie" "movie")
+ ("x-world/x-vrml" "vrm" "vrml" "wrl")))
+
+(defconst muttrc-command-alist
+ '(
+ ("folder-hook" ((string) (statement)) nil nil)
+ ("alias" ((alias) (address)) t nil)
+ ("unalias" ((alias) (address)) t nil)
+ ("alternative_order" ((mimetype)) t nil)
+ ("auto_view" ((mimetype)) t nil)
+ ("bind" ((map) (key) (function)) nil t)
+ ("color" ((object)
+ (color "Foreground")
+ (color "Background")
+ (regexp)) nil t)
+ ("charset-hook" ((string "Alias")
+ (string "Charset")) nil nil)
+ ("fcc-hook" ((regexp) (path)) nil nil)
+ ("fcc-save-hook" ((regexp) (path)) nil nil)
+ ("folder-hook" ((regexp) (statement)) nil nil)
+ ("ignore" ((header)) t nil)
+ ("iconv-hook" ((string "Charset")
+ (string "Local charset")) nil nil)
+ ("unignore" ((header)) t nil)
+ ("hdr_order" ((header)) t nil)
+ ("unhdr_order" ((header)) t nil)
+ ("lists" ((address)) t nil)
+ ("unlists" ((address)) t nil)
+ ("macro" ((map) (key) (sequence)
+ (string "Description")) nil t)
+ ("mailboxes" ((path)) t nil)
+ ("mono" ((object) (face) (regexp)) nil t)
+ ("mbox-hook" ((regexp) (path)) nil nil)
+ ("message-hook" ((regexp) (statement)) nil nil)
+ ("my_hdr" ((string "Header")) nil nil)
+ ("unmy_hdr" ((header)) t nil)
+ ("push" ((string)) nil nil)
+ ("pgp-hook" ((regexp)
+ (string "Keyid")) nil nil)
+ ("save-hook" ((regexp) (path)) nil nil)
+ ("score" ((regexp)
+ (number "Value")) nil nil)
+ ("unscore" ((regexp)) t nil)
+ ("send-hook" ((regexp) (statement)) nil nil)
+ ("source" ((path)) nil nil)
+ ("subscribe" ((address)) t nil)
+ ("unsubscribe" ((address)) t nil)
+ ("unhook" ((hook-type)) nil nil)
+ ("alternates" ((regexp)) nil nil)
+ ("unalternates" ((regexp)) nil nil))
+ "List of muttrc commands with their arguments. Format is:
+COMMAND '\(ARG1 ARG2 ...\) REPEAT OPTIONAL
+REPEAT and OPTIONAL apply to the last argument.
+ARGn is the list of arguments for muttrc-call-arg-handler. Each args
+is a list \(ARGTYPE \[ARGNAME\]\).")
+
+(defconst muttrc-statement-alist
+ (append
+ '(("set" ((assignment)) t nil)
+ ("unset" ((variable)) t nil))
+ muttrc-command-alist)
+ "Additional muttrc commands with their arguments that are handled
+differently. See muttrc-command-alist")
+
+
+(defconst muttrc-variables-alist
+ '(("abort_nosubject" quadoption "ask-yes")
+ ("abort_unmodified" quadoption "yes")
+ ("alias_file" path "~/.muttrc")
+ ("alias_format" string "%4n %2f %t %-10a %r")
+ ("allow_8bit" boolean t)
+ ("allow_ansi" boolean nil)
+ ("arrow_cursor" boolean nil)
+ ("ascii_chars" boolean nil)
+ ("askbcc" boolean nil)
+ ("askcc" boolean nil)
+ ("assumed_charset" string "us-ascii")
+ ("attach_format" string "%u%D%I %t%4n %T%.40d%> [%.7m/%.10M, %.6e%?C?, %C?, %s] ")
+ ("attach_sep" string "\\n")
+ ("attach_split" boolean t)
+ ("attribution" string "On %d, %n wrote:")
+ ("autoedit" boolean nil)
+ ("auto_tag" boolean nil)
+ ("beep" boolean t)
+ ("beep_new" boolean nil)
+ ("bounce" quadoption "ask-yes")
+ ("bounce_delivered" boolean t)
+ ("braille_friendly" boolean nil)
+ ("charset" string "")
+ ("check_new" boolean t)
+ ("collapse_unread" boolean t)
+ ("uncollapse_jump" boolean nil)
+ ("compose_format" string "-- Mutt: Compose [Approx. msg size: %l Atts: %a]%>-")
+ ("config_charset" string "")
+ ("confirmappend" boolean t)
+ ("confirmcreate" boolean t)
+ ("connect_timeout" number 30)
+ ("content_type" string "text/plain")
+ ("copy" quadoption "yes")
+ ("crypt_use_gpgme" boolean nil)
+ ("crypt_autopgp" boolean t)
+ ("crypt_autosmime" boolean t)
+ ("date_format" string "!%a, %b %d, %Y at %I:%M:%S%p %Z")
+ ("default_hook" string "~f %s !~P | (~P ~C %s)")
+ ("delete" quadoption "ask-yes")
+ ("delete_untag" boolean t)
+ ("digest_collapse" boolean t)
+ ("display_filter" path "")
+ ("dotlock_program" path "/usr/bin/mutt_dotlock")
+ ("dsn_notify" string "")
+ ("dsn_return" string "")
+ ("duplicate_threads" boolean t)
+ ("edit_headers" boolean nil)
+ ("editor" path "")
+ ("encode_from" boolean nil)
+ ("envelope_from_address" e-mail "")
+ ("escape" string "~")
+ ("fast_reply" boolean nil)
+ ("fcc_attach" boolean t)
+ ("fcc_clear" boolean nil)
+ ("file_charset" string "")
+ ("folder" path "~/Mail")
+ ("folder_format" string "%2C %t %N %F %2l %-8.8u %-8.8g %8s %d %f")
+ ("followup_to" boolean t)
+ ("force_name" boolean nil)
+ ("forward_decode" boolean t)
+ ("forward_edit" quadoption "yes")
+ ("forward_format" string "[%a: %s]")
+ ("forward_quote" boolean nil)
+ ("from" e-mail "")
+ ("gecos_mask" regular "^[^,]*")
+ ("hdrs" boolean t)
+ ("header" boolean nil)
+ ("help" boolean t)
+ ("hidden_host" boolean nil)
+ ("hide_limited" boolean nil)
+ ("hide_missing" boolean t)
+ ("hide_thread_subject" boolean t)
+ ("hide_top_limited" boolean nil)
+ ("hide_top_missing" boolean t)
+ ("history" number 10)
+ ("honor_followup_to" quadoption "yes")
+ ("hostname" string "")
+ ("ignore_list_reply_to" boolean nil)
+ ("imap_authenticators" string "")
+ ("imap_check_subscribed" boolean nil)
+ ("imap_delim_chars" string "/.")
+ ("imap_headers" string "")
+ ("imap_home_namespace" string "")
+ ("imap_idle" boolean nil)
+ ("imap_keepalive" number 900)
+ ("imap_list_subscribed" boolean nil)
+ ("imap_login" string "")
+ ("imap_pass" string "")
+ ("imap_passive" boolean t)
+ ("imap_peek" boolean t)
+ ("imap_servernoise" boolean t)
+ ("imap_user" string "")
+ ("implicit_autoview" boolean nil)
+ ("include" quadoption "ask-yes")
+ ("include_onlyfirst" boolean nil)
+ ("indent_string" string "> ")
+ ("index_format" string "%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s")
+ ("hdr_format" string "%4C %Z %{%b %d} %-15.15L (%?l?%4l&%4c?) %s")
+ ("ispell" path "ispell")
+ ("keep_flagged" boolean nil)
+ ("locale" string "C")
+ ("mail_check" number 5)
+ ("mailcap_path" string "")
+ ("mailcap_sanitize" boolean t)
+ ("maildir_mtime" boolean nil)
+ ("header_cache" path "")
+ ("maildir_header_cache_verify" boolean t)
+ ("header_cache_pagesize" string "16384")
+ ("maildir_trash" boolean nil)
+ ("mark_old" boolean t)
+ ("markers" boolean t)
+ ("mask" regular "!^\.[^.]")
+ ("mbox" path "~/mbox")
+ ("mbox_type" folder mbox)
+ ("metoo" boolean nil)
+ ("menu_context" number 0)
+ ("menu_move_off" boolean t)
+ ("menu_scroll" boolean nil)
+ ("meta_key" boolean nil)
+ ("mh_purge" boolean nil)
+ ("mh_seq_flagged" string "flagged")
+ ("mh_seq_replied" string "replied")
+ ("mh_seq_unseen" string "unseen")
+ ("mime_forward" quadoption "no")
+ ("mime_forward_decode" boolean nil)
+ ("mime_forward_rest" quadoption "yes")
+ ("pgp_mime_signature_filename" string "signature.asc")
+ ("pgp_mime_signature_description" string "Digital signature")
+ ("mix_entry_format" string "%4n %c %-16s %a")
+ ("mixmaster" path "mixmaster")
+ ("move" quadoption "ask-no")
+ ("message_cachedir" path "")
+ ("message_format" string "%s")
+ ("narrow_tree" boolean nil)
+ ("net_inc" number 10)
+ ("pager" path "builtin")
+ ("pager_context" number 0)
+ ("pager_format" string "-%Z- %C/%m: %-20.20n %s")
+ ("pager_index_lines" number 0)
+ ("pager_stop" boolean nil)
+ ("crypt_autosign" boolean nil)
+ ("crypt_autoencrypt" boolean nil)
+ ("pgp_ignore_subkeys" boolean t)
+ ("crypt_replyencrypt" boolean t)
+ ("crypt_replysign" boolean nil)
+ ("crypt_replysignencrypted" boolean nil)
+ ("crypt_timestamp" boolean t)
+ ("pgp_use_gpg_agent" boolean nil)
+ ("crypt_verify_sig" quadoption "yes")
+ ("pgp_verify_sig" quadoption "yes")
+ ("smime_is_default" boolean nil)
+ ("smime_ask_cert_label" boolean t)
+ ("smime_decrypt_use_default_key" boolean t)
+ ("pgp_entry_format" string "%4n %t%f %4l/0x%k %-4a %2c %u")
+ ("pgp_good_sign" regular "")
+ ("pgp_check_exit" boolean t)
+ ("pgp_long_ids" boolean nil)
+ ("pgp_retainable_sigs" boolean nil)
+ ("pgp_autoinline" boolean nil)
+ ("pgp_replyinline" boolean nil)
+ ("pgp_show_unusable" boolean t)
+ ("pgp_sign_as" string "")
+ ("pgp_strict_enc" boolean t)
+ ("pgp_timeout" number 300)
+ ("pgp_sort_keys" sort address)
+ ("pgp_mime_auto" quadoption "ask-yes")
+ ("pgp_auto_decode" boolean nil)
+ ("pgp_decode_command" string "")
+ ("pgp_getkeys_command" string "")
+ ("pgp_verify_command" string "")
+ ("pgp_decrypt_command" string "")
+ ("pgp_clearsign_command" string "")
+ ("pgp_sign_command" string "")
+ ("pgp_encrypt_sign_command" string "")
+ ("pgp_encrypt_only_command" string "")
+ ("pgp_import_command" string "")
+ ("pgp_export_command" string "")
+ ("pgp_verify_key_command" string "")
+ ("pgp_list_secring_command" string "")
+ ("pgp_list_pubring_command" string "")
+ ("forward_decrypt" boolean t)
+ ("smime_timeout" number 300)
+ ("smime_encrypt_with" string "")
+ ("smime_keys" path "")
+ ("smime_ca_location" path "")
+ ("smime_certificates" path "")
+ ("smime_decrypt_command" string "")
+ ("smime_verify_command" string "")
+ ("smime_verify_opaque_command" string "")
+ ("smime_sign_command" string "")
+ ("smime_sign_opaque_command" string "")
+ ("smime_encrypt_command" string "")
+ ("smime_pk7out_command" string "")
+ ("smime_get_cert_command" string "")
+ ("smime_get_signer_cert_command" string "")
+ ("smime_import_cert_command" string "")
+ ("smime_get_cert_email_command" string "")
+ ("smime_default_key" string "")
+ ("ssl_force_tls" boolean nil)
+ ("ssl_starttls" quadoption "yes")
+ ("certificate_file" path "~/.mutt_certificates")
+ ("ssl_use_sslv3" boolean t)
+ ("ssl_use_tlsv1" boolean t)
+ ("ssl_min_dh_prime_bits" number 0)
+ ("ssl_ca_certificates_file" path "")
+ ("pipe_split" boolean nil)
+ ("pipe_decode" boolean nil)
+ ("pipe_sep" string "\\n")
+ ("pop_authenticators" string "")
+ ("pop_auth_try_all" boolean t)
+ ("pop_checkinterval" number 60)
+ ("pop_delete" quadoption "ask-no")
+ ("pop_host" string "")
+ ("pop_last" boolean nil)
+ ("pop_reconnect" quadoption "ask-yes")
+ ("pop_user" string "")
+ ("pop_pass" string "")
+ ("post_indent_string" string "")
+ ("postpone" quadoption "ask-yes")
+ ("postponed" path "~/postponed")
+ ("preconnect" string "")
+ ("print" quadoption "ask-no")
+ ("print_command" path "lpr")
+ ("print_decode" boolean t)
+ ("print_split" boolean nil)
+ ("prompt_after" boolean t)
+ ("query_command" path "")
+ ("quit" quadoption "yes")
+ ("quote_regexp" regular "^([ \t]*[|>:}#])+")
+ ("read_inc" number 10)
+ ("read_only" boolean nil)
+ ("realname" string "")
+ ("recall" quadoption "ask-yes")
+ ("record" path "~/sent")
+ ("reply_regexp" regular "^(re([\[0-9\]+])*|aw):[ \t]*")
+ ("reply_self" boolean nil)
+ ("reply_to" quadoption "ask-yes")
+ ("resolve" boolean t)
+ ("reverse_alias" boolean nil)
+ ("reverse_name" boolean nil)
+ ("reverse_realname" boolean t)
+ ("rfc2047_parameters" boolean nil)
+ ("save_address" boolean nil)
+ ("save_empty" boolean t)
+ ("save_name" boolean nil)
+ ("score" boolean t)
+ ("score_threshold_delete" number -1)
+ ("score_threshold_flag" number 9999)
+ ("score_threshold_read" number -1)
+ ("send_charset" string "us-ascii:iso-8859-1:utf-8")
+ ("sendmail" path "/usr/sbin/sendmail -oem -oi")
+ ("sendmail_wait" number 0)
+ ("shell" path "")
+ ("sig_dashes" boolean t)
+ ("sig_on_top" boolean nil)
+ ("signature" path "~/.signature")
+ ("simple_search" string "~f %s | ~s %s")
+ ("smart_wrap" boolean t)
+ ("smileys" regular "(>From )|(:[-^]?[][)(><}{|/DP])")
+ ("sleep_time" number 1)
+ ("sort" sort date)
+ ("sort_alias" sort alias)
+ ("sort_aux" sort date)
+ ("sort_browser" sort alpha)
+ ("sort_re" boolean t)
+ ("spam_separator" string ",")
+ ("spoolfile" path "")
+ ("status_chars" string "-*%A")
+ ("status_format" string "-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b?%?l? %l?]---(%s/%S)-%>-(%P)---")
+ ("status_on_top" boolean nil)
+ ("strict_mime" boolean t)
+ ("strict_threads" boolean nil)
+ ("suspend" boolean t)
+ ("text_flowed" boolean nil)
+ ("thread_received" boolean nil)
+ ("thorough_search" boolean nil)
+ ("tilde" boolean nil)
+ ("timeout" number 600)
+ ("tmpdir" path "")
+ ("to_chars" string " +TCFL")
+ ("tunnel" string "")
+ ("use_8bitmime" boolean nil)
+ ("use_domain" boolean t)
+ ("use_envelope_from" boolean nil)
+ ("use_from" boolean t)
+ ("use_idn" boolean t)
+ ("use_ipv6" boolean t)
+ ("user_agent" boolean t)
+ ("visual" path "")
+ ("wait_key" boolean t)
+ ("weed" boolean t)
+ ("wrap_search" boolean t)
+ ("wrapmargin" number 0)
+ ("write_inc" number 10)
+ ("write_bcc" boolean t)
+ ("xterm_icon" string "M%?n?AIL&ail?")
+ ("xterm_set_titles" boolean nil)
+ ("xterm_title" string "Mutt with %?m?%m messages&no messages?%?n? [%n NEW]?"))
+ "List of muttrc variables. Format is:
+VARIABLE TYPE DEFAULT"
+ )
+
+(defconst muttrc-mutt-function-alist
+ '(("attach-file" . 0)
+ ("attach-key" . 1)
+ ("attach-message" . 2)
+ ("backspace" . 3)
+ ("backward-char" . 4)
+ ("bol" . 5)
+ ("bottom-page" . 6)
+ ("bounce-message" . 7)
+ ("buffy-cycle" . 8)
+ ("change-dir" . 9)
+ ("change-folder" . 10)
+ ("change-folder-readonly" . 11)
+ ("check-new" . 12)
+ ("clear-flag" . 13)
+ ("complete" . 14)
+ ("complete-query" . 15)
+ ("copy-file" . 16)
+ ("copy-message" . 17)
+ ("create-alias" . 18)
+ ("current-bottom" . 19)
+ ("current-middle" . 20)
+ ("current-top" . 21)
+ ("decode-copy" . 22)
+ ("decode-save" . 23)
+ ("delete-char" . 24)
+ ("delete-entry" . 25)
+ ("delete-message" . 26)
+ ("delete-pattern" . 27)
+ ("delete-subthread" . 28)
+ ("delete-thread" . 29)
+ ("detach-file" . 30)
+ ("display-address" . 31)
+ ("display-message" . 32)
+ ("display-toggle-weed" . 33)
+ ("edit" . 34)
+ ("edit-bcc" . 35)
+ ("edit-cc" . 36)
+ ("edit-description" . 37)
+ ("edit-encoding" . 38)
+ ("edit-fcc" . 39)
+ ("edit-file" . 40)
+ ("edit-from" . 41)
+ ("edit-headers" . 42)
+ ("edit-message" . 43)
+ ("edit-mime" . 44)
+ ("edit-reply-to" . 45)
+ ("edit-subject" . 46)
+ ("edit-to" . 47)
+ ("edit-type" . 48)
+ ("enter-command" . 49)
+ ("enter-mask" . 50)
+ ("eol" . 51)
+ ("exit" . 52)
+ ("extract-keys" . 53)
+ ("fetch-mail" . 54)
+ ("filter-entry" . 55)
+ ("first-entry" . 56)
+ ("flag-message" . 57)
+ ("forget-passphrase" . 58)
+ ("forward-char" . 59)
+ ("forward-message" . 60)
+ ("group-reply" . 61)
+ ("half-down" . 62)
+ ("half-up" . 63)
+ ("help" . 64)
+ ("history-down" . 65)
+ ("history-up" . 66)
+ ("ispell" . 67)
+ ("jump" . 68)
+ ("kill-eol" . 69)
+ ("kill-line" . 70)
+ ("kill-word" . 71)
+ ("last-entry" . 72)
+ ("limit" . 73)
+ ("list-reply" . 74)
+ ("mail" . 75)
+ ("mail-key" . 76)
+ ("mark-as-new" . 77)
+ ("middle-page" . 78)
+ ("new-mime" . 79)
+ ("next-entry" . 80)
+ ("next-line" . 81)
+ ("next-new" . 82)
+ ("next-page" . 83)
+ ("next-subthread" . 84)
+ ("next-thread" . 85)
+ ("next-undeleted" . 86)
+ ("next-unread" . 87)
+ ("parent-message" . 88)
+ ("pgp-menu" . 89)
+ ("pipe-entry" . 90)
+ ("pipe-message" . 91)
+ ("postpone-message" . 92)
+ ("previous-entry" . 93)
+ ("previous-line" . 94)
+ ("previous-new" . 95)
+ ("previous-page" . 96)
+ ("previous-subthread" . 97)
+ ("previous-thread" . 98)
+ ("previous-undeleted" . 99)
+ ("previous-unread" . 100)
+ ("print-entry" . 101)
+ ("print-message" . 102)
+ ("query" . 103)
+ ("query-append" . 104)
+ ("quit" . 105)
+ ("quote-char" . 106)
+ ("read-subthread" . 107)
+ ("read-thread" . 108)
+ ("recall-message" . 109)
+ ("redraw-screen" . 110)
+ ("refresh" . 111)
+ ("rename-file" . 112)
+ ("reply" . 113)
+ ("save-entry" . 114)
+ ("save-message" . 115)
+ ("search" . 116)
+ ("search-next" . 117)
+ ("search-opposite" . 118)
+ ("search-reverse" . 119)
+ ("search-toggle" . 120)
+ ("select-entry" . 121)
+ ("select-new" . 122)
+ ("send-message" . 123)
+ ("set-flag" . 124)
+ ("shell-escape" . 125)
+ ("show-limit" . 126)
+ ("show-version" . 127)
+ ("skip-quoted" . 128)
+ ("sort" . 129)
+ ("sort-mailbox" . 130)
+ ("sort-reverse" . 131)
+ ("subscribe" . 132)
+ ("sync-mailbox" . 133)
+ ("tag-entry" . 134)
+ ("tag-message" . 135)
+ ("tag-pattern" . 136)
+ ("tag-prefix" . 137)
+ ("tag-thread" . 138)
+ ("toggle-mailboxes" . 139)
+ ("toggle-new" . 140)
+ ("toggle-quoted" . 141)
+ ("toggle-subscribed" . 142)
+ ("toggle-unlink" . 143)
+ ("toggle-write" . 144)
+ ("top" . 145)
+ ("top-page" . 146)
+ ("undelete-entry" . 147)
+ ("undelete-message" . 148)
+ ("undelete-pattern" . 149)
+ ("undelete-subthread" . 150)
+ ("undelete-thread" . 151)
+ ("unsubscribe" . 152)
+ ("untag-pattern" . 153)
+ ("verify-key" . 154)
+ ("view-attach" . 155)
+ ("view-attachments" . 156)
+ ("view-file" . 157)
+ ("view-mailcap" . 158)
+ ("view-name" . 159)
+ ("view-text" . 160)
+ ("write-fcc" . 161))
+ "List of Mutt command (not muttrc!)")
+
+(defconst muttrc-alias-sort-order-alist
+ '(("address" . 0) ("alias" . 1) ("unsorted" . 2)))
+
+(defconst muttrc-aux-sort-order-alist
+ '(("date-sent" . 0) ("reverse-date-sent" . 1) ("last-date-sent" . 2)
+ ("date-received" . 3) ("reverse-date-received" . 4)
+ ("last-date-received" . 5)
+ ("from" . 6) ("reverse-from" . 7) ("last-from" . 8)
+ ("mailbox-order" . 9) ("reverse-mailbox-order" . 10)
+ ("last-mailbox-order" . 11)
+ ("score" . 12) ("reverse-score" . 13) ("last-score" . 14)
+ ("size" . 15) ("reverse-size" . 16) ("last-size" . 17)
+ ("subject" . 18) ("reverse-subject" . 19) ("last-subject" . 20)
+ ("threads" . 21) ("reverse-threads" . 22) ("last-threads" . 23)
+ ("to" . 24) ("reverse-to" . 25) ("last-to" . 26)))
+
+(defconst muttrc-browser-sort-order-alist
+ '(("alpha" . 0) ("date" . 1) ("size" . 2) ("unsorted" . 3)))
+
+(defconst muttrc-pgp-sort-order-alist
+ '(("address" . 0) ("date" . 1) ("keyid" . 2)
+ ("reverse-address" . 3) ("reverse-date" . 4)
+ ("reverse-keyid" . 5) ("reverse-trust" . 6)
+ ("trust" . 7)))
+
+(defconst muttrc-quadoption-alist
+ '(("yes" .0) ("no" .1) ("ask-yes" .2) ("ask-no" .3)))
+
+(defconst muttrc-sort-order-alist
+ '(("date-sent" . 0) ("reverse-date-sent" . 1)
+ ("date-received" . 2) ("reverse-date-received" . 3)
+ ("from" . 4) ("reverse-from" . 5)
+ ("mailbox-order" . 6) ("reverse-mailbox-order" . 7)
+ ("score" . 8) ("reverse-score" . 9)
+ ("size" . 10) ("reverse-size" . 11)
+ ("subject" . 12) ("reverse-subject" . 13)
+ ("threads" . 14) ("reverse-threads" . 15)
+ ("to" . 16) ("reverse-to" . 17)))
+
+;;; ------------------------------------------------------------
+;;; Font-lock definitions
+;;; ------------------------------------------------------------
+
+(defun muttrc-string-regexp (quote-char)
+ (let ((c (char-to-string quote-char)))
+ (format "%s\\([^\n%s]\\|[\\].\\)*%s" c c c)))
+
+(defvar muttrc-generic-arg-regexp
+ (concat "\\("
+ (muttrc-string-regexp ?\")
+ "\\|"
+ "'\\([^']*\\)'"
+ "\\|"
+ (muttrc-string-regexp ?\`)
+ "\\|"
+ "\\([^\n\t \"'`#;\\]\\|[\\].\\)+"
+ "\\)"))
+
+(defvar muttrc-generic-arg-sequence-regexp
+ (concat "\\(\\s-*" muttrc-generic-arg-regexp "+\\)*"))
+
+(defvar muttrc-non-command-keyword-regexp
+ "\\(^\\|;\\)\\s-*\\<\\(set\\|unset\\|toggle\\|reset\\)\\>")
+
+(defvar muttrc-variable-regexp
+ (concat "\\<\\(\\(no\\|inv\\)?\\("
+ (mapconcat 'car muttrc-variables-alist "\\|")
+ "\\)\\)\\>"))
+
+(defvar muttrc-assignement-regexp
+ (concat muttrc-variable-regexp
+ "\\s-*\\(=\\s-*" muttrc-generic-arg-regexp "\\)?"))
+
+(defun muttrc-search-command-forward (command &optional limit)
+ (let ((cmd-desc (assoc command muttrc-command-alist)))
+ (if cmd-desc
+ (let ((cmd-match-data '())
+ (cmd-args (cadr cmd-desc))
+ (origin (point))
+ beg-0 end-0)
+ (catch 'done
+ (while (and (not cmd-match-data)
+ (re-search-forward
+ (concat "\\(;\\|^\\)\\s-*\\(" command "\\)")
+ limit t))
+ (let ((beg (nth 4 (match-data)))
+ (end (nth 5 (match-data))))
+ (setq beg-0 beg)
+ (setq cmd-match-data (list beg end)))
+ (let ((args cmd-args))
+ (while args
+ (let ((arg-type (caar args))
+ (arg-re (if (null (cdr args))
+ muttrc-generic-arg-sequence-regexp
+ muttrc-generic-arg-regexp)))
+ (skip-syntax-forward "-")
+ (if (looking-at arg-re)
+ (let ((beg (nth 0 (match-data)))
+ (end (nth 1 (match-data))))
+ (goto-char end)
+ (setq cmd-match-data (append cmd-match-data
+ (list beg end)))
+ (setq end-0 end)
+ (setq args (cdr args)))
+ (progn
+ (setq args nil)
+ (setq cmd-match-data nil)))))
+ (when cmd-match-data
+ (set-match-data (cons beg-0
+ (cons end-0
+ cmd-match-data)))
+ (throw 'done t))))
+ (goto-char origin)
+ nil)))))
+
+
+(defun muttrc-font-lock-keywords ()
+ (let ((command-alist muttrc-command-alist)
+ keywords)
+ (while command-alist
+ (let* ((cmd (caar command-alist))
+ (args (cadr (car command-alist)))
+ (regexp (eval ; Simulate a closure
+ (list
+ 'lambda '(&optional limit)
+ (list 'muttrc-search-command-forward cmd 'limit))))
+ (hilighters '((1 font-lock-keyword-face)))
+ (n 2))
+ (while args
+ (let ((arg-type (caar args))
+ (last-arg-p (null (cdr args))))
+ (setq hilighters
+ (append hilighters
+ (let ((face
+ (or (cdr-safe
+ (assoc arg-type
+ muttrc-argument-faces-alist))
+ 'default)))
+ (list (append (list n (list 'quote face))
+ (if last-arg-p '(nil t))))))))
+ (setq n (1+ n))
+ (setq args (cdr args)))
+ (setq keywords (append keywords (list (cons regexp hilighters))))
+ (setq command-alist (cdr command-alist))))
+ (append keywords
+ (list
+ (list muttrc-non-command-keyword-regexp 2
+ font-lock-keyword-face)
+ (list muttrc-assignement-regexp 1
+ font-lock-variable-name-face)))
+ ))
+
+;;; ------------------------------------------------------------
+;;; Mode specific customization
+;;; ------------------------------------------------------------
+
+(defconst muttrc-mode-map nil
+ "The keymap that is used in Muttrc mode.")
+(if (null muttrc-mode-map)
+ (setq muttrc-mode-map
+ (let ((map (make-sparse-keymap))
+ (help-map (make-sparse-keymap))
+ (ctrl-c-map (make-sparse-keymap)))
+ (define-key map "\C-c" ctrl-c-map)
+ (define-key ctrl-c-map "c" 'muttrc-insert-command)
+ (define-key ctrl-c-map "C" 'comment-region)
+ (define-key ctrl-c-map "s" 'muttrc-set-variable)
+ (define-key ctrl-c-map "S" 'muttrc-unset-variable)
+ (define-key ctrl-c-map "f" 'muttrc-find-variable-in-buffer)
+ (define-key ctrl-c-map "h" help-map)
+ (define-key help-map "m" 'muttrc-find-manual-file)
+ (define-key help-map "v" 'muttrc-find-variable-help)
+ (define-key help-map "c" 'muttrc-find-command-help)
+ map)))
+
+(defvar muttrc-mode-syntax-table nil)
+(when (null muttrc-mode-syntax-table)
+ (setq muttrc-mode-syntax-table (make-syntax-table))
+ (modify-syntax-entry ?# "< " muttrc-mode-syntax-table)
+ (modify-syntax-entry ?\n "> " muttrc-mode-syntax-table)
+ (modify-syntax-entry ?\' "$ " muttrc-mode-syntax-table)
+ (modify-syntax-entry ?\' "$ " muttrc-mode-syntax-table)
+ (modify-syntax-entry ?_ "w " muttrc-mode-syntax-table)
+ (modify-syntax-entry ?- "w " muttrc-mode-syntax-table)
+ )
+
+;;; ------------------------------------------------------------
+;;; The mode function itself.
+;;; ------------------------------------------------------------
+
+;;;###autoload
+(defun muttrc-mode ()
+ "Major mode for editing Muttrc files.
+This function ends by invoking the function(s) `muttrc-mode-hook'.
+
+\\{muttrc-mode-map}
+"
+
+ (interactive)
+ (kill-all-local-variables)
+
+ ;; Font lock.
+ (make-local-variable 'font-lock-defaults)
+ (setq font-lock-defaults
+ '('muttrc-font-lock-keywords
+ nil nil nil nil
+ (font-lock-syntactic-keywords . (("'[^'\n]*'" 0 "\"")))))
+
+ ;; Comment stuff.
+ (make-local-variable 'comment-start)
+ (setq comment-start "#")
+ (make-local-variable 'comment-end)
+ (setq comment-end "")
+ (make-local-variable 'comment-start-skip)
+ (setq comment-start-skip "#+[ \t]*")
+
+ ;; become the current major mode
+ (setq major-mode 'muttrc-mode)
+ (setq mode-name "Muttrc")
+
+ ;; Activate keymap and syntax table.
+ (use-local-map muttrc-mode-map)
+ (set-syntax-table muttrc-mode-syntax-table)
+
+ (run-hooks 'muttrc-mode-hook))
+
+
+
+;;; ------------------------------------------------------------
+;;; Other functions
+;;; ------------------------------------------------------------
+
+(defun muttrc-perform-nonreg-test ()
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^# Begin\\s-+\\(.*\\)$" nil t)
+ (let ((test-name (match-string-no-properties 1))
+ (expr ""))
+ (catch 'loop
+ (while t
+ (or (= (forward-line 1) 0)
+ (throw 'loop t))
+ (if (looking-at (format "^# End\\s-+%s\\s-*"
+ (regexp-quote test-name)))
+ (throw 'loop t))
+ (if (looking-at "^# End\\s-+\\(.*\\)$")
+ (error "Found end of %s before %s"
+ (match-string-no-properties 1) test-name))
+ (if (looking-at "^[^#]")
+ (error "End of %s not found" test-name))
+ (if (looking-at "^#\\s-*\\(.*\\)$")
+ (setq expr (concat expr (match-string-no-properties 1))))))
+ (if (eval (read expr))
+ (message "Passed: %s" test-name)
+ (error "Failed: %s" test-name))))))
+
+(defun muttrc-quote-string (s)
+ "Add a backslash on quotes and surround by quotes if needed."
+ (save-match-data
+ (cond ((or (not s) (equal s "")) "''")
+ ((string-match "^[^']*\\s-[^']*$" s) (format "'%s'" s))
+ ((string-match "\\s-" s)
+ (concat "\""
+ (mapconcat (lambda (c)
+ (if (eq c ?\") "\\\""
+ (char-to-string c)))
+ s "")
+ "\""))
+ (t s))))
+
+(defun muttrc-prompt-string (prompt-base &optional default)
+ (if default
+ (format "%s [%s]: " prompt-base default)
+ (format "%s: " prompt-base)))
+
+(defun muttrc-token-around-point (alist &optional strip-fun)
+ (let ((word (and (functionp 'thing-at-point)
+ (funcall (or strip-fun 'identity)
+ (funcall 'thing-at-point 'word)))))
+ (if (and word (assoc word alist))
+ word)))
+
+(defun muttrc-assignement (varname modifier &optional value)
+ (concat (format "%s%s" (or modifier "") varname)
+ (if (stringp value)
+ (format "=%s"
+ (muttrc-quote-string value))
+ "")))
+
+(defun muttrc-split-next-set-line ()
+ "Returns the current line splitted into tokens. The result is a list
+of tokens like:
+\((CMD START END) ((VAR1 MODIFIER1 ASSIGNMENT1 START END) ... REST)).
+Last element REST is one string that is the rest of the line."
+ (if (re-search-forward
+ "^\\s-*\\(set\\|unset\\|toggle\\|reset\\)\\s-+" nil t)
+ (let ((line (list (list (match-string-no-properties 1)
+ (match-beginning 1)
+ (match-end 1))))
+ (limit (save-excursion
+ (end-of-line)
+ (point))))
+ (catch 'done
+ (while (< (point) limit)
+ (or (looking-at
+ (format "\\<\\(inv\\|no\\)?\\([a-z][a-z_]*\\)\\>"))
+ (throw 'done t))
+ (let ((modifier (match-string-no-properties 1))
+ (varname (match-string-no-properties 2))
+ (assignment nil))
+ (goto-char (match-end 0))
+ (skip-syntax-forward "-" limit)
+ (if (or (looking-at ; Set without quote
+ "=\\s-*\\([^'\" \t\n#]+\\)")
+ (looking-at ; Set with double quote (")
+ "=\\s-*\"\\(\\([^\"\\]\\|\\\\.\\)*\\)\"")
+ (looking-at ; Set with single quote (')
+ "=\\s-*'\\([^']*\\)'"))
+ (let ((type (let ((desc (assoc varname
+ muttrc-variables-alist)))
+ (if desc (cadr desc)))))
+ (if type
+ (and (eq type 'boolean)
+ (message "%s: can't assign a boolean" varname))
+ (message "%s: unknown Muttrc variable"
+ varname))
+ (setq assignment (match-string-no-properties 1))
+ (goto-char (match-end 0))))
+ (nconc line (list (list varname modifier
+ assignment
+ (match-beginning 0)
+ (match-end 0))))
+ (skip-syntax-forward "-" limit))))
+ (skip-syntax-backward "-")
+ (if (looking-at ".+$")
+ (nconc line (list (list (match-string-no-properties 0)))))
+ (end-of-line)
+ line)))
+
+(defun muttrc-splice-assignment (line varname)
+ "Returns a list where assignements for VARNAME are separated from
+assignment for other variables."
+ (let ((l (cdr line))
+ (in '())
+ (out '()))
+ (while (and l (consp (car l)))
+ (let ((arg (car l)))
+ (if (string= (car arg) varname)
+ (setq in (append in (list arg)))
+ (setq out (append out (list arg)))))
+ (setq l (cdr l)))
+ (list in out)))
+
+(defun muttrc-new-value (cmd varname type modifier value default)
+ (if (eq type 'boolean)
+ (cond ((string= cmd "set")
+ (cond ((null modifier) t)
+ ((string= modifier "no") nil)
+ ((string= modifier "inv") (not value))))
+ ((string= cmd "unset")
+ (cond ((null modifier) nil)
+ ((string= modifier "no") t)
+ ((string= modifier "inv") value)))
+ ((string= cmd "toggle") (not value))
+ ((string= cmd "reset")
+ (cond ((null modifier) default)
+ ((string= modifier "no") (not default))
+ ((string= modifier "inv") (not default)))))
+ (cond ((string= cmd "set") value)
+ ((string= cmd "unset") default)
+ ((string= cmd "toggle")
+ (error "%s: can't toggle non boolean" varname))
+ ((string= cmd "reset") default))))
+
+(defun muttrc-get-value-and-point (varname)
+ "Fetch the value of VARIABLE from the current buffer. It returns a
+cons (VALUE . POINT) where POINT is the beginning of the line defining
+VARNAME."
+ (save-excursion
+ (let ((var-descriptor (assoc varname muttrc-variables-alist)))
+ (or var-descriptor
+ (error "%s: unknown variable." varname))
+ (goto-char (point-min))
+ (let ((type (nth 0 (cdr var-descriptor)))
+ (default (nth 1 (cdr var-descriptor)))
+ (pos nil))
+ (let ((value default))
+ ;; We search all the definitions in the buffer because some
+ ;; users may use toggle or set inv...
+ (catch 'done
+ (while t
+ (let ((line (muttrc-split-next-set-line)))
+ (or line (throw 'done t))
+ (let ((cmd (caar line))
+ (assignments
+ (car (muttrc-splice-assignment line varname))))
+ (if assignments
+ (setq pos (save-excursion
+ (beginning-of-line)
+ (point))))
+ (while assignments
+ (let ((modifier (nth 1 (car assignments)))
+ (new-value (nth 2 (car assignments))))
+ (setq value
+ (muttrc-new-value cmd varname type modifier
+ (or new-value value)
+ default)))
+ (setq assignments (cdr assignments)))))))
+ (cons value pos))))))
+
+(defun muttrc-get-value (varname)
+ "Fetch the value of VARIABLE from the current buffer."
+ (let ((value (muttrc-get-value-and-point varname)))
+ (and value (car value))))
+
+;;; ------------------------------------------------------------
+;;; Viewing manual
+;;; ------------------------------------------------------------
+
+(defvar muttrc-manual-buffer-name "*Mutt Manual*")
+
+(defun muttrc-find-manual-file-no-select ()
+ "Convert overstriking and underlining to the correct fonts in a
+file. The buffer does not visit the file."
+ (interactive)
+ (or (file-readable-p muttrc-manual-path)
+ (error "%s: file not found" muttrc-manual-path))
+ (let ((buf (get-buffer-create muttrc-manual-buffer-name)))
+ (save-excursion
+ (set-buffer buf)
+ (if (not buffer-read-only)
+ (let ((insert-contents-fun
+ (condition-case nil
+ (and (require 'jka-compr)
+ 'jka-compr-insert-file-contents)
+ (error 'insert-file-contents))))
+ (funcall insert-contents-fun muttrc-manual-path nil nil nil t)
+ (buffer-disable-undo buf)
+ (Man-fontify-manpage)
+ (set-buffer-modified-p nil)
+ (toggle-read-only)
+ (goto-char (point-min))))
+ buf)))
+
+(defun muttrc-find-manual-file ()
+ "Convert overstriking and underlining to the correct fonts in a
+file. The buffer does not visit the file."
+ (interactive)
+ (switch-to-buffer-other-window
+ (muttrc-find-manual-file-no-select) t))
+
+(defun muttrc-search-command-help-forward (command)
+ (when (re-search-forward
+ (format "^[ \t]*Usage:\\s-*\\(\\[un\\]\\)?%s" command)
+ nil t)
+ (goto-char (match-beginning 0))
+ (forward-line -2)
+ (point)))
+
+(defun muttrc-search-variable-help-forward (command)
+ (when (and (re-search-forward
+ (format "^[ \t]*%s\\.?\\s-*%s\\s-*$"
+ "\\([1-9][0-9.]*\\)"
+ (regexp-quote variable))
+ nil t)
+ (re-search-forward
+ (format "^[ \t]*%s\\.?\\s-*%s\\s-*$"
+ "\\([1-9][0-9.]*\\)"
+ (regexp-quote variable))
+ nil t)
+ (re-search-forward
+ (format "^[ \t]*%s\\.?\\s-*%s\\s-*$"
+ (regexp-quote (match-string-no-properties 1))
+ (regexp-quote variable))
+ nil t))
+ (goto-char (match-beginning 0))
+ (point)))
+
+(defun muttrc-find-help (search-fun topic)
+ "Find an help topic in the manual and display it. Returns the manual
+buffer."
+ (let ((buf (muttrc-find-manual-file-no-select)))
+ (let ((win (get-buffer-window buf))
+ help-start)
+ (save-excursion
+ (set-buffer buf)
+ (goto-char (point-min))
+ (or (funcall search-fun topic)
+ (error "%s: entry not found in Mutt manual." command))
+ (setq help-start (point))
+ (unless (get-buffer-window buf)
+ (switch-to-buffer-other-window buf t))
+ (set-window-start win help-start)))
+ buf))
+
+(defun muttrc-find-command-help (&optional command)
+ (interactive
+ (let ((word (muttrc-token-around-point muttrc-command-alist)))
+ (list (muttrc-get-from-list "Command" word 'muttrc-command-alist t))))
+ (muttrc-find-help 'muttrc-search-command-help-forward
+ (if (string-match "^un\\(.*\\)$" command)
+ (match-string-no-properties 1 command)
+ command)))
+
+(defun muttrc-find-variable-help (&optional variable)
+ (interactive
+ (list
+ (let ((word (muttrc-token-around-point
+ muttrc-variables-alist
+ (function
+ (lambda (word)
+ (if (and word
+ (string-match "^\\(no\\|inv\\)\\(.*\\)$" word))
+ (match-string-no-properties 2 word)
+ word))))))
+ (muttrc-get-from-list "Variable" word 'muttrc-variables-alist))))
+ (muttrc-find-help 'muttrc-search-variable-help-forward variable))
+
+(defun muttrc-bury-manual-buffer ()
+ (let ((buf (get-buffer muttrc-manual-buffer-name)))
+ (if buf (bury-buffer buf))))
+
+;;; ------------------------------------------------------------
+;;; Argument handlers
+;;; ------------------------------------------------------------
+
+(defun muttrc-call-arg-handler (key default &optional prompt)
+ "Call the function that properly prompts for an argument type."
+ (let ((handler-args (assoc key muttrc-arg-handler-alist)))
+ (or handler-args
+ (error "%s: unknown argument type." (symbol-name key)))
+ (let ((cmd (nth 0 (cdr handler-args)))
+ (default-prompt (nth 1 (cdr handler-args)))
+ (args (cdr (cddr handler-args))))
+ (apply cmd (or prompt default-prompt) default args))))
+
+(defun muttrc-get-boolean (prompt &optional default)
+ "Prompt for a boolean."
+ (y-or-n-p (format "%s? " prompt)))
+
+(defun muttrc-get-number (prompt default)
+ "Prompt for a string and return DEFAULT if the string is empty"
+ (or (read-from-minibuffer (muttrc-prompt-string prompt default))
+ default))
+
+(defun muttrc-get-string (prompt default)
+ "Prompt for a string and return DEFAULT if the string is empty"
+ (let ((s (read-from-minibuffer (muttrc-prompt-string prompt default))))
+ (if (> (length s) 0) s default)))
+
+(defun muttrc-get-word (prompt default)
+ "Prompt for a word and return DEFAULT if it is empty"
+ (let ((s (read-from-minibuffer (muttrc-prompt-string prompt default))))
+ (or (string-match "^\\w*$" s)
+ (error "%s: invalid entry, expecting a word" s))
+ (if (> (length s) 0) s default)))
+
+(defun muttrc-get-from-list (prompt default list &optional require-match)
+ "Prompt for a string from list and return DEFAULT if the string is empty"
+ (let ((s (completing-read (muttrc-prompt-string prompt default)
+ (symbol-value list)
+ nil require-match)))
+ (if (> (length s) 0) s default)))
+
+(defun muttrc-get-path (prompt default)
+ "Prompt for a path and return DEFAULT if the string is empty. The
+muttrc folder prefix is replaced by MUTTRC-FOLDER-ABBREV."
+ (let* ((folder (muttrc-get-value "folder"))
+ (path (read-file-name (muttrc-prompt-string prompt default)
+ folder folder)))
+ (let ((compacted-path
+ (if (string-match (format "^%s/?\\(.*\\)$" (regexp-quote folder))
+ path)
+ (format "%s%s"
+ (char-to-string muttrc-folder-abbrev)
+ (match-string-no-properties 1 path))
+ path)))
+ (if (not (string= compacted-path
+ (char-to-string muttrc-folder-abbrev)))
+ compacted-path
+ default))))
+
+(defun muttrc-get-assignment (&optional prompt default
+ with-value-p)
+ (let ((varname (completing-read (muttrc-prompt-string prompt default)
+ muttrc-variables-alist)))
+ (if (assoc varname muttrc-variables-alist)
+ (let* ((type (cadr (assoc varname muttrc-variables-alist)))
+ (default (car-safe (muttrc-get-value-and-point varname)))
+ (value (if with-value-p
+ (muttrc-call-arg-handler type default "Value"))))
+ (if with-value-p
+ (muttrc-assignement varname
+ (and (eq type 'boolean)
+ (not value)
+ "no")
+ value)
+ varname))
+ default)))
+
+;;; ------------------------------------------------------------
+;;; Commands insertion
+;;; ------------------------------------------------------------
+
+(defun muttrc-get-command (&optional prompt default)
+ "Prompts the usr for a command to enter and asks for all the arguments."
+ (let* ((cmd (muttrc-get-from-list "Command" nil 'muttrc-command-alist t))
+ (cmd-descriptor (cdr (assoc cmd muttrc-command-alist)))
+ (arg-list-type (nth 0 cmd-descriptor))
+ (repeat-p (nth 1 cmd-descriptor))
+ (optional-p (nth 2 cmd-descriptor))
+ (arg-list-value (list cmd)))
+ (save-window-excursion
+ (if (and muttrc-display-help)
+ (save-excursion
+ (muttrc-find-command-help cmd)))
+ (while arg-list-type
+ (let* ((arg-type (caar arg-list-type))
+ (arg (apply 'muttrc-call-arg-handler
+ (append (list arg-type nil)
+ (cdar arg-list-type)))))
+ (if arg
+ (progn
+ (nconc arg-list-value
+ (list (if (eq arg-type 'assignment)
+ arg ; assignment are quoted by handler
+ (muttrc-quote-string arg))))
+ (if (and repeat-p
+ (null (cdr arg-list-type)))
+ (setq optional-p t)
+ (setq arg-list-type (cdr arg-list-type))))
+ (if (and (null (cdr arg-list-type))
+ optional-p)
+ (setq arg-list-type nil)
+ (error "Argument required"))))))
+ (muttrc-bury-manual-buffer)
+ (mapconcat 'identity arg-list-value " ")))
+
+(defun muttrc-get-statement (&optional prompt default)
+ (let ((muttrc-command-alist muttrc-statement-alist))
+ (muttrc-get-command prompt default)))
+
+(defun muttrc-insert-command ()
+ "Insert a muttrc command on the current line."
+ (interactive)
+ (let ((cmd-line (muttrc-get-command)))
+ (beginning-of-line)
+ (or (eolp) (forward-line 1))
+ (insert cmd-line)
+ (newline)))
+
+;;; ------------------------------------------------------------
+;;; Setting variables
+;;; ------------------------------------------------------------
+
+(defun muttrc-update-current-line (varname type &optional value)
+ "Rewrites the current line by setting VARNAME to VALUE. If the
+statement is not \"set\", the variable is removed. In set statement,
+it is removed if the value is NIL and the variable is not a boolean.
+The function returns t is the variable is really assigned in the line."
+ (let* ((line (muttrc-split-next-set-line))
+ (cmd (caar line))
+ (kill-whole-line t)
+ (args "")
+ (set-p nil))
+ (beginning-of-line)
+ (kill-line)
+ (let ((l (cdr line)))
+ (while l
+ (let ((elt (car l)))
+ (if (consp elt)
+ (let ((this-var (nth 0 elt))
+ (this-modifier (nth 1 elt))
+ (this-value (nth 2 elt)))
+ (let ((assignement
+ (if (string= this-var varname)
+ (when (string= cmd "set")
+ (setq set-p t)
+ (cond ((eq type 'boolean)
+ (muttrc-assignement varname
+ (if (not value) "no")
+ value))
+ (value
+ (muttrc-assignement varname nil value))
+ (t (setq set-p nil))))
+ (muttrc-assignement this-var
+ this-modifier
+ this-value))))
+ (if assignement
+ (setq args (concat args " " assignement)))))
+ (setq args (concat args elt))))
+ (setq l (cdr l))))
+ (when (not (string= args ""))
+ (insert cmd)
+ (insert args)
+ (newline))
+ (backward-char 1)
+ set-p))
+
+(defun muttrc-update-variable (varname type value pos)
+ (catch 'done
+ (when pos
+ (goto-char pos)
+ (if (muttrc-update-current-line varname type value)
+ (throw 'done t)))
+ (end-of-line)
+ (let ((cr-after-p (bolp))
+ (cmd (if (or value (eq type 'boolean)) "set" "unset"))
+ (modifier (if (and (not value) (eq type 'boolean)) "no")))
+ (or cr-after-p (newline))
+ (insert cmd " "
+ (muttrc-assignement varname modifier value))
+ (if cr-after-p (newline))))
+ t)
+
+(defun muttrc-set-variable (&optional varname type value pos)
+ (interactive
+ (let* ((varname (muttrc-get-from-list "Variable" nil
+ 'muttrc-variables-alist t))
+ (type (cadr (assoc varname muttrc-variables-alist)))
+ (default (muttrc-get-value-and-point varname)))
+ (list varname type
+ (save-window-excursion
+ (if muttrc-display-help
+ (save-excursion
+ (muttrc-find-variable-help varname)))
+ (muttrc-call-arg-handler type (car default)))
+ (cdr default))))
+ (muttrc-bury-manual-buffer)
+ (muttrc-update-variable varname type value pos))
+
+(defun muttrc-unset-variable (&optional varname type pos)
+ (interactive
+ (let* ((varname (muttrc-get-from-list "Variable" nil
+ 'muttrc-variables-alist t))
+ (type (cadr (assoc varname muttrc-variables-alist)))
+ (default (muttrc-get-value-and-point varname)))
+ (list varname type (cdr default))))
+ (muttrc-update-variable varname type nil pos))
+
+(defun muttrc-find-variable-in-buffer (&optional varname)
+ (interactive
+ (list (muttrc-get-from-list "Variable" nil
+ 'muttrc-variables-alist t)))
+ (let* ((var-info (muttrc-get-value-and-point varname))
+ (value (car var-info))
+ (pos (cdr-safe var-info)))
+ (if pos
+ (goto-char pos)
+ (progn
+ (message "%s: variable not set (default: %s)" varname value)))))
+
+;;; ------------------------------------------------------------
+;;; Almost the end
+;;; ------------------------------------------------------------
+
+(provide 'muttrc-mode)
+
+;;; muttrc-mode.el ends here
diff --git a/emacs.d/functions.el b/emacs.d/functions.el
new file mode 100644
index 0000000..6d2a5e5
--- /dev/null
+++ b/emacs.d/functions.el
@@ -0,0 +1,191 @@
+(defun quote-region ()
+ (interactive)
+ (let ((beginning (region-beginning))
+ (end (region-end)))
+ (save-excursion
+ (goto-char end)
+ (insert ?')
+ (goto-char beginning)
+ (insert ?'))))
+
+(defun what-face (pos)
+ "Find out which face the current position uses"
+ (interactive "d")
+ (let ((face (or (get-char-property (point) 'read-face-name)
+ (get-char-property (point) 'face))))
+ (if face
+ (message "Face: %s" face)
+ (message "No face at %d" pos))))
+
+(defun my-comp-finish-function (buf str)
+ "Don't show compilation window if everything went ok"
+ (if (string-match "exited abnormally" str)
+ ;; there were errors
+ (message "compilation errors, press C-x ` to visit")
+ ;; no errors, make the compilation window go away in 0.5 seconds
+ (run-at-time 0.5 nil 'delete-windows-on buf)
+ (message "NO COMPILATION ERRORS!")))
+
+(defun fullscreen ()
+ "Fill the entire screen with emacs"
+ (interactive)
+ (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
+ '(2 "_NET_WM_STATE_MAXIMIZED_VERT" 0))
+ (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
+ '(2 "_NET_WM_STATE_MAXIMIZED_HORZ" 0)))
+
+(defun c-toggle-header-source ()
+ "Toggle between a C source and header file"
+ (interactive)
+ (let ((ext (file-name-extension (buffer-file-name)))
+ (noext (file-name-sans-extension (buffer-file-name))))
+ (if (string= (substring ext 0 1) "c")
+ (find-file (concat noext ".h"))
+ (find-file (concat noext ".c")))))
+
+(defun browse-to-current-file ()
+ "Show current file in browser"
+ (interactive)
+ (browse-url buffer-file-name))
+
+(defun comment-line ()
+ "Toggle comment on a line"
+ (interactive)
+ (save-excursion
+ (beginning-of-line)
+ (insert "//")))
+
+(defun add-php-keywords ()
+ "Designed for c and c-style languages
+
+Currently adds | & ! . + = - / % * , < > ? : ->"
+ ;; Add ! at the beginning of font lock
+ (font-lock-add-keywords
+ 'php-mode
+ '(("\\([!]\\|\\=>\\)" 1 font-lock-operator-face)))
+ ;; Add the rest at the end of font lock
+ (font-lock-add-keywords
+ 'php-mode
+ '(("\\(->\\|[|.+=&/%*,:?<>-]\\)" 1 font-lock-operator-face)
+ ("\\(;\\)" 1 font-lock-end-statement)) 1))
+
+(defun add-html-keywords ()
+ "Designed for html, show some smarty tags"
+ (font-lock-add-keywords
+ 'html-mode
+ '(("{\\(\\*.*\\*\\)}" 1 font-comment-face)
+ ("{\\/?\\(extends\\|block\\|foreach\\|if\\)"
+ 1 font-lock-builtin-face)
+ ("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)\\(?:|\\(\\(?:\\sw\\|\\s_\\)+\\):\\)"
+ (1 font-lock-variable-name-face)
+ (2 font-lock-function-name-face))
+ ("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)"
+ 1 font-lock-variable-name-face)
+ ("{\\(\\(?:\\sw\\|\\s_\\)+\\).*}"
+ 1 font-lock-function-name-face))))
+
+(defun buffer-major-mode (buffer-or-string)
+ "Find out which major-mode is currently used"
+ (with-current-buffer buffer-or-string major-mode))
+
+(defun set-column-marker ()
+ "Default column markers"
+ (column-marker-1 73)
+ (column-marker-2 81))
+
+(defun setup-system-frame-colours (&rest frame)
+ (let ((f (if (car frame)
+ (car frame)
+ (selected-frame))))
+ (progn
+ (set-frame-font "-*-tamsyn-medium-*-*-*-15-*-*-*-*-80-*-*"))))
+
+(defun show-init-sections ()
+ (interactive)
+ (occur ";;\s +.*\s +;;")
+ (other-window 1))
+
+(defun list-functions ()
+ (interactive)
+ (occur
+ "\\(?:\\(?:private\\|protected\\|public\\) \\)?function \\(?:\\sw\\)+(\\sw*)"))
+
+(defun insert-init-title (title width)
+ (interactive "stitle: \nnwidth: ")
+ (insert-char ?\; width)
+ (insert "\n;;")
+ (insert-char ?\s (floor (/ (- (- width 4.0) (length title)) 2)))
+ (insert title)
+ (insert-char ?\s (ceiling (/ (- (- width 4.0) (length title)) 2)))
+ (insert ";;\n")
+ (insert-char ?\; width))
+
+(defun x-init ()
+ "Start ide-skel and set some keys")
+
+(defun cli-init ()
+ "Add a space to the linum column"
+ (setq linum-format "%d "))
+
+(defun replace-occurrences (from to)
+ (save-excursion
+ (goto-char (point-min))
+ (while (search-forward from nil t)
+ (replace-match to))))
+
+(defun replace-html-special-chars ()
+ (replace-occurrences "é" "&eacute;"))
+
+(defun on-before-save ()
+ (if (eq (buffer-major-mode (current-buffer)) 'html-mode)
+ (replace-html-special-chars))
+ (if (not (eq (buffer-major-mode (current-buffer)) 'markdown-mode))
+ (delete-trailing-whitespace)))
+
+(defun on-after-save ()
+ (let ((fname (buffer-file-name)))
+ (let ((suffix (file-name-extension fname)))
+ (if (string-equal suffix "el")
+ (byte-compile-file fname)))))
+
+(defun on-prog-mode ()
+ (font-lock-add-keywords
+ nil
+ '(("\\b\\(0[xX][0-9a-fA-F]+[lL]?\\|[0-9]+\\.?[0-9]*\\([eE][-+]?[0-9]+\\)?\\([lL]\\|[fF]\\|[dD]\\)?\\)\\b"
+ 0 font-lock-constant-face)
+ ("\\b\\(\\.[0-9]+\\([eE][-+]?[0-9]+\\)?\\([lL]\\|[fF]\\|[dD]\\)?\\)\\b"
+ 0 font-lock-constant-face)))
+ (set-column-marker)
+ (rainbow-delimiters-mode))
+
+(defun on-c-mode ()
+ (local-set-key [f8] 'c-toggle-header-source)
+ (local-set-key [f9] 'compile)
+ (local-set-key [C-m] 'newline-and-indent)
+ (local-set-key [C-return] 'newline))
+
+(defun on-html-mode ()
+ (local-set-key [f9] 'browse-to-current-file)
+ (auto-fill-mode)
+ (set-column-marker))
+
+(defun on-markdown-mode ()
+ (whitespace-mode)
+ (auto-fill-mode))
+
+(defun on-org-mode ()
+ (flyspell-mode 1)
+ (auto-fill-mode 1))
+
+(defun on-php-mode ()
+ (defvar php-warn-if-mumamo-off nil)
+ (setq case-fold-search t)
+ (c-set-offset 'arglist-intro '+)
+ (c-set-offset 'arglist-close '0)
+ (column-marker-1 76)
+ (column-marker-2 81)
+ (local-set-key [f6] 'comment-line))
+
+(defun on-mail-mode ()
+ (turn-on-auto-fill)
+ (search-forward "\n\n"))
diff --git a/emacs.el b/emacs.el
index 5b744e3..ef5ceb2 100644
--- a/emacs.el
+++ b/emacs.el
@@ -6,6 +6,7 @@
(add-to-list 'load-path "~/.emacs.d/naquadah-theme")
(add-to-list 'load-path "~/.emacs.d/elisp/markdown-mode")
(add-to-list 'load-path "~/.emacs.d/elisp/git-commit-mode")
+(add-to-list 'load-path "~/.emacs.d/elisp/lua-mode")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; REQUIRES ;;
@@ -20,217 +21,28 @@
(require 'server)
(require 'org-publish)
(require 'htmlize)
+(require 'muttrc-mode)
+(load-file "~/.emacs.d/functions.el")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AUTOLOADS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(autoload 'vala-mode "vala-mode"
- "A Major mode for editing Vala files" t)
-(autoload 'csharp-mode "csharp-mode"
- "A Major mode for editing C# files" t)
-(autoload 'sqlplus-mode "sqlplus"
- "A Major mode for communicating with Oracle" t)
-(autoload 'batch-mode "batch-mode"
- "A Major mode for editing Batch files" t)
-(autoload 'lua-mode "lua-mode"
- "A Major mode for editing Lua files" t)
-(autoload 'php-mode "php-mode-improved"
- "A Major mode for editing PHP files" t)
-(autoload 'graphviz-dot-mode "graphviz-dot-mode"
- "A Major mode for editing graphviz dot files" t)
-(autoload 'cmake-mode "cmake-mode"
- "A major-mode for editing CMake sources" t)
-(autoload 'markdown-mode "markdown-mode"
- "Major mode for editing Markdown files" t)
-(autoload 'rainbow-mode "rainbow-mode"
- "A Minor mode for showing colors inline" t)
-(autoload 'stumpwm-mode "stumpwm-mode"
- "Special lisp mode for evaluating code into running stumpwm" t)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; DEFUNS ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun what-face (pos)
- "Find out which face the current position uses"
- (interactive "d")
- (let ((face (or (get-char-property (point) 'read-face-name)
- (get-char-property (point) 'face))))
- (if face
- (message "Face: %s" face)
- (message "No face at %d" pos))))
-
-(defun my-comp-finish-function (buf str)
- "Don't show compilation window if everything went ok"
- (if (string-match "exited abnormally" str)
- ;; there were errors
- (message "compilation errors, press C-x ` to visit")
- ;; no errors, make the compilation window go away in 0.5 seconds
- (run-at-time 0.5 nil 'delete-windows-on buf)
- (message "NO COMPILATION ERRORS!")))
-
-(defun fullscreen ()
- "Fill the entire screen with emacs"
- (interactive)
- (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
- '(2 "_NET_WM_STATE_MAXIMIZED_VERT" 0))
- (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
- '(2 "_NET_WM_STATE_MAXIMIZED_HORZ" 0)))
-
-(defun c-toggle-header-source ()
- "Toggle between a C source and header file"
- (interactive)
- (let ((ext (file-name-extension (buffer-file-name)))
- (noext (file-name-sans-extension (buffer-file-name))))
- (if (string= (substring ext 0 1) "c")
- (find-file (concat noext ".h"))
- (find-file (concat noext ".c")))))
-
-(defun browse-to-current-file ()
- "Show current file in browser"
- (interactive)
- (browse-url buffer-file-name))
-
-(defun comment-line ()
- "Toggle comment on a line"
- (interactive)
- (save-excursion
- (beginning-of-line)
- (insert "//")))
-
-(defun add-php-keywords ()
- "Designed for c and c-style languages
-
-Currently adds | & ! . + = - / % * , < > ? : ->"
- ;; Add ! at the beginning of font lock
- (font-lock-add-keywords
- 'php-mode
- '(("\\([!]\\|\\=>\\)" 1 font-lock-operator-face)))
- ;; Add the rest at the end of font lock
- (font-lock-add-keywords
- 'php-mode
- '(("\\(->\\|[|.+=&/%*,:?<>-]\\)" 1 font-lock-operator-face)
- ("\\(;\\)" 1 font-lock-end-statement)) 1))
-
-(defun add-html-keywords ()
- "Designed for html, show some smarty tags"
- (font-lock-add-keywords
- 'html-mode
- '(("{\\(\\*.*\\*\\)}" 1 font-comment-face)
- ("{\\/?\\(extends\\|block\\|foreach\\|if\\)"
- 1 font-lock-builtin-face)
- ("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)\\(?:|\\(\\(?:\\sw\\|\\s_\\)+\\):\\)"
- (1 font-lock-variable-name-face)
- (2 font-lock-function-name-face))
- ("\\$\\(\\(?:\\sw\\|\\s_\\)+\\)"
- 1 font-lock-variable-name-face)
- ("{\\(\\(?:\\sw\\|\\s_\\)+\\).*}"
- 1 font-lock-function-name-face))))
-
-(defun buffer-major-mode (buffer-or-string)
- "Find out which major-mode is currently used"
- (with-current-buffer buffer-or-string major-mode))
-
-(defun set-column-marker ()
- "Default column markers"
- (column-marker-1 73)
- (column-marker-2 81))
-
-(defun setup-system-frame-colours (&rest frame)
- (let ((f (if (car frame)
- (car frame)
- (selected-frame))))
- (progn
- (set-frame-font "-*-tamsyn-medium-*-*-*-15-*-*-*-*-80-*-*"))))
-
-(defun show-init-sections ()
- (interactive)
- (occur ";;\s +.*\s +;;")
- (other-window 1))
-
-(defun list-functions ()
- (interactive)
- (occur
- "\\(?:\\(?:private\\|protected\\|public\\) \\)?function \\(?:\\sw\\)+(\\sw*)"))
-
-(defun insert-init-title (title width)
- (interactive "stitle: \nnwidth: ")
- (insert-char ?\; width)
- (insert "\n;;")
- (insert-char ?\s (floor (/ (- (- width 4.0) (length title)) 2)))
- (insert title)
- (insert-char ?\s (ceiling (/ (- (- width 4.0) (length title)) 2)))
- (insert ";;\n")
- (insert-char ?\; width))
-
-(defun x-init ()
- "Start ide-skel and set some keys")
-
-(defun cli-init ()
- "Add a space to the linum column"
- (setq linum-format "%d "))
-
-(defun replace-occurrences (from to)
- (save-excursion
- (goto-char (point-min))
- (while (search-forward from nil t)
- (replace-match to))))
-
-(defun replace-html-special-chars ()
- (replace-occurrences "é" "&eacute;"))
-
-(defun on-before-save ()
- (if (eq (buffer-major-mode (current-buffer)) 'html-mode)
- (replace-html-special-chars))
- (if (not (eq (buffer-major-mode (current-buffer)) 'markdown-mode))
- (delete-trailing-whitespace)))
-
-(defun on-after-save ()
- (let ((fname (buffer-file-name)))
- (let ((suffix (file-name-extension fname)))
- (if (string-equal suffix "el")
- (byte-compile-file fname)))))
-
-(defun on-prog-mode ()
- (font-lock-add-keywords
- nil
- '(("\\b\\(0[xX][0-9a-fA-F]+[lL]?\\|[0-9]+\\.?[0-9]*\\([eE][-+]?[0-9]+\\)?\\([lL]\\|[fF]\\|[dD]\\)?\\)\\b"
- 0 font-lock-constant-face)
- ("\\b\\(\\.[0-9]+\\([eE][-+]?[0-9]+\\)?\\([lL]\\|[fF]\\|[dD]\\)?\\)\\b"
- 0 font-lock-constant-face)))
- (set-column-marker)
- (rainbow-delimiters-mode))
-
-(defun on-c-mode ()
- (local-set-key [f8] 'c-toggle-header-source)
- (local-set-key [f9] 'compile)
- (local-set-key [C-m] 'newline-and-indent)
- (local-set-key [C-return] 'newline))
-
-(defun on-html-mode ()
- (local-set-key [f9] 'browse-to-current-file)
- (auto-fill-mode)
- (set-column-marker))
-
-(defun on-markdown-mode ()
- (whitespace-mode)
- (auto-fill-mode))
-
-(defun on-org-mode ()
- (flyspell-mode 1)
- (auto-fill-mode 1))
-
-(defun on-php-mode ()
- (defvar php-warn-if-mumamo-off nil)
- (setq case-fold-search t)
- (c-set-offset 'arglist-intro '+)
- (c-set-offset 'arglist-close '0)
- (column-marker-1 76)
- (column-marker-2 81)
- (local-set-key [f6] 'comment-line))
-
-(defun on-mail-mode ()
- (turn-on-auto-fill)
- (search-forward "\n\n"))
+(autoload 'vala-mode "vala-mode" "Major mode for Vala" t)
+(autoload 'csharp-mode "csharp-mode" "Major mode for C#" t)
+(autoload 'sqlplus-mode "sqlplus" "Major mode for PL/SQL" t)
+(autoload 'batch-mode "batch-mode" "Major mode for Batch" t)
+(autoload 'lua-mode "lua-mode" "A Major mode for Lua" t)
+(autoload 'php-mode "php-mode-improved" "Major mode for PHP" t)
+(autoload 'graphviz-dot-mode "graphviz-dot-mode" "Major mode for dot" t)
+(autoload 'cmake-mode "cmake-mode" "Major mode for CMake" t)
+(autoload 'markdown-mode "markdown-mode" "Major mode for Markdown" t)
+(autoload 'rainbow-mode "rainbow-mode" "Minor mode for colors" t)
+(autoload 'stumpwm-mode "stumpwm-mode" "Major mode for stumpwm" t)
+(autoload 'muttrc-mode "muttrc-mode" "Major mode for muttrc" t)
+;; Go
+(autoload 'go-mode "go-mode" "Major mode for google go" t)
+(autoload 'gofmt "go-mode" "" t)
+(autoload 'go-fmt-before-save "go-mode" "" t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; VARIABLES ;;
@@ -260,6 +72,7 @@ Currently adds | & ! . + = - / % * , < > ? : ->"
(add-to-list 'auto-mode-alist '("\\.css$" . css-mode))
(add-to-list 'auto-mode-alist '("mutt-cloud-" . mail-mode))
(add-to-list 'auto-mode-alist '("stumpwmrc" . stumpwm-mode))
+(add-to-list 'auto-mode-alist '("\\.go$" . go-mode))
(add-to-list 'file-coding-system-alist '("\\.vala$" . utf-8))
(add-to-list 'file-coding-system-alist '("\\.vapi$" . utf-8))
@@ -275,7 +88,10 @@ Currently adds | & ! . + = - / % * , < > ? : ->"
(global-set-key [f5] '(lambda ()
(interactive)
(revert-buffer nil t nil)))
-
+(global-set-key [M-left] 'windmove-left)
+(global-set-key [M-right] 'windmove-right)
+(global-set-key [M-up] 'windmove-up)
+(global-set-key [M-down] 'windmove-down)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; THEME SETTINGS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -437,9 +253,6 @@ Currently adds | & ! . + = - / % * , < > ? : ->"
" characters */"
'(fill-paragraph))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; AUTORUN ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(org-crypt-use-before-save-magic)
(ad-activate 'server-create-window-system-frame)
(add-php-keywords)