From 4975f6fa535a17c83f1680570671959f1ec452fa Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 3 Oct 2022 20:27:17 +0200 Subject: [PATCH] Add commands to edit/remove ecomplete entries * lisp/ecomplete.el (ecomplete-add-item): Allow forcing new values. (ecomplete--remove-item): (ecomplete--prompt-type): New functions. (ecomplete-edit, ecomplete-remove): New commands. --- etc/NEWS | 5 ++++ lisp/ecomplete.el | 66 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index dd048b9df39..05e05afc8ea 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1341,6 +1341,11 @@ change the input method's translation rules, customize the user option ** ecomplete +--- +*** New commands 'ecomplete-edit' and 'ecomplete-remove'. +These allow you to (respectively) edit and bulk-remove entries from +the ecomplete database. + --- *** New user option 'ecomplete-auto-select'. If non-nil and there's only one matching option, auto-select that. diff --git a/lisp/ecomplete.el b/lisp/ecomplete.el index 76438fd25a7..6e40eb74564 100644 --- a/lisp/ecomplete.el +++ b/lisp/ecomplete.el @@ -99,8 +99,10 @@ string that was matched." (insert-file-contents ecomplete-database-file) (setq ecomplete-database (read (current-buffer))))))) -(defun ecomplete-add-item (type key text) - "Add item TEXT of TYPE to the database, using KEY as the identifier." +(defun ecomplete-add-item (type key text &optional force) + "Add item TEXT of TYPE to the database, using KEY as the identifier. +By default, the longest version of TEXT will be preserved, but if +FORCE is non-nil, use TEXT exactly as is." (unless ecomplete-database (ecomplete-setup)) (let ((elems (assq type ecomplete-database)) (now (time-convert nil 'integer)) @@ -111,10 +113,24 @@ string that was matched." (pcase-let ((`(,_key ,count ,_time ,oldtext) entry)) (setcdr entry (list (1+ count) now ;; Preserve the "more complete" text. - (if (>= (length text) (length oldtext)) - text oldtext)))) + (if (or force + (>= (length text) (length oldtext))) + text + oldtext)))) (nconc elems (list (list key 1 now text)))))) +(defun ecomplete--remove-item (type key) + "Remove the element of TYPE and KEY from the ecomplete database." + (unless ecomplete-database + (ecomplete-setup)) + (let ((elems (assq type ecomplete-database))) + (unless elems + (user-error "No elements of type %s" type)) + (let ((entry (assoc key elems))) + (unless entry + (user-error "No entry with key %s" key)) + (setcdr elems (delq entry (cdr elems)))))) + (defun ecomplete-get-item (type key) "Return the text for the item identified by KEY of the required TYPE." (assoc key (cdr (assq type ecomplete-database)))) @@ -263,6 +279,48 @@ non-nil and there is only a single completion option available." ecomplete-sort-predicate)))) (complete-with-action action candidates string pred)))))) +(defun ecomplete--prompt-type () + (unless ecomplete-database + (ecomplete-setup)) + (if (length= ecomplete-database 1) + (caar ecomplete-database) + (completing-read "Item type to edit: " + (mapcar #'car ecomplete-database) + nil t))) + +(defun ecomplete-edit () + "Prompt for an item and allow editing it." + (interactive) + (let* ((type (ecomplete--prompt-type)) + (data (cdr (assq type ecomplete-database))) + (key (completing-read "Key to edit: " data nil t)) + (new (read-string "New value (empty to remove): " + (nth 3 (assoc key data))))) + (if (zerop (length new)) + (progn + (ecomplete--remove-item type key) + (message "Removed %s" key)) + (ecomplete-add-item type key new t) + (message "Updated %s to %s" key new)) + (ecomplete-save))) + +(defun ecomplete-remove () + "Remove entries matching a regexp from the ecomplete database." + (interactive) + (let* ((type (ecomplete--prompt-type)) + (data (cdr (assq type ecomplete-database))) + (match (read-regexp (format "Remove %s keys matching (regexp): " + type))) + (elems (seq-filter (lambda (elem) + (string-match-p match (car elem))) + data))) + (when (yes-or-no-p (format "Delete %s matching ecomplete entries? " + (length elems))) + (dolist (elem elems) + (ecomplete--remove-item type (car elem))) + (ecomplete-save) + (message "Deleted entries")))) + (provide 'ecomplete) ;;; ecomplete.el ends here -- 2.39.2