[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/scala-mode 634736aba8 1/2: add a `scala-organise' command
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/scala-mode 634736aba8 1/2: add a `scala-organise' command |
Date: |
Tue, 25 Oct 2022 10:59:46 -0400 (EDT) |
branch: elpa/scala-mode
commit 634736aba871ba3910b64ad649e7638a49bb5d85
Author: Sam Halliday <sam.halliday@gmail.com>
Commit: Sam Halliday <sam.halliday@gmail.com>
add a `scala-organise' command
---
scala-organise.el | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
diff --git a/scala-organise.el b/scala-organise.el
new file mode 100644
index 0000000000..450cffa868
--- /dev/null
+++ b/scala-organise.el
@@ -0,0 +1,104 @@
+;;; scala-organise.el --- organise scala imports -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Sam Halliday
+;; License: GPL 3 or any later version
+
+;;; Commentary:
+;;
+;; A simplistic command that organises Java-style import sections (i.e. no
+;; relative paths). Only the first import section, up to any non-import line
+;; (including comments) is organised. For anything more complex than this,
+;; consider using https://github.com/liancheng/scalafix-organize-imports
+;;
+;;; Code:
+
+(require 'subr-x)
+
+(defcustom scala-organise-first '(("java." "javax." "sun.") "scala.")
+ "Prefixes (strings or lists of strings), that are organised first."
+ :type 'listp
+ :group 'scala
+ :safe 'listp
+ :local t)
+
+(defun scala-organise ()
+ "Organise the import section"
+ (interactive)
+ (save-excursion
+ (goto-char 0)
+ (let (;; alist of the form ("prefix." ("Symbol", "_", "etc"))
+ (imports))
+ (when (re-search-forward (rx line-start "import "))
+ (forward-line 0)
+ (let ((start (point)))
+ (while (looking-at (rx (or "\n" (: "import " (group (+ (not (or "{"
"\n"))))))))
+ (when-let ((match (match-string-no-properties 1)))
+ (goto-char (match-end 1))
+ (setq imports
+ (if (looking-at "{")
+ ;; multi-part import
+ (let ((block-start (point)))
+ (forward-sexp)
+ (let* ((block (buffer-substring-no-properties
block-start (point)))
+ (parts (split-string block "," nil (rx (+ (or
space "{" "}"))))))
+ (scala-organise--alist-append match parts
imports)))
+ ;; standalone import
+ (let* ((part (car (reverse (split-string match (rx
".")))))
+ (prefix (string-remove-suffix part match)))
+ (scala-organise--alist-append prefix part imports)))))
+ (forward-line 1))
+
+ (delete-region start (point))
+ (let* ((keys (sort (delete-dups (mapcar #'car imports)) #'string<)))
+ (dolist (setting scala-organise-first)
+ (let (done)
+ (dolist (key keys)
+ (when (scala-organise--special-p key setting)
+ (insert (scala-organise--render (assoc key imports)))
+ (push key done)))
+ (when done
+ (insert "\n"))
+ (setq keys (seq-difference keys done))))
+ (dolist (key keys)
+ (insert (scala-organise--render (assoc key imports))))
+ (when keys
+ (insert "\n"))))))
+
+ (when (re-search-forward (rx line-start (* space) "import "))
+ (message "Inline imports, starting at line %i, have not been organised."
(line-number-at-pos)))))
+
+(defun scala-organise--special-p (entry setting)
+ "Return non-nil if the ENTRY string matches the SETTING (a string
+or a list of strings)."
+ (if (listp setting)
+ (seq-find (lambda (s) (string-prefix-p s entry)) setting)
+ (string-prefix-p setting entry)))
+
+(defun scala-organise--render (entry)
+ "Return a string for the ENTRY (prefix . entries).
+Entries will be alphabetically sorted and deduped. If the special
+character `_' appears, it will replace all other (non-renamed)
+entries."
+ (let* ((parts (sort (delete-dups (cdr entry)) #'string<))
+ (parts_ (if (member "_" parts)
+ (cons "_" (seq-filter (lambda (e) (string-match-p (rx
"=>") e)) parts))
+ parts))
+ (clean (lambda (s) (replace-regexp-in-string (rx (* space) "=>" (*
space)) " => " s)))
+ (rendered (if (and (length= parts_ 1)
+ (not (string-match-p (rx "=>") (car parts_))) )
+ (car parts_)
+ (concat "{ " (mapconcat clean parts_ ", ") " }"))))
+ (concat "import " (car entry) rendered "\n")))
+
+(defun scala-organise--alist-append (key value alist)
+ "Return an ALIST with KEY mapped to VALUE `append'ed to the existing value.
+If VALUE (or the existing value) is not a list, it will be
+converted into a single element list before being appended."
+ (let* ((existing (cdr (assoc key alist)))
+ (existing_ (if (listp existing) existing (list existing)))
+ (value_ (if (listp value) value (list value)))
+ (update (append value_ existing_)))
+ (cons (cons key update) alist)))
+
+(provide 'scala-organise)
+;;; scala-organise.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [nongnu] elpa/scala-mode 634736aba8 1/2: add a `scala-organise' command,
ELPA Syncer <=