136 lines
4.8 KiB
EmacsLisp
136 lines
4.8 KiB
EmacsLisp
;;; syd-text.el -*- lexical-binding: t; -*-
|
|
|
|
;;;###autoload
|
|
(defun syd-region-active-p ()
|
|
"Return non-nil if selection is active.
|
|
Detects evil visual mode as well."
|
|
(declare (side-effect-free t))
|
|
(or (use-region-p)
|
|
(and (bound-and-true-p evil-local-mode)
|
|
(evil-visual-state-p))))
|
|
|
|
;;;###autoload
|
|
(defun syd-region-beginning ()
|
|
"Return beginning position of selection.
|
|
Uses `evil-visual-beginning' if available."
|
|
(declare (side-effect-free t))
|
|
(or (and (bound-and-true-p evil-local-mode)
|
|
(evil-visual-state-p)
|
|
(markerp evil-visual-beginning)
|
|
(marker-position evil-visual-beginning))
|
|
(region-beginning)))
|
|
|
|
;;;###autoload
|
|
(defun syd-region-end ()
|
|
"Return end position of selection.
|
|
Uses `evil-visual-end' if available."
|
|
(declare (side-effect-free t))
|
|
(or (and (bound-and-true-p evil-local-mode)
|
|
(evil-visual-state-p)
|
|
(markerp evil-visual-end)
|
|
(marker-position evil-visual-end))
|
|
(region-end)))
|
|
|
|
;;;###autoload
|
|
(cl-defun syd-thing-at-point-or-region (&optional thing &key prompt)
|
|
"Grab the current selection, THING at point, or xref identifier at point.
|
|
|
|
Returns THING if it is a string. Otherwise, if nothing is found at point and
|
|
PROMPT is non-nil, prompt for a string (if PROMPT is a string it'll be used as
|
|
the prompting string). Returns nil if all else fails.
|
|
|
|
NOTE: Don't use THING for grabbing symbol-at-point. The xref fallback is smarter
|
|
in some cases."
|
|
(declare (side-effect-free t))
|
|
(cond ((stringp thing)
|
|
thing)
|
|
((syd-region-active-p)
|
|
(buffer-substring-no-properties
|
|
(syd-region-beginning)
|
|
(syd-region-end)))
|
|
(thing
|
|
(thing-at-point thing t))
|
|
((require 'xref nil t)
|
|
;; Eglot, nox (a fork of eglot), and elpy implementations for
|
|
;; `xref-backend-identifier-at-point' betray the documented purpose of
|
|
;; the interface. Eglot/nox return a hardcoded string and elpy
|
|
;; prepends the line number to the symbol.
|
|
(let ((backend (xref-find-backend)))
|
|
(if (memq backend '(eglot elpy nox))
|
|
(thing-at-point 'symbol t)
|
|
;; A little smarter than using `symbol-at-point', though in most
|
|
;; cases, xref ends up using `symbol-at-point' anyway.
|
|
(if-let ((ident (xref-backend-identifier-at-point backend)))
|
|
;; REVIEW: `xref-backend-identifier' seems to have some special
|
|
;; uses of text properties. Are we sure we want to remove
|
|
;; them?
|
|
(substring-no-properties ident)))))
|
|
(prompt
|
|
(read-string (if (stringp prompt) prompt "")))))
|
|
|
|
;;;###autoload
|
|
(defun syd-insert-newline-above (count)
|
|
"Insert a blank line below the current line."
|
|
(interactive "p")
|
|
(dotimes (_ count)
|
|
(let ((point-was-at-bol-p (= (current-column) 0)))
|
|
(save-excursion
|
|
(evil-insert-newline-above))
|
|
;; Special case: with `syd-insert-newline-above' is called with point at
|
|
;; BOL, the point unexpectedly fails to "stick" to its original position.
|
|
(when point-was-at-bol-p
|
|
(next-line)))))
|
|
|
|
;;;###autoload
|
|
(defun syd-insert-newline-below (count)
|
|
"Insert a blank line below the current line."
|
|
(interactive "p")
|
|
(dotimes (_ count)
|
|
(save-excursion (evil-insert-newline-below))))
|
|
|
|
;;;###autoload
|
|
(defun syd-render-ansi-escape-codes (beg end)
|
|
(interactive "r")
|
|
(require 'ansi-color)
|
|
(if (region-active-p)
|
|
(ansi-color-apply-on-region beg end)
|
|
(ansi-color-apply-on-region (point-min) (point-max))))
|
|
|
|
(defun syd-evil-paste (before-p arg &optional register yank-handler)
|
|
"Like `evil-paste-after', but a 'C-u' prefix argument will instead act like
|
|
':put' (i.e. the register will be pasted onto a new line)."
|
|
(if (consp arg)
|
|
(evil-ex-put (syd-region-beginning) (syd-region-end)
|
|
;; `evil-ex-put' wants a string, but it is immediately
|
|
;; converted back to a char. }xP
|
|
(and register (string register))
|
|
before-p)
|
|
(funcall (if before-p #'evil-paste-before #'evil-paste-after)
|
|
arg register yank-handler)))
|
|
|
|
;;;###autoload
|
|
(evil-define-command syd-evil-paste-after (arg &optional register yank-handler)
|
|
"See `syd-evil-paste'.'"
|
|
(interactive "P<x><y>")
|
|
(syd-evil-paste nil arg register yank-handler))
|
|
|
|
;;;###autoload
|
|
(evil-define-command syd-evil-paste-before (arg &optional register yank-handler)
|
|
"See `syd-evil-paste'.'"
|
|
(interactive "P<x><y>")
|
|
(syd-evil-paste t arg register yank-handler))
|
|
|
|
;;;###autoload
|
|
(defun syd-pcre-quote (str)
|
|
"Like `reqexp-quote', but for PCREs."
|
|
(let ((special '(?. ?^ ?$ ?* ?+ ?? ?{ ?\\ ?\[ ?\| ?\())
|
|
(quoted nil))
|
|
(mapc (lambda (c)
|
|
(when (memq c special)
|
|
(push ?\\ quoted))
|
|
(push c quoted))
|
|
str)
|
|
(concat (nreverse quoted))))
|
|
|
|
(provide 'syd-text)
|