Merge pull request #1 from purcell/master

Numerous fixes
This commit is contained in:
T.v.Dein
2017-07-15 16:33:51 +02:00
committed by GitHub

View File

@@ -1,4 +1,3 @@
;;; config-general-mode.el --- Config::General config file mode ;;; config-general-mode.el --- Config::General config file mode
;; Copyright (C) 2016-2017, T.v.Dein <tlinden@cpan.org> ;; Copyright (C) 2016-2017, T.v.Dein <tlinden@cpan.org>
@@ -38,9 +37,7 @@
;; It is based on `conf-mode' with the following features: ;; It is based on `conf-mode' with the following features:
;; ;;
;; - good syntax highlighting for config files ;; - good syntax highlighting for config files
;; - completion support with `TAB' (using `dabbrev')
;; - imenu support for <blocks> ;; - imenu support for <blocks>
;; - electric paring mode (for quotes, parens, etc) enabled
;; - automatic indenting ;; - automatic indenting
;; - jump to include file with `C-return' ;; - jump to include file with `C-return'
@@ -96,9 +93,7 @@
;;; Code: ;;; Code:
;;;; Dependencies ;;;; Dependencies
(require 'sh-script) (require 'conf-mode)
(require 'cc-mode)
(require 'hippie-exp)
;;;; Customizables ;;;; Customizables
@@ -124,7 +119,7 @@
("on" . "off") ("on" . "off")
("yes" . "no") ("yes" . "no")
("enable" . "disable")) ("enable" . "disable"))
"Values which can be toggled with <C-c C-t>. Only pairs are supported." "Values which can be toggled with \\[config-general-toggle-flag]. Only pairs are supported."
:group 'config-general :group 'config-general
:type 'list) :type 'list)
@@ -174,11 +169,6 @@
"face for strings" "face for strings"
:group 'config-general-faces) :group 'config-general-faces)
(defface config-general-value-face
'((t (:inherit default)))
"face for variable values"
:group 'config-general-faces)
;;;; Global Vars ;;;; Global Vars
(defconst config-general-mode-version "0.01" "Config::General mode version.") (defconst config-general-mode-version "0.01" "Config::General mode version.")
@@ -208,9 +198,9 @@ character."
(defun config-general-do-electric-return () (defun config-general-do-electric-return ()
"Electric return, follows file link or add newline below. "Electric return, follows file link or add newline below.
If (point) is on an include filename, call If (point) is on an include filename, call `find-file-at-point'
`find-file-at-point' with it, otherwise add a new line below, with it, otherwise add a new line below, indent it and
indent it and move (point) there." move (point) there."
(interactive) (interactive)
(if (eq config-general-electric-return t) (if (eq config-general-electric-return t)
(if (eq (get-text-property (point) 'face) 'config-general-file-face) (if (eq (get-text-property (point) 'face) 'config-general-file-face)
@@ -222,32 +212,10 @@ indent it and move (point) there."
"Add a new line below, indent it and move (point) there." "Add a new line below, indent it and move (point) there."
(interactive) (interactive)
(end-of-line) (end-of-line)
(if (eq (get-text-property (point) 'face) 'font-lock-comment-face) (if (elt (syntax-ppss) 4)
(indent-new-comment-line) (indent-new-comment-line)
(newline-and-indent))) (newline-and-indent)))
(defun config-general-completion-at-point ()
"Complete word at point using hippie-expand, if not on a comment."
(interactive)
(when (looking-back "[-%$_a-zA-Z0-9]")
(unless (eq (get-text-property (point) 'face) 'font-lock-comment-face)
(hippie-expand nil))))
(defun config-general-do-electric-tab ()
"Enter a <TAB> or goto current indentation."
(interactive)
(if (eq (point) (line-end-position))
(indent-for-tab-command)
(back-to-indentation)))
(defun config-general-tab-or-expand ()
"Do electric TAB or completion depending where point is.
This is just a convenience function, which can be mapped
to `tab' by the user. .Not in use by default."
(interactive)
(unless (config-general-completion-at-point)
(config-general-do-electric-tab)))
(defun config-general-toggle-flag () (defun config-general-toggle-flag ()
"Toggle a value from the list `config-general-toggle-values' to its reverse. "Toggle a value from the list `config-general-toggle-values' to its reverse.
@@ -343,74 +311,10 @@ Argument LIMIT limits the search."
(when (= SS 34) (when (= SS 34)
(throw 'done (point))))))))) (throw 'done (point)))))))))
;; FIXME: Use this patched version for older emacsen and the default
;; for version which contain the patch (if any, ever).
;;
;; The original function try-expand-dabbrev-all-buffers doesn't work
;; correctly, it ignores a buffer-local configuration of the variables
;; hippie-expand-only-buffers and hippie-expand-ignore-buffers. This
;; is the patched version of the function.
;;
;; Bugreport: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=27501
(defun config-general--try-expand-dabbrev-all-buffers (old)
"Try to expand word \"dynamically\", searching all other buffers.
The argument OLD has to be nil the first call of this function, and t
for subsequent calls (for further possible expansions of the same
string). It returns t if a new expansion is found, nil otherwise."
(let ((expansion ())
(buf (current-buffer))
(orig-case-fold-search case-fold-search)
(heib hippie-expand-ignore-buffers)
(heob hippie-expand-only-buffers)
)
(if (not old)
(progn
(he-init-string (he-dabbrev-beg) (point))
(setq he-search-bufs (buffer-list))
(setq he-searched-n-bufs 0)
(set-marker he-search-loc 1 (car he-search-bufs))))
(if (not (equal he-search-string ""))
(while (and he-search-bufs
(not expansion)
(or (not hippie-expand-max-buffers)
(< he-searched-n-bufs hippie-expand-max-buffers)))
(set-buffer (car he-search-bufs))
(if (and (not (eq (current-buffer) buf))
(if heob
(he-buffer-member heob)
(not (he-buffer-member heib))))
(save-excursion
(save-restriction
(if hippie-expand-no-restriction
(widen))
(goto-char he-search-loc)
(setq expansion
(let ((case-fold-search orig-case-fold-search))
(he-dabbrev-search he-search-string nil)))
(set-marker he-search-loc (point))
(if (not expansion)
(progn
(setq he-search-bufs (cdr he-search-bufs))
(setq he-searched-n-bufs (1+ he-searched-n-bufs))
(set-marker he-search-loc 1 (car he-search-bufs))))))
(setq he-search-bufs (cdr he-search-bufs))
(set-marker he-search-loc 1 (car he-search-bufs)))))
(set-buffer buf)
(if (not expansion)
(progn
(if old (he-reset-string))
())
(progn
(he-substitute-string expansion t)
t))))
;;;; Init Functions ;;;; Init Functions
(defun config-general--init-syntax () (defvar config-general-mode-syntax-table
"We need our own syntax table for mixed C++ and Shell comment support."
(set-syntax-table
(let ((st (make-syntax-table))) (let ((st (make-syntax-table)))
(modify-syntax-entry ?\/ ". 14n" st) (modify-syntax-entry ?\/ ". 14n" st)
(modify-syntax-entry ?\* ". 23n" st) (modify-syntax-entry ?\* ". 23n" st)
@@ -418,14 +322,13 @@ string). It returns t if a new expansion is found, nil otherwise."
(modify-syntax-entry ?\n ">" st) (modify-syntax-entry ?\n ">" st)
(modify-syntax-entry ?\\ "\\" st) (modify-syntax-entry ?\\ "\\" st)
(modify-syntax-entry ?$ "'" st) (modify-syntax-entry ?$ "'" st)
(modify-syntax-entry ?\' "\"\"") ;; make ' electric too (modify-syntax-entry ?\' "\"\"" st) ;; make ' electric too
(modify-syntax-entry ?\` "\"\"") ;; make ` electric too (modify-syntax-entry ?\` "\"\"" st) ;; make ` electric too
(modify-syntax-entry ?< ".") (modify-syntax-entry ?< "." st)
(modify-syntax-entry ?> ".") (modify-syntax-entry ?> "." st)
st))) st)
"Syntax table for `config-general-mode'.")
(defun config-general--init-font-lock ()
"Initialize font locking."
(setq config-general-font-lock-keywords (setq config-general-font-lock-keywords
'( '(
;; <> ;; <>
@@ -470,63 +373,6 @@ string). It returns t if a new expansion is found, nil otherwise."
("\\(\\\\\\)" (1 'config-general-escape-char-face)) ("\\(\\\\\\)" (1 'config-general-escape-char-face))
)) ))
;; activate
(set (make-local-variable 'font-lock-defaults)
'(config-general-font-lock-keywords nil nil nil nil))
(font-lock-mode 1)
;; set default font for everything else, which can only be variable values
(setq buffer-face-mode-face 'config-general-value-face)
(buffer-face-mode))
(defun config-general--init-minors ()
"Enable and configure usefull minor modes."
;; from shell-script-mode, turn << into here-doc
(sh-electric-here-document-mode 1)
;; Inserting a brace or quote automatically inserts the matching pair
(electric-pair-mode t))
(defun config-general--init-vars ()
"Initialize major mode configuration."
;; prepare clean startup
(kill-all-local-variables)
;; support for 'comment-region et al
(set (make-local-variable 'comment-start) "# ")
(set (make-local-variable 'comment-end) "")
;; we don't need a complicated indent strategy, relative is totally ok
(set (make-local-variable 'indent-line-function) #'indent-relative)
;; alert about trailing whitespaces, important for continuations
(set (make-local-variable 'show-trailing-whitespace) t))
(defun config-general--init-hippie ()
"Configure `hippie-expand'."
;; use CG mode local only
(set (make-local-variable 'hippie-expand-only-buffers) '(config-general-mode))
;; configure order of expansion functions
(if (version< emacs-version "25.1")
(set (make-local-variable 'hippie-expand-try-functions-list)
'(try-expand-dabbrev ;; use patched version
config-general--try-expand-dabbrev-all-buffers
try-complete-file-name-partially
try-complete-file-name))
(set (make-local-variable 'hippie-expand-try-functions-list)
'(try-expand-dabbrev
try-expand-dabbrev-all-buffers
try-complete-file-name-partially
try-complete-file-name)))
;; enable
(add-hook 'completion-at-point-functions 'config-general-completion-at-point))
(defun config-general--init-imenu ()
"Configure `imenu'."
(make-local-variable 'imenu-generic-expression)
(setq imenu-generic-expression config-general-imenu-expression)
(setq imenu-case-fold-search nil)
(require 'imenu))
;;;###autoload ;;;###autoload
(defvar config-general-mode-map (defvar config-general-mode-map
@@ -539,7 +385,6 @@ string). It returns t if a new expansion is found, nil otherwise."
(define-key map (kbd "C-c C-t") 'config-general-toggle-flag) (define-key map (kbd "C-c C-t") 'config-general-toggle-flag)
(define-key map (kbd "C-c C-j") 'imenu) ;; aka jump (define-key map (kbd "C-c C-j") 'imenu) ;; aka jump
(define-key map (kbd "<C-return>") 'config-general-do-electric-return) (define-key map (kbd "<C-return>") 'config-general-do-electric-return)
(define-key map (kbd "<tab>") 'config-general-do-electric-tab)
(define-key map (kbd "C-k") 'config-general-kill-line-or-block-or-continuation) (define-key map (kbd "C-k") 'config-general-kill-line-or-block-or-continuation)
(define-key map [remap delete-backward-char] 'backward-delete-char-untabify) (define-key map [remap delete-backward-char] 'backward-delete-char-untabify)
map) map)
@@ -547,7 +392,7 @@ string). It returns t if a new expansion is found, nil otherwise."
) )
;;;###autoload ;;;###autoload
(define-derived-mode config-general-mode conf-mode "config-general" (define-derived-mode config-general-mode conf-mode "Conf[General]"
"Config::General config file mode. "Config::General config file mode.
Config::General is a Perl module for parsing config files with Config::General is a Perl module for parsing config files with
@@ -563,67 +408,35 @@ It is based on `conf-mode' with the following features:
- automatic indenting - automatic indenting
- jump to include file with `<ret>' - jump to include file with `<ret>'
To use, save config-general-mode.el to a directory in your
load-path.
Add something like this to your config:
(require 'config-general-mode)
(add-to-list 'auto-mode-alist '(\"\\.conf$\" . config-general-mode))
or load it manually, when needed:
M-x config-general-mode
You can also enable it with a buffer-local variable by adding
this as the first line of a config file:
# -*-config-general-*-
Usage Usage
Edit your config file as usual. Use `<tab>' for completion of Edit your config file as usual. Use `<tab>' for completion of
values and variables. Use `C-c C-t' to toggle flags (like true values and variables. Use \\[config-general-toggle-flag] to
to false). Use `C-c C-=' on a region to automatically align on toggle flags (like true to false). Use
the `=` character. Use `C-c C-/' to breakup a region with long \\[config-general-align-vars] on a region to automatically align
lines into shorter ones using backslash notation. Use on the `=` character. Use \\[sh-backslash-region] to break up a
`<C-return>' to visit an included file or (when not on a link) region with long lines into shorter ones using backslash
insert a new line below the current one, indent and move point notation. Use \\[config-general-do-electric-return] to visit an
there. Use `<C-k>' to delete lines, including continuation lines included file or (when not on a link) insert a new line below the
or whole blocks. Use `C-c C-j' to jump to a block current one, indent and move point there. Use
definition (same as using `imenu' with the mouse). \\[config-general-kill-line-or-block-or-continuation] to delete
lines, including continuation lines or whole blocks. Use
Customize \\[imenu] to jump to a block definition (same as using `imenu'
with the mouse).
You can customize the mode with:
M-x customize-group RET config-general-mode RET
You can also use hooks to config-general mode as a way to modify
or enhance its behavior. The following hooks are available:
config-general-mode-hook
For example:
(add-hook 'config-general-mode-hook 'electric-indent-mode)
\\{config-general-mode-map}" \\{config-general-mode-map}"
;; initialize mode ;; initialize mode
(config-general--init-vars) (conf-mode-initialize "#" 'config-general-font-lock-keywords)
(config-general--init-hippie)
(config-general--init-font-lock)
(config-general--init-minors)
(config-general--init-syntax)
(config-general--init-imenu)
;; make us known correctly ;; we don't need a complicated indent strategy, relative is totally ok
;; FIXME: doesn't work when removed (set (make-local-variable 'indent-line-function) #'indent-relative)
(setq major-mode 'config-general-mode)
(setq mode-name "C::G")
(use-local-map config-general-mode-map))
;; alert about trailing whitespaces, important for continuations
(setq show-trailing-whitespace t)
(setq imenu-generic-expression config-general-imenu-expression)
(setq imenu-case-fold-search nil))
;; done ;; done
(provide 'config-general-mode) (provide 'config-general-mode)