guix-location.el 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. ;;; guix-location.el --- Package and service locations -*- lexical-binding: t -*-
  2. ;; Copyright © 2016–2018 Alex Kost <alezost@gmail.com>
  3. ;; This file is part of Emacs-Guix.
  4. ;; Emacs-Guix is free software; you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation, either version 3 of the License, or
  7. ;; (at your option) any later version.
  8. ;;
  9. ;; Emacs-Guix is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with Emacs-Guix. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; This file provides the code to work with locations of Guix packages
  18. ;; and services.
  19. ;;; Code:
  20. (require 'cl-lib)
  21. (require 'bui)
  22. (require 'guix-repl)
  23. (require 'guix-guile)
  24. (defface guix-location
  25. '((t :inherit bui-file-name))
  26. "Face used for locations of packages and services."
  27. :group 'guix-faces)
  28. (define-button-type 'guix-location
  29. :supertype 'bui
  30. 'face 'guix-location
  31. 'help-echo "Find this location"
  32. 'action (lambda (btn)
  33. (guix-find-location (or (button-get btn 'location)
  34. (button-label btn)))))
  35. (defun guix-location-list-specification (location &optional _)
  36. "Return LOCATION button specification for `tabulated-list-entries'."
  37. (bui-get-non-nil location
  38. (list location
  39. :type 'guix-location
  40. 'location location)))
  41. (defun guix-location-file (location)
  42. "Return file name of the LOCATION."
  43. (car (split-string location ":")))
  44. (defun guix-find-location (location &optional directory)
  45. "Go to LOCATION.
  46. LOCATION is a string of the form:
  47. \"FILE:LINE:COLUMN\"
  48. If FILE is relative, it is considered to be relative to
  49. DIRECTORY (if it is specified and exists)."
  50. (cl-multiple-value-bind (file line column)
  51. (split-string location ":")
  52. (let* ((file-name (expand-file-name file (or directory
  53. (guix-directory))))
  54. (file-name (if (file-exists-p file-name)
  55. file-name
  56. (guix-eval-read
  57. (guix-make-guile-expression
  58. 'search-load-path file)))))
  59. (unless file-name ; not found in Guile %load-path
  60. (error "Location file not found: %s" file))
  61. (find-file file-name))
  62. (when (and line column)
  63. (let ((line (string-to-number line))
  64. (column (string-to-number column)))
  65. (goto-char (point-min))
  66. (forward-line (- line 1))
  67. (move-to-column column)
  68. (recenter 1)))))
  69. (provide 'guix-location)
  70. ;;; guix-location.el ends here