;;; Enhanced beginning- and end-of-buffer in special mode buffers (dired etc.) ;; https://fuco1.github.io/2017-05-06-Enhanced-beginning--and-end-of-buffer-in-special-mode-buffers-(dired-etc.).html (defmacro fuco1-special-beginning-of-buffer (mode &rest forms) "Define a special version of `beginning-of-buffer' in MODE. The special function is defined such that the point first moves to `point-min' and then FORMS are evaluated. If the point did not change because of the evaluation of FORMS, jump unconditionally to `point-min'. This way repeated invocations toggle between real beginning and logical beginning of the buffer." (declare (indent 1)) (let ((fname (intern (concat "my-" (symbol-name mode) "-beginning-of-buffer"))) (mode-map (intern (concat (symbol-name mode) "-mode-map"))) (mode-hook (intern (concat (symbol-name mode) "-mode-hook")))) `(progn (defun ,fname () (interactive) (let ((p (point))) (goto-char (point-min)) ,@forms (when (= p (point)) (goto-char (point-min))))) (add-hook ',mode-hook (lambda () (define-key ,mode-map [remap beginning-of-buffer] ',fname)))))) (defmacro fuco1-special-end-of-buffer (mode &rest forms) "Define a special version of `end-of-buffer' in MODE. The special function is defined such that the point first moves to `point-max' and then FORMS are evaluated. If the point did not change because of the evaluation of FORMS, jump unconditionally to `point-max'. This way repeated invocations toggle between real end and logical end of the buffer." (declare (indent 1)) (let ((fname (intern (concat "my-" (symbol-name mode) "-end-of-buffer"))) (mode-map (intern (concat (symbol-name mode) "-mode-map"))) (mode-hook (intern (concat (symbol-name mode) "-mode-hook")))) `(progn (defun ,fname () (interactive) (let ((p (point))) (goto-char (point-max)) ,@forms (when (= p (point)) (goto-char (point-max))))) (add-hook ',mode-hook (lambda () (define-key ,mode-map [remap end-of-buffer] ',fname))))))