From f7fdac911b6a2ca3a29c97ff7da87a12e7e8929b Mon Sep 17 00:00:00 2001 From: Hugo Thunnissen Date: Wed, 21 Aug 2024 09:37:48 +0200 Subject: [PATCH] Make import sort function customizable + only sort when necessary --- phpinspect-imports.el | 46 +++++++++++++++++++++++++++++++++++-------- test/test-imports.el | 2 +- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/phpinspect-imports.el b/phpinspect-imports.el index 0b0c9db..6ff7bc8 100644 --- a/phpinspect-imports.el +++ b/phpinspect-imports.el @@ -231,6 +231,24 @@ determine the scope of the imports (global or local namespace)." (phpinspect-add-use-interactive type buffer project namespace) (phpinspect-buffer-parse buffer 'no-interrupt)))))) +(defcustom phpinspect-import-sort-comparison #'string< + "The comparison function used to sort use statements." + :type 'function + :group 'phpinspect) + +(defun phpinspect-sort-compare-import-strings (str1 str2) + (funcall phpinspect-import-sort-comparison str1 str2)) + +(defun phpinspect-seq-sorted-p (pred seq) + (let (prev) + (catch 'sorted + (seq-doseq (el seq) + (when prev + (unless (funcall pred prev el) + (throw 'sorted nil))) + (setq prev el)) + t))) + (defun phpinspect-format-use-statements (buffer first-meta) "Format a group of use statements to be sorted in alphabetical order and have the right amount of whitespace. @@ -254,27 +272,39 @@ group." current) statements)) - (sort statements (lambda (a b) (string< (car a) (car b)))) + (setq statements (nreverse statements)) - ;; Re-insert use statements (with-current-buffer (phpinspect-buffer-buffer buffer) (save-excursion - (goto-char start) - (combine-after-change-calls - (delete-region start end) + ;; Check if use statements are already sorted + (if (phpinspect-seq-sorted-p + (lambda (a b) + (phpinspect-sort-compare-import-strings (car a) (car b))) + statements) + ;; statements are sorted, skip to the end of the region + (goto-char end) + + ;; else: sort and re-insert + (sort statements (lambda (a b) (phpinspect-sort-compare-import-strings (car a) (car b)))) + (goto-char start) + (combine-after-change-calls + (delete-region start end) (dolist (statement statements) (phpinspect-codify-token (cdr statement)) (insert-char ?\n))) + ;; go char backward for accurate whitespace detection in the code + ;; below that removes/adds whitespace. + (backward-char)) (if (looking-at "[[:blank:]\n]+") ;; Delete excess trailing whitespace (there's more than 2 between the ;; last use statement and the next token) - (when (< 1 (- (match-end 0) (match-beginning 0))) + (when (< 2 (- (match-end 0) (match-beginning 0))) (delete-region (match-beginning 0) (match-end 0)) - (insert-char ?\n)) + (insert-char ?\n 2)) ;; Insert an extra newline (there's only one between the last use ;; statement and the next token) - (insert-char ?\n))))))) + (insert-char ?\n))))))) (defun phpinspect-fix-imports () "Find types that are used in the current buffer and make sure diff --git a/test/test-imports.el b/test/test-imports.el index 91439c9..353c497 100644 --- a/test/test-imports.el +++ b/test/test-imports.el @@ -201,8 +201,8 @@ class Baz { namespace Not\\App; use App\\Bar; -use App\\Foo as FooBar; use App\\Foo; +use App\\Foo as FooBar; function bar(): Bar {}