mirror of
https://codeberg.org/scip/config-general-mode.git
synced 2025-12-17 04:20:57 +01:00
Use conf-mode properly, and remove inappropriate features
- buffer-face-mode is unnecessary - Use conf-mode to set up comment behaviour and font lock defaults - Overriding the user's preferences for completion behaviour and mechanisms is inappropriate: removed. - Overriding the user's electric pair preferences is inappropriate: removed. - Fix code that was breaking the global syntax table (calling modify-syntax-table without a table arg) - Misc small fixes & improvements
This commit is contained in:
@@ -37,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'
|
||||||
|
|
||||||
@@ -95,9 +93,7 @@
|
|||||||
;;; Code:
|
;;; Code:
|
||||||
;;;; Dependencies
|
;;;; Dependencies
|
||||||
|
|
||||||
(require 'sh-script)
|
(require 'conf-mode)
|
||||||
(require 'cc-mode)
|
|
||||||
(require 'hippie-exp)
|
|
||||||
|
|
||||||
;;;; Customizables
|
;;;; Customizables
|
||||||
|
|
||||||
@@ -173,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.")
|
||||||
@@ -221,32 +212,10 @@ 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.
|
||||||
@@ -342,190 +311,68 @@ 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."
|
(let ((st (make-syntax-table)))
|
||||||
(set-syntax-table
|
(modify-syntax-entry ?\/ ". 14n" st)
|
||||||
(let ((st (make-syntax-table)))
|
(modify-syntax-entry ?\* ". 23n" st)
|
||||||
(modify-syntax-entry ?\/ ". 14n" st)
|
(modify-syntax-entry ?# "<" st)
|
||||||
(modify-syntax-entry ?\* ". 23n" st)
|
(modify-syntax-entry ?\n ">" st)
|
||||||
(modify-syntax-entry ?# "<" st)
|
(modify-syntax-entry ?\\ "\\" st)
|
||||||
(modify-syntax-entry ?\n ">" st)
|
(modify-syntax-entry ?$ "'" st)
|
||||||
(modify-syntax-entry ?\\ "\\" st)
|
(modify-syntax-entry ?\' "\"\"" st) ;; make ' electric too
|
||||||
(modify-syntax-entry ?$ "'" st)
|
(modify-syntax-entry ?\` "\"\"" st) ;; make ` electric too
|
||||||
(modify-syntax-entry ?\' "\"\"") ;; make ' electric too
|
(modify-syntax-entry ?< "." st)
|
||||||
(modify-syntax-entry ?\` "\"\"") ;; make ` electric too
|
(modify-syntax-entry ?> "." st)
|
||||||
(modify-syntax-entry ?< ".")
|
st)
|
||||||
(modify-syntax-entry ?> ".")
|
"Syntax table for `config-general-mode'.")
|
||||||
st)))
|
|
||||||
|
|
||||||
(defun config-general--init-font-lock ()
|
(setq config-general-font-lock-keywords
|
||||||
"Initialize font locking."
|
'(
|
||||||
(setq config-general-font-lock-keywords
|
;; <>
|
||||||
'(
|
("\\([<>|]+\\)" 1 'config-general-special-char-face)
|
||||||
;; <>
|
|
||||||
("\\([<>|]+\\)" 1 'config-general-special-char-face)
|
|
||||||
|
|
||||||
;; special handling of single or double quoted variables
|
;; special handling of single or double quoted variables
|
||||||
(config-general--match-variables-in-quotes
|
(config-general--match-variables-in-quotes
|
||||||
(1 'default t)
|
(1 'default t)
|
||||||
(2 font-lock-variable-name-face t))
|
(2 font-lock-variable-name-face t))
|
||||||
|
|
||||||
;; EOF
|
;; EOF
|
||||||
("\\(<<\\)\\([A-Z0-9]+\\)$"
|
("\\(<<\\)\\([A-Z0-9]+\\)$"
|
||||||
(1 'config-general-escape-char-face)
|
(1 'config-general-escape-char-face)
|
||||||
(2 'config-general-constant-face))
|
(2 'config-general-constant-face))
|
||||||
("^[ \t]*\\([A-Z0-9]+?\\)$"
|
("^[ \t]*\\([A-Z0-9]+?\\)$"
|
||||||
(1 'config-general-constant-face))
|
(1 'config-general-constant-face))
|
||||||
|
|
||||||
;; <<include ...>>
|
;; <<include ...>>
|
||||||
("^[ \t]*<<\\(include\\) [ \t]*\\(.+?\\)>>*"
|
("^[ \t]*<<\\(include\\) [ \t]*\\(.+?\\)>>*"
|
||||||
(1 'config-general-constant-face)
|
(1 'config-general-constant-face)
|
||||||
(2 'config-general-file-face)) ;; FIXME: turn into real link property!
|
(2 'config-general-file-face)) ;; FIXME: turn into real link property!
|
||||||
|
|
||||||
;; include ...
|
;; include ...
|
||||||
("^[ \t]*\\(include\\) [ \t]*\\(.*\\)"
|
("^[ \t]*\\(include\\) [ \t]*\\(.*\\)"
|
||||||
(1 'config-general-constant-face)
|
(1 'config-general-constant-face)
|
||||||
(2 'config-general-file-face))
|
(2 'config-general-file-face))
|
||||||
|
|
||||||
;; <block ..>
|
;; <block ..>
|
||||||
("^\s*</*\\(.+\\)>" 1 'config-general-blockname-face)
|
("^\s*</*\\(.+\\)>" 1 'config-general-blockname-face)
|
||||||
|
|
||||||
;; variable definitions
|
;; variable definitions
|
||||||
;; FIXME: add support for -SplitPolicy and -SplitDelimiter and make
|
;; FIXME: add support for -SplitPolicy and -SplitDelimiter and make
|
||||||
;; the = a customizable variable, if possible
|
;; the = a customizable variable, if possible
|
||||||
("^[ \t]*\\(.+?\\)[ \t]*=\\(.*\\)"
|
("^[ \t]*\\(.+?\\)[ \t]*=\\(.*\\)"
|
||||||
(1 'config-general-variable-name-face))
|
(1 'config-general-variable-name-face))
|
||||||
|
|
||||||
;; interpolating variables
|
;; interpolating variables
|
||||||
("\\$\\({#?\\)?\\([[:alpha:]_][[:alnum:]_]*\\|[-#?@!]\\)"
|
("\\$\\({#?\\)?\\([[:alpha:]_][[:alnum:]_]*\\|[-#?@!]\\)"
|
||||||
(2 'config-general-interpolating-variable-face))
|
(2 'config-general-interpolating-variable-face))
|
||||||
|
|
||||||
;; escape char
|
;; escape char
|
||||||
("\\(\\\\\\)" (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
|
||||||
@@ -538,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)
|
||||||
@@ -546,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
|
||||||
@@ -581,19 +427,16 @@ with the mouse).
|
|||||||
\\{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)
|
||||||
|
|||||||
Reference in New Issue
Block a user