about summary refs log tree commit diff stats
path: root/lisp/+compat.el
blob: 286d5da8a509af0b98dad773a3f96710fbf3c3d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;;; +compat.el --- Thin backward-compatibility shim -*- lexical-binding: t; -*-

;;; Commentary:

;; I use different versionso of Emacs.  Sometimes I have to copy-paste functions
;; from newer Emacs to make my customizations work.  This is that file.

;; This is probably ill-advised.

;;; Code:

;;; Load stuff in +compat/ subdirectory
(dolist (file (directory-files (locate-user-emacs-file "lisp/+compat") :full "\\.el\\'"))
  (load file :noerror))

;;; Only define things if not already defined
(defmacro +compat-defun (name &rest args)
  `(if (fboundp ',name)
      (message "+compat: `%s' already bound." ',name)
    (defun ,name ,@args)))

(defmacro +compat-defmacro (name &rest args)
  `(if (fboundp ',name)
      (message "+compat: `%s' already bound." ',name)
    (defmacro ,name ,@args)))

;;; Single functions

(+compat-defmacro dlet (binders &rest body)
  "Like `let' but using dynamic scoping."
  (declare (indent 1) (debug let))
  ;; (defvar FOO) only affects the current scope, but in order for
  ;; this not to affect code after the main `let' we need to create a new scope,
  ;; which is what the surrounding `let' is for.
  ;; FIXME: (let () ...) currently doesn't actually create a new scope,
  ;; which is why we use (let (_) ...).
  `(let (_)
     ,@(mapcar (lambda (binder)
                 `(defvar ,(if (consp binder) (car binder) binder)))
               binders)
     (let ,binders ,@body)))

;; https://git.savannah.gnu.org/cgit/emacs.git/diff/?id=772b189143453745a8e014e21d4b6b78f855bba3
(+compat-defun rename-visited-file (new-location)
  "Rename the file visited by the current buffer to NEW-LOCATION.
This command also sets the visited file name.  If the buffer
isn't visiting any file, that's all it does.

Interactively, this prompts for NEW-LOCATION."
  (interactive
   (list (if buffer-file-name
             (read-file-name "Rename visited file to: ")
           (read-file-name "Set visited file name: "
                           default-directory
                           (expand-file-name
                            (file-name-nondirectory (buffer-name))
                            default-directory)))))
  (when (and buffer-file-name
             (file-exists-p buffer-file-name))
    (rename-file buffer-file-name new-location))
  (set-visited-file-name new-location nil t))

(provide '+compat)
;;; +compat.el ends here