From 4bf9860bcc9f2b7a704b5acaa4439576b57bbb71 Mon Sep 17 00:00:00 2001 From: Steve Purcell Date: Thu, 21 Apr 2016 23:04:20 +1200 Subject: [PATCH] Use cl-lib instead of shimming, which breaks in older emacsen Aliasing built-in (cl) functions to cl-lib versions when they are available in older Emacs versions can seemingly lead to problems including infinite loops during byte compilation. Since cl-lib works with all Emacs versions supported by multiple-cursors, just depend on this directly instead. This commit makes the necessary changes, both to code, documentation and package metadata. --- README.md | 6 ++- .../multiple-cursors-steps.el | 37 +++++++++++-------- mc-cycle-cursors.el | 27 ++++++-------- mc-mark-more.el | 14 +++---- multiple-cursors-core.el | 35 ++++++------------ multiple-cursors-pkg.el | 3 +- 6 files changed, 60 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 5955e3c..3efcbe4 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,17 @@ great success and much merriment. ## Installation -I highly recommend installing multiple-cursors through elpa. +I highly recommend installing multiple-cursors through `package.el`. It's available on [marmalade](http://marmalade-repo.org/) and [melpa](http://melpa.milkbox.net/): M-x package-install multiple-cursors +The package depends on the `cl-lib` package, so if you do not use +`package.el` or have a recent Emacs, you would need to install that +too: see [GNU ELPA](http://elpa.gnu.org/packages/cl-lib.html). + ## Basic usage Start out with: diff --git a/features/step-definitions/multiple-cursors-steps.el b/features/step-definitions/multiple-cursors-steps.el index 11e59dd..b57bd03 100644 --- a/features/step-definitions/multiple-cursors-steps.el +++ b/features/step-definitions/multiple-cursors-steps.el @@ -1,3 +1,5 @@ +(require 'cl) ;; For lexical-let + (When "^I mark next like this$" (lambda () (call-interactively 'mc/mark-next-like-this))) @@ -48,25 +50,25 @@ (Then "^I should have \\([0-9]+\\) cursors$" (lambda (num) (let ((actual (mc/num-cursors))) - (assert (eq (string-to-number num) actual) nil - "Expected to have %s cursors, but was %d." num actual)))) + (cl-assert (eq (string-to-number num) actual) nil + "Expected to have %s cursors, but was %d." num actual)))) (Then "^I should have one cursor$" (lambda () - (assert (not multiple-cursors-mode) nil - "Expected to have one cursor, but multiple-cursors-mode is still active.") - (assert (eq 1 (mc/num-cursors)) nil - "Expected to have one cursor, but there are still fake cursor overlays."))) + (cl-assert (not multiple-cursors-mode) nil + "Expected to have one cursor, but multiple-cursors-mode is still active.") + (cl-assert (eq 1 (mc/num-cursors)) nil + "Expected to have one cursor, but there are still fake cursor overlays."))) (Then "^rectangular-region-mode should be off$" - (lambda () - (assert (not rectangular-region-mode) nil - "Expected rectangular-region-mode mode to be off, but wasn't."))) + (lambda () + (cl-assert (not rectangular-region-mode) nil + "Expected rectangular-region-mode mode to be off, but wasn't."))) (Then "^rectangular-region-mode should be on$" - (lambda () - (assert rectangular-region-mode nil - "Expected rectangular-region-mode mode to be on, but wasn't."))) + (lambda () + (cl-assert rectangular-region-mode nil + "Expected rectangular-region-mode mode to be on, but wasn't."))) (When "^I press \"\\(.+\\)\"$" (lambda (keybinding) @@ -132,21 +134,21 @@ (goto-char (point-min)) (let ((search (re-search-forward (format "%s" char) nil t)) (message "Can not go to character '%s' since it does not exist in the current buffer: %s")) - (assert search nil message char (espuds-buffer-contents))))) + (cl-assert search nil message char (espuds-buffer-contents))))) (When "^I go to the \\(front\\|end\\) of the word \"\\(.+\\)\"$" (lambda (pos word) (goto-char (point-min)) (let ((search (re-search-forward (format "%s" word) nil t)) (message "Can not go to character '%s' since it does not exist in the current buffer: %s")) - (assert search nil message word (espuds-buffer-contents)) + (cl-assert search nil message word (espuds-buffer-contents)) (if (string-equal "front" pos) (backward-word))))) (When "^I select the last \"\\(.+\\)\"$" (lambda (text) (goto-char (point-max)) (let ((search (re-search-backward text nil t))) - (assert search nil "The text '%s' was not found in the current buffer." text)) + (cl-assert search nil "The text '%s' was not found in the current buffer." text)) (set-mark (point)) (re-search-forward text))) @@ -173,3 +175,8 @@ (setq p (1+ p)) ) (cl-assert (s-equals? expected visible-text) nil message expected visible-text)))) + + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions) +;; End: diff --git a/mc-cycle-cursors.el b/mc-cycle-cursors.el index bb86aaa..01597ac 100644 --- a/mc-cycle-cursors.el +++ b/mc-cycle-cursors.el @@ -28,8 +28,6 @@ (require 'multiple-cursors-core) -(eval-when-compile (require 'cl)) - (defun mc/next-fake-cursor-after-point () (let ((pos (point)) (next-pos (1+ (point-max))) @@ -63,7 +61,7 @@ :group 'multiple-cursors) (defun mc/handle-loop-condition (error-message) - (ecase mc/cycle-looping-behaviour + (cl-ecase mc/cycle-looping-behaviour (error (error error-message)) (warn (message error-message)) (continue 'continue) @@ -72,22 +70,22 @@ (defun mc/first-fake-cursor-after (point) "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." (let* ((cursors (mc/all-fake-cursors)) - (cursors-after-point (remove-if (lambda (cursor) - (< (mc/cursor-beg cursor) point)) - cursors)) - (cursors-in-order (sort* cursors-after-point '< :key 'mc/cursor-beg))) - (first cursors-in-order))) + (cursors-after-point (cl-remove-if (lambda (cursor) + (< (mc/cursor-beg cursor) point)) + cursors)) + (cursors-in-order (cl-sort cursors-after-point '< :key 'mc/cursor-beg))) + (car cursors-in-order))) (defun mc/last-fake-cursor-before (point) "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." (let* ((cursors (mc/all-fake-cursors)) - (cursors-before-point (remove-if (lambda (cursor) - (> (mc/cursor-end cursor) point)) - cursors)) - (cursors-in-order (sort* cursors-before-point '> :key 'mc/cursor-end))) - (first cursors-in-order))) + (cursors-before-point (cl-remove-if (lambda (cursor) + (> (mc/cursor-end cursor) point)) + cursors)) + (cursors-in-order (cl-sort cursors-before-point '> :key 'mc/cursor-end))) + (car cursors-in-order))) -(defun* mc/cycle (next-cursor fallback-cursor loop-message) +(cl-defun mc/cycle (next-cursor fallback-cursor loop-message) (when (null next-cursor) (when (eql 'stop (mc/handle-loop-condition loop-message)) (return-from mc/cycle nil)) @@ -116,7 +114,6 @@ ;; Local Variables: ;; coding: utf-8 -;; byte-compile-warnings: (not cl-functions) ;; End: ;;; mc-cycle-cursors.el ends here diff --git a/mc-mark-more.el b/mc-mark-more.el index ab72a82..be4f1d9 100644 --- a/mc-mark-more.el +++ b/mc-mark-more.el @@ -104,19 +104,19 @@ Use like case-fold-search, don't recommend setting it globally.") (defun mc/mark-more-like-this (skip-last direction) (let ((case-fold-search nil) (re (regexp-opt (mc/region-strings) mc/enclose-search-term)) - (point-out-of-order (ecase direction + (point-out-of-order (cl-ecase direction (forwards (< (point) (mark))) (backwards (not (< (point) (mark)))))) - (furthest-cursor (ecase direction + (furthest-cursor (cl-ecase direction (forwards (mc/furthest-cursor-after-point)) (backwards (mc/furthest-cursor-before-point)))) - (start-char (ecase direction + (start-char (cl-ecase direction (forwards (mc/furthest-region-end)) (backwards (mc/first-region-start)))) - (search-function (ecase direction + (search-function (cl-ecase direction (forwards 'search-forward-regexp) (backwards 'search-backward-regexp))) - (match-point-getter (ecase direction + (match-point-getter (cl-ecase direction (forwards 'match-beginning) (backwards 'match-end)))) (if (and skip-last (not furthest-cursor)) @@ -229,12 +229,12 @@ With zero ARG, skip the last one and mark next." (defun mc/mark-lines (num-lines direction) (dotimes (i num-lines) (mc/save-excursion - (let ((furthest-cursor (ecase direction + (let ((furthest-cursor (cl-ecase direction (forwards (mc/furthest-cursor-after-point)) (backwards (mc/furthest-cursor-before-point))))) (if (overlayp furthest-cursor) (goto-char (overlay-get furthest-cursor 'point)))) - (ecase direction + (cl-ecase direction (forwards (next-logical-line 1 nil)) (backwards (previous-logical-line 1 nil))) (mc/create-fake-cursor-at-point)))) diff --git a/multiple-cursors-core.el b/multiple-cursors-core.el index e64bec5..09b1b01 100644 --- a/multiple-cursors-core.el +++ b/multiple-cursors-core.el @@ -25,17 +25,7 @@ ;;; Code: -(if (require 'cl-lib nil t) - (eval-and-compile - (defalias 'count-if 'cl-count-if) - (defalias 'find-if 'cl-find-if) - (defalias 'incf 'cl-incf) - (defalias 'sort* 'cl-sort) - (defalias 'remove-if 'cl-remove-if) - (defalias 'remove-if-not 'cl-remove-if-not) - (defalias 'symbol-macrolet 'cl-symbol-macrolet)) - (require 'cl)) - +(require 'cl-lib) (require 'rect) (defvar mc--read-char) @@ -62,9 +52,9 @@ (cons (cons 'apply (cons 'activate-cursor-for-undo (list id))) buffer-undo-list)))))) (defun mc/all-fake-cursors (&optional start end) - (remove-if-not 'mc/fake-cursor-p - (overlays-in (or start (point-min)) - (or end (point-max))))) + (cl-remove-if-not 'mc/fake-cursor-p + (overlays-in (or start (point-min)) + (or end (point-max))))) (defmacro mc/for-each-fake-cursor (&rest forms) "Runs the body for each fake cursor, bound to the name cursor" @@ -183,7 +173,7 @@ highlights the entire width of the window." (defun mc/create-cursor-id () "Returns a unique cursor id" - (incf mc--current-cursor-id)) + (cl-incf mc--current-cursor-id)) (defvar mc--max-cursors-original nil "This variable maintains the original maximum number of cursors. @@ -298,9 +288,9 @@ cursor with updated info." (defun mc/cursor-with-id (id) "Find the first cursor with the given id, or nil" - (find-if #'(lambda (o) (and (mc/fake-cursor-p o) - (= id (overlay-get o 'mc-id)))) - (overlays-in (point-min) (point-max)))) + (cl-find-if #'(lambda (o) (and (mc/fake-cursor-p o) + (= id (overlay-get o 'mc-id)))) + (overlays-in (point-min) (point-max)))) (defvar mc--stored-state-for-undo nil "Variable to keep the state of the real cursor while undoing a fake one") @@ -331,8 +321,8 @@ cursor with updated info." (defun mc/num-cursors () "The number of cursors (real and fake) in the buffer." - (1+ (count-if 'mc/fake-cursor-p - (overlays-in (point-min) (point-max))))) + (1+ (cl-count-if 'mc/fake-cursor-p + (overlays-in (point-min) (point-max))))) (defvar mc--this-command nil "Used to store the original command being run.") @@ -570,13 +560,13 @@ for running commands with multiple cursors.") (defun mc/dump-list (list-symbol) "Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer." - (symbol-macrolet ((value (symbol-value list-symbol))) + (cl-symbol-macrolet ((value (symbol-value list-symbol))) (insert "(setq " (symbol-name list-symbol) "\n" " '(") (newline-and-indent) (set list-symbol (sort value (lambda (x y) (string-lessp (symbol-name x) - (symbol-name y))))) + (symbol-name y))))) (mapc #'(lambda (cmd) (insert (format "%S" cmd)) (newline-and-indent)) value) (insert "))") @@ -772,7 +762,6 @@ for running commands with multiple cursors.") ;; Local Variables: ;; coding: utf-8 -;; byte-compile-warnings: (not cl-functions) ;; End: ;;; multiple-cursors-core.el ends here diff --git a/multiple-cursors-pkg.el b/multiple-cursors-pkg.el index af2e2e1..331fb08 100644 --- a/multiple-cursors-pkg.el +++ b/multiple-cursors-pkg.el @@ -1,2 +1,3 @@ (define-package "multiple-cursors" "1.3.0" - "Multiple cursors for Emacs.") + "Multiple cursors for Emacs." + '((cl-lib "0.5")))