Klimi's new dotfiles with stow.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

333 рядки
11 KiB

4 роки тому
  1. ;;; helm-misc.el --- Various functions for helm -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2012 ~ 2019 Thierry Volpiatto <thierry.volpiatto@gmail.com>
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ;;; Code:
  14. (require 'cl-lib)
  15. (require 'helm)
  16. (require 'helm-help)
  17. (require 'helm-types)
  18. (declare-function display-time-world-display "time.el")
  19. (defvar display-time-world-list)
  20. (declare-function LaTeX-math-mode "ext:latex.el")
  21. (declare-function jabber-chat-with "ext:jabber.el")
  22. (declare-function jabber-read-account "ext:jabber.el")
  23. (defgroup helm-misc nil
  24. "Various Applications and libraries for Helm."
  25. :group 'helm)
  26. (defcustom helm-time-zone-home-location "Paris"
  27. "The time zone of your home"
  28. :group 'helm-misc
  29. :type 'string)
  30. (defcustom helm-timezone-actions
  31. '(("Set timezone env (TZ)" . (lambda (candidate)
  32. (setenv "TZ" candidate))))
  33. "Actions for helm-timezone."
  34. :group 'helm-misc
  35. :type '(alist :key-type string :value-type function))
  36. (defface helm-time-zone-current
  37. '((t (:foreground "green")))
  38. "Face used to colorize current time in `helm-world-time'."
  39. :group 'helm-misc)
  40. (defface helm-time-zone-home
  41. '((t (:foreground "red")))
  42. "Face used to colorize home time in `helm-world-time'."
  43. :group 'helm-misc)
  44. ;;; Latex completion
  45. ;;
  46. ;; Test
  47. ;; (setq LaTeX-math-menu '("Math"
  48. ;; ["foo" val0 t]
  49. ;; ("bar"
  50. ;; ["baz" val1 t])
  51. ;; ("aze"
  52. ;; ["zer" val2 t])
  53. ;; ("AMS"
  54. ;; ("rec"
  55. ;; ["fer" val3 t])
  56. ;; ("rty"
  57. ;; ["der" val4 t]))
  58. ;; ("ABC"
  59. ;; ("xcv"
  60. ;; ["sdf" val5 t])
  61. ;; ("dfg"
  62. ;; ["fgh" val6 t]))))
  63. ;; (helm-latex-math-candidates)
  64. ;; =>
  65. ;; (("foo" . val0)
  66. ;; ("baz" . val1)
  67. ;; ("zer" . val2)
  68. ;; ("fer" . val3)
  69. ;; ("der" . val4)
  70. ;; ("sdf" . val5)
  71. ;; ("fgh" . val6))
  72. (defvar LaTeX-math-menu)
  73. (defun helm-latex-math-candidates ()
  74. (cl-labels ((helm-latex--math-collect (L)
  75. (cond ((vectorp L)
  76. (list (cons (aref L 0) (aref L 1))))
  77. ((listp L)
  78. (cl-loop for a in L nconc
  79. (helm-latex--math-collect a))))))
  80. (helm-latex--math-collect LaTeX-math-menu)))
  81. (defvar helm-source-latex-math
  82. (helm-build-sync-source "Latex Math Menu"
  83. :init (lambda ()
  84. (with-helm-current-buffer
  85. (LaTeX-math-mode 1)))
  86. :candidate-number-limit 9999
  87. :candidates 'helm-latex-math-candidates
  88. :action (lambda (candidate)
  89. (call-interactively candidate))))
  90. ;;; Jabber Contacts (jabber.el)
  91. (defun helm-jabber-online-contacts ()
  92. "List online Jabber contacts."
  93. (with-no-warnings
  94. (cl-loop for item in (jabber-concat-rosters)
  95. when (get item 'connected)
  96. collect
  97. (if (get item 'name)
  98. (cons (get item 'name) item)
  99. (cons (symbol-name item) item)))))
  100. (defvar helm-source-jabber-contacts
  101. (helm-build-sync-source "Jabber Contacts"
  102. :init (lambda () (require 'jabber))
  103. :candidates (lambda () (mapcar 'car (helm-jabber-online-contacts)))
  104. :action (lambda (x)
  105. (jabber-chat-with
  106. (jabber-read-account)
  107. (symbol-name
  108. (cdr (assoc x (helm-jabber-online-contacts))))))))
  109. ;;; World time
  110. ;;
  111. (defvar zoneinfo-style-world-list)
  112. (defvar legacy-style-world-list)
  113. (defun helm-time-zone-transformer (candidates _source)
  114. (cl-loop for i in candidates
  115. for (z . p) in display-time-world-list
  116. collect
  117. (cons
  118. (cond ((string-match (format-time-string "%H:%M" (current-time)) i)
  119. (propertize i 'face 'helm-time-zone-current))
  120. ((string-match helm-time-zone-home-location i)
  121. (propertize i 'face 'helm-time-zone-home))
  122. (t i))
  123. z)))
  124. (defvar helm-source-time-world
  125. (helm-build-in-buffer-source "Time World List"
  126. :init (lambda ()
  127. (require 'time)
  128. (unless (and display-time-world-list
  129. (listp display-time-world-list))
  130. ;; adapted from `time--display-world-list' from
  131. ;; emacs-27 for compatibility as
  132. ;; `display-time-world-list' is set by default to t.
  133. (setq display-time-world-list
  134. ;; Determine if zoneinfo style timezones are
  135. ;; supported by testing that America/New York and
  136. ;; Europe/London return different timezones.
  137. (let ((nyt (format-time-string "%z" nil "America/New_York"))
  138. (gmt (format-time-string "%z" nil "Europe/London")))
  139. (if (string-equal nyt gmt)
  140. legacy-style-world-list
  141. zoneinfo-style-world-list)))))
  142. :data (lambda ()
  143. (with-temp-buffer
  144. (display-time-world-display display-time-world-list)
  145. (buffer-string)))
  146. :action 'helm-timezone-actions
  147. :filtered-candidate-transformer 'helm-time-zone-transformer))
  148. ;;; Commands
  149. ;;
  150. (defun helm-call-interactively (cmd-or-name)
  151. "Execute CMD-OR-NAME as Emacs command.
  152. It is added to `extended-command-history'.
  153. `helm-current-prefix-arg' is used as the command's prefix argument."
  154. (setq extended-command-history
  155. (cons (helm-stringify cmd-or-name)
  156. (delete (helm-stringify cmd-or-name) extended-command-history)))
  157. (let ((current-prefix-arg helm-current-prefix-arg)
  158. (cmd (helm-symbolify cmd-or-name)))
  159. (if (stringp (symbol-function cmd))
  160. (execute-kbd-macro (symbol-function cmd))
  161. (setq this-command cmd)
  162. (call-interactively cmd))))
  163. ;;; Minibuffer History
  164. ;;
  165. ;;
  166. (defvar helm-minibuffer-history-map
  167. (let ((map (make-sparse-keymap)))
  168. (set-keymap-parent map helm-map)
  169. (define-key map [remap helm-minibuffer-history] 'undefined)
  170. map))
  171. (defcustom helm-minibuffer-history-must-match t
  172. "Allow inserting non matching elements when nil or 'confirm."
  173. :group 'helm-misc
  174. :type '(choice
  175. (const :tag "Must match" t)
  176. (const :tag "Confirm" 'confirm)
  177. (const :tag "Always allow" nil)))
  178. ;;; Helm ratpoison UI
  179. ;;
  180. ;;
  181. (defvar helm-source-ratpoison-commands
  182. (helm-build-in-buffer-source "Ratpoison Commands"
  183. :init 'helm-ratpoison-commands-init
  184. :action (helm-make-actions
  185. "Execute the command" 'helm-ratpoison-commands-execute)
  186. :display-to-real 'helm-ratpoison-commands-display-to-real
  187. :candidate-number-limit 999999))
  188. (defun helm-ratpoison-commands-init ()
  189. (unless (helm-candidate-buffer)
  190. (with-current-buffer (helm-candidate-buffer 'global)
  191. ;; with ratpoison prefix key
  192. (save-excursion
  193. (call-process "ratpoison" nil (current-buffer) nil "-c" "help"))
  194. (while (re-search-forward "^\\([^ ]+\\) \\(.+\\)$" nil t)
  195. (replace-match "<ratpoison> \\1: \\2"))
  196. (goto-char (point-max))
  197. ;; direct binding
  198. (save-excursion
  199. (call-process "ratpoison" nil (current-buffer) nil "-c" "help top"))
  200. (while (re-search-forward "^\\([^ ]+\\) \\(.+\\)$" nil t)
  201. (replace-match "\\1: \\2")))))
  202. (defun helm-ratpoison-commands-display-to-real (display)
  203. (and (string-match ": " display)
  204. (substring display (match-end 0))))
  205. (defun helm-ratpoison-commands-execute (candidate)
  206. (call-process "ratpoison" nil nil nil "-ic" candidate))
  207. ;;; Helm stumpwm UI
  208. ;;
  209. ;;
  210. (defvar helm-source-stumpwm-commands
  211. (helm-build-in-buffer-source "Stumpwm Commands"
  212. :init 'helm-stumpwm-commands-init
  213. :action (helm-make-actions
  214. "Execute the command" 'helm-stumpwm-commands-execute)
  215. :candidate-number-limit 999999))
  216. (defun helm-stumpwm-commands-init ()
  217. (with-current-buffer (helm-candidate-buffer 'global)
  218. (save-excursion
  219. (call-process "stumpish" nil (current-buffer) nil "commands"))
  220. (while (re-search-forward "[ ]*\\([^ ]+\\)[ ]*\n?" nil t)
  221. (replace-match "\n\\1\n"))
  222. (delete-blank-lines)
  223. (sort-lines nil (point-min) (point-max))
  224. (goto-char (point-max))))
  225. (defun helm-stumpwm-commands-execute (candidate)
  226. (call-process "stumpish" nil nil nil candidate))
  227. ;;;###autoload
  228. (defun helm-world-time ()
  229. "Preconfigured `helm' to show world time.
  230. Default action change TZ environment variable locally to emacs."
  231. (interactive)
  232. (helm-other-buffer 'helm-source-time-world "*helm world time*"))
  233. ;;;###autoload
  234. (defun helm-insert-latex-math ()
  235. "Preconfigured helm for latex math symbols completion."
  236. (interactive)
  237. (helm-other-buffer 'helm-source-latex-math "*helm latex*"))
  238. ;;;###autoload
  239. (defun helm-ratpoison-commands ()
  240. "Preconfigured `helm' to execute ratpoison commands."
  241. (interactive)
  242. (helm-other-buffer 'helm-source-ratpoison-commands
  243. "*helm ratpoison commands*"))
  244. ;;;###autoload
  245. (defun helm-stumpwm-commands()
  246. "Preconfigured helm for stumpwm commands."
  247. (interactive)
  248. (helm-other-buffer 'helm-source-stumpwm-commands
  249. "*helm stumpwm commands*"))
  250. ;;;###autoload
  251. (defun helm-minibuffer-history ()
  252. "Preconfigured `helm' for `minibuffer-history'."
  253. (interactive)
  254. (cl-assert (minibuffer-window-active-p (selected-window)) nil
  255. "Error: Attempt to use minibuffer history outside a minibuffer")
  256. (let* ((enable-recursive-minibuffers t)
  257. (query-replace-p (or (eq last-command 'query-replace)
  258. (eq last-command 'query-replace-regexp)))
  259. (elm (helm-comp-read "Next element matching (regexp): "
  260. (cl-loop for i in
  261. (symbol-value minibuffer-history-variable)
  262. unless (string= "" i) collect i into history
  263. finally return
  264. (if (consp (car history))
  265. (mapcar 'prin1-to-string history)
  266. history))
  267. :header-name
  268. (lambda (name)
  269. (format "%s (%s)" name minibuffer-history-variable))
  270. :buffer "*helm minibuffer-history*"
  271. :must-match helm-minibuffer-history-must-match
  272. :multiline t
  273. :keymap helm-minibuffer-history-map
  274. :allow-nest t)))
  275. ;; Fix issue #1667 with emacs-25+ `query-replace-from-to-separator'.
  276. (when (and (boundp 'query-replace-from-to-separator) query-replace-p)
  277. (let ((pos (string-match "\0" elm)))
  278. (and pos
  279. (add-text-properties
  280. pos (1+ pos)
  281. `(display ,query-replace-from-to-separator separator t)
  282. elm))))
  283. (delete-minibuffer-contents)
  284. (insert elm)))
  285. (provide 'helm-misc)
  286. ;; Local Variables:
  287. ;; byte-compile-warnings: (not obsolete)
  288. ;; coding: utf-8
  289. ;; indent-tabs-mode: nil
  290. ;; End:
  291. ;;; helm-misc.el ends here