all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Emanuel Berg <incal@dataswamp.org>
To: emacs-devel@gnu.org
Subject: Re: buffer segments, uniform and automatic (was: Re: [Elisp: 8 out of 10 problems] I think the last one! (point))
Date: Wed, 14 Aug 2024 22:02:07 +0200	[thread overview]
Message-ID: <87wmkic1q8.fsf@dataswamp.org> (raw)
In-Reply-To: 87cymcfga5.fsf@dataswamp.org

Consistent Elisp :)

See downmost for examples what you can do with it.

It supports buff-, para-, sent-, word-, and char- right now
but it is easy to add whatever you want.

Everything is defined as: (beg end next)

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/pos.el
;;
;; -----------------------------------------------------------------------

(require 'cl-lib)

(defun pos--wash-str (str)
  (string-trim
    (replace-regexp-in-string "%" "%%"
      (replace-regexp-in-string "[\n[:blank:]]+" " " str))))

;; -----------------------------------------------------------------------

(defun pos--all-in-f (goto-beg end cur next)
  (when (cl-every #'functionp (list goto-beg end cur next))
    (funcall goto-beg)
    (let ((end (funcall end))
          (res))
      (while (< (point) end)
        (push (funcall cur) res)
        (funcall next))
      (nreverse res))))

(defmacro pos--all-in (seg in)
  (let ( (goto-beg (intern (format "goto-%s-beg" in)))
         (end      (intern (format "%s-end"      in)))
         (cur      (intern (format "%s-cur"      seg)))
         (next     (intern (format "%s-next"     seg))) )
    `(pos--all-in-f (quote ,goto-beg)
                    (quote ,end)
                    (quote ,cur)
                    (quote ,next))))

;; -----------------------------------------------------------------------

(defmacro pos--def (name spn)
  (let ((reg (intern (format "%s-reg" name)))
        (beg (intern (format "%s-beg" name)))
        (end (intern (format "%s-end" name)))
        (cur (intern (format "%s-cur" name)))
        (len (intern (format "%s-len" name)))
        (bop (intern (format "%s-bop" name)))
        (eop (intern (format "%s-eop" name)))
        (goto-beg (intern (format "goto-%s-beg" name)))
        (goto-end (intern (format "goto-%s-end" name)))
        (next (intern (format "%s-next" name)))
        (prev (intern (format "%s-prev" name)))
        )
    `(progn
       (defun ,reg () (pos--reg ,spn))
       (defun ,beg () (pos--beg ,spn))
       (defun ,end () (pos--end ,spn))
       (defun ,cur () (pos--cur ,spn))
       (defun ,len () (pos--len ,spn))
       (defun ,bop () (pos--bop ,spn))
       (defun ,eop () (pos--eop ,spn))
       (defun ,goto-beg () (interactive) (pos--goto-beg ,spn))
       (defun ,goto-end () (interactive) (pos--goto-end ,spn))
       (when (= 3 (length ,spn))
         (defun ,next (&optional n) (interactive "p") (pos--next ,spn n))
         (defun ,prev (&optional n) (interactive "p") (pos--prev ,spn n)))
       )))

(defun pos--reg (spn &optional def)
  (pcase-let* ((`(,beg ,end ,next) spn))
    (if def
        (list beg end next)
      (list beg end))))

(defun pos--beg (spn)
  (car (pos--reg spn)))

(defun pos--end (spn)
  (cadr (pos--reg spn)))

(defun pos--cur (spn)
  (pcase-let* ((`(,beg ,end) (pos--reg spn))
               (cur (pos--wash-str (buffer-substring-no-properties beg end))))
    cur))

(defun pos--len (spn)
  (- (pos--end spn) (pos--beg spn)))

(defun pos--bop (spn)
  (= (point) (pos--beg spn)))

(defun pos--eop (spn)
  (= (point) (pos--end spn)))

(defun pos--goto-beg (spn)
  (goto-char (pos--beg spn)))

(defun pos--goto-end (spn)
  (goto-char (pos--end spn)))

(defun pos--next (spn &optional n)
  (or n (setq n 1))
  (pcase-let* ((`(,_beg ,_end ,next) (pos--reg spn t)))
    (when (functionp next)
      (funcall next n))))

(defun pos--prev (spn &optional n)
  (or n (setq n 1))
  (pcase-let* ((`(,_beg ,_end ,next) (pos--reg spn t)))
    (when (functionp next)
      (funcall next (* -1 n)))))

;; -----------------------------------------------------------------------

(defun pos--buff ()
  (list (point-min) (point-max)))

(defun pos--para ()
  (save-mark-and-excursion
    (let ((beg (progn (start-of-paragraph-text) (point)))
          (end (progn (end-of-paragraph-text)   (point))))
      (list beg end #'forward-paragraph))))

(defun pos--sent ()
  (save-mark-and-excursion
    (let ((end (forward-sentence))
          (beg (forward-sentence -1)))
      (list beg end #'forward-sentence))))

(defun pos--word ()
  (save-mark-and-excursion
    (let ((end (progn (forward-word)    (point)))
          (beg (progn (forward-word -1) (point))))
      (list beg end #'forward-word))))

(defun pos--char ()
  (save-mark-and-excursion
    (let ((beg (point))
          (end (progn (forward-char) (point))))
      (list beg end #'forward-char))))

;; -----------------------------------------------------------------------

(when nil
  (pos--def "buff" (pos--buff))
  (pos--def "para" (pos--para))
  (pos--def "sent" (pos--sent))
  (pos--def "word" (pos--word))
  (pos--def "char" (pos--char))
  )

(when nil
  ;; for buff-, para-, sent-, word-, and char-
  (word-reg)
  (word-beg)
  (word-end)
  (word-cur)
  (word-len)
  (word-bop)
  (word-eop)

  ;; M-x
  (goto-word-beg)
  (goto-word-end)

  ;; for para-, sent-, word-, char-
  ;; with C-u M-x and C-u n M-x
  (word-next)
  (word-next 5)
  (word-prev)
  (word-prev 5)
  (pos--all-in word sent) ; all combinations
)

(provide 'pos)

-- 
underground experts united
https://dataswamp.org/~incal




  reply	other threads:[~2024-08-14 20:02 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-11  0:14 [Elisp: 8 out of 10 problems] I think the last one! (point) Emanuel Berg
2024-08-11  4:46 ` Emanuel Berg
2024-08-11  5:43   ` Eli Zaretskii
2024-08-11  5:22 ` Eli Zaretskii
2024-08-11  7:44 ` Yuri Khan
2024-08-11  9:06   ` Emanuel Berg
2024-08-11 12:16   ` Emanuel Berg
2024-08-13 13:13     ` buffer segments, uniform and automatic (was: Re: [Elisp: 8 out of 10 problems] I think the last one! (point)) Emanuel Berg
2024-08-13 14:10       ` Ihor Radchenko
2024-08-13 17:10         ` Emanuel Berg
2024-08-13 18:07           ` Emanuel Berg
2024-08-14 20:02             ` Emanuel Berg [this message]
2024-08-15  5:39               ` Emanuel Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wmkic1q8.fsf@dataswamp.org \
    --to=incal@dataswamp.org \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.