;;; +util.el --- utility whatevers -*- lexical-binding: t -*-

;;; Commentary:

;; This file is going to be my version of like, subr.el -- lots of
;; random shit that all goes in here.

;;; Code:

(require 'cl-lib)

(defgroup +util nil
  "Utility whatevers."
  :group 'convenience)

;;; STRINGS

(defcustom +string-default-alignment 'left
  "Default alignment."
  :type '(choice (const :tag "Left" 'left)
                 (const :tag "Right" 'right)))

;; stolen from s.el
(defun +string-repeat (n s)
  "Make a string of S repeated N times."
  (declare (pure t)
           (side-effect-free t))
  (let (ss)
    (while (> n 0)
      (setq ss (cons s ss)
            n (1- n)))
    (apply 'concat ss)))

(defun +string-truncate (s length &optional ellipsis alignment)
  "Return S, shortened to LENGTH including ELLIPSIS and aligned to ALIGNMENT.

ELLIPSIS defaults to `truncate-string-ellipsis', or \"...\".

ALIGNMENT defaults to `+string-default-alignment'."
  (declare (pure t)
           (side-effect-free t))
  (let ((ellipsis (or ellipsis truncate-string-ellipsis "..."))
        (alignment (or alignment +string-default-alignment)))
    (if (> (length s) length)
        (format "%s%s"
                (substring s 0 (- length (length ellipsis)))
                ellipsis)
      s)))

(cl-defun +string-align (s len
                           &key
                           (before "") (after "") (fill " ")
                           (ellipsis (or truncate-string-ellipsis "..."))
                           (alignment +string-default-alignment))
  "Print S to fit in LEN characters.
Optional arguments BEFORE and AFTER specify strings to go on
either side of S.

FILL is the string to fill extra space with (default \" \").

ELLIPSIS is the string to show when S is too long to fit (default
`truncate-string-ellipsis' or \"...\"). If nil, don't truncate
the string.

ALIGNMENT can be one of these:
- nil: align to `+string-default-alignment'
- `left': align left
- `right': align right"
  (let* ((s-length (length s))
         (before-length (length before))
         (after-length (length after))
         (max-length (- len (+ before-length after-length)))
         (left-over (max 0 (- max-length s-length)))
         (filler (+string-repeat left-over fill)))
    (format "%s%s%s%s%s"
            before
            (if (eq alignment 'left) "" filler)
            (if ellipsis (+string-truncate s max-length ellipsis alignment) s)
            (if (eq alignment 'right) "" filler)
            after)))

;;; COMMANDS

(defun +dos2unix (buffer)
  "Replace \r\n with \n in BUFFER."
  (interactive "*b")
  (save-excursion
    (with-current-buffer buffer
      (goto-char (point-min))
      (while (search-forward (string ?\C-m ?\C-j) nil t)
        (replace-match (string ?\C-j) nil t)))))

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