2014-08-27 14:44:17 +02:00
|
|
|
|
;;; guix-utils.el --- General utility functions
|
|
|
|
|
|
|
|
|
|
;; Copyright © 2014 Alex Kost <alezost@gmail.com>
|
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Guix.
|
|
|
|
|
|
|
|
|
|
;; GNU Guix is free software; you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Guix is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; This file provides auxiliary general functions for guix.el package.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
emacs: Support font-locking.
Avoid breaking highlighting after adding new font-lock keywords.
* emacs/guix-base.el (guix-insert-package-strings): Use 'propertize' instead
of 'guix-get-string'.
* emacs/guix-info.el (guix, guix-action, guix-file, guix-url,
guix-package-location, guix-package-name): New button types.
(guix-info-insert-action-button, guix-info-insert-file-path,
guix-info-insert-url, guix-package-info-insert-location,
guix-package-info-insert-full-names,
guix-package-info-insert-non-unique-text): Adjust for 'guix-insert-button'
and button types.
(guix-package-info-name-button): New face.
(guix-package-info-define-insert-inputs): Use it. Add new button types.
(guix-package-info-insert-full-name): Remove.
* emacs/guix-utils.el (guix-get-string): Replace 'face' with 'font-lock-face'.
(guix-insert-button): Adjust for using button types.
2014-09-27 22:59:08 +02:00
|
|
|
|
(require 'cl-lib)
|
2014-08-27 14:44:17 +02:00
|
|
|
|
|
|
|
|
|
(defvar guix-true-string "Yes")
|
|
|
|
|
(defvar guix-false-string "–")
|
|
|
|
|
(defvar guix-list-separator ", ")
|
|
|
|
|
|
|
|
|
|
(defvar guix-time-format "%F %T"
|
|
|
|
|
"String used to format time values.
|
|
|
|
|
For possible formats, see `format-time-string'.")
|
|
|
|
|
|
|
|
|
|
(defun guix-get-string (val &optional face)
|
|
|
|
|
"Convert VAL into a string and return it.
|
|
|
|
|
|
|
|
|
|
VAL can be an expression of any type.
|
|
|
|
|
If VAL is t/nil, it is replaced with
|
|
|
|
|
`guix-true-string'/`guix-false-string'.
|
|
|
|
|
If VAL is list, its elements are concatenated using
|
|
|
|
|
`guix-list-separator'.
|
|
|
|
|
|
|
|
|
|
If FACE is non-nil, propertize returned string with this FACE."
|
|
|
|
|
(let ((str (cond
|
|
|
|
|
((stringp val) val)
|
|
|
|
|
((null val) guix-false-string)
|
|
|
|
|
((eq t val) guix-true-string)
|
|
|
|
|
((numberp val) (number-to-string val))
|
|
|
|
|
((listp val) (mapconcat #'guix-get-string
|
|
|
|
|
val guix-list-separator))
|
|
|
|
|
(t (prin1-to-string val)))))
|
|
|
|
|
(if (and val face)
|
emacs: Support font-locking.
Avoid breaking highlighting after adding new font-lock keywords.
* emacs/guix-base.el (guix-insert-package-strings): Use 'propertize' instead
of 'guix-get-string'.
* emacs/guix-info.el (guix, guix-action, guix-file, guix-url,
guix-package-location, guix-package-name): New button types.
(guix-info-insert-action-button, guix-info-insert-file-path,
guix-info-insert-url, guix-package-info-insert-location,
guix-package-info-insert-full-names,
guix-package-info-insert-non-unique-text): Adjust for 'guix-insert-button'
and button types.
(guix-package-info-name-button): New face.
(guix-package-info-define-insert-inputs): Use it. Add new button types.
(guix-package-info-insert-full-name): Remove.
* emacs/guix-utils.el (guix-get-string): Replace 'face' with 'font-lock-face'.
(guix-insert-button): Adjust for using button types.
2014-09-27 22:59:08 +02:00
|
|
|
|
(propertize str 'font-lock-face face)
|
2014-08-27 14:44:17 +02:00
|
|
|
|
str)))
|
|
|
|
|
|
|
|
|
|
(defun guix-get-time-string (seconds)
|
|
|
|
|
"Return formatted time string from SECONDS.
|
|
|
|
|
Use `guix-time-format'."
|
|
|
|
|
(format-time-string guix-time-format (seconds-to-time seconds)))
|
|
|
|
|
|
|
|
|
|
(defun guix-get-one-line (str)
|
|
|
|
|
"Return one-line string from a multi-line STR."
|
|
|
|
|
(replace-regexp-in-string "\n" " " str))
|
|
|
|
|
|
|
|
|
|
(defun guix-format-insert (val &optional face format)
|
|
|
|
|
"Convert VAL into a string and insert it at point.
|
|
|
|
|
If FACE is non-nil, propertize VAL with FACE.
|
|
|
|
|
If FORMAT is non-nil, format VAL with FORMAT."
|
|
|
|
|
(let ((str (guix-get-string val face)))
|
|
|
|
|
(insert (if format
|
|
|
|
|
(format format str)
|
|
|
|
|
str))))
|
|
|
|
|
|
|
|
|
|
(defun guix-mapinsert (function sequence separator)
|
|
|
|
|
"Like `mapconcat' but for inserting text.
|
|
|
|
|
Apply FUNCTION to each element of SEQUENCE, and insert SEPARATOR
|
|
|
|
|
at point between each FUNCTION call."
|
|
|
|
|
(when sequence
|
|
|
|
|
(funcall function (car sequence))
|
|
|
|
|
(mapc (lambda (obj)
|
|
|
|
|
(insert separator)
|
|
|
|
|
(funcall function obj))
|
|
|
|
|
(cdr sequence))))
|
|
|
|
|
|
emacs: Support font-locking.
Avoid breaking highlighting after adding new font-lock keywords.
* emacs/guix-base.el (guix-insert-package-strings): Use 'propertize' instead
of 'guix-get-string'.
* emacs/guix-info.el (guix, guix-action, guix-file, guix-url,
guix-package-location, guix-package-name): New button types.
(guix-info-insert-action-button, guix-info-insert-file-path,
guix-info-insert-url, guix-package-info-insert-location,
guix-package-info-insert-full-names,
guix-package-info-insert-non-unique-text): Adjust for 'guix-insert-button'
and button types.
(guix-package-info-name-button): New face.
(guix-package-info-define-insert-inputs): Use it. Add new button types.
(guix-package-info-insert-full-name): Remove.
* emacs/guix-utils.el (guix-get-string): Replace 'face' with 'font-lock-face'.
(guix-insert-button): Adjust for using button types.
2014-09-27 22:59:08 +02:00
|
|
|
|
(defun guix-insert-button (label &optional type &rest properties)
|
|
|
|
|
"Make button of TYPE with LABEL and insert it at point.
|
2014-08-27 14:44:17 +02:00
|
|
|
|
See `insert-text-button' for the meaning of PROPERTIES."
|
|
|
|
|
(if (null label)
|
|
|
|
|
(guix-format-insert nil)
|
emacs: Support font-locking.
Avoid breaking highlighting after adding new font-lock keywords.
* emacs/guix-base.el (guix-insert-package-strings): Use 'propertize' instead
of 'guix-get-string'.
* emacs/guix-info.el (guix, guix-action, guix-file, guix-url,
guix-package-location, guix-package-name): New button types.
(guix-info-insert-action-button, guix-info-insert-file-path,
guix-info-insert-url, guix-package-info-insert-location,
guix-package-info-insert-full-names,
guix-package-info-insert-non-unique-text): Adjust for 'guix-insert-button'
and button types.
(guix-package-info-name-button): New face.
(guix-package-info-define-insert-inputs): Use it. Add new button types.
(guix-package-info-insert-full-name): Remove.
* emacs/guix-utils.el (guix-get-string): Replace 'face' with 'font-lock-face'.
(guix-insert-button): Adjust for using button types.
2014-09-27 22:59:08 +02:00
|
|
|
|
(apply #'insert-text-button label
|
|
|
|
|
:type (or type 'button)
|
2014-08-27 14:44:17 +02:00
|
|
|
|
properties)))
|
|
|
|
|
|
|
|
|
|
(defun guix-split-insert (val &optional face col separator)
|
|
|
|
|
"Convert VAL into a string, split it and insert at point.
|
|
|
|
|
|
|
|
|
|
If FACE is non-nil, propertize returned string with this FACE.
|
|
|
|
|
|
|
|
|
|
If COL is non-nil and result string is a one-line string longer
|
|
|
|
|
than COL, split it into several short lines.
|
|
|
|
|
|
|
|
|
|
Separate inserted lines with SEPARATOR."
|
|
|
|
|
(if (null val)
|
|
|
|
|
(guix-format-insert nil)
|
|
|
|
|
(let ((strings (guix-split-string (guix-get-string val) col)))
|
|
|
|
|
(guix-mapinsert (lambda (str) (guix-format-insert str face))
|
|
|
|
|
strings
|
|
|
|
|
(or separator "")))))
|
|
|
|
|
|
|
|
|
|
(defun guix-split-string (str &optional col)
|
|
|
|
|
"Split string STR by lines and return list of result strings.
|
|
|
|
|
If COL is non-nil and STR is a one-line string longer than COL,
|
|
|
|
|
split it into several short lines."
|
|
|
|
|
(let ((strings (split-string str "\n *")))
|
|
|
|
|
(if (and col
|
|
|
|
|
(null (cdr strings)) ; if not multi-line
|
|
|
|
|
(> (length str) col))
|
|
|
|
|
(split-string (guix-get-filled-string str col) "\n")
|
|
|
|
|
strings)))
|
|
|
|
|
|
|
|
|
|
(defun guix-get-filled-string (str col)
|
|
|
|
|
"Return string by filling STR to column COL."
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(insert str)
|
|
|
|
|
(let ((fill-column col))
|
|
|
|
|
(fill-region (point-min) (point-max)))
|
|
|
|
|
(buffer-string)))
|
|
|
|
|
|
|
|
|
|
(defun guix-completing-read-multiple (prompt table &optional predicate
|
|
|
|
|
require-match initial-input
|
|
|
|
|
hist def inherit-input-method)
|
|
|
|
|
"Same as `completing-read-multiple' but remove duplicates in result."
|
|
|
|
|
(cl-remove-duplicates
|
|
|
|
|
(completing-read-multiple prompt table predicate
|
|
|
|
|
require-match initial-input
|
|
|
|
|
hist def inherit-input-method)
|
|
|
|
|
:test #'string=))
|
|
|
|
|
|
2014-10-16 19:35:47 +02:00
|
|
|
|
(declare-function org-read-date "org" t)
|
|
|
|
|
|
|
|
|
|
(defun guix-read-date (prompt)
|
|
|
|
|
"Prompt for a date or time using `org-read-date'.
|
|
|
|
|
Return time value."
|
|
|
|
|
(require 'org)
|
|
|
|
|
(org-read-date nil t nil prompt))
|
|
|
|
|
|
2014-08-27 14:44:17 +02:00
|
|
|
|
(defun guix-get-key-val (alist &rest keys)
|
|
|
|
|
"Return value from ALIST by KEYS.
|
|
|
|
|
ALIST is alist of alists of alists ... which can be consecutively
|
|
|
|
|
accessed with KEYS."
|
|
|
|
|
(let ((val alist))
|
|
|
|
|
(dolist (key keys val)
|
|
|
|
|
(setq val (cdr (assq key val))))))
|
|
|
|
|
|
|
|
|
|
(provide 'guix-utils)
|
|
|
|
|
|
|
|
|
|
;;; guix-utils.el ends here
|