Elisp: Validate Matching Brackets ๐
Video Tutorial
Problem
Write a emacs lisp script to process ten thousand files and check for mismatched brackets.
The matching pairs includes these: () {} [] โโ โนโบ ยซยป ใใ ใใ ใใ ใใ ใใ ใใ. ใsee Unicode: Brackets, Quotes ใใใใใใใ
The program should be able to check all files in a dir, and report any file that has mismatched bracket, and also indicate the line number or position where a mismatch occurs.
Solution
;; -*- coding: utf-8; lexical-binding: t; -*- (defvar xah-validate-brackets-alist nil "a alist of brackets. Each element is a cons pair, of the left and right bracket. Each is a string of single char.") (setq xah-validate-brackets-alist '(("โ" . "โ") ("โน" . "โบ") ("ยซ" . "ยป") ("ใ" . "ใ") ("ใ" . "ใ") ("ใ" . "ใ") ("ใ" . "ใ") ("ใ" . "ใ") ("ใ" . "ใ") ("ใ" . "ใ") ("{" . "}") ("[" . "]") ("(" . ")") )) (defun xah-validate-brackets-file (Filepath) "Validate brackets of file at Filepath. The type of brackets to check is stored in var `xah-validate-brackets-alist'. When called interactively, it checks current buffer. Also, it saves first if modified. URL `http://xahlee.info/emacs/emacs/elisp_validate_matching_brackets.html' Created: 2024-08-10 Version: 2024-08-12" (interactive (progn (when (buffer-modified-p) (save-buffer)) (list buffer-file-name))) (let (xregex xstack xchar xpos) (when (not (file-exists-p Filepath)) (user-error "Error: file no exist: %s" Filepath)) (setq xregex (mapconcat (lambda (x) (concat (regexp-quote (car x)) "\\|" (regexp-quote (cdr x)))) xah-validate-brackets-alist "\\|")) (with-temp-buffer (insert-file-contents Filepath) (goto-char 1) (while (re-search-forward xregex nil t) (setq xpos (point)) (setq xchar (char-to-string (char-before))) (let (xrightBra-p xleftBra) (setq xrightBra-p (rassoc xchar xah-validate-brackets-alist)) (when xrightBra-p (setq xleftBra (car xrightBra-p))) (if xstack (if (string-equal (elt (car xstack) 0) xleftBra) (pop xstack) (push (vector xchar xpos) xstack)) (if xrightBra-p (warn "Bracket mismatch in file %s. Nothing matches this bracket: %s. at position %s." Filepath xchar xpos ) (push (vector xchar xpos) xstack))))) (if xstack (warn "Bracket mismatch in file %s. Nothing matches this bracket: %s. at position %s." Filepath (aref (car xstack) 0) (aref (car xstack) 1)) (message "Brackets valid. You are beautiful."))))) (defun xah-validate-brackets-dir (Dir &optional FileExtension) "Validate brackets in all files in Dir, recursively. The type of brackets to check is stored in var `xah-validate-brackets-alist'. Check only files with FileExtension. If FileExtension is nil, do all files. Any file or dir name starting with dot is ignored. URL `http://xahlee.info/emacs/emacs/elisp_validate_matching_brackets.html' Created: 2024-08-11 Version: 2024-08-14" (interactive (list default-directory (if buffer-file-name (if (file-name-extension buffer-file-name) (file-name-extension buffer-file-name) nil ) nil))) (let (xpaths xextRegex) (setq xextRegex (if FileExtension (concat "\\." FileExtension "$") "")) (setq xpaths (directory-files-recursively Dir xextRegex nil (lambda (x) (not (string-match "/\\..*/" x))))) (mapc 'xah-validate-brackets-file xpaths)))