package updates / upgrades
This commit is contained in:
parent
d68d39cf24
commit
e7e7c4eafe
|
@ -1,12 +1,14 @@
|
||||||
;;; all-the-icons-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; all-the-icons-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "all-the-icons" "all-the-icons.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from all-the-icons.el
|
;;; Generated autoloads from all-the-icons.el
|
||||||
|
|
||||||
(autoload 'all-the-icons-icon-for-dir "all-the-icons" "\
|
(autoload 'all-the-icons-icon-for-dir "all-the-icons" "\
|
||||||
|
@ -17,24 +19,21 @@ inserting functions.
|
||||||
|
|
||||||
Note: You want chevron, please use `all-the-icons-icon-for-dir-with-chevron'.
|
Note: You want chevron, please use `all-the-icons-icon-for-dir-with-chevron'.
|
||||||
|
|
||||||
\(fn DIR &rest ARG-OVERRIDES)" nil nil)
|
(fn DIR &rest ARG-OVERRIDES)")
|
||||||
|
|
||||||
(autoload 'all-the-icons-icon-for-file "all-the-icons" "\
|
(autoload 'all-the-icons-icon-for-file "all-the-icons" "\
|
||||||
Get the formatted icon for FILE.
|
Get the formatted icon for FILE.
|
||||||
ARG-OVERRIDES should be a plist containining `:height',
|
ARG-OVERRIDES should be a plist containining `:height',
|
||||||
`:v-adjust' or `:face' properties like in the normal icon
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
inserting functions.
|
inserting functions.
|
||||||
|
|
||||||
\(fn FILE &rest ARG-OVERRIDES)" nil nil)
|
(fn FILE &rest ARG-OVERRIDES)")
|
||||||
|
|
||||||
(autoload 'all-the-icons-icon-for-mode "all-the-icons" "\
|
(autoload 'all-the-icons-icon-for-mode "all-the-icons" "\
|
||||||
Get the formatted icon for MODE.
|
Get the formatted icon for MODE.
|
||||||
ARG-OVERRIDES should be a plist containining `:height',
|
ARG-OVERRIDES should be a plist containining `:height',
|
||||||
`:v-adjust' or `:face' properties like in the normal icon
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
inserting functions.
|
inserting functions.
|
||||||
|
|
||||||
\(fn MODE &rest ARG-OVERRIDES)" nil nil)
|
(fn MODE &rest ARG-OVERRIDES)")
|
||||||
|
|
||||||
(autoload 'all-the-icons-icon-for-url "all-the-icons" "\
|
(autoload 'all-the-icons-icon-for-url "all-the-icons" "\
|
||||||
Get the formatted icon for URL.
|
Get the formatted icon for URL.
|
||||||
If an icon for URL isn't found in `all-the-icons-url-alist', a globe is used.
|
If an icon for URL isn't found in `all-the-icons-url-alist', a globe is used.
|
||||||
|
@ -42,34 +41,30 @@ ARG-OVERRIDES should be a plist containining `:height',
|
||||||
`:v-adjust' or `:face' properties like in the normal icon
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
inserting functions.
|
inserting functions.
|
||||||
|
|
||||||
\(fn URL &rest ARG-OVERRIDES)" nil nil)
|
(fn URL &rest ARG-OVERRIDES)")
|
||||||
|
|
||||||
(autoload 'all-the-icons-install-fonts "all-the-icons" "\
|
(autoload 'all-the-icons-install-fonts "all-the-icons" "\
|
||||||
Helper function to download and install the latests fonts based on OS.
|
Helper function to download and install the latests fonts based on OS.
|
||||||
When PFX is non-nil, ignore the prompt and just install
|
When PFX is non-nil, ignore the prompt and just install
|
||||||
|
|
||||||
\(fn &optional PFX)" t nil)
|
(fn &optional PFX)" t)
|
||||||
|
|
||||||
(autoload 'all-the-icons-insert "all-the-icons" "\
|
(autoload 'all-the-icons-insert "all-the-icons" "\
|
||||||
Interactive icon insertion function.
|
Interactive icon insertion function.
|
||||||
When Prefix ARG is non-nil, insert the propertized icon.
|
When Prefix ARG is non-nil, insert the propertized icon.
|
||||||
When FAMILY is non-nil, limit the candidates to the icon set matching it.
|
When FAMILY is non-nil, limit the candidates to the icon set matching it.
|
||||||
|
|
||||||
\(fn &optional ARG FAMILY)" t nil)
|
(fn &optional ARG FAMILY)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "all-the-icons" '("all-the-icons-"))
|
(register-definition-prefixes "all-the-icons" '("all-the-icons-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil nil ("all-the-icons-faces.el" "all-the-icons-pkg.el")
|
;;; End of scraped data
|
||||||
;;;;;; (0 0 0 0))
|
|
||||||
|
(provide 'all-the-icons-autoloads)
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; all-the-icons-autoloads.el ends here
|
;;; all-the-icons-autoloads.el ends here
|
|
@ -1,6 +1,6 @@
|
||||||
(define-package "all-the-icons" "20230615.2016" "A library for inserting Developer icons"
|
(define-package "all-the-icons" "20240108.559" "A library for inserting Developer icons"
|
||||||
'((emacs "24.3"))
|
'((emacs "24.3"))
|
||||||
:commit "f491f39c21336d354e85bdb4cca281e0a0c2f880" :authors
|
:commit "ee414384938ccf2ce93c77d717b85dc5538a257d" :authors
|
||||||
'(("Dominic Charlesworth" . "dgc336@gmail.com"))
|
'(("Dominic Charlesworth" . "dgc336@gmail.com"))
|
||||||
:maintainers
|
:maintainers
|
||||||
'(("Dominic Charlesworth" . "dgc336@gmail.com"))
|
'(("Dominic Charlesworth" . "dgc336@gmail.com"))
|
|
@ -210,6 +210,8 @@
|
||||||
("rd" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
("rd" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
||||||
("rdx" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
("rdx" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
||||||
("rsx" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
("rsx" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
||||||
|
("beancount" all-the-icons-faicon "credit-card" :face all-the-icons-lgreen)
|
||||||
|
("ledger" all-the-icons-faicon "credit-card" :face all-the-icons-lgreen)
|
||||||
("svelte" all-the-icons-fileicon "svelte" :v-adjust 0.0 :face all-the-icons-red)
|
("svelte" all-the-icons-fileicon "svelte" :v-adjust 0.0 :face all-the-icons-red)
|
||||||
("gql" all-the-icons-fileicon "graphql" :face all-the-icons-dpink)
|
("gql" all-the-icons-fileicon "graphql" :face all-the-icons-dpink)
|
||||||
("graphql" all-the-icons-fileicon "graphql" :face all-the-icons-dpink)
|
("graphql" all-the-icons-fileicon "graphql" :face all-the-icons-dpink)
|
||||||
|
@ -584,6 +586,7 @@ for performance sake.")
|
||||||
(erc-mode all-the-icons-faicon "commenting-o" :height 1.0 :v-adjust 0.0)
|
(erc-mode all-the-icons-faicon "commenting-o" :height 1.0 :v-adjust 0.0)
|
||||||
(inferior-emacs-lisp-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.1 :face all-the-icons-lblue)
|
(inferior-emacs-lisp-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.1 :face all-the-icons-lblue)
|
||||||
(dired-mode all-the-icons-octicon "file-directory" :v-adjust 0.0)
|
(dired-mode all-the-icons-octicon "file-directory" :v-adjust 0.0)
|
||||||
|
(wdired-mode all-the-icons-octicon "file-directory" :v-adjust 0.0 :face all-the-icons-dcyan)
|
||||||
(lisp-interaction-mode all-the-icons-fileicon "lisp" :v-adjust -0.1 :face all-the-icons-orange)
|
(lisp-interaction-mode all-the-icons-fileicon "lisp" :v-adjust -0.1 :face all-the-icons-orange)
|
||||||
(sly-mrepl-mode all-the-icons-fileicon "clisp" :v-adjust -0.1 :face all-the-icons-orange)
|
(sly-mrepl-mode all-the-icons-fileicon "clisp" :v-adjust -0.1 :face all-the-icons-orange)
|
||||||
(slime-repl-mode all-the-icons-fileicon "clisp" :v-adjust -0.1 :face all-the-icons-orange)
|
(slime-repl-mode all-the-icons-fileicon "clisp" :v-adjust -0.1 :face all-the-icons-orange)
|
||||||
|
@ -593,6 +596,7 @@ for performance sake.")
|
||||||
(typescript-tsx-mode all-the-icons-fileicon "tsx" :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
(typescript-tsx-mode all-the-icons-fileicon "tsx" :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
||||||
(tsx-ts-mode all-the-icons-fileicon "tsx" :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
(tsx-ts-mode all-the-icons-fileicon "tsx" :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
||||||
(js-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
(js-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
|
(js-ts-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
(js-jsx-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
(js-jsx-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
(js2-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
(js2-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
(js3-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
(js3-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
|
@ -644,6 +648,7 @@ for performance sake.")
|
||||||
(rspec-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
(rspec-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
(rake-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
(rake-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
(sh-mode all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
(sh-mode all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
||||||
|
(bash-ts-mode all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
||||||
(shell-mode all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
(shell-mode all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
||||||
(fish-mode all-the-icons-alltheicon "terminal" :face all-the-icons-lpink)
|
(fish-mode all-the-icons-alltheicon "terminal" :face all-the-icons-lpink)
|
||||||
(nginx-mode all-the-icons-fileicon "nginx" :height 0.9 :face all-the-icons-dgreen)
|
(nginx-mode all-the-icons-fileicon "nginx" :height 0.9 :face all-the-icons-dgreen)
|
||||||
|
@ -669,6 +674,7 @@ for performance sake.")
|
||||||
(java-ts-mode all-the-icons-alltheicon "java" :height 1.0 :face all-the-icons-purple)
|
(java-ts-mode all-the-icons-alltheicon "java" :height 1.0 :face all-the-icons-purple)
|
||||||
(go-mode all-the-icons-fileicon "go" :height 1.0 :face all-the-icons-blue)
|
(go-mode all-the-icons-fileicon "go" :height 1.0 :face all-the-icons-blue)
|
||||||
(go-ts-mode all-the-icons-fileicon "go" :height 1.0 :face all-the-icons-blue)
|
(go-ts-mode all-the-icons-fileicon "go" :height 1.0 :face all-the-icons-blue)
|
||||||
|
(go-mod-ts-mode all-the-icons-fileicon "config-go" :height 1.0 :face all-the-icons-blue-alt)
|
||||||
(go-dot-mod-mode all-the-icons-fileicon "config-go" :height 1.0 :face all-the-icons-blue-alt)
|
(go-dot-mod-mode all-the-icons-fileicon "config-go" :height 1.0 :face all-the-icons-blue-alt)
|
||||||
(go-dot-work-mode all-the-icons-fileicon "config-go" :height 1.0 :face all-the-icons-blue-alt)
|
(go-dot-work-mode all-the-icons-fileicon "config-go" :height 1.0 :face all-the-icons-blue-alt)
|
||||||
(graphql-mode all-the-icons-fileicon "graphql" :face all-the-icons-dpink)
|
(graphql-mode all-the-icons-fileicon "graphql" :face all-the-icons-dpink)
|
||||||
|
@ -752,6 +758,9 @@ for performance sake.")
|
||||||
(hy-mode all-the-icons-fileicon "hy" :face all-the-icons-blue)
|
(hy-mode all-the-icons-fileicon "hy" :face all-the-icons-blue)
|
||||||
(glsl-mode all-the-icons-fileicon "vertex-shader" :face all-the-icons-green)
|
(glsl-mode all-the-icons-fileicon "vertex-shader" :face all-the-icons-green)
|
||||||
(zig-mode all-the-icons-fileicon "zig" :face all-the-icons-orange)
|
(zig-mode all-the-icons-fileicon "zig" :face all-the-icons-orange)
|
||||||
|
(exwm-mode all-the-icons-octicon "browser" :v-adjust 0.2 :face all-the-icons-purple)
|
||||||
|
(beancount-mode all-the-icons-faicon "credit-card" :face all-the-icons-lgreen)
|
||||||
|
(ledger-mode all-the-icons-faicon "credit-card" :face all-the-icons-lgreen)
|
||||||
(odin-mode all-the-icons-fileicon "odin" :height 1.1 :face all-the-icons-lblue)
|
(odin-mode all-the-icons-fileicon "odin" :height 1.1 :face all-the-icons-lblue)
|
||||||
(pdf-view-mode all-the-icons-octicon "file-pdf" :v-adjust 0.0 :face all-the-icons-dred)
|
(pdf-view-mode all-the-icons-octicon "file-pdf" :v-adjust 0.0 :face all-the-icons-dred)
|
||||||
(spacemacs-buffer-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.1 :face all-the-icons-purple)
|
(spacemacs-buffer-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.1 :face all-the-icons-purple)
|
||||||
|
@ -767,7 +776,8 @@ for performance sake.")
|
||||||
(magik-session-mode all-the-icons-alltheicon "terminal" :face all-the-icons-blue)
|
(magik-session-mode all-the-icons-alltheicon "terminal" :face all-the-icons-blue)
|
||||||
(magik-cb-mode all-the-icons-faicon "book" :face all-the-icons-blue)
|
(magik-cb-mode all-the-icons-faicon "book" :face all-the-icons-blue)
|
||||||
(meson-mode all-the-icons-fileicon "meson" :face all-the-icons-purple)
|
(meson-mode all-the-icons-fileicon "meson" :face all-the-icons-purple)
|
||||||
(man-common all-the-icons-fileicon "man-page" :face all-the-icons-blue)))
|
(man-common all-the-icons-fileicon "man-page" :face all-the-icons-blue)
|
||||||
|
(ess-r-mode all-the-icons-fileicon "R" :face all-the-icons-lblue)))
|
||||||
|
|
||||||
(defvar all-the-icons-url-alist
|
(defvar all-the-icons-url-alist
|
||||||
'(
|
'(
|
||||||
|
@ -880,8 +890,8 @@ for performance sake.")
|
||||||
(eq major-mode auto-mode)))
|
(eq major-mode auto-mode)))
|
||||||
|
|
||||||
(defun all-the-icons-match-to-alist (file alist)
|
(defun all-the-icons-match-to-alist (file alist)
|
||||||
"Match FILE against an entry in ALIST using `string-match'."
|
"Match FILE against an entry in ALIST using `string-match-p'."
|
||||||
(cdr (cl-find-if (lambda (it) (string-match (car it) file)) alist)))
|
(cdr (cl-find-if (lambda (it) (string-match-p (car it) file)) alist)))
|
||||||
|
|
||||||
(defun all-the-icons-dir-is-submodule (dir)
|
(defun all-the-icons-dir-is-submodule (dir)
|
||||||
"Checker whether or not DIR is a git submodule."
|
"Checker whether or not DIR is a git submodule."
|
||||||
|
@ -1042,7 +1052,7 @@ inserting functions."
|
||||||
(defun all-the-icons-icon-family-for-file (file)
|
(defun all-the-icons-icon-family-for-file (file)
|
||||||
"Get the icons font family for FILE."
|
"Get the icons font family for FILE."
|
||||||
(let* ((ext (file-name-extension file))
|
(let* ((ext (file-name-extension file))
|
||||||
(icon (or (all-the-icons-match-to-alist file all-the-icons-regexp-icon-alist)
|
(icon (or (all-the-icons-match-to-alist file all-the-icons-regexp-icon-alist)
|
||||||
(and ext
|
(and ext
|
||||||
(cdr (assoc (downcase ext)
|
(cdr (assoc (downcase ext)
|
||||||
all-the-icons-extension-icon-alist)))
|
all-the-icons-extension-icon-alist)))
|
|
@ -312,7 +312,7 @@
|
||||||
( "objective-j" . "\xe99e" )
|
( "objective-j" . "\xe99e" )
|
||||||
( "ocaml" . "\xe91a" )
|
( "ocaml" . "\xe91a" )
|
||||||
( "octave" . "\xea33" )
|
( "octave" . "\xea33" )
|
||||||
( "odin" . "\eb36" )
|
( "odin" . "\xeb36" )
|
||||||
( "onenote" . "\xe9eb" )
|
( "onenote" . "\xe9eb" )
|
||||||
( "ooc" . "\xe9cb" )
|
( "ooc" . "\xe9cb" )
|
||||||
( "opa" . "\x2601" )
|
( "opa" . "\x2601" )
|
|
@ -1,2 +0,0 @@
|
||||||
;;; Generated package description from all-the-icons-dired.el -*- no-byte-compile: t -*-
|
|
||||||
(define-package "all-the-icons-dired" "20220929.1135" "Shows icons for each file in dired mode" '((emacs "26.1") (all-the-icons "2.2.0")) :commit "bcaed35bb3ad7fc46007f16e0d670beb82bb613e" :authors '(("jtbm37")) :maintainer '("Jimmy Yuen Ho Wong" . "wyuenho@gmail.com") :keywords '("files" "icons" "dired") :url "https://github.com/wyuenho/all-the-icons-dired")
|
|
|
@ -1,13 +1,14 @@
|
||||||
;;; all-the-icons-dired-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; all-the-icons-dired-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "all-the-icons-dired" "all-the-icons-dired.el"
|
|
||||||
;;;;;; (0 0 0 0))
|
|
||||||
;;; Generated autoloads from all-the-icons-dired.el
|
;;; Generated autoloads from all-the-icons-dired.el
|
||||||
|
|
||||||
(autoload 'all-the-icons-dired-mode "all-the-icons-dired" "\
|
(autoload 'all-the-icons-dired-mode "all-the-icons-dired" "\
|
||||||
|
@ -28,16 +29,19 @@ evaluate `all-the-icons-dired-mode'.
|
||||||
The mode's hook is called both when the mode is enabled and when
|
The mode's hook is called both when the mode is enabled and when
|
||||||
it is disabled.
|
it is disabled.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "all-the-icons-dired" '("all-the-icons-dired-"))
|
(register-definition-prefixes "all-the-icons-dired" '("all-the-icons-dired-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'all-the-icons-dired-autoloads)
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; all-the-icons-dired-autoloads.el ends here
|
;;; all-the-icons-dired-autoloads.el ends here
|
|
@ -0,0 +1,15 @@
|
||||||
|
(define-package "all-the-icons-dired" "20231207.1324" "Shows icons for each file in dired mode"
|
||||||
|
'((emacs "26.1")
|
||||||
|
(all-the-icons "2.2.0"))
|
||||||
|
:commit "e157f0668f22ed586aebe0a2c0186ab07702986c" :authors
|
||||||
|
'(("jtbm37"))
|
||||||
|
:maintainers
|
||||||
|
'(("Jimmy Yuen Ho Wong" . "wyuenho@gmail.com"))
|
||||||
|
:maintainer
|
||||||
|
'("Jimmy Yuen Ho Wong" . "wyuenho@gmail.com")
|
||||||
|
:keywords
|
||||||
|
'("files" "icons" "dired")
|
||||||
|
:url "https://github.com/wyuenho/all-the-icons-dired")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
|
@ -6,8 +6,6 @@
|
||||||
;; Author: jtbm37
|
;; Author: jtbm37
|
||||||
;; Maintainer: Jimmy Yuen Ho Wong <wyuenho@gmail.com>
|
;; Maintainer: Jimmy Yuen Ho Wong <wyuenho@gmail.com>
|
||||||
;; Version: 2.0
|
;; Version: 2.0
|
||||||
;; Package-Version: 20220929.1135
|
|
||||||
;; Package-Commit: bcaed35bb3ad7fc46007f16e0d670beb82bb613e
|
|
||||||
;; Keywords: files icons dired
|
;; Keywords: files icons dired
|
||||||
;; Package-Requires: ((emacs "26.1") (all-the-icons "2.2.0"))
|
;; Package-Requires: ((emacs "26.1") (all-the-icons "2.2.0"))
|
||||||
;; URL: https://github.com/wyuenho/all-the-icons-dired
|
;; URL: https://github.com/wyuenho/all-the-icons-dired
|
||||||
|
@ -43,13 +41,18 @@
|
||||||
(require 'jit-lock)
|
(require 'jit-lock)
|
||||||
(require 'font-core)
|
(require 'font-core)
|
||||||
(require 'font-lock)
|
(require 'font-lock)
|
||||||
|
(require 'map)
|
||||||
|
|
||||||
(defface all-the-icons-dired-dir-face
|
(defface all-the-icons-dired-dir-face
|
||||||
'((((background dark)) :foreground "white")
|
'((t (:inherit dired-directory)))
|
||||||
(((background light)) :foreground "black"))
|
|
||||||
"Face for the directory icon."
|
"Face for the directory icon."
|
||||||
:group 'all-the-icons-faces)
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
(defcustom all-the-icons-dired-lighter " all-the-icons-dired-mode"
|
||||||
|
"Lighter of all-the-icons-dired-mode"
|
||||||
|
:group 'all-the-icons
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
(defcustom all-the-icons-dired-v-adjust 0.01
|
(defcustom all-the-icons-dired-v-adjust 0.01
|
||||||
"The default vertical adjustment of the icon in the Dired buffer."
|
"The default vertical adjustment of the icon in the Dired buffer."
|
||||||
:group 'all-the-icons
|
:group 'all-the-icons
|
||||||
|
@ -78,14 +81,15 @@
|
||||||
"Propertize POS with icon."
|
"Propertize POS with icon."
|
||||||
(let* ((file (dired-get-filename 'relative 'noerror))
|
(let* ((file (dired-get-filename 'relative 'noerror))
|
||||||
(icon (all-the-icons-dired--icon file))
|
(icon (all-the-icons-dired--icon file))
|
||||||
(image (get-text-property 0 'display icon)))
|
(image (copy-sequence (get-text-property 0 'display icon)))
|
||||||
|
(props (map-delete (copy-sequence (text-properties-at 0 icon)) 'display)))
|
||||||
(if (or (not (eq (car image) 'image)) (member file '("." "..")))
|
(if (or (not (eq (car image) 'image)) (member file '("." "..")))
|
||||||
(put-text-property (1- pos) pos 'display
|
(put-text-property (1- pos) pos 'display
|
||||||
(if (member file '("." ".."))
|
(if (member file '("." ".."))
|
||||||
" "
|
" "
|
||||||
(concat " " icon " ")))
|
(concat " " icon " ")))
|
||||||
(setf (image-property image :margin) (cons (/ (window-text-width nil t) (window-text-width)) 0))
|
(setf (image-property image :margin) (cons (/ (window-text-width nil t) (window-text-width)) 0))
|
||||||
(put-text-property (1- pos) pos 'display image))))
|
(add-text-properties (1- pos) pos (append props `(display ,image) )))))
|
||||||
|
|
||||||
(defun all-the-icons-dired--fontify-region (start end &optional loudly)
|
(defun all-the-icons-dired--fontify-region (start end &optional loudly)
|
||||||
"Add icons using text properties from START to END.
|
"Add icons using text properties from START to END.
|
||||||
|
@ -128,7 +132,7 @@ START, END and the optional argument LOUDLY is passed to
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-minor-mode all-the-icons-dired-mode
|
(define-minor-mode all-the-icons-dired-mode
|
||||||
"Display all-the-icons icon for each file in a Dired buffer."
|
"Display all-the-icons icon for each file in a Dired buffer."
|
||||||
:lighter " all-the-icons-dired-mode"
|
:lighter all-the-icons-dired-lighter
|
||||||
(when (derived-mode-p 'dired-mode)
|
(when (derived-mode-p 'dired-mode)
|
||||||
(if all-the-icons-dired-mode
|
(if all-the-icons-dired-mode
|
||||||
(all-the-icons-dired--setup)
|
(all-the-icons-dired--setup)
|
File diff suppressed because it is too large
Load diff
|
@ -1,12 +1,14 @@
|
||||||
;;; async-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; async-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "async" "async.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from async.el
|
;;; Generated autoloads from async.el
|
||||||
|
|
||||||
(autoload 'async-start-process "async" "\
|
(autoload 'async-start-process "async" "\
|
||||||
|
@ -17,8 +19,7 @@ object will return the process object when the program is
|
||||||
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
|
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
|
||||||
working directory.
|
working directory.
|
||||||
|
|
||||||
\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil)
|
(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)")
|
||||||
|
|
||||||
(autoload 'async-start "async" "\
|
(autoload 'async-start "async" "\
|
||||||
Execute START-FUNC (often a lambda) in a subordinate Emacs process.
|
Execute START-FUNC (often a lambda) in a subordinate Emacs process.
|
||||||
When done, the return value is passed to FINISH-FUNC. Example:
|
When done, the return value is passed to FINISH-FUNC. Example:
|
||||||
|
@ -88,22 +89,17 @@ passed to FINISH-FUNC). Call `async-get' on such a future always
|
||||||
returns nil. It can still be useful, however, as an argument to
|
returns nil. It can still be useful, however, as an argument to
|
||||||
`async-ready' or `async-wait'.
|
`async-ready' or `async-wait'.
|
||||||
|
|
||||||
\(fn START-FUNC &optional FINISH-FUNC)" nil nil)
|
(fn START-FUNC &optional FINISH-FUNC)")
|
||||||
|
|
||||||
(register-definition-prefixes "async" '("async-"))
|
(register-definition-prefixes "async" '("async-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (0 0 0
|
|
||||||
;;;;;; 0))
|
|
||||||
;;; Generated autoloads from async-bytecomp.el
|
;;; Generated autoloads from async-bytecomp.el
|
||||||
|
|
||||||
(autoload 'async-byte-recompile-directory "async-bytecomp" "\
|
(autoload 'async-byte-recompile-directory "async-bytecomp" "\
|
||||||
Compile all *.el files in DIRECTORY asynchronously.
|
Compile all *.el files in DIRECTORY asynchronously.
|
||||||
All *.elc files are systematically deleted before proceeding.
|
All *.elc files are systematically deleted before proceeding.
|
||||||
|
|
||||||
\(fn DIRECTORY &optional QUIET)" nil nil)
|
(fn DIRECTORY &optional QUIET)")
|
||||||
|
|
||||||
(defvar async-bytecomp-package-mode nil "\
|
(defvar async-bytecomp-package-mode nil "\
|
||||||
Non-nil if Async-Bytecomp-Package mode is enabled.
|
Non-nil if Async-Bytecomp-Package mode is enabled.
|
||||||
See the `async-bytecomp-package-mode' command
|
See the `async-bytecomp-package-mode' command
|
||||||
|
@ -111,15 +107,14 @@ for a description of this minor mode.
|
||||||
Setting this variable directly does not take effect;
|
Setting this variable directly does not take effect;
|
||||||
either customize it (see the info node `Easy Customization')
|
either customize it (see the info node `Easy Customization')
|
||||||
or call the function `async-bytecomp-package-mode'.")
|
or call the function `async-bytecomp-package-mode'.")
|
||||||
|
|
||||||
(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil)
|
(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil)
|
||||||
|
|
||||||
(autoload 'async-bytecomp-package-mode "async-bytecomp" "\
|
(autoload 'async-bytecomp-package-mode "async-bytecomp" "\
|
||||||
Byte compile asynchronously packages installed with package.el.
|
Byte compile asynchronously packages installed with package.el.
|
||||||
|
|
||||||
Async compilation of packages can be controlled by
|
Async compilation of packages can be controlled by
|
||||||
`async-bytecomp-allowed-packages'.
|
`async-bytecomp-allowed-packages'.
|
||||||
|
|
||||||
This is a minor mode. If called interactively, toggle the
|
This is a global minor mode. If called interactively, toggle the
|
||||||
`Async-Bytecomp-Package mode' mode. If the prefix argument is
|
`Async-Bytecomp-Package mode' mode. If the prefix argument is
|
||||||
positive, enable the mode, and if it is zero or negative, disable
|
positive, enable the mode, and if it is zero or negative, disable
|
||||||
the mode.
|
the mode.
|
||||||
|
@ -134,20 +129,16 @@ evaluate `(default-value \\='async-bytecomp-package-mode)'.
|
||||||
The mode's hook is called both when the mode is enabled and when
|
The mode's hook is called both when the mode is enabled and when
|
||||||
it is disabled.
|
it is disabled.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(autoload 'async-byte-compile-file "async-bytecomp" "\
|
(autoload 'async-byte-compile-file "async-bytecomp" "\
|
||||||
Byte compile Lisp code FILE asynchronously.
|
Byte compile Lisp code FILE asynchronously.
|
||||||
|
|
||||||
Same as `byte-compile-file' but asynchronous.
|
Same as `byte-compile-file' but asynchronous.
|
||||||
|
|
||||||
\(fn FILE)" t nil)
|
(fn FILE)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "async-bytecomp" '("async-"))
|
(register-definition-prefixes "async-bytecomp" '("async-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil "dired-async" "dired-async.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from dired-async.el
|
;;; Generated autoloads from dired-async.el
|
||||||
|
|
||||||
(defvar dired-async-mode nil "\
|
(defvar dired-async-mode nil "\
|
||||||
|
@ -157,13 +148,11 @@ for a description of this minor mode.
|
||||||
Setting this variable directly does not take effect;
|
Setting this variable directly does not take effect;
|
||||||
either customize it (see the info node `Easy Customization')
|
either customize it (see the info node `Easy Customization')
|
||||||
or call the function `dired-async-mode'.")
|
or call the function `dired-async-mode'.")
|
||||||
|
|
||||||
(custom-autoload 'dired-async-mode "dired-async" nil)
|
(custom-autoload 'dired-async-mode "dired-async" nil)
|
||||||
|
|
||||||
(autoload 'dired-async-mode "dired-async" "\
|
(autoload 'dired-async-mode "dired-async" "\
|
||||||
Do dired actions asynchronously.
|
Do dired actions asynchronously.
|
||||||
|
|
||||||
This is a minor mode. If called interactively, toggle the
|
This is a global minor mode. If called interactively, toggle the
|
||||||
`Dired-Async mode' mode. If the prefix argument is positive,
|
`Dired-Async mode' mode. If the prefix argument is positive,
|
||||||
enable the mode, and if it is zero or negative, disable the mode.
|
enable the mode, and if it is zero or negative, disable the mode.
|
||||||
|
|
||||||
|
@ -177,48 +166,40 @@ evaluate `(default-value \\='dired-async-mode)'.
|
||||||
The mode's hook is called both when the mode is enabled and when
|
The mode's hook is called both when the mode is enabled and when
|
||||||
it is disabled.
|
it is disabled.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(autoload 'dired-async-do-copy "dired-async" "\
|
(autoload 'dired-async-do-copy "dired-async" "\
|
||||||
Run ‘dired-do-copy’ asynchronously.
|
Run ‘dired-do-copy’ asynchronously.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(autoload 'dired-async-do-symlink "dired-async" "\
|
(autoload 'dired-async-do-symlink "dired-async" "\
|
||||||
Run ‘dired-do-symlink’ asynchronously.
|
Run ‘dired-do-symlink’ asynchronously.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(autoload 'dired-async-do-hardlink "dired-async" "\
|
(autoload 'dired-async-do-hardlink "dired-async" "\
|
||||||
Run ‘dired-do-hardlink’ asynchronously.
|
Run ‘dired-do-hardlink’ asynchronously.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(autoload 'dired-async-do-rename "dired-async" "\
|
(autoload 'dired-async-do-rename "dired-async" "\
|
||||||
Run ‘dired-do-rename’ asynchronously.
|
Run ‘dired-do-rename’ asynchronously.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "dired-async" '("dired-async-"))
|
(register-definition-prefixes "dired-async" '("dired-async-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil "smtpmail-async" "smtpmail-async.el" (0 0 0
|
|
||||||
;;;;;; 0))
|
|
||||||
;;; Generated autoloads from smtpmail-async.el
|
;;; Generated autoloads from smtpmail-async.el
|
||||||
|
|
||||||
(register-definition-prefixes "smtpmail-async" '("async-smtpmail-"))
|
(register-definition-prefixes "smtpmail-async" '("async-smtpmail-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil nil ("async-pkg.el") (0 0 0 0))
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'async-autoloads)
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; async-autoloads.el ends here
|
;;; async-autoloads.el ends here
|
|
@ -32,7 +32,7 @@
|
||||||
;; the new files in the current environment with the old files loaded, creating
|
;; the new files in the current environment with the old files loaded, creating
|
||||||
;; errors in most packages after upgrades.
|
;; errors in most packages after upgrades.
|
||||||
;;
|
;;
|
||||||
;; NB: This package is advicing the function `package--compile'.
|
;; NB: This package is advising the function `package--compile'.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(define-package "async" "20230528.622" "Asynchronous processing in Emacs"
|
(define-package "async" "20240312.1716" "Asynchronous processing in Emacs"
|
||||||
'((emacs "24.4"))
|
'((emacs "24.4"))
|
||||||
:commit "3ae74c0a4ba223ba373e0cb636c385e08d8838be" :authors
|
:commit "a368df08d34ae0c0a36fc3e90b1ecda252915257" :authors
|
||||||
'(("John Wiegley" . "jwiegley@gmail.com"))
|
'(("John Wiegley" . "jwiegley@gmail.com"))
|
||||||
:maintainers
|
:maintainers
|
||||||
'(("Thierry Volpiatto" . "thievol@posteo.net"))
|
'(("Thierry Volpiatto" . "thievol@posteo.net"))
|
|
@ -6,7 +6,7 @@
|
||||||
;; Maintainer: Thierry Volpiatto <thievol@posteo.net>
|
;; Maintainer: Thierry Volpiatto <thievol@posteo.net>
|
||||||
|
|
||||||
;; Created: 18 Jun 2012
|
;; Created: 18 Jun 2012
|
||||||
;; Version: 1.9.7
|
;; Version: 1.9.8
|
||||||
;; Package-Requires: ((emacs "24.4"))
|
;; Package-Requires: ((emacs "24.4"))
|
||||||
|
|
||||||
;; Keywords: async
|
;; Keywords: async
|
||||||
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
(eval-when-compile (require 'cl-lib))
|
(eval-when-compile (require 'cl-lib))
|
||||||
|
|
||||||
|
(defvar tramp-password-prompt-regexp)
|
||||||
|
|
||||||
(defgroup async nil
|
(defgroup async nil
|
||||||
"Simple asynchronous processing in Emacs"
|
"Simple asynchronous processing in Emacs"
|
||||||
:group 'lisp)
|
:group 'lisp)
|
||||||
|
@ -42,6 +44,12 @@
|
||||||
"Default function to remove text properties in variables."
|
"Default function to remove text properties in variables."
|
||||||
:type 'function)
|
:type 'function)
|
||||||
|
|
||||||
|
(defcustom async-prompt-for-password t
|
||||||
|
"Prompt for password in parent Emacs if needed when non nil.
|
||||||
|
When this is nil child Emacs will hang forever when a user interaction
|
||||||
|
for password is required unless a password is stored in a \".authinfo\" file."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
(defvar async-debug nil)
|
(defvar async-debug nil)
|
||||||
(defvar async-send-over-pipe t)
|
(defvar async-send-over-pipe t)
|
||||||
(defvar async-in-child-emacs nil)
|
(defvar async-in-child-emacs nil)
|
||||||
|
@ -207,7 +215,7 @@ It is intended to be used as follows:
|
||||||
(process-name proc) (process-exit-status proc))))
|
(process-name proc) (process-exit-status proc))))
|
||||||
(set (make-local-variable 'async-callback-value-set) t))))))
|
(set (make-local-variable 'async-callback-value-set) t))))))
|
||||||
|
|
||||||
(defun async-read-from-client (proc string)
|
(defun async-read-from-client (proc string &optional prompt-for-pwd)
|
||||||
"Process text from client process.
|
"Process text from client process.
|
||||||
|
|
||||||
The string chunks usually arrive in maximum of 4096 bytes, so a
|
The string chunks usually arrive in maximum of 4096 bytes, so a
|
||||||
|
@ -217,8 +225,18 @@ function.
|
||||||
We use a marker `async-read-marker' to track the position of the
|
We use a marker `async-read-marker' to track the position of the
|
||||||
lasts complete line. Every time we get new input, we try to look
|
lasts complete line. Every time we get new input, we try to look
|
||||||
for newline, and if found, process the entire line and bump the
|
for newline, and if found, process the entire line and bump the
|
||||||
marker position to the end of this next line."
|
marker position to the end of this next line.
|
||||||
|
|
||||||
|
Argument PROMPT-FOR-PWD allow binding lexically the value of
|
||||||
|
`async-prompt-for-password', if unspecified its global value
|
||||||
|
is used."
|
||||||
(with-current-buffer (process-buffer proc)
|
(with-current-buffer (process-buffer proc)
|
||||||
|
(when (and prompt-for-pwd
|
||||||
|
(boundp 'tramp-password-prompt-regexp)
|
||||||
|
tramp-password-prompt-regexp
|
||||||
|
(string-match tramp-password-prompt-regexp string))
|
||||||
|
(process-send-string
|
||||||
|
proc (concat (read-passwd (match-string 0 string)) "\n")))
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(insert string))
|
(insert string))
|
||||||
|
@ -350,7 +368,7 @@ its FINISH-FUNC is nil."
|
||||||
(plist-get value :async-message)))
|
(plist-get value :async-message)))
|
||||||
|
|
||||||
(defun async-send (process-or-key &rest args)
|
(defun async-send (process-or-key &rest args)
|
||||||
"Send the given message to the asychronous child or parent Emacs.
|
"Send the given message to the asynchronous child or parent Emacs.
|
||||||
|
|
||||||
To send messages from the parent to a child, PROCESS-OR-KEY is
|
To send messages from the parent to a child, PROCESS-OR-KEY is
|
||||||
the child process object. ARGS is a plist. Example:
|
the child process object. ARGS is a plist. Example:
|
||||||
|
@ -402,6 +420,7 @@ finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
|
||||||
working directory."
|
working directory."
|
||||||
(let* ((buf (generate-new-buffer (concat "*" name "*")))
|
(let* ((buf (generate-new-buffer (concat "*" name "*")))
|
||||||
(buf-err (generate-new-buffer (concat "*" name ":err*")))
|
(buf-err (generate-new-buffer (concat "*" name ":err*")))
|
||||||
|
(prt-for-pwd async-prompt-for-password)
|
||||||
(proc (let ((process-connection-type nil))
|
(proc (let ((process-connection-type nil))
|
||||||
(make-process
|
(make-process
|
||||||
:name name
|
:name name
|
||||||
|
@ -418,9 +437,12 @@ working directory."
|
||||||
(set (make-local-variable 'async-read-marker)
|
(set (make-local-variable 'async-read-marker)
|
||||||
(set-marker (make-marker) (point-min) buf))
|
(set-marker (make-marker) (point-min) buf))
|
||||||
(set-marker-insertion-type async-read-marker nil)
|
(set-marker-insertion-type async-read-marker nil)
|
||||||
|
|
||||||
(set-process-sentinel proc #'async-when-done)
|
(set-process-sentinel proc #'async-when-done)
|
||||||
(set-process-filter proc #'async-read-from-client)
|
;; Pass the value of `async-prompt-for-password' to the process
|
||||||
|
;; filter fn through the lexical local var prt-for-pwd (Issue#182).
|
||||||
|
(set-process-filter proc (lambda (proc string)
|
||||||
|
(async-read-from-client
|
||||||
|
proc string prt-for-pwd)))
|
||||||
(unless (string= name "emacs")
|
(unless (string= name "emacs")
|
||||||
(set (make-local-variable 'async-callback-for-process) t))
|
(set (make-local-variable 'async-callback-for-process) t))
|
||||||
proc)))
|
proc)))
|
|
@ -81,6 +81,10 @@ or rename for `dired-async-skip-fast'."
|
||||||
:risky t
|
:risky t
|
||||||
:type 'integer)
|
:type 'integer)
|
||||||
|
|
||||||
|
(defcustom dired-async-large-file-warning-threshold large-file-warning-threshold
|
||||||
|
"Same as `large-file-warning-threshold' but for dired-async."
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
(defface dired-async-message
|
(defface dired-async-message
|
||||||
'((t (:foreground "yellow")))
|
'((t (:foreground "yellow")))
|
||||||
"Face used for mode-line message.")
|
"Face used for mode-line message.")
|
||||||
|
@ -115,9 +119,9 @@ or rename for `dired-async-skip-fast'."
|
||||||
(sit-for 3)
|
(sit-for 3)
|
||||||
(force-mode-line-update)))
|
(force-mode-line-update)))
|
||||||
|
|
||||||
(defun dired-async-processes ()
|
(defun dired-async-processes (&optional propname)
|
||||||
(cl-loop for p in (process-list)
|
(cl-loop for p in (process-list)
|
||||||
when (process-get p 'dired-async-process)
|
when (process-get p (or propname 'dired-async-process))
|
||||||
collect p))
|
collect p))
|
||||||
|
|
||||||
(defun dired-async-kill-process ()
|
(defun dired-async-kill-process ()
|
||||||
|
@ -242,6 +246,14 @@ cases if `dired-async-skip-fast' is non-nil."
|
||||||
(funcall old-func file-creator operation
|
(funcall old-func file-creator operation
|
||||||
(nreverse quick-list) name-constructor marker-char))))
|
(nreverse quick-list) name-constructor marker-char))))
|
||||||
|
|
||||||
|
(defun dired-async--abort-if-file-too-large (size op-type filename)
|
||||||
|
"Warn when FILENAME larger than `dired-async-large-file-warning-threshold'.
|
||||||
|
Same as `abort-if-file-too-large' but without user-error."
|
||||||
|
(when (and dired-async-large-file-warning-threshold size
|
||||||
|
(> size dired-async-large-file-warning-threshold))
|
||||||
|
(files--ask-user-about-large-file
|
||||||
|
size op-type filename nil)))
|
||||||
|
|
||||||
(defvar overwrite-query)
|
(defvar overwrite-query)
|
||||||
(defun dired-async-create-files (file-creator operation fn-list name-constructor
|
(defun dired-async-create-files (file-creator operation fn-list name-constructor
|
||||||
&optional _marker-char)
|
&optional _marker-char)
|
||||||
|
@ -299,14 +311,22 @@ ESC or `q' to not overwrite any of the remaining files,
|
||||||
(file-in-directory-p destname from)
|
(file-in-directory-p destname from)
|
||||||
(error "Cannot copy `%s' into its subdirectory `%s'"
|
(error "Cannot copy `%s' into its subdirectory `%s'"
|
||||||
from to)))
|
from to)))
|
||||||
(if overwrite
|
;; Skip file if it is too large.
|
||||||
(or (and dired-overwrite-confirmed
|
(if (and (member operation '("Copy" "Rename"))
|
||||||
(push (cons from to) async-fn-list))
|
(eq (dired-async--abort-if-file-too-large
|
||||||
(progn
|
(file-attribute-size
|
||||||
(push (dired-make-relative from) failures)
|
(file-attributes (file-truename from)))
|
||||||
(dired-log "%s `%s' to `%s' failed\n"
|
(downcase operation) from)
|
||||||
operation from to)))
|
'abort))
|
||||||
(push (cons from to) async-fn-list)))))
|
(push from skipped)
|
||||||
|
(if overwrite
|
||||||
|
(or (and dired-overwrite-confirmed
|
||||||
|
(push (cons from to) async-fn-list))
|
||||||
|
(progn
|
||||||
|
(push (dired-make-relative from) failures)
|
||||||
|
(dired-log "%s `%s' to `%s' failed\n"
|
||||||
|
operation from to)))
|
||||||
|
(push (cons from to) async-fn-list))))))
|
||||||
;; Fix tramp issue #80 with emacs-26, use "-q" only when needed.
|
;; Fix tramp issue #80 with emacs-26, use "-q" only when needed.
|
||||||
(setq async-quiet-switch
|
(setq async-quiet-switch
|
||||||
(if (and (boundp 'tramp-cache-read-persistent-data)
|
(if (and (boundp 'tramp-cache-read-persistent-data)
|
||||||
|
@ -361,10 +381,13 @@ ESC or `q' to not overwrite any of the remaining files,
|
||||||
(async-start `(lambda ()
|
(async-start `(lambda ()
|
||||||
(require 'cl-lib) (require 'dired-aux) (require 'dired-x)
|
(require 'cl-lib) (require 'dired-aux) (require 'dired-x)
|
||||||
,(async-inject-variables dired-async-env-variables-regexp)
|
,(async-inject-variables dired-async-env-variables-regexp)
|
||||||
|
(advice-add #'files--ask-user-about-large-file
|
||||||
|
:override (lambda (&rest args) nil))
|
||||||
(let ((dired-recursive-copies (quote always))
|
(let ((dired-recursive-copies (quote always))
|
||||||
(dired-copy-preserve-time
|
(dired-copy-preserve-time
|
||||||
,dired-copy-preserve-time)
|
,dired-copy-preserve-time)
|
||||||
(dired-create-destination-dirs ',create-dir))
|
(dired-create-destination-dirs ',create-dir)
|
||||||
|
auth-source-save-behavior)
|
||||||
(setq overwrite-backup-query nil)
|
(setq overwrite-backup-query nil)
|
||||||
;; Inline `backup-file' as long as it is not
|
;; Inline `backup-file' as long as it is not
|
||||||
;; available in emacs.
|
;; available in emacs.
|
|
@ -1,17 +1,29 @@
|
||||||
;;; dash-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; dash-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "dash" "dash.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from dash.el
|
;;; Generated autoloads from dash.el
|
||||||
|
|
||||||
(autoload 'dash-fontify-mode "dash" "\
|
(autoload 'dash-fontify-mode "dash" "\
|
||||||
Toggle fontification of Dash special variables.
|
Toggle fontification of Dash special variables.
|
||||||
|
|
||||||
|
Dash-Fontify mode is a buffer-local minor mode intended for Emacs
|
||||||
|
Lisp buffers. Enabling it causes the special variables bound in
|
||||||
|
anaphoric Dash macros to be fontified. These anaphoras include
|
||||||
|
`it', `it-index', `acc', and `other'. In older Emacs versions
|
||||||
|
which do not dynamically detect macros, Dash-Fontify mode
|
||||||
|
additionally fontifies Dash macro calls.
|
||||||
|
|
||||||
|
See also `dash-fontify-mode-lighter' and
|
||||||
|
`global-dash-fontify-mode'.
|
||||||
|
|
||||||
This is a minor mode. If called interactively, toggle the
|
This is a minor mode. If called interactively, toggle the
|
||||||
`Dash-Fontify mode' mode. If the prefix argument is positive,
|
`Dash-Fontify mode' mode. If the prefix argument is positive,
|
||||||
enable the mode, and if it is zero or negative, disable the mode.
|
enable the mode, and if it is zero or negative, disable the mode.
|
||||||
|
@ -26,20 +38,8 @@ evaluate `dash-fontify-mode'.
|
||||||
The mode's hook is called both when the mode is enabled and when
|
The mode's hook is called both when the mode is enabled and when
|
||||||
it is disabled.
|
it is disabled.
|
||||||
|
|
||||||
Dash-Fontify mode is a buffer-local minor mode intended for Emacs
|
(fn &optional ARG)" t)
|
||||||
Lisp buffers. Enabling it causes the special variables bound in
|
|
||||||
anaphoric Dash macros to be fontified. These anaphoras include
|
|
||||||
`it', `it-index', `acc', and `other'. In older Emacs versions
|
|
||||||
which do not dynamically detect macros, Dash-Fontify mode
|
|
||||||
additionally fontifies Dash macro calls.
|
|
||||||
|
|
||||||
See also `dash-fontify-mode-lighter' and
|
|
||||||
`global-dash-fontify-mode'.
|
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
|
||||||
|
|
||||||
(put 'global-dash-fontify-mode 'globalized-minor-mode t)
|
(put 'global-dash-fontify-mode 'globalized-minor-mode t)
|
||||||
|
|
||||||
(defvar global-dash-fontify-mode nil "\
|
(defvar global-dash-fontify-mode nil "\
|
||||||
Non-nil if Global Dash-Fontify mode is enabled.
|
Non-nil if Global Dash-Fontify mode is enabled.
|
||||||
See the `global-dash-fontify-mode' command
|
See the `global-dash-fontify-mode' command
|
||||||
|
@ -47,9 +47,7 @@ for a description of this minor mode.
|
||||||
Setting this variable directly does not take effect;
|
Setting this variable directly does not take effect;
|
||||||
either customize it (see the info node `Easy Customization')
|
either customize it (see the info node `Easy Customization')
|
||||||
or call the function `global-dash-fontify-mode'.")
|
or call the function `global-dash-fontify-mode'.")
|
||||||
|
|
||||||
(custom-autoload 'global-dash-fontify-mode "dash" nil)
|
(custom-autoload 'global-dash-fontify-mode "dash" nil)
|
||||||
|
|
||||||
(autoload 'global-dash-fontify-mode "dash" "\
|
(autoload 'global-dash-fontify-mode "dash" "\
|
||||||
Toggle Dash-Fontify mode in all buffers.
|
Toggle Dash-Fontify mode in all buffers.
|
||||||
With prefix ARG, enable Global Dash-Fontify mode if ARG is positive;
|
With prefix ARG, enable Global Dash-Fontify mode if ARG is positive;
|
||||||
|
@ -64,24 +62,22 @@ Dash-Fontify mode is enabled in all buffers where
|
||||||
|
|
||||||
See `dash-fontify-mode' for more information on Dash-Fontify mode.
|
See `dash-fontify-mode' for more information on Dash-Fontify mode.
|
||||||
|
|
||||||
\(fn &optional ARG)" t nil)
|
(fn &optional ARG)" t)
|
||||||
|
|
||||||
(autoload 'dash-register-info-lookup "dash" "\
|
(autoload 'dash-register-info-lookup "dash" "\
|
||||||
Register the Dash Info manual with `info-lookup-symbol'.
|
Register the Dash Info manual with `info-lookup-symbol'.
|
||||||
This allows Dash symbols to be looked up with \\[info-lookup-symbol]." t nil)
|
This allows Dash symbols to be looked up with \\[info-lookup-symbol]." t)
|
||||||
|
|
||||||
(register-definition-prefixes "dash" '("!cdr" "!cons" "--" "->" "-a" "-butlast" "-c" "-d" "-e" "-f" "-gr" "-i" "-juxt" "-keep" "-l" "-m" "-no" "-o" "-p" "-r" "-s" "-t" "-u" "-value-to-list" "-when-let" "-zip" "dash-"))
|
(register-definition-prefixes "dash" '("!cdr" "!cons" "--" "->" "-a" "-butlast" "-c" "-d" "-e" "-f" "-gr" "-i" "-juxt" "-keep" "-l" "-m" "-no" "-o" "-p" "-r" "-s" "-t" "-u" "-value-to-list" "-when-let" "-zip" "dash-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil nil ("dash-pkg.el") (0 0 0 0))
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'dash-autoloads)
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; dash-autoloads.el ends here
|
;;; dash-autoloads.el ends here
|
|
@ -1,6 +1,6 @@
|
||||||
(define-package "dash" "20230714.723" "A modern list library for Emacs"
|
(define-package "dash" "20240103.1301" "A modern list library for Emacs"
|
||||||
'((emacs "24"))
|
'((emacs "24"))
|
||||||
:commit "f46268c75cb7c18361d3cee942cd4dc14a03aef4" :authors
|
:commit "e32a70ca636bad42232b6c79f1491dc86802a721" :authors
|
||||||
'(("Magnar Sveen" . "magnars@gmail.com"))
|
'(("Magnar Sveen" . "magnars@gmail.com"))
|
||||||
:maintainers
|
:maintainers
|
||||||
'(("Magnar Sveen" . "magnars@gmail.com"))
|
'(("Magnar Sveen" . "magnars@gmail.com"))
|
|
@ -1,6 +1,6 @@
|
||||||
;;; dash.el --- A modern list library for Emacs -*- lexical-binding: t -*-
|
;;; dash.el --- A modern list library for Emacs -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
;; Copyright (C) 2012-2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;; Author: Magnar Sveen <magnars@gmail.com>
|
;; Author: Magnar Sveen <magnars@gmail.com>
|
||||||
;; Version: 2.19.1
|
;; Version: 2.19.1
|
|
@ -2,7 +2,7 @@ This is dash.info, produced by makeinfo version 6.7 from dash.texi.
|
||||||
|
|
||||||
This manual is for Dash version 2.19.1.
|
This manual is for Dash version 2.19.1.
|
||||||
|
|
||||||
Copyright © 2012–2023 Free Software Foundation, Inc.
|
Copyright © 2012–2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Permission is granted to copy, distribute and/or modify this
|
Permission is granted to copy, distribute and/or modify this
|
||||||
document under the terms of the GNU Free Documentation License,
|
document under the terms of the GNU Free Documentation License,
|
||||||
|
@ -24,7 +24,7 @@ Dash
|
||||||
|
|
||||||
This manual is for Dash version 2.19.1.
|
This manual is for Dash version 2.19.1.
|
||||||
|
|
||||||
Copyright © 2012–2023 Free Software Foundation, Inc.
|
Copyright © 2012–2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Permission is granted to copy, distribute and/or modify this
|
Permission is granted to copy, distribute and/or modify this
|
||||||
document under the terms of the GNU Free Documentation License,
|
document under the terms of the GNU Free Documentation License,
|
|
@ -1,12 +0,0 @@
|
||||||
(define-package "dashboard" "20230331.2304" "A startup screen extracted from Spacemacs"
|
|
||||||
'((emacs "26.1"))
|
|
||||||
:commit "0f970d298931f9de7b511086728af140bf44a642" :authors
|
|
||||||
'(("Rakan Al-Hneiti" . "rakan.alhneiti@gmail.com"))
|
|
||||||
:maintainer
|
|
||||||
'("Jesús Martínez" . "jesusmartinez93@gmail.com")
|
|
||||||
:keywords
|
|
||||||
'("startup" "screen" "tools" "dashboard")
|
|
||||||
:url "https://github.com/emacs-dashboard/emacs-dashboard")
|
|
||||||
;; Local Variables:
|
|
||||||
;; no-byte-compile: t
|
|
||||||
;; End:
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,472 +0,0 @@
|
||||||
;;; dashboard.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
|
|
||||||
|
|
||||||
;; Copyright (c) 2016-2023 emacs-dashboard maintainers
|
|
||||||
;;
|
|
||||||
;; Author : Rakan Al-Hneiti <rakan.alhneiti@gmail.com>
|
|
||||||
;; Maintainer : Jesús Martínez <jesusmartinez93@gmail.com>
|
|
||||||
;; Shen, Jen-Chieh <jcs090218@gmail.com>
|
|
||||||
;; URL : https://github.com/emacs-dashboard/emacs-dashboard
|
|
||||||
;;
|
|
||||||
;; This file is not part of GNU Emacs.
|
|
||||||
;;
|
|
||||||
;;; License: GPLv3
|
|
||||||
;;
|
|
||||||
;; Created: October 05, 2016
|
|
||||||
;; Package-Version: 1.8.0-SNAPSHOT
|
|
||||||
;; Keywords: startup, screen, tools, dashboard
|
|
||||||
;; Package-Requires: ((emacs "26.1"))
|
|
||||||
;;; Commentary:
|
|
||||||
|
|
||||||
;; An extensible Emacs dashboard, with sections for
|
|
||||||
;; bookmarks, projects (projectile or project.el), org-agenda and more.
|
|
||||||
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
(require 'ffap)
|
|
||||||
(require 'recentf)
|
|
||||||
|
|
||||||
(require 'dashboard-widgets)
|
|
||||||
|
|
||||||
(declare-function bookmark-get-filename "ext:bookmark.el")
|
|
||||||
(declare-function bookmark-all-names "ext:bookmark.el")
|
|
||||||
(declare-function dashboard-ls--dirs "ext:dashboard-ls.el")
|
|
||||||
(declare-function dashboard-ls--files "ext:dashboard-ls.el")
|
|
||||||
(declare-function page-break-lines-mode "ext:page-break-lines.el")
|
|
||||||
(declare-function projectile-remove-known-project "ext:projectile.el")
|
|
||||||
(declare-function project-forget-projects-under "ext:project.el")
|
|
||||||
(declare-function linum-mode "linum.el")
|
|
||||||
|
|
||||||
(declare-function dashboard-refresh-buffer "dashboard.el")
|
|
||||||
|
|
||||||
(defgroup dashboard nil
|
|
||||||
"Extensible startup screen."
|
|
||||||
:group 'applications)
|
|
||||||
|
|
||||||
;; Custom splash screen
|
|
||||||
(defvar dashboard-mode-map
|
|
||||||
(let ((map (make-sparse-keymap)))
|
|
||||||
(define-key map (kbd "C-p") 'dashboard-previous-line)
|
|
||||||
(define-key map (kbd "C-n") 'dashboard-next-line)
|
|
||||||
(define-key map (kbd "<up>") 'dashboard-previous-line)
|
|
||||||
(define-key map (kbd "<down>") 'dashboard-next-line)
|
|
||||||
(define-key map (kbd "k") 'dashboard-previous-line)
|
|
||||||
(define-key map (kbd "j") 'dashboard-next-line)
|
|
||||||
(define-key map [tab] 'widget-forward)
|
|
||||||
(define-key map (kbd "C-i") 'widget-forward)
|
|
||||||
(define-key map [backtab] 'widget-backward)
|
|
||||||
(define-key map (kbd "RET") 'dashboard-return)
|
|
||||||
(define-key map [mouse-1] 'dashboard-mouse-1)
|
|
||||||
(define-key map (kbd "}") #'dashboard-next-section)
|
|
||||||
(define-key map (kbd "{") #'dashboard-previous-section)
|
|
||||||
|
|
||||||
(define-key map (kbd "<backspace>") #'dashboard-remove-item-under)
|
|
||||||
(define-key map (kbd "<delete>") #'dashboard-remove-item-under)
|
|
||||||
(define-key map (kbd "DEL") #'dashboard-remove-item-under)
|
|
||||||
|
|
||||||
(define-key map (kbd "1") #'dashboard-section-1)
|
|
||||||
(define-key map (kbd "2") #'dashboard-section-2)
|
|
||||||
(define-key map (kbd "3") #'dashboard-section-3)
|
|
||||||
(define-key map (kbd "4") #'dashboard-section-4)
|
|
||||||
(define-key map (kbd "5") #'dashboard-section-5)
|
|
||||||
(define-key map (kbd "6") #'dashboard-section-6)
|
|
||||||
(define-key map (kbd "7") #'dashboard-section-7)
|
|
||||||
(define-key map (kbd "8") #'dashboard-section-8)
|
|
||||||
(define-key map (kbd "9") #'dashboard-section-9)
|
|
||||||
map)
|
|
||||||
"Keymap for dashboard mode.")
|
|
||||||
|
|
||||||
(defcustom dashboard-after-initialize-hook nil
|
|
||||||
"Hook that is run after dashboard buffer is initialized."
|
|
||||||
:group 'dashboard
|
|
||||||
:type 'hook)
|
|
||||||
|
|
||||||
(define-derived-mode dashboard-mode special-mode "Dashboard"
|
|
||||||
"Dashboard major mode for startup screen."
|
|
||||||
:group 'dashboard
|
|
||||||
:syntax-table nil
|
|
||||||
:abbrev-table nil
|
|
||||||
(buffer-disable-undo)
|
|
||||||
(when (featurep 'whitespace) (whitespace-mode -1))
|
|
||||||
(when (featurep 'linum) (linum-mode -1))
|
|
||||||
(when (featurep 'display-line-numbers) (display-line-numbers-mode -1))
|
|
||||||
(when (featurep 'page-break-lines) (page-break-lines-mode 1))
|
|
||||||
(setq-local revert-buffer-function #'dashboard-refresh-buffer)
|
|
||||||
(setq inhibit-startup-screen t
|
|
||||||
buffer-read-only t
|
|
||||||
truncate-lines t))
|
|
||||||
|
|
||||||
(defcustom dashboard-center-content nil
|
|
||||||
"Whether to center content within the window."
|
|
||||||
:type 'boolean
|
|
||||||
:group 'dashboard)
|
|
||||||
|
|
||||||
(defconst dashboard-buffer-name "*dashboard*"
|
|
||||||
"Dashboard's buffer name.")
|
|
||||||
|
|
||||||
(defvar dashboard-force-refresh nil
|
|
||||||
"If non-nil, force refresh dashboard buffer.")
|
|
||||||
|
|
||||||
(defvar dashboard--section-starts nil
|
|
||||||
"List of section starting positions.")
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Util
|
|
||||||
;;
|
|
||||||
(defun dashboard--goto-line (line)
|
|
||||||
"Goto LINE."
|
|
||||||
(goto-char (point-min)) (forward-line (1- line)))
|
|
||||||
|
|
||||||
(defmacro dashboard--save-excursion (&rest body)
|
|
||||||
"Execute BODY save window point."
|
|
||||||
(declare (indent 0) (debug t))
|
|
||||||
`(let ((line (line-number-at-pos nil t))
|
|
||||||
(column (current-column)))
|
|
||||||
,@body
|
|
||||||
(dashboard--goto-line line)
|
|
||||||
(move-to-column column)))
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Core
|
|
||||||
;;
|
|
||||||
(defun dashboard--current-section ()
|
|
||||||
"Return section symbol in dashboard."
|
|
||||||
(save-excursion
|
|
||||||
(if (and (search-backward dashboard-page-separator nil t)
|
|
||||||
(search-forward dashboard-page-separator nil t))
|
|
||||||
(let ((ln (thing-at-point 'line)))
|
|
||||||
(cond ((string-match-p "Recent Files:" ln) 'recents)
|
|
||||||
((string-match-p "Bookmarks:" ln) 'bookmarks)
|
|
||||||
((string-match-p "Projects:" ln) 'projects)
|
|
||||||
((string-match-p "Agenda for " ln) 'agenda)
|
|
||||||
((string-match-p "Registers:" ln) 'registers)
|
|
||||||
((string-match-p "List Directories:" ln) 'ls-directories)
|
|
||||||
((string-match-p "List Files:" ln) 'ls-files)
|
|
||||||
(t (user-error "Unknown section from dashboard"))))
|
|
||||||
(user-error "Failed searching dashboard section"))))
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Navigation
|
|
||||||
;;
|
|
||||||
(defun dashboard-previous-section ()
|
|
||||||
"Navigate back to previous section."
|
|
||||||
(interactive)
|
|
||||||
(let ((current-position (point)) current-section-start previous-section-start)
|
|
||||||
(dolist (elt dashboard--section-starts)
|
|
||||||
(when (and current-section-start (not previous-section-start))
|
|
||||||
(setq previous-section-start elt))
|
|
||||||
(when (and (not current-section-start) (< elt current-position))
|
|
||||||
(setq current-section-start elt)))
|
|
||||||
(goto-char (if (eq current-position current-section-start)
|
|
||||||
previous-section-start
|
|
||||||
current-section-start))))
|
|
||||||
|
|
||||||
(defun dashboard-next-section ()
|
|
||||||
"Navigate forward to next section."
|
|
||||||
(interactive)
|
|
||||||
(let ((current-position (point)) next-section-start
|
|
||||||
(section-starts (reverse dashboard--section-starts)))
|
|
||||||
(dolist (elt section-starts)
|
|
||||||
(when (and (not next-section-start)
|
|
||||||
(> elt current-position))
|
|
||||||
(setq next-section-start elt)))
|
|
||||||
(when next-section-start
|
|
||||||
(goto-char next-section-start))))
|
|
||||||
|
|
||||||
(defun dashboard--section-lines ()
|
|
||||||
"Return a list of integer represent the starting line number of each section."
|
|
||||||
(let (pb-lst)
|
|
||||||
(save-excursion
|
|
||||||
(goto-char (point-min))
|
|
||||||
(while (search-forward dashboard-page-separator nil t)
|
|
||||||
(when (ignore-errors (dashboard--current-section))
|
|
||||||
(push (line-number-at-pos) pb-lst))))
|
|
||||||
(setq pb-lst (reverse pb-lst))
|
|
||||||
pb-lst))
|
|
||||||
|
|
||||||
(defun dashboard--goto-section-by-index (index)
|
|
||||||
"Navigate to item section by INDEX."
|
|
||||||
(let* ((pg-lst (dashboard--section-lines))
|
|
||||||
(items-id (1- index))
|
|
||||||
(items-pg (nth items-id pg-lst))
|
|
||||||
(items-len (length pg-lst)))
|
|
||||||
(when (and items-pg (< items-id items-len))
|
|
||||||
(dashboard--goto-line items-pg))))
|
|
||||||
|
|
||||||
(defun dashboard-section-1 ()
|
|
||||||
"Navigate to section 1." (interactive) (dashboard--goto-section-by-index 1))
|
|
||||||
(defun dashboard-section-2 ()
|
|
||||||
"Navigate to section 2." (interactive) (dashboard--goto-section-by-index 2))
|
|
||||||
(defun dashboard-section-3 ()
|
|
||||||
"Navigate to section 3." (interactive) (dashboard--goto-section-by-index 3))
|
|
||||||
(defun dashboard-section-4 ()
|
|
||||||
"Navigate to section 4." (interactive) (dashboard--goto-section-by-index 4))
|
|
||||||
(defun dashboard-section-5 ()
|
|
||||||
"Navigate to section 5." (interactive) (dashboard--goto-section-by-index 5))
|
|
||||||
(defun dashboard-section-6 ()
|
|
||||||
"Navigate to section 6." (interactive) (dashboard--goto-section-by-index 6))
|
|
||||||
(defun dashboard-section-7 ()
|
|
||||||
"Navigate to section 7." (interactive) (dashboard--goto-section-by-index 7))
|
|
||||||
(defun dashboard-section-8 ()
|
|
||||||
"Navigate to section 8." (interactive) (dashboard--goto-section-by-index 8))
|
|
||||||
(defun dashboard-section-9 ()
|
|
||||||
"Navigate to section 9." (interactive) (dashboard--goto-section-by-index 9))
|
|
||||||
|
|
||||||
(defun dashboard-previous-line (arg)
|
|
||||||
"Move point up and position it at that line’s item.
|
|
||||||
Optional prefix ARG says how many lines to move; default is one line."
|
|
||||||
(interactive "^p")
|
|
||||||
(dashboard-next-line (- arg)))
|
|
||||||
|
|
||||||
(defun dashboard-next-line (arg)
|
|
||||||
"Move point down and position it at that line’s item.
|
|
||||||
Optional prefix ARG says how many lines to move; default is one line."
|
|
||||||
;; code heavily inspired by `dired-next-line'
|
|
||||||
(interactive "^p")
|
|
||||||
(let (line-move-visual goal-column)
|
|
||||||
(line-move arg t))
|
|
||||||
;; We never want to move point into an invisible line. Dashboard doesn’t
|
|
||||||
;; use invisible text currently but when it does we’re ready!
|
|
||||||
(while (and (invisible-p (point))
|
|
||||||
(not (if (and arg (< arg 0)) (bobp) (eobp))))
|
|
||||||
(forward-char (if (and arg (< arg 0)) -1 1)))
|
|
||||||
(beginning-of-line-text))
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; ffap
|
|
||||||
;;
|
|
||||||
(defun dashboard--goto-section (section)
|
|
||||||
"Move to SECTION declares in variable `dashboard-item-shortcuts'."
|
|
||||||
(let ((fnc (intern (format "dashboard-jump-to-%s" section))))
|
|
||||||
(dashboard-funcall-fboundp fnc)))
|
|
||||||
|
|
||||||
(defun dashboard--current-index (section &optional pos)
|
|
||||||
"Return the idex by SECTION from POS."
|
|
||||||
(let (target-ln section-line)
|
|
||||||
(save-excursion
|
|
||||||
(when pos (goto-char pos))
|
|
||||||
(setq target-ln (line-number-at-pos))
|
|
||||||
(dashboard--goto-section section)
|
|
||||||
(setq section-line (line-number-at-pos)))
|
|
||||||
(- target-ln section-line)))
|
|
||||||
|
|
||||||
(defun dashboard--section-list (section)
|
|
||||||
"Return the list from SECTION."
|
|
||||||
(cl-case section
|
|
||||||
(`recents recentf-list)
|
|
||||||
(`bookmarks (bookmark-all-names))
|
|
||||||
(`projects (dashboard-projects-backend-load-projects))
|
|
||||||
(`ls-directories (dashboard-ls--dirs))
|
|
||||||
(`ls-files (dashboard-ls--files))
|
|
||||||
(t (user-error "Unknown section for search: %s" section))))
|
|
||||||
|
|
||||||
(defun dashboard--current-item-in-path ()
|
|
||||||
"Return the path from current dashboard section in path."
|
|
||||||
(let ((section (dashboard--current-section)) path)
|
|
||||||
(cl-case section
|
|
||||||
(`bookmarks (setq path (bookmark-get-filename path)))
|
|
||||||
(t
|
|
||||||
(let ((lst (dashboard--section-list section))
|
|
||||||
(index (dashboard--current-index section)))
|
|
||||||
(setq path (nth index lst)))))
|
|
||||||
path))
|
|
||||||
|
|
||||||
(defun dashboard--on-path-item-p ()
|
|
||||||
"Return non-nil if current point is on the item path from dashboard."
|
|
||||||
(save-excursion
|
|
||||||
(when (= (point) (line-end-position)) (ignore-errors (forward-char -1)))
|
|
||||||
(eq (get-char-property (point) 'face) 'dashboard-items-face)))
|
|
||||||
|
|
||||||
(defun dashboard--ffap-guesser--adv (fnc &rest args)
|
|
||||||
"Advice execution around function `ffap-guesser'.
|
|
||||||
|
|
||||||
Argument FNC is the adviced function.
|
|
||||||
Optional argument ARGS adviced function arguments."
|
|
||||||
(cl-case major-mode
|
|
||||||
(`dashboard-mode
|
|
||||||
(or (and (dashboard--on-path-item-p)
|
|
||||||
(dashboard--current-item-in-path))
|
|
||||||
(apply fnc args))) ; fallback
|
|
||||||
(t (apply fnc args))))
|
|
||||||
(advice-add 'ffap-guesser :around #'dashboard--ffap-guesser--adv)
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Removal
|
|
||||||
;;
|
|
||||||
(defun dashboard-remove-item-under ()
|
|
||||||
"Remove a item from the current item section."
|
|
||||||
(interactive)
|
|
||||||
(cl-case (dashboard--current-section)
|
|
||||||
(`recents (dashboard-remove-item-recentf))
|
|
||||||
(`bookmarks (dashboard-remove-item-bookmarks))
|
|
||||||
(`projects (dashboard-remove-item-projects))
|
|
||||||
(`agenda (dashboard-remove-item-agenda))
|
|
||||||
(`registers (dashboard-remove-item-registers)))
|
|
||||||
(dashboard--save-excursion (dashboard-refresh-buffer)))
|
|
||||||
|
|
||||||
(defun dashboard-remove-item-recentf ()
|
|
||||||
"Remove a file from `recentf-list'."
|
|
||||||
(interactive)
|
|
||||||
(let ((path (save-excursion (end-of-line) (ffap-guesser))))
|
|
||||||
(setq recentf-list (delete path recentf-list)))
|
|
||||||
(dashboard-mute-apply (recentf-save-list)))
|
|
||||||
|
|
||||||
(defun dashboard-remove-item-projects ()
|
|
||||||
"Remove a path from `project--list'."
|
|
||||||
(interactive)
|
|
||||||
(let ((path (save-excursion (end-of-line) (ffap-guesser))))
|
|
||||||
(dashboard-mute-apply
|
|
||||||
(cl-case dashboard-projects-backend
|
|
||||||
(`projectile (projectile-remove-known-project path))
|
|
||||||
(`project-el (project-forget-projects-under path))))))
|
|
||||||
|
|
||||||
(defun dashboard-remove-item-bookmarks ()
|
|
||||||
"Remove a bookmarks from `bookmark-alist'."
|
|
||||||
(interactive)) ; TODO: ..
|
|
||||||
|
|
||||||
(defun dashboard-remove-item-agenda ()
|
|
||||||
"Remove an agenda from `org-agenda-files'."
|
|
||||||
(interactive "P")
|
|
||||||
(let ((agenda-file (get-text-property (point) 'dashboard-agenda-file))
|
|
||||||
(agenda-loc (get-text-property (point) 'dashboard-agenda-loc)))
|
|
||||||
(with-current-buffer (find-file-noselect agenda-file)
|
|
||||||
(goto-char agenda-loc)
|
|
||||||
(call-interactively 'org-todo))))
|
|
||||||
|
|
||||||
(defun dashboard-remove-item-registers ()
|
|
||||||
"Remove a registers from `register-alist'."
|
|
||||||
(interactive)) ; TODO: ..
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Confirmation
|
|
||||||
;;
|
|
||||||
(defun dashboard-return ()
|
|
||||||
"Hit return key in dashboard buffer."
|
|
||||||
(interactive)
|
|
||||||
(let ((start-ln (line-number-at-pos)) (fd-cnt 0) diff-line entry-pt)
|
|
||||||
(save-excursion
|
|
||||||
(while (and (not diff-line)
|
|
||||||
(not (= (point) (point-min)))
|
|
||||||
(not (get-char-property (point) 'button))
|
|
||||||
(not (= (point) (point-max))))
|
|
||||||
(forward-char 1)
|
|
||||||
(setq fd-cnt (1+ fd-cnt))
|
|
||||||
(unless (= start-ln (line-number-at-pos))
|
|
||||||
(setq diff-line t)))
|
|
||||||
(unless (= (point) (point-max))
|
|
||||||
(setq entry-pt (point))))
|
|
||||||
(when (= fd-cnt 1)
|
|
||||||
(setq entry-pt (1- (point))))
|
|
||||||
(if entry-pt
|
|
||||||
(widget-button-press entry-pt)
|
|
||||||
(call-interactively #'widget-button-press))))
|
|
||||||
|
|
||||||
(defun dashboard-mouse-1 ()
|
|
||||||
"Key for keymap `mouse-1'."
|
|
||||||
(interactive)
|
|
||||||
(let ((old-track-mouse track-mouse))
|
|
||||||
(when (call-interactively #'widget-button-click)
|
|
||||||
(setq track-mouse old-track-mouse))))
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Insertion
|
|
||||||
;;
|
|
||||||
(defmacro dashboard--with-buffer (&rest body)
|
|
||||||
"Execute BODY in dashboard buffer."
|
|
||||||
(declare (indent 0))
|
|
||||||
`(with-current-buffer (get-buffer-create dashboard-buffer-name)
|
|
||||||
(let ((inhibit-read-only t)) ,@body)
|
|
||||||
(current-buffer)))
|
|
||||||
|
|
||||||
(defun dashboard-maximum-section-length ()
|
|
||||||
"For the just-inserted section, calculate the length of the longest line."
|
|
||||||
(let ((max-line-length 0))
|
|
||||||
(save-excursion
|
|
||||||
(dashboard-previous-section)
|
|
||||||
(while (not (eobp))
|
|
||||||
(setq max-line-length
|
|
||||||
(max max-line-length
|
|
||||||
(- (line-end-position) (line-beginning-position))))
|
|
||||||
(forward-line 1)))
|
|
||||||
max-line-length))
|
|
||||||
|
|
||||||
(defun dashboard-insert-startupify-lists ()
|
|
||||||
"Insert the list of widgets into the buffer."
|
|
||||||
(interactive)
|
|
||||||
(let ((inhibit-redisplay t)
|
|
||||||
(recentf-is-on (recentf-enabled-p))
|
|
||||||
(origial-recentf-list recentf-list)
|
|
||||||
(dashboard-num-recents (or (cdr (assoc 'recents dashboard-items)) 0))
|
|
||||||
(max-line-length 0))
|
|
||||||
(when recentf-is-on
|
|
||||||
(setq recentf-list (dashboard-subseq recentf-list dashboard-num-recents)))
|
|
||||||
(dashboard--with-buffer
|
|
||||||
(when (or dashboard-force-refresh (not (eq major-mode 'dashboard-mode)))
|
|
||||||
(erase-buffer)
|
|
||||||
(dashboard-insert-banner)
|
|
||||||
(insert "\n")
|
|
||||||
(setq dashboard--section-starts nil)
|
|
||||||
(mapc (lambda (els)
|
|
||||||
(let* ((el (or (car-safe els) els))
|
|
||||||
(list-size
|
|
||||||
(or (cdr-safe els)
|
|
||||||
dashboard-items-default-length))
|
|
||||||
(item-generator
|
|
||||||
(cdr-safe (assoc el dashboard-item-generators))))
|
|
||||||
(push (point) dashboard--section-starts)
|
|
||||||
(funcall item-generator list-size)
|
|
||||||
(goto-char (point-max))
|
|
||||||
;; add a newline so the next section-name doesn't get include
|
|
||||||
;; on the same line.
|
|
||||||
(insert "\n")
|
|
||||||
(when recentf-is-on
|
|
||||||
(setq recentf-list origial-recentf-list))
|
|
||||||
(setq max-line-length
|
|
||||||
(max max-line-length (dashboard-maximum-section-length)))))
|
|
||||||
dashboard-items)
|
|
||||||
(when dashboard-center-content
|
|
||||||
(dashboard-center-text
|
|
||||||
(if dashboard--section-starts
|
|
||||||
(car (last dashboard--section-starts))
|
|
||||||
(point))
|
|
||||||
(point-max)))
|
|
||||||
(save-excursion
|
|
||||||
(dolist (start dashboard--section-starts)
|
|
||||||
(goto-char start)
|
|
||||||
(delete-char -1) ; delete the newline we added previously
|
|
||||||
(insert dashboard-page-separator)))
|
|
||||||
(progn
|
|
||||||
(delete-char -1)
|
|
||||||
(insert dashboard-page-separator))
|
|
||||||
(dashboard-insert-footer)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(dashboard-mode)))
|
|
||||||
(when recentf-is-on
|
|
||||||
(setq recentf-list origial-recentf-list))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun dashboard-open (&rest _)
|
|
||||||
"Open (or refresh) the *dashboard* buffer."
|
|
||||||
(interactive)
|
|
||||||
(let ((dashboard-force-refresh t)) (dashboard-insert-startupify-lists))
|
|
||||||
(switch-to-buffer dashboard-buffer-name))
|
|
||||||
|
|
||||||
(defalias #'dashboard-refresh-buffer #'dashboard-open)
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun dashboard-setup-startup-hook ()
|
|
||||||
"Setup post initialization hooks.
|
|
||||||
If a command line argument is provided, assume a filename and skip displaying
|
|
||||||
Dashboard."
|
|
||||||
(when (< (length command-line-args) 2)
|
|
||||||
(add-hook 'after-init-hook (lambda ()
|
|
||||||
;; Display useful lists of items
|
|
||||||
(dashboard-insert-startupify-lists)))
|
|
||||||
(add-hook 'emacs-startup-hook (lambda ()
|
|
||||||
(switch-to-buffer dashboard-buffer-name)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(redisplay)
|
|
||||||
(run-hooks 'dashboard-after-initialize-hook)))))
|
|
||||||
|
|
||||||
(provide 'dashboard)
|
|
||||||
;;; dashboard.el ends here
|
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
@ -1,44 +1,39 @@
|
||||||
;;; dashboard-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; dashboard-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "dashboard" "dashboard.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from dashboard.el
|
;;; Generated autoloads from dashboard.el
|
||||||
|
|
||||||
(autoload 'dashboard-open "dashboard" "\
|
(autoload 'dashboard-open "dashboard" "\
|
||||||
Open (or refresh) the *dashboard* buffer.
|
Open (or refresh) the *dashboard* buffer.
|
||||||
|
|
||||||
\(fn &rest _)" t nil)
|
(fn &rest _)" t)
|
||||||
|
|
||||||
(autoload 'dashboard-setup-startup-hook "dashboard" "\
|
(autoload 'dashboard-setup-startup-hook "dashboard" "\
|
||||||
Setup post initialization hooks.
|
Setup post initialization hooks unless a command line argument is provided.")
|
||||||
If a command line argument is provided, assume a filename and skip displaying
|
|
||||||
Dashboard." nil nil)
|
|
||||||
|
|
||||||
(register-definition-prefixes "dashboard" '("dashboard-"))
|
(register-definition-prefixes "dashboard" '("dashboard-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil "dashboard-widgets" "dashboard-widgets.el"
|
|
||||||
;;;;;; (0 0 0 0))
|
|
||||||
;;; Generated autoloads from dashboard-widgets.el
|
;;; Generated autoloads from dashboard-widgets.el
|
||||||
|
|
||||||
(register-definition-prefixes "dashboard-widgets" '("dashboard-" "org-time-less-p" "recentf-list"))
|
(register-definition-prefixes "dashboard-widgets" '("dashboard-" "recentf-list"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil nil ("dashboard-pkg.el") (0 0 0 0))
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'dashboard-autoloads)
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; dashboard-autoloads.el ends here
|
;;; dashboard-autoloads.el ends here
|
|
@ -1,6 +1,6 @@
|
||||||
(define-package "dashboard" "20230726.2018" "A startup screen extracted from Spacemacs"
|
(define-package "dashboard" "20240319.915" "A startup screen extracted from Spacemacs"
|
||||||
'((emacs "26.1"))
|
'((emacs "26.1"))
|
||||||
:commit "6480e0797b41c8ce1de4f37ba8016d177c22ab04" :authors
|
:commit "e34ce1b4730fb88a33a571b9065114b7a77645f0" :authors
|
||||||
'(("Rakan Al-Hneiti" . "rakan.alhneiti@gmail.com"))
|
'(("Rakan Al-Hneiti" . "rakan.alhneiti@gmail.com"))
|
||||||
:maintainers
|
:maintainers
|
||||||
'(("Jesús Martínez" . "jesusmartinez93@gmail.com"))
|
'(("Jesús Martínez" . "jesusmartinez93@gmail.com"))
|
|
@ -1,20 +1,11 @@
|
||||||
;;; dashboard-widgets.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
|
;;; dashboard-widgets.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; Copyright (c) 2016-2023 emacs-dashboard maintainers
|
;; Copyright (c) 2016-2024 emacs-dashboard maintainers
|
||||||
;;
|
|
||||||
;; Author : Rakan Al-Hneiti <rakan.alhneiti@gmail.com>
|
|
||||||
;; Maintainer : Jesús Martínez <jesusmartinez93@gmail.com>
|
|
||||||
;; Shen, Jen-Chieh <jcs090218@gmail.com>
|
|
||||||
;; URL : https://github.com/emacs-dashboard/emacs-dashboard
|
|
||||||
;;
|
|
||||||
;; This file is not part of GNU Emacs.
|
;; This file is not part of GNU Emacs.
|
||||||
;;
|
;;
|
||||||
;;; License: GPLv3
|
;;; License: GPLv3
|
||||||
;;
|
;;
|
||||||
;; Created: October 05, 2016
|
|
||||||
;; Package-Version: 1.9.0-SNAPSHOT
|
|
||||||
;; Keywords: startup, screen, tools, dashboard
|
|
||||||
;; Package-Requires: ((emacs "26.1"))
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; An extensible Emacs dashboard, with sections for
|
;; An extensible Emacs dashboard, with sections for
|
||||||
|
@ -26,6 +17,9 @@
|
||||||
(require 'image)
|
(require 'image)
|
||||||
(require 'subr-x)
|
(require 'subr-x)
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Externals
|
||||||
|
|
||||||
;; Compiler pacifier
|
;; Compiler pacifier
|
||||||
(declare-function all-the-icons-icon-for-dir "ext:all-the-icons.el")
|
(declare-function all-the-icons-icon-for-dir "ext:all-the-icons.el")
|
||||||
(declare-function all-the-icons-icon-for-file "ext:all-the-icons.el")
|
(declare-function all-the-icons-icon-for-file "ext:all-the-icons.el")
|
||||||
|
@ -42,7 +36,6 @@
|
||||||
(declare-function projectile-cleanup-known-projects "ext:projectile.el")
|
(declare-function projectile-cleanup-known-projects "ext:projectile.el")
|
||||||
(declare-function projectile-load-known-projects "ext:projectile.el")
|
(declare-function projectile-load-known-projects "ext:projectile.el")
|
||||||
(declare-function projectile-mode "ext:projectile.el")
|
(declare-function projectile-mode "ext:projectile.el")
|
||||||
(declare-function projectile-relevant-known-projects "ext:projectile.el")
|
|
||||||
;;; project.el in Emacs 26 does not contain this function
|
;;; project.el in Emacs 26 does not contain this function
|
||||||
(declare-function project-known-project-roots "ext:project.el" nil t)
|
(declare-function project-known-project-roots "ext:project.el" nil t)
|
||||||
(declare-function project-forget-zombie-projects "ext:project.el" nil t)
|
(declare-function project-forget-zombie-projects "ext:project.el" nil t)
|
||||||
|
@ -66,7 +59,6 @@
|
||||||
(declare-function org-time-string-to-time "ext:org.el")
|
(declare-function org-time-string-to-time "ext:org.el")
|
||||||
(declare-function org-today "ext:org.el")
|
(declare-function org-today "ext:org.el")
|
||||||
(declare-function recentf-cleanup "ext:recentf.el")
|
(declare-function recentf-cleanup "ext:recentf.el")
|
||||||
(defalias 'org-time-less-p 'time-less-p)
|
|
||||||
(defvar org-level-faces)
|
(defvar org-level-faces)
|
||||||
(defvar org-agenda-new-buffers)
|
(defvar org-agenda-new-buffers)
|
||||||
(defvar org-agenda-prefix-format)
|
(defvar org-agenda-prefix-format)
|
||||||
|
@ -78,9 +70,29 @@
|
||||||
(declare-function string-pixel-width "subr-x.el") ; TODO: remove this after 29.1
|
(declare-function string-pixel-width "subr-x.el") ; TODO: remove this after 29.1
|
||||||
(declare-function shr-string-pixel-width "shr.el") ; TODO: remove this after 29.1
|
(declare-function shr-string-pixel-width "shr.el") ; TODO: remove this after 29.1
|
||||||
|
|
||||||
(defcustom dashboard-page-separator "\n\n"
|
(make-obsolete-variable 'dashboard-set-navigator
|
||||||
|
'dashboard-startupify-list "1.9.0")
|
||||||
|
|
||||||
|
(make-obsolete-variable 'dashboard-set-init-info
|
||||||
|
'dashboard-startupify-list "1.9.0")
|
||||||
|
|
||||||
|
(make-obsolete-variable 'dashboard-set-footer
|
||||||
|
'dashboard-startupify-list "1.9.0")
|
||||||
|
|
||||||
|
(defvar recentf-list nil)
|
||||||
|
|
||||||
|
(defvar dashboard-buffer-name)
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Customization
|
||||||
|
|
||||||
|
(defcustom dashboard-page-separator "\n"
|
||||||
"Separator to use between the different pages."
|
"Separator to use between the different pages."
|
||||||
:type 'string
|
:type '(choice
|
||||||
|
(const :tag "Default" "\n")
|
||||||
|
(const :tag "Use Page indicator (requires page-break-lines)"
|
||||||
|
"\n\f\n")
|
||||||
|
(string :tag "Use Custom String"))
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-image-banner-max-height 0
|
(defcustom dashboard-image-banner-max-height 0
|
||||||
|
@ -103,6 +115,14 @@ preserved."
|
||||||
:type 'integer
|
:type 'integer
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defcustom dashboard-image-extra-props nil
|
||||||
|
"Additional image attributes to assign to the image.
|
||||||
|
This could be useful for displaying images with transparency,
|
||||||
|
for example, by setting the `:mask' property to `heuristic'.
|
||||||
|
See `create-image' and Info node `(elisp)Image Descriptors'."
|
||||||
|
:type 'plist
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-set-heading-icons nil
|
(defcustom dashboard-set-heading-icons nil
|
||||||
"When non nil, heading sections will have icons."
|
"When non nil, heading sections will have icons."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
|
@ -113,21 +133,6 @@ preserved."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-set-navigator nil
|
|
||||||
"When non nil, a navigator will be displayed under the banner."
|
|
||||||
:type 'boolean
|
|
||||||
:group 'dashboard)
|
|
||||||
|
|
||||||
(defcustom dashboard-set-init-info t
|
|
||||||
"When non nil, init info will be displayed under the banner."
|
|
||||||
:type 'boolean
|
|
||||||
:group 'dashboard)
|
|
||||||
|
|
||||||
(defcustom dashboard-set-footer t
|
|
||||||
"When non nil, a footer will be displayed at the bottom."
|
|
||||||
:type 'boolean
|
|
||||||
:group 'dashboard)
|
|
||||||
|
|
||||||
(defcustom dashboard-footer-messages
|
(defcustom dashboard-footer-messages
|
||||||
'("The one true editor, Emacs!"
|
'("The one true editor, Emacs!"
|
||||||
"Who the hell uses VIM anyway? Go Evil!"
|
"Who the hell uses VIM anyway? Go Evil!"
|
||||||
|
@ -261,17 +266,10 @@ Example:
|
||||||
:type '(function string)
|
:type '(function string)
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-footer
|
|
||||||
(nth (random (1- (1+ (length dashboard-footer-messages)))) dashboard-footer-messages)
|
|
||||||
"A footer with some short message."
|
|
||||||
:type 'string
|
|
||||||
:group 'dashboard)
|
|
||||||
|
|
||||||
(defcustom dashboard-display-icons-p #'display-graphic-p
|
(defcustom dashboard-display-icons-p #'display-graphic-p
|
||||||
"Predicate to determine whether dashboard should show icons.
|
"Predicate to determine whether dashboard should show icons.
|
||||||
Can be nil to not show icons and any truthy value to show them. When set
|
Can be nil to not show icons and any truthy value to show them. When set to a
|
||||||
to a function the result of the function will be interpreted as the
|
function the result of the function will be interpreted as the predicate value."
|
||||||
predicate value."
|
|
||||||
:type '(choice (function :tag "Predicate function")
|
:type '(choice (function :tag "Predicate function")
|
||||||
(boolean :tag "Predicate value"))
|
(boolean :tag "Predicate value"))
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
@ -316,7 +314,7 @@ ARGS should be a plist containing `:height', `:v-adjust', or `:face' properties.
|
||||||
('nerd-icons (apply #'nerd-icons-icon-for-file file args)))))
|
('nerd-icons (apply #'nerd-icons-icon-for-file file args)))))
|
||||||
|
|
||||||
(defun dashboard-octicon (name &rest args)
|
(defun dashboard-octicon (name &rest args)
|
||||||
"Get the formatted octicon.
|
"Get the formatted octicon by NAME.
|
||||||
ARGS should be a plist containing `:height', `:v-adjust', or `:face' properties."
|
ARGS should be a plist containing `:height', `:v-adjust', or `:face' properties."
|
||||||
(dashboard-replace-displayable
|
(dashboard-replace-displayable
|
||||||
(pcase dashboard-icon-type
|
(pcase dashboard-icon-type
|
||||||
|
@ -330,33 +328,48 @@ ARGS should be a plist containing `:height', `:v-adjust', or `:face' properties.
|
||||||
(all-the-icons-fileicon "emacs"
|
(all-the-icons-fileicon "emacs"
|
||||||
:height 1.1
|
:height 1.1
|
||||||
:v-adjust -0.05
|
:v-adjust -0.05
|
||||||
:face 'font-lock-keyword-face))
|
:face 'dashboard-footer-icon-face))
|
||||||
('nerd-icons
|
('nerd-icons
|
||||||
(nerd-icons-sucicon "nf-custom-emacs"
|
(nerd-icons-sucicon "nf-custom-emacs"
|
||||||
:height 1.1
|
:height 1.1
|
||||||
:v-adjust -0.05
|
:v-adjust -0.05
|
||||||
:face 'font-lock-keyword-face)))
|
:face 'dashboard-footer-icon-face)))
|
||||||
(propertize ">" 'face 'dashboard-footer))
|
(propertize ">" 'face 'dashboard-footer-icon-face))
|
||||||
"Footer's icon."
|
"Footer's icon."
|
||||||
:type 'string
|
:type 'string
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defcustom dashboard-heading-shorcut-format " (%s)"
|
||||||
|
"String for display key used in headings."
|
||||||
|
:type 'string
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-startup-banner 'official
|
(defcustom dashboard-startup-banner 'official
|
||||||
"Specify the startup banner.
|
"Specify the banner type to use.
|
||||||
Default value is `official', it displays the Emacs logo. `logo' displays Emacs
|
Value can be
|
||||||
alternative logo. If set to `ascii', the value of `dashboard-banner-ascii'
|
- \\='official displays the official Emacs logo.
|
||||||
will be used as the banner. An integer value is the index of text banner.
|
- \\='logo displays an alternative Emacs logo.
|
||||||
A string value must be a path to a .PNG or .TXT file. If the value is
|
- an integer which displays one of the text banners.
|
||||||
nil then no banner is displayed."
|
- a string that specifies the path of an custom banner
|
||||||
:type '(choice (const :tag "no banner" nil)
|
supported files types are gif/image/text/xbm.
|
||||||
(const :tag "offical" official)
|
- a cons of 2 strings which specifies the path of an image to use
|
||||||
|
and other path of a text file to use if image isn't supported.
|
||||||
|
- a list that can display an random banner, supported values are:
|
||||||
|
string (filepath), \\='official, \\='logo and integers."
|
||||||
|
:type '(choice (const :tag "official" official)
|
||||||
(const :tag "logo" logo)
|
(const :tag "logo" logo)
|
||||||
(const :tag "ascii" ascii)
|
(const :tag "ascii" ascii)
|
||||||
(integer :tag "index of a text banner")
|
(integer :tag "index of a text banner")
|
||||||
(string :tag "a path to an image or text banner")
|
(string :tag "path to an image or text banner")
|
||||||
(cons :tag "an image and text banner"
|
(cons :tag "image and text banner"
|
||||||
(string :tag "image banner path")
|
(string :tag "image banner path")
|
||||||
(string :tag "text banner path")))
|
(string :tag "text banner path"))
|
||||||
|
(repeat :tag "random banners"
|
||||||
|
(choice (string :tag "a path to an image or text banner")
|
||||||
|
(const :tag "official" official)
|
||||||
|
(const :tag "logo" logo)
|
||||||
|
(const :tag "ascii" ascii)
|
||||||
|
(integer :tag "index of a text banner"))))
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-item-generators
|
(defcustom dashboard-item-generators
|
||||||
|
@ -369,10 +382,10 @@ nil then no banner is displayed."
|
||||||
Will be of the form `(list-type . list-function)'.
|
Will be of the form `(list-type . list-function)'.
|
||||||
Possible values for list-type are: `recents', `bookmarks', `projects',
|
Possible values for list-type are: `recents', `bookmarks', `projects',
|
||||||
`agenda' ,`registers'."
|
`agenda' ,`registers'."
|
||||||
:type '(repeat (alist :key-type symbol :value-type function))
|
:type '(alist :key-type symbol :value-type function)
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-projects-backend 'projectile
|
(defcustom dashboard-projects-backend 'project-el
|
||||||
"The package that supplies the list of recent projects.
|
"The package that supplies the list of recent projects.
|
||||||
With the value `projectile', the projects widget uses the package
|
With the value `projectile', the projects widget uses the package
|
||||||
projectile (available in MELPA). With the value `project-el',
|
projectile (available in MELPA). With the value `project-el',
|
||||||
|
@ -385,6 +398,11 @@ installed."
|
||||||
(const :tag "Use project.el" project-el))
|
(const :tag "Use project.el" project-el))
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defcustom dashboard-remove-missing-entry nil
|
||||||
|
"If non-nil, try to remove missing entries."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
(defcustom dashboard-items
|
(defcustom dashboard-items
|
||||||
'((recents . 5)
|
'((recents . 5)
|
||||||
(bookmarks . 5)
|
(bookmarks . 5)
|
||||||
|
@ -443,13 +461,9 @@ Set to nil for unbounded."
|
||||||
:type 'string
|
:type 'string
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defvar recentf-list nil)
|
|
||||||
|
|
||||||
(defvar dashboard-buffer-name)
|
|
||||||
|
|
||||||
;;
|
|
||||||
;; Faces
|
|
||||||
;;
|
;;
|
||||||
|
;;; Faces
|
||||||
|
|
||||||
(defface dashboard-text-banner
|
(defface dashboard-text-banner
|
||||||
'((t (:inherit font-lock-keyword-face)))
|
'((t (:inherit font-lock-keyword-face)))
|
||||||
"Face used for text banners."
|
"Face used for text banners."
|
||||||
|
@ -480,9 +494,14 @@ Set to nil for unbounded."
|
||||||
"Face used for no items."
|
"Face used for no items."
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(defface dashboard-footer
|
(defface dashboard-footer-face
|
||||||
'((t (:inherit font-lock-doc-face)))
|
'((t (:inherit font-lock-doc-face)))
|
||||||
"Face used for widget headings."
|
"Face used for footer text."
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defface dashboard-footer-icon-face
|
||||||
|
'((t (:inherit dashboard-footer-face)))
|
||||||
|
"Face used for icon in footer."
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
(define-obsolete-face-alias
|
(define-obsolete-face-alias
|
||||||
|
@ -493,8 +512,8 @@ Set to nil for unbounded."
|
||||||
'dashboard-heading-face 'dashboard-heading "1.2.6")
|
'dashboard-heading-face 'dashboard-heading "1.2.6")
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Util
|
;;; Util
|
||||||
;;
|
|
||||||
(defmacro dashboard-mute-apply (&rest body)
|
(defmacro dashboard-mute-apply (&rest body)
|
||||||
"Execute BODY without message."
|
"Execute BODY without message."
|
||||||
(declare (indent 0) (debug t))
|
(declare (indent 0) (debug t))
|
||||||
|
@ -522,8 +541,8 @@ Set to nil for unbounded."
|
||||||
(if (zerop (% len width)) 0 1)))) ; add one if exceeed
|
(if (zerop (% len width)) 0 1)))) ; add one if exceeed
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Generic widget helpers
|
;;; Widget helpers
|
||||||
;;
|
|
||||||
(defun dashboard-subseq (seq end)
|
(defun dashboard-subseq (seq end)
|
||||||
"Return the subsequence of SEQ from 0 to END."
|
"Return the subsequence of SEQ from 0 to END."
|
||||||
(let ((len (length seq))) (butlast seq (- len (min len end)))))
|
(let ((len (length seq))) (butlast seq (- len (min len end)))))
|
||||||
|
@ -543,6 +562,9 @@ Set to nil for unbounded."
|
||||||
search-label
|
search-label
|
||||||
&optional no-next-line)
|
&optional no-next-line)
|
||||||
"Insert a shortcut SHORTCUT-CHAR for a given SEARCH-LABEL.
|
"Insert a shortcut SHORTCUT-CHAR for a given SEARCH-LABEL.
|
||||||
|
|
||||||
|
SHORTCUT-ID is the section identifier.
|
||||||
|
|
||||||
Optionally, provide NO-NEXT-LINE to move the cursor forward a line."
|
Optionally, provide NO-NEXT-LINE to move the cursor forward a line."
|
||||||
(let* (;; Ensure punctuation and upper case in search string is not
|
(let* (;; Ensure punctuation and upper case in search string is not
|
||||||
;; used to construct the `defun'
|
;; used to construct the `defun'
|
||||||
|
@ -577,6 +599,11 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
"Insert a page break line in dashboard buffer."
|
"Insert a page break line in dashboard buffer."
|
||||||
(dashboard-append dashboard-page-separator))
|
(dashboard-append dashboard-page-separator))
|
||||||
|
|
||||||
|
(defun dashboard-insert-newline (&optional n)
|
||||||
|
"Insert N times of newlines."
|
||||||
|
(dotimes (_ (or n 1))
|
||||||
|
(insert "\n")))
|
||||||
|
|
||||||
(defun dashboard-insert-heading (heading &optional shortcut icon)
|
(defun dashboard-insert-heading (heading &optional shortcut icon)
|
||||||
"Insert a widget HEADING in dashboard buffer, adding SHORTCUT, ICON if provided."
|
"Insert a widget HEADING in dashboard buffer, adding SHORTCUT, ICON if provided."
|
||||||
(when (and (dashboard-display-icons-p) dashboard-set-heading-icons)
|
(when (and (dashboard-display-icons-p) dashboard-set-heading-icons)
|
||||||
|
@ -615,10 +642,10 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
(let ((ov (make-overlay (- (point) (length heading)) (point) nil t)))
|
(let ((ov (make-overlay (- (point) (length heading)) (point) nil t)))
|
||||||
(overlay-put ov 'display (or (cdr (assoc heading dashboard-item-names)) heading))
|
(overlay-put ov 'display (or (cdr (assoc heading dashboard-item-names)) heading))
|
||||||
(overlay-put ov 'face 'dashboard-heading))
|
(overlay-put ov 'face 'dashboard-heading))
|
||||||
(when shortcut (insert (format " (%s)" shortcut))))
|
(when shortcut (insert (format dashboard-heading-shorcut-format shortcut))))
|
||||||
|
|
||||||
(defun dashboard-center-text (start end)
|
(defun dashboard--find-max-width (start end)
|
||||||
"Center the text between START and END."
|
"Return the max width within the region START and END."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char start)
|
(goto-char start)
|
||||||
(let ((width 0))
|
(let ((width 0))
|
||||||
|
@ -627,8 +654,13 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
(line-length (dashboard-str-len line-str)))
|
(line-length (dashboard-str-len line-str)))
|
||||||
(setq width (max width line-length)))
|
(setq width (max width line-length)))
|
||||||
(forward-line 1))
|
(forward-line 1))
|
||||||
(let ((prefix (propertize " " 'display `(space . (:align-to (- center ,(/ width 2)))))))
|
width)))
|
||||||
(add-text-properties start end `(line-prefix ,prefix indent-prefix ,prefix))))))
|
|
||||||
|
(defun dashboard-center-text (start end)
|
||||||
|
"Center the text between START and END."
|
||||||
|
(let* ((width (dashboard--find-max-width start end))
|
||||||
|
(prefix (propertize " " 'display `(space . (:align-to (- center ,(/ (float width) 2)))))))
|
||||||
|
(add-text-properties start end `(line-prefix ,prefix indent-prefix ,prefix))))
|
||||||
|
|
||||||
(defun dashboard-insert-center (&rest strings)
|
(defun dashboard-insert-center (&rest strings)
|
||||||
"Insert STRINGS in the center of the buffer."
|
"Insert STRINGS in the center of the buffer."
|
||||||
|
@ -637,8 +669,7 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
(dashboard-center-text start (point))))
|
(dashboard-center-text start (point))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; BANNER
|
;;; Banner
|
||||||
;;
|
|
||||||
|
|
||||||
(defun dashboard-get-banner-path (index)
|
(defun dashboard-get-banner-path (index)
|
||||||
"Return the full path to banner with index INDEX."
|
"Return the full path to banner with index INDEX."
|
||||||
|
@ -651,10 +682,9 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
;; - That function will only look at filenames, this one will inspect the file data itself.
|
;; - That function will only look at filenames, this one will inspect the file data itself.
|
||||||
(and (file-exists-p img) (ignore-errors (image-type-available-p (image-type img)))))
|
(and (file-exists-p img) (ignore-errors (image-type-available-p (image-type img)))))
|
||||||
|
|
||||||
(defun dashboard-choose-banner ()
|
(defun dashboard-choose-banner (banner)
|
||||||
"Return a plist specifying the chosen banner based on `dashboard-startup-banner'."
|
"Return a plist specifying the chosen banner based on BANNER."
|
||||||
(pcase dashboard-startup-banner
|
(pcase banner
|
||||||
('nil nil)
|
|
||||||
('official
|
('official
|
||||||
(append (when (image-type-available-p 'png)
|
(append (when (image-type-available-p 'png)
|
||||||
(list :image dashboard-banner-official-png))
|
(list :image dashboard-banner-official-png))
|
||||||
|
@ -666,24 +696,27 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
('ascii
|
('ascii
|
||||||
(append (list :text dashboard-banner-ascii)))
|
(append (list :text dashboard-banner-ascii)))
|
||||||
((pred integerp)
|
((pred integerp)
|
||||||
(list :text (dashboard-get-banner-path dashboard-startup-banner)))
|
(list :text (dashboard-get-banner-path banner)))
|
||||||
((pred stringp)
|
((pred stringp)
|
||||||
(pcase dashboard-startup-banner
|
(pcase banner
|
||||||
((pred (lambda (f) (not (file-exists-p f))))
|
((pred (lambda (f) (not (file-exists-p f))))
|
||||||
(message "could not find banner %s, use default instead" dashboard-startup-banner)
|
(message "could not find banner %s, use default instead" banner)
|
||||||
(list :text (dashboard-get-banner-path 1)))
|
(list :text (dashboard-get-banner-path 1)))
|
||||||
((pred (string-suffix-p ".txt"))
|
((pred (string-suffix-p ".txt"))
|
||||||
(list :text (if (file-exists-p dashboard-startup-banner)
|
(list :text (if (file-exists-p banner)
|
||||||
dashboard-startup-banner
|
banner
|
||||||
(message "could not find banner %s, use default instead" dashboard-startup-banner)
|
(message "could not find banner %s, use default instead" banner)
|
||||||
(dashboard-get-banner-path 1))))
|
(dashboard-get-banner-path 1))))
|
||||||
((pred dashboard--image-supported-p)
|
((pred dashboard--image-supported-p)
|
||||||
(list :image dashboard-startup-banner
|
(list :image banner
|
||||||
:text (dashboard-get-banner-path 1)))
|
:text (dashboard-get-banner-path 1)))
|
||||||
(_
|
(_
|
||||||
(message "unsupported file type %s" (file-name-nondirectory dashboard-startup-banner))
|
(message "unsupported file type %s" (file-name-nondirectory banner))
|
||||||
(list :text (dashboard-get-banner-path 1)))))
|
(list :text (dashboard-get-banner-path 1)))))
|
||||||
(`(,img . ,txt)
|
((and
|
||||||
|
(pred listp)
|
||||||
|
(pred (lambda (c) (not (proper-list-p c))))
|
||||||
|
`(,img . ,txt))
|
||||||
(list :image (if (dashboard--image-supported-p img)
|
(list :image (if (dashboard--image-supported-p img)
|
||||||
img
|
img
|
||||||
(message "could not find banner %s, use default instead" img)
|
(message "could not find banner %s, use default instead" img)
|
||||||
|
@ -692,57 +725,72 @@ If MESSAGEBUF is not nil then MSG is also written in message buffer."
|
||||||
txt
|
txt
|
||||||
(message "could not find banner %s, use default instead" txt)
|
(message "could not find banner %s, use default instead" txt)
|
||||||
(dashboard-get-banner-path 1))))
|
(dashboard-get-banner-path 1))))
|
||||||
|
((pred proper-list-p)
|
||||||
|
(let* ((max (length banner))
|
||||||
|
(choose (nth (random max) banner)))
|
||||||
|
(dashboard-choose-banner choose)))
|
||||||
(_
|
(_
|
||||||
(message "unsupported banner config %s" dashboard-startup-banner))))
|
(message "unsupported banner config %s" banner))))
|
||||||
|
|
||||||
(defun dashboard--type-is-gif-p (image-path)
|
(defun dashboard--image-animated-p (image-path)
|
||||||
"Return if image is a gif.
|
"Return if image is a gif or webp.
|
||||||
String -> bool.
|
String -> bool.
|
||||||
Argument IMAGE-PATH path to the image."
|
Argument IMAGE-PATH path to the image."
|
||||||
(eq 'gif (image-type image-path)))
|
(memq (image-type image-path) '(gif webp)))
|
||||||
|
|
||||||
|
(defun dashboard--type-is-xbm-p (image-path)
|
||||||
|
"Return if image is a xbm.
|
||||||
|
String -> bool.
|
||||||
|
Argument IMAGE-PATH path to the image."
|
||||||
|
(eq 'xbm (image-type image-path)))
|
||||||
|
|
||||||
(defun dashboard-insert-banner ()
|
(defun dashboard-insert-banner ()
|
||||||
"Insert the banner at the top of the dashboard."
|
"Insert the banner at the top of the dashboard."
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(when-let (banner (dashboard-choose-banner))
|
(when-let ((banner (dashboard-choose-banner dashboard-startup-banner)))
|
||||||
(insert "\n")
|
(insert "\n")
|
||||||
(let ((start (point))
|
(let ((start (point))
|
||||||
buffer-read-only
|
buffer-read-only
|
||||||
text-width
|
text-width
|
||||||
image-spec)
|
image-spec
|
||||||
(insert "\n")
|
(graphic-mode (display-graphic-p)))
|
||||||
|
(when graphic-mode (insert "\n"))
|
||||||
;; If specified, insert a text banner.
|
;; If specified, insert a text banner.
|
||||||
(when-let (txt (plist-get banner :text))
|
(when-let ((txt (plist-get banner :text)))
|
||||||
(if (eq dashboard-startup-banner 'ascii)
|
(if (file-exists-p txt)
|
||||||
(save-excursion (insert txt))
|
(insert-file-contents txt)
|
||||||
(insert-file-contents txt))
|
(save-excursion (insert txt)))
|
||||||
(put-text-property (point) (point-max) 'face 'dashboard-text-banner)
|
(put-text-property (point) (point-max) 'face 'dashboard-text-banner)
|
||||||
(setq text-width 0)
|
(setq text-width 0)
|
||||||
(while (not (eobp))
|
(while (not (eobp))
|
||||||
(let ((line-length (- (line-end-position) (line-beginning-position))))
|
(let ((line-length (- (line-end-position) (line-beginning-position))))
|
||||||
(if (< text-width line-length)
|
(when (< text-width line-length)
|
||||||
(setq text-width line-length)))
|
(setq text-width line-length)))
|
||||||
(forward-line 1)))
|
(forward-line 1)))
|
||||||
;; If specified, insert an image banner. When displayed in a graphical frame, this will
|
;; If specified, insert an image banner. When displayed in a graphical frame, this will
|
||||||
;; replace the text banner.
|
;; replace the text banner.
|
||||||
(when-let (img (plist-get banner :image))
|
(when-let ((img (plist-get banner :image)))
|
||||||
(let ((size-props
|
(let ((img-props
|
||||||
(append (when (> dashboard-image-banner-max-width 0)
|
(append (when (> dashboard-image-banner-max-width 0)
|
||||||
(list :max-width dashboard-image-banner-max-width))
|
(list :max-width dashboard-image-banner-max-width))
|
||||||
(when (> dashboard-image-banner-max-height 0)
|
(when (> dashboard-image-banner-max-height 0)
|
||||||
(list :max-height dashboard-image-banner-max-height)))))
|
(list :max-height dashboard-image-banner-max-height))
|
||||||
|
dashboard-image-extra-props)))
|
||||||
(setq image-spec
|
(setq image-spec
|
||||||
(cond ((dashboard--type-is-gif-p img)
|
(cond ((dashboard--image-animated-p img)
|
||||||
|
(create-image img))
|
||||||
|
((dashboard--type-is-xbm-p img)
|
||||||
(create-image img))
|
(create-image img))
|
||||||
((image-type-available-p 'imagemagick)
|
((image-type-available-p 'imagemagick)
|
||||||
(apply 'create-image img 'imagemagick nil size-props))
|
(apply 'create-image img 'imagemagick nil img-props))
|
||||||
(t
|
(t
|
||||||
(apply 'create-image img nil nil
|
(apply 'create-image img nil nil
|
||||||
(when (and (fboundp 'image-transforms-p)
|
(when (and (fboundp 'image-transforms-p)
|
||||||
(memq 'scale (funcall 'image-transforms-p)))
|
(memq 'scale (funcall 'image-transforms-p)))
|
||||||
size-props))))))
|
img-props))))))
|
||||||
(add-text-properties start (point) `(display ,image-spec))
|
(add-text-properties start (point) `(display ,image-spec))
|
||||||
(when (dashboard--type-is-gif-p img) (image-animate image-spec 0 t)))
|
(when (ignore-errors (image-multi-frame-p image-spec)) (image-animate image-spec 0 t)))
|
||||||
|
|
||||||
;; Finally, center the banner (if any).
|
;; Finally, center the banner (if any).
|
||||||
(when-let* ((text-align-spec `(space . (:align-to (- center ,(/ text-width 2)))))
|
(when-let* ((text-align-spec `(space . (:align-to (- center ,(/ text-width 2)))))
|
||||||
(image-align-spec `(space . (:align-to (- center (0.5 . ,image-spec)))))
|
(image-align-spec `(space . (:align-to (- center (0.5 . ,image-spec)))))
|
||||||
|
@ -761,28 +809,27 @@ Argument IMAGE-PATH path to the image."
|
||||||
(t nil)))
|
(t nil)))
|
||||||
(prefix (propertize " " 'display prop)))
|
(prefix (propertize " " 'display prop)))
|
||||||
(add-text-properties start (point) `(line-prefix ,prefix wrap-prefix ,prefix)))
|
(add-text-properties start (point) `(line-prefix ,prefix wrap-prefix ,prefix)))
|
||||||
(insert "\n\n")
|
(insert "\n")
|
||||||
(add-text-properties start (point) '(cursor-intangible t inhibit-isearch t))))
|
(add-text-properties start (point) '(cursor-intangible t inhibit-isearch t)))))
|
||||||
|
|
||||||
|
(defun dashboard-insert-banner-title ()
|
||||||
|
"Insert `dashboard-banner-logo-title' if it's non-nil."
|
||||||
(when dashboard-banner-logo-title
|
(when dashboard-banner-logo-title
|
||||||
(dashboard-insert-center (propertize dashboard-banner-logo-title 'face 'dashboard-banner-logo-title))
|
(dashboard-insert-center (propertize dashboard-banner-logo-title 'face 'dashboard-banner-logo-title))
|
||||||
(insert "\n\n"))
|
(insert "\n")))
|
||||||
(dashboard-insert-navigator)
|
|
||||||
(dashboard-insert-init-info))
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; INIT INFO
|
;;; Initialize info
|
||||||
;;
|
|
||||||
(defun dashboard-insert-init-info ()
|
(defun dashboard-insert-init-info ()
|
||||||
"Insert init info when `dashboard-set-init-info' is t."
|
"Insert init info."
|
||||||
(when dashboard-set-init-info
|
(let ((init-info (if (functionp dashboard-init-info)
|
||||||
(let ((init-info (if (functionp dashboard-init-info)
|
(funcall dashboard-init-info)
|
||||||
(funcall dashboard-init-info)
|
dashboard-init-info)))
|
||||||
dashboard-init-info)))
|
(dashboard-insert-center (propertize init-info 'face 'font-lock-comment-face))))
|
||||||
(dashboard-insert-center (propertize init-info 'face 'font-lock-comment-face)))))
|
|
||||||
|
|
||||||
(defun dashboard-insert-navigator ()
|
(defun dashboard-insert-navigator ()
|
||||||
"Insert Navigator of the dashboard."
|
"Insert Navigator of the dashboard."
|
||||||
(when (and dashboard-set-navigator dashboard-navigator-buttons)
|
(when dashboard-navigator-buttons
|
||||||
(dolist (line dashboard-navigator-buttons)
|
(dolist (line dashboard-navigator-buttons)
|
||||||
(dolist (btn line)
|
(dolist (btn line)
|
||||||
(let* ((icon (car btn))
|
(let* ((icon (car btn))
|
||||||
|
@ -814,12 +861,12 @@ Argument IMAGE-PATH path to the image."
|
||||||
:format "%[%t%]")
|
:format "%[%t%]")
|
||||||
(insert " ")))
|
(insert " ")))
|
||||||
(dashboard-center-text (line-beginning-position) (line-end-position))
|
(dashboard-center-text (line-beginning-position) (line-end-position))
|
||||||
(insert "\n"))
|
(insert "\n"))))
|
||||||
(insert "\n")))
|
|
||||||
|
|
||||||
(defmacro dashboard-insert-section (section-name list list-size shortcut-id shortcut-char action &rest widget-params)
|
(defmacro dashboard-insert-section (section-name list list-size shortcut-id shortcut-char action &rest widget-params)
|
||||||
"Add a section with SECTION-NAME and LIST of LIST-SIZE items to the dashboard.
|
"Add a section with SECTION-NAME and LIST of LIST-SIZE items to the dashboard.
|
||||||
|
|
||||||
|
SHORTCUT-ID is the section identifier.
|
||||||
SHORTCUT-CHAR is the keyboard shortcut used to access the section.
|
SHORTCUT-CHAR is the keyboard shortcut used to access the section.
|
||||||
ACTION is theaction taken when the user activates the widget button.
|
ACTION is theaction taken when the user activates the widget button.
|
||||||
WIDGET-PARAMS are passed to the \"widget-create\" function."
|
WIDGET-PARAMS are passed to the \"widget-create\" function."
|
||||||
|
@ -837,8 +884,8 @@ WIDGET-PARAMS are passed to the \"widget-create\" function."
|
||||||
(insert (propertize "\n --- No items ---" 'face 'dashboard-no-items-face)))))
|
(insert (propertize "\n --- No items ---" 'face 'dashboard-no-items-face)))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Section list
|
;;; Section list
|
||||||
;;
|
|
||||||
(defmacro dashboard-insert-section-list (section-name list action &rest rest)
|
(defmacro dashboard-insert-section-list (section-name list action &rest rest)
|
||||||
"Insert into SECTION-NAME a LIST of items, expanding ACTION and passing REST
|
"Insert into SECTION-NAME a LIST of items, expanding ACTION and passing REST
|
||||||
to widget creation."
|
to widget creation."
|
||||||
|
@ -874,27 +921,26 @@ to widget creation."
|
||||||
:format "%[%t%]")))
|
:format "%[%t%]")))
|
||||||
,list)))
|
,list)))
|
||||||
|
|
||||||
;; Footer
|
;;
|
||||||
|
;;; Footer
|
||||||
|
|
||||||
(defun dashboard-random-footer ()
|
(defun dashboard-random-footer ()
|
||||||
"Return a random footer from `dashboard-footer-messages'."
|
"Return a random footer from `dashboard-footer-messages'."
|
||||||
(nth (random (length dashboard-footer-messages)) dashboard-footer-messages))
|
(nth (random (length dashboard-footer-messages)) dashboard-footer-messages))
|
||||||
|
|
||||||
(defun dashboard-insert-footer ()
|
(defun dashboard-insert-footer ()
|
||||||
"Insert footer of dashboard."
|
"Insert footer of dashboard."
|
||||||
(when-let ((footer (and dashboard-set-footer (dashboard-random-footer))))
|
(when-let ((footer (dashboard-random-footer))
|
||||||
(insert "\n")
|
(footer-icon (dashboard-replace-displayable dashboard-footer-icon)))
|
||||||
(dashboard-insert-center
|
(dashboard-insert-center
|
||||||
(dashboard-replace-displayable dashboard-footer-icon)
|
(if (string-empty-p footer-icon) footer-icon
|
||||||
(if (and (stringp dashboard-footer-icon)
|
(concat footer-icon " "))
|
||||||
(not (string-empty-p dashboard-footer-icon)))
|
(propertize footer 'face 'dashboard-footer-face)
|
||||||
" "
|
|
||||||
"")
|
|
||||||
(propertize footer 'face 'dashboard-footer)
|
|
||||||
"\n")))
|
"\n")))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Truncate
|
;;; Truncate
|
||||||
;;
|
|
||||||
(defcustom dashboard-shorten-by-window-width nil
|
(defcustom dashboard-shorten-by-window-width nil
|
||||||
"Shorten path by window edges."
|
"Shorten path by window edges."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
|
@ -1043,8 +1089,8 @@ to widget creation."
|
||||||
align-length))
|
align-length))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Recentf
|
;;; Recentf
|
||||||
;;
|
|
||||||
(defcustom dashboard-recentf-show-base nil
|
(defcustom dashboard-recentf-show-base nil
|
||||||
"Show the base file name infront of it's path."
|
"Show the base file name infront of it's path."
|
||||||
:type '(choice
|
:type '(choice
|
||||||
|
@ -1067,7 +1113,10 @@ to widget creation."
|
||||||
(defun dashboard-insert-recents (list-size)
|
(defun dashboard-insert-recents (list-size)
|
||||||
"Add the list of LIST-SIZE items from recently edited files."
|
"Add the list of LIST-SIZE items from recently edited files."
|
||||||
(setq dashboard--recentf-cache-item-format nil)
|
(setq dashboard--recentf-cache-item-format nil)
|
||||||
(dashboard-mute-apply (recentf-mode 1) (recentf-cleanup))
|
(dashboard-mute-apply
|
||||||
|
(recentf-mode 1)
|
||||||
|
(when dashboard-remove-missing-entry
|
||||||
|
(ignore-errors (recentf-cleanup))))
|
||||||
(dashboard-insert-section
|
(dashboard-insert-section
|
||||||
"Recent Files:"
|
"Recent Files:"
|
||||||
(dashboard-shorten-paths recentf-list 'dashboard-recentf-alist 'recents)
|
(dashboard-shorten-paths recentf-list 'dashboard-recentf-alist 'recents)
|
||||||
|
@ -1091,8 +1140,8 @@ to widget creation."
|
||||||
(t (format dashboard-recentf-item-format filename path))))))
|
(t (format dashboard-recentf-item-format filename path))))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Bookmarks
|
;;; Bookmarks
|
||||||
;;
|
|
||||||
(defcustom dashboard-bookmarks-show-base t
|
(defcustom dashboard-bookmarks-show-base t
|
||||||
"Show the base file name infront of it's path."
|
"Show the base file name infront of it's path."
|
||||||
:type '(choice
|
:type '(choice
|
||||||
|
@ -1135,8 +1184,8 @@ to widget creation."
|
||||||
el)))
|
el)))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Projects
|
;;; Projects
|
||||||
;;
|
|
||||||
(defcustom dashboard-projects-switch-function
|
(defcustom dashboard-projects-switch-function
|
||||||
nil
|
nil
|
||||||
"Custom function to switch to projects from dashboard.
|
"Custom function to switch to projects from dashboard.
|
||||||
|
@ -1198,11 +1247,16 @@ Return function that returns a list of projects."
|
||||||
(cl-case dashboard-projects-backend
|
(cl-case dashboard-projects-backend
|
||||||
(`projectile
|
(`projectile
|
||||||
(require 'projectile)
|
(require 'projectile)
|
||||||
(dashboard-mute-apply (projectile-cleanup-known-projects))
|
(when dashboard-remove-missing-entry
|
||||||
|
(dashboard-mute-apply
|
||||||
|
(ignore-errors (projectile-cleanup-known-projects))))
|
||||||
(projectile-load-known-projects))
|
(projectile-load-known-projects))
|
||||||
(`project-el
|
(`project-el
|
||||||
(require 'project)
|
(require 'project)
|
||||||
(dashboard-mute-apply (dashboard-funcall-fboundp #'project-forget-zombie-projects))
|
(when dashboard-remove-missing-entry
|
||||||
|
(dashboard-mute-apply
|
||||||
|
(ignore-errors
|
||||||
|
(dashboard-funcall-fboundp #'project-forget-zombie-projects))))
|
||||||
(project-known-project-roots))
|
(project-known-project-roots))
|
||||||
(t
|
(t
|
||||||
(display-warning '(dashboard)
|
(display-warning '(dashboard)
|
||||||
|
@ -1227,8 +1281,8 @@ over custom backends."
|
||||||
:error)))))
|
:error)))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Org Agenda
|
;;; Org Agenda
|
||||||
;;
|
|
||||||
(defcustom dashboard-week-agenda t
|
(defcustom dashboard-week-agenda t
|
||||||
"Show agenda weekly if its not nil."
|
"Show agenda weekly if its not nil."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
|
@ -1359,12 +1413,12 @@ point."
|
||||||
(unless (and (not (org-entry-is-done-p))
|
(unless (and (not (org-entry-is-done-p))
|
||||||
(not (org-in-archived-heading-p))
|
(not (org-in-archived-heading-p))
|
||||||
(or (and scheduled-time
|
(or (and scheduled-time
|
||||||
(org-time-less-p scheduled-time due-date))
|
(time-less-p scheduled-time due-date))
|
||||||
(and deadline-time
|
(and deadline-time
|
||||||
(org-time-less-p deadline-time due-date))
|
(time-less-p deadline-time due-date))
|
||||||
(and entry-timestamp
|
(and entry-timestamp
|
||||||
(org-time-less-p now entry-timestamp)
|
(time-less-p now entry-timestamp)
|
||||||
(org-time-less-p entry-timestamp due-date))))
|
(time-less-p entry-timestamp due-date))))
|
||||||
(point))))
|
(point))))
|
||||||
|
|
||||||
(defun dashboard-filter-agenda-by-todo ()
|
(defun dashboard-filter-agenda-by-todo ()
|
||||||
|
@ -1437,8 +1491,8 @@ found for the strategy it uses nil predicate."
|
||||||
(cl-case strategy
|
(cl-case strategy
|
||||||
(`priority-up '>)
|
(`priority-up '>)
|
||||||
(`priority-down '<)
|
(`priority-down '<)
|
||||||
(`time-up 'org-time-less-p)
|
(`time-up 'time-less-p)
|
||||||
(`time-down (lambda (a b) (org-time-less-p b a)))
|
(`time-down (lambda (a b) (time-less-p b a)))
|
||||||
(`todo-state-up '>)
|
(`todo-state-up '>)
|
||||||
(`todo-state-down '<)))
|
(`todo-state-down '<)))
|
||||||
|
|
||||||
|
@ -1482,8 +1536,8 @@ to compare."
|
||||||
(format "%s" el)))
|
(format "%s" el)))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Registers
|
;;; Registers
|
||||||
;;
|
|
||||||
(defun dashboard-insert-registers (list-size)
|
(defun dashboard-insert-registers (list-size)
|
||||||
"Add the list of LIST-SIZE items of registers."
|
"Add the list of LIST-SIZE items of registers."
|
||||||
(require 'register)
|
(require 'register)
|
|
@ -1,6 +1,6 @@
|
||||||
;;; dashboard.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
|
;;; dashboard.el --- A startup screen extracted from Spacemacs -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; Copyright (c) 2016-2023 emacs-dashboard maintainers
|
;; Copyright (c) 2016-2024 emacs-dashboard maintainers
|
||||||
;;
|
;;
|
||||||
;; Author : Rakan Al-Hneiti <rakan.alhneiti@gmail.com>
|
;; Author : Rakan Al-Hneiti <rakan.alhneiti@gmail.com>
|
||||||
;; Maintainer : Jesús Martínez <jesusmartinez93@gmail.com>
|
;; Maintainer : Jesús Martínez <jesusmartinez93@gmail.com>
|
||||||
|
@ -27,6 +27,9 @@
|
||||||
|
|
||||||
(require 'dashboard-widgets)
|
(require 'dashboard-widgets)
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Externals
|
||||||
|
|
||||||
(declare-function bookmark-get-filename "ext:bookmark.el")
|
(declare-function bookmark-get-filename "ext:bookmark.el")
|
||||||
(declare-function bookmark-all-names "ext:bookmark.el")
|
(declare-function bookmark-all-names "ext:bookmark.el")
|
||||||
(declare-function dashboard-ls--dirs "ext:dashboard-ls.el")
|
(declare-function dashboard-ls--dirs "ext:dashboard-ls.el")
|
||||||
|
@ -38,6 +41,9 @@
|
||||||
|
|
||||||
(declare-function dashboard-refresh-buffer "dashboard.el")
|
(declare-function dashboard-refresh-buffer "dashboard.el")
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Customization
|
||||||
|
|
||||||
(defgroup dashboard nil
|
(defgroup dashboard nil
|
||||||
"Extensible startup screen."
|
"Extensible startup screen."
|
||||||
:group 'applications)
|
:group 'applications)
|
||||||
|
@ -45,17 +51,17 @@
|
||||||
;; Custom splash screen
|
;; Custom splash screen
|
||||||
(defvar dashboard-mode-map
|
(defvar dashboard-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map (kbd "C-p") 'dashboard-previous-line)
|
(define-key map (kbd "C-p") #'dashboard-previous-line)
|
||||||
(define-key map (kbd "C-n") 'dashboard-next-line)
|
(define-key map (kbd "C-n") #'dashboard-next-line)
|
||||||
(define-key map (kbd "<up>") 'dashboard-previous-line)
|
(define-key map (kbd "<up>") #'dashboard-previous-line)
|
||||||
(define-key map (kbd "<down>") 'dashboard-next-line)
|
(define-key map (kbd "<down>") #'dashboard-next-line)
|
||||||
(define-key map (kbd "k") 'dashboard-previous-line)
|
(define-key map (kbd "k") #'dashboard-previous-line)
|
||||||
(define-key map (kbd "j") 'dashboard-next-line)
|
(define-key map (kbd "j") #'dashboard-next-line)
|
||||||
(define-key map [tab] 'widget-forward)
|
(define-key map [tab] #'widget-forward)
|
||||||
(define-key map (kbd "C-i") 'widget-forward)
|
(define-key map (kbd "C-i") #'widget-forward)
|
||||||
(define-key map [backtab] 'widget-backward)
|
(define-key map [backtab] #'widget-backward)
|
||||||
(define-key map (kbd "RET") 'dashboard-return)
|
(define-key map (kbd "RET") #'dashboard-return)
|
||||||
(define-key map [mouse-1] 'dashboard-mouse-1)
|
(define-key map [mouse-1] #'dashboard-mouse-1)
|
||||||
(define-key map (kbd "}") #'dashboard-next-section)
|
(define-key map (kbd "}") #'dashboard-next-section)
|
||||||
(define-key map (kbd "{") #'dashboard-previous-section)
|
(define-key map (kbd "{") #'dashboard-previous-section)
|
||||||
|
|
||||||
|
@ -75,11 +81,21 @@
|
||||||
map)
|
map)
|
||||||
"Keymap for dashboard mode.")
|
"Keymap for dashboard mode.")
|
||||||
|
|
||||||
|
(defcustom dashboard-before-initialize-hook nil
|
||||||
|
"Hook that is run before dashboard buffer is initialized."
|
||||||
|
:group 'dashboard
|
||||||
|
:type 'hook)
|
||||||
|
|
||||||
(defcustom dashboard-after-initialize-hook nil
|
(defcustom dashboard-after-initialize-hook nil
|
||||||
"Hook that is run after dashboard buffer is initialized."
|
"Hook that is run after dashboard buffer is initialized."
|
||||||
:group 'dashboard
|
:group 'dashboard
|
||||||
:type 'hook)
|
:type 'hook)
|
||||||
|
|
||||||
|
(defcustom dashboard-hide-cursor nil
|
||||||
|
"Whether to hide the cursor in the dashboard."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
(define-derived-mode dashboard-mode special-mode "Dashboard"
|
(define-derived-mode dashboard-mode special-mode "Dashboard"
|
||||||
"Dashboard major mode for startup screen."
|
"Dashboard major mode for startup screen."
|
||||||
:group 'dashboard
|
:group 'dashboard
|
||||||
|
@ -91,6 +107,8 @@
|
||||||
(when (featurep 'display-line-numbers) (display-line-numbers-mode -1))
|
(when (featurep 'display-line-numbers) (display-line-numbers-mode -1))
|
||||||
(when (featurep 'page-break-lines) (page-break-lines-mode 1))
|
(when (featurep 'page-break-lines) (page-break-lines-mode 1))
|
||||||
(setq-local revert-buffer-function #'dashboard-refresh-buffer)
|
(setq-local revert-buffer-function #'dashboard-refresh-buffer)
|
||||||
|
(when dashboard-hide-cursor
|
||||||
|
(setq-local cursor-type nil))
|
||||||
(setq inhibit-startup-screen t
|
(setq inhibit-startup-screen t
|
||||||
buffer-read-only t
|
buffer-read-only t
|
||||||
truncate-lines t))
|
truncate-lines t))
|
||||||
|
@ -100,6 +118,42 @@
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'dashboard)
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defcustom dashboard-vertically-center-content nil
|
||||||
|
"Whether to vertically center content within the window."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defcustom dashboard-startupify-list
|
||||||
|
'(dashboard-insert-banner
|
||||||
|
dashboard-insert-newline
|
||||||
|
dashboard-insert-banner-title
|
||||||
|
dashboard-insert-newline
|
||||||
|
dashboard-insert-init-info
|
||||||
|
dashboard-insert-items
|
||||||
|
dashboard-insert-newline
|
||||||
|
dashboard-insert-footer)
|
||||||
|
"List of dashboard widgets (in order) to insert in dashboard buffer.
|
||||||
|
Avalaible functions:
|
||||||
|
`dashboard-insert-newline'
|
||||||
|
`dashboard-insert-page-break'
|
||||||
|
`dashboard-insert-banner'
|
||||||
|
`dashboard-insert-banner-title'
|
||||||
|
`dashboard-insert-navigator'
|
||||||
|
`dashboard-insert-init-info'
|
||||||
|
`dashboard-insert-items'
|
||||||
|
`dashboard-insert-footer'
|
||||||
|
|
||||||
|
You can also add your custom function or a lambda to the list.
|
||||||
|
example:
|
||||||
|
(lambda () (delete-char -1))"
|
||||||
|
:type '(repeat function)
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
|
(defcustom dashboard-navigation-cycle nil
|
||||||
|
"Non-nil cycle the section navigation."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'dashboard)
|
||||||
|
|
||||||
(defconst dashboard-buffer-name "*dashboard*"
|
(defconst dashboard-buffer-name "*dashboard*"
|
||||||
"Dashboard's buffer name.")
|
"Dashboard's buffer name.")
|
||||||
|
|
||||||
|
@ -110,8 +164,8 @@
|
||||||
"List of section starting positions.")
|
"List of section starting positions.")
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Util
|
;;; Util
|
||||||
;;
|
|
||||||
(defun dashboard--goto-line (line)
|
(defun dashboard--goto-line (line)
|
||||||
"Goto LINE."
|
"Goto LINE."
|
||||||
(goto-char (point-min)) (forward-line (1- line)))
|
(goto-char (point-min)) (forward-line (1- line)))
|
||||||
|
@ -126,13 +180,18 @@
|
||||||
(move-to-column column)))
|
(move-to-column column)))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Core
|
;;; Core
|
||||||
;;
|
|
||||||
|
(defun dashboard--separator ()
|
||||||
|
"Return separator used to search."
|
||||||
|
(concat "\n" dashboard-page-separator))
|
||||||
|
|
||||||
(defun dashboard--current-section ()
|
(defun dashboard--current-section ()
|
||||||
"Return section symbol in dashboard."
|
"Return section symbol in dashboard."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(if (and (search-backward dashboard-page-separator nil t)
|
(if-let* ((sep (dashboard--separator))
|
||||||
(search-forward dashboard-page-separator nil t))
|
((and (search-backward sep nil t)
|
||||||
|
(search-forward sep nil t))))
|
||||||
(let ((ln (thing-at-point 'line)))
|
(let ((ln (thing-at-point 'line)))
|
||||||
(cond ((string-match-p "Recent Files:" ln) 'recents)
|
(cond ((string-match-p "Recent Files:" ln) 'recents)
|
||||||
((string-match-p "Bookmarks:" ln) 'bookmarks)
|
((string-match-p "Bookmarks:" ln) 'bookmarks)
|
||||||
|
@ -145,39 +204,51 @@
|
||||||
(user-error "Failed searching dashboard section"))))
|
(user-error "Failed searching dashboard section"))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Navigation
|
;;; Navigation
|
||||||
;;
|
|
||||||
(defun dashboard-previous-section ()
|
(defun dashboard-previous-section ()
|
||||||
"Navigate back to previous section."
|
"Navigate forward to next section."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((current-position (point)) current-section-start previous-section-start)
|
(let* ((items-len (1- (length dashboard-items)))
|
||||||
(dolist (elt dashboard--section-starts)
|
(first-item (car (nth 0 dashboard-items)))
|
||||||
(when (and current-section-start (not previous-section-start))
|
(current (or (ignore-errors (dashboard--current-section))
|
||||||
(setq previous-section-start elt))
|
first-item))
|
||||||
(when (and (not current-section-start) (< elt current-position))
|
(items (mapcar #'car dashboard-items))
|
||||||
(setq current-section-start elt)))
|
(find (cl-position current items :test #'equal))
|
||||||
(goto-char (if (eq current-position current-section-start)
|
(prev-index (1- find))
|
||||||
previous-section-start
|
(prev (cond (dashboard-navigation-cycle
|
||||||
current-section-start))))
|
(if (< prev-index 0) (nth items-len items)
|
||||||
|
(nth prev-index items)))
|
||||||
|
(t
|
||||||
|
(if (< prev-index 0) (nth 0 items)
|
||||||
|
(nth prev-index items))))))
|
||||||
|
(dashboard--goto-section prev)))
|
||||||
|
|
||||||
(defun dashboard-next-section ()
|
(defun dashboard-next-section ()
|
||||||
"Navigate forward to next section."
|
"Navigate forward to next section."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((current-position (point)) next-section-start
|
(let* ((items-len (1- (length dashboard-items)))
|
||||||
(section-starts (reverse dashboard--section-starts)))
|
(last-item (car (nth items-len dashboard-items)))
|
||||||
(dolist (elt section-starts)
|
(current (or (ignore-errors (dashboard--current-section))
|
||||||
(when (and (not next-section-start)
|
last-item))
|
||||||
(> elt current-position))
|
(items (mapcar #'car dashboard-items))
|
||||||
(setq next-section-start elt)))
|
(find (cl-position current items :test #'equal))
|
||||||
(when next-section-start
|
(next-index (1+ find))
|
||||||
(goto-char next-section-start))))
|
(next (cond (dashboard-navigation-cycle
|
||||||
|
(or (nth next-index items)
|
||||||
|
(nth 0 items)))
|
||||||
|
(t
|
||||||
|
(if (< items-len next-index)
|
||||||
|
(nth (min items-len next-index) items)
|
||||||
|
(nth next-index items))))))
|
||||||
|
(dashboard--goto-section next)))
|
||||||
|
|
||||||
(defun dashboard--section-lines ()
|
(defun dashboard--section-lines ()
|
||||||
"Return a list of integer represent the starting line number of each section."
|
"Return a list of integer represent the starting line number of each section."
|
||||||
(let (pb-lst)
|
(let (pb-lst)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(while (search-forward dashboard-page-separator nil t)
|
(while (search-forward (dashboard--separator) nil t)
|
||||||
(when (ignore-errors (dashboard--current-section))
|
(when (ignore-errors (dashboard--current-section))
|
||||||
(push (line-number-at-pos) pb-lst))))
|
(push (line-number-at-pos) pb-lst))))
|
||||||
(setq pb-lst (reverse pb-lst))
|
(setq pb-lst (reverse pb-lst))
|
||||||
|
@ -232,8 +303,8 @@ Optional prefix ARG says how many lines to move; default is one line."
|
||||||
(beginning-of-line-text))
|
(beginning-of-line-text))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; ffap
|
;;; ffap
|
||||||
;;
|
|
||||||
(defun dashboard--goto-section (section)
|
(defun dashboard--goto-section (section)
|
||||||
"Move to SECTION declares in variable `dashboard-item-shortcuts'."
|
"Move to SECTION declares in variable `dashboard-item-shortcuts'."
|
||||||
(let ((fnc (intern (format "dashboard-jump-to-%s" section))))
|
(let ((fnc (intern (format "dashboard-jump-to-%s" section))))
|
||||||
|
@ -290,8 +361,8 @@ Optional argument ARGS adviced function arguments."
|
||||||
(advice-add 'ffap-guesser :around #'dashboard--ffap-guesser--adv)
|
(advice-add 'ffap-guesser :around #'dashboard--ffap-guesser--adv)
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Removal
|
;;; Removal
|
||||||
;;
|
|
||||||
(defun dashboard-remove-item-under ()
|
(defun dashboard-remove-item-under ()
|
||||||
"Remove a item from the current item section."
|
"Remove a item from the current item section."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -337,8 +408,8 @@ Optional argument ARGS adviced function arguments."
|
||||||
(interactive)) ; TODO: ..
|
(interactive)) ; TODO: ..
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Confirmation
|
;;; Confirmation
|
||||||
;;
|
|
||||||
(defun dashboard-return ()
|
(defun dashboard-return ()
|
||||||
"Hit return key in dashboard buffer."
|
"Hit return key in dashboard buffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -368,8 +439,8 @@ Optional argument ARGS adviced function arguments."
|
||||||
(setq track-mouse old-track-mouse))))
|
(setq track-mouse old-track-mouse))))
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; Insertion
|
;;; Insertion
|
||||||
;;
|
|
||||||
(defmacro dashboard--with-buffer (&rest body)
|
(defmacro dashboard--with-buffer (&rest body)
|
||||||
"Execute BODY in dashboard buffer."
|
"Execute BODY in dashboard buffer."
|
||||||
(declare (indent 0))
|
(declare (indent 0))
|
||||||
|
@ -377,17 +448,42 @@ Optional argument ARGS adviced function arguments."
|
||||||
(let ((inhibit-read-only t)) ,@body)
|
(let ((inhibit-read-only t)) ,@body)
|
||||||
(current-buffer)))
|
(current-buffer)))
|
||||||
|
|
||||||
(defun dashboard-maximum-section-length ()
|
(defun dashboard-insert-items ()
|
||||||
"For the just-inserted section, calculate the length of the longest line."
|
"Function to insert dashboard items.
|
||||||
(let ((max-line-length 0))
|
See `dashboard-item-generators' for all items available."
|
||||||
|
(let ((recentf-is-on (recentf-enabled-p))
|
||||||
|
(origial-recentf-list recentf-list))
|
||||||
|
(mapc (lambda (els)
|
||||||
|
(let* ((el (or (car-safe els) els))
|
||||||
|
(list-size
|
||||||
|
(or (cdr-safe els)
|
||||||
|
dashboard-items-default-length))
|
||||||
|
(item-generator
|
||||||
|
(cdr-safe (assoc el dashboard-item-generators))))
|
||||||
|
|
||||||
|
(insert "\n")
|
||||||
|
(push (point) dashboard--section-starts)
|
||||||
|
(funcall item-generator list-size)
|
||||||
|
(goto-char (point-max))
|
||||||
|
|
||||||
|
(when recentf-is-on
|
||||||
|
(setq recentf-list origial-recentf-list))))
|
||||||
|
dashboard-items)
|
||||||
|
|
||||||
|
(when dashboard-center-content
|
||||||
|
(dashboard-center-text
|
||||||
|
(if dashboard--section-starts
|
||||||
|
(car (last dashboard--section-starts))
|
||||||
|
(point))
|
||||||
|
(point-max)))
|
||||||
|
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(dashboard-previous-section)
|
(dolist (start dashboard--section-starts)
|
||||||
(while (not (eobp))
|
(goto-char start)
|
||||||
(setq max-line-length
|
(insert dashboard-page-separator)))
|
||||||
(max max-line-length
|
|
||||||
(- (line-end-position) (line-beginning-position))))
|
(insert "\n")
|
||||||
(forward-line 1)))
|
(insert dashboard-page-separator)))
|
||||||
max-line-length))
|
|
||||||
|
|
||||||
(defun dashboard-insert-startupify-lists ()
|
(defun dashboard-insert-startupify-lists ()
|
||||||
"Insert the list of widgets into the buffer."
|
"Insert the list of widgets into the buffer."
|
||||||
|
@ -395,55 +491,33 @@ Optional argument ARGS adviced function arguments."
|
||||||
(let ((inhibit-redisplay t)
|
(let ((inhibit-redisplay t)
|
||||||
(recentf-is-on (recentf-enabled-p))
|
(recentf-is-on (recentf-enabled-p))
|
||||||
(origial-recentf-list recentf-list)
|
(origial-recentf-list recentf-list)
|
||||||
(dashboard-num-recents (or (cdr (assoc 'recents dashboard-items)) 0))
|
(dashboard-num-recents (or (cdr (assoc 'recents dashboard-items)) 0)))
|
||||||
(max-line-length 0))
|
|
||||||
(when recentf-is-on
|
(when recentf-is-on
|
||||||
(setq recentf-list (dashboard-subseq recentf-list dashboard-num-recents)))
|
(setq recentf-list (dashboard-subseq recentf-list dashboard-num-recents)))
|
||||||
(dashboard--with-buffer
|
(dashboard--with-buffer
|
||||||
(when (or dashboard-force-refresh (not (eq major-mode 'dashboard-mode)))
|
(when (or dashboard-force-refresh (not (eq major-mode 'dashboard-mode)))
|
||||||
|
(run-hooks 'dashboard-before-initialize-hook)
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(dashboard-insert-banner)
|
|
||||||
(insert "\n")
|
|
||||||
(setq dashboard--section-starts nil)
|
(setq dashboard--section-starts nil)
|
||||||
(mapc (lambda (els)
|
|
||||||
(let* ((el (or (car-safe els) els))
|
(mapc (lambda (fn)
|
||||||
(list-size
|
(funcall fn))
|
||||||
(or (cdr-safe els)
|
dashboard-startupify-list)
|
||||||
dashboard-items-default-length))
|
|
||||||
(item-generator
|
(when dashboard-vertically-center-content
|
||||||
(cdr-safe (assoc el dashboard-item-generators))))
|
(goto-char (point-min))
|
||||||
(push (point) dashboard--section-starts)
|
(when-let* ((content-height (cdr (window-absolute-pixel-position (point-max))))
|
||||||
(funcall item-generator list-size)
|
(vertical-padding (floor (/ (- (window-pixel-height) content-height) 2)))
|
||||||
(goto-char (point-max))
|
((> vertical-padding 0))
|
||||||
;; add a newline so the next section-name doesn't get include
|
(vertical-lines (1- (floor (/ vertical-padding (line-pixel-height)))))
|
||||||
;; on the same line.
|
((> vertical-lines 0)))
|
||||||
(insert "\n")
|
(insert (make-string vertical-lines ?\n))))
|
||||||
(when recentf-is-on
|
|
||||||
(setq recentf-list origial-recentf-list))
|
|
||||||
(setq max-line-length
|
|
||||||
(max max-line-length (dashboard-maximum-section-length)))))
|
|
||||||
dashboard-items)
|
|
||||||
(when dashboard-center-content
|
|
||||||
(dashboard-center-text
|
|
||||||
(if dashboard--section-starts
|
|
||||||
(car (last dashboard--section-starts))
|
|
||||||
(point))
|
|
||||||
(point-max)))
|
|
||||||
(save-excursion
|
|
||||||
(dolist (start dashboard--section-starts)
|
|
||||||
(goto-char start)
|
|
||||||
(delete-char -1) ; delete the newline we added previously
|
|
||||||
(insert dashboard-page-separator)))
|
|
||||||
(progn
|
|
||||||
(delete-char -1)
|
|
||||||
(insert dashboard-page-separator))
|
|
||||||
(dashboard-insert-footer)
|
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(dashboard-mode)))
|
(dashboard-mode)))
|
||||||
(when recentf-is-on
|
(when recentf-is-on
|
||||||
(setq recentf-list origial-recentf-list))))
|
(setq recentf-list origial-recentf-list))))
|
||||||
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun dashboard-open (&rest _)
|
(defun dashboard-open (&rest _)
|
||||||
"Open (or refresh) the *dashboard* buffer."
|
"Open (or refresh) the *dashboard* buffer."
|
||||||
|
@ -462,24 +536,21 @@ Optional argument ARGS adviced function arguments."
|
||||||
(with-selected-window space-win
|
(with-selected-window space-win
|
||||||
(dashboard-insert-startupify-lists)))))
|
(dashboard-insert-startupify-lists)))))
|
||||||
|
|
||||||
|
(defun dashboard-initialize ()
|
||||||
|
"Switch to dashboard and run `dashboard-after-initialize-hook'."
|
||||||
|
(switch-to-buffer dashboard-buffer-name)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(redisplay)
|
||||||
|
(run-hooks 'dashboard-after-initialize-hook))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun dashboard-setup-startup-hook ()
|
(defun dashboard-setup-startup-hook ()
|
||||||
"Setup post initialization hooks.
|
"Setup post initialization hooks unless a command line argument is provided."
|
||||||
If a command line argument is provided, assume a filename and skip displaying
|
(when (< (length command-line-args) 2) ;; Assume no file name passed
|
||||||
Dashboard."
|
(add-hook 'window-size-change-functions #'dashboard-resize-on-hook 100)
|
||||||
(when (< (length command-line-args) 2)
|
(add-hook 'window-setup-hook #'dashboard-resize-on-hook)
|
||||||
(add-hook 'window-setup-hook (lambda ()
|
(add-hook 'after-init-hook #'dashboard-insert-startupify-lists)
|
||||||
;; 100 means `dashboard-resize-on-hook' will run last
|
(add-hook 'emacs-startup-hook #'dashboard-initialize)))
|
||||||
(add-hook 'window-size-change-functions 'dashboard-resize-on-hook 100)
|
|
||||||
(dashboard-resize-on-hook)))
|
|
||||||
(add-hook 'after-init-hook (lambda ()
|
|
||||||
;; Display useful lists of items
|
|
||||||
(dashboard-insert-startupify-lists)))
|
|
||||||
(add-hook 'emacs-startup-hook (lambda ()
|
|
||||||
(switch-to-buffer dashboard-buffer-name)
|
|
||||||
(goto-char (point-min))
|
|
||||||
(redisplay)
|
|
||||||
(run-hooks 'dashboard-after-initialize-hook)))))
|
|
||||||
|
|
||||||
(provide 'dashboard)
|
(provide 'dashboard)
|
||||||
;;; dashboard.el ends here
|
;;; dashboard.el ends here
|
|
@ -1,2 +0,0 @@
|
||||||
;;; Generated package description from devdocs.el -*- no-byte-compile: t -*-
|
|
||||||
(define-package "devdocs" "20230220.2042" "Emacs viewer for DevDocs" '((emacs "27.1")) :commit "2988d4d201df16d72c3bea465d2b93b554dbddfc" :authors '(("Augusto Stoffel" . "arstoffel@gmail.com")) :maintainer '("Augusto Stoffel" . "arstoffel@gmail.com") :keywords '("help") :url "https://github.com/astoff/devdocs.el")
|
|
|
@ -1,29 +1,29 @@
|
||||||
;;; devdocs-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; devdocs-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "devdocs" "devdocs.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from devdocs.el
|
;;; Generated autoloads from devdocs.el
|
||||||
|
|
||||||
(autoload 'devdocs-delete "devdocs" "\
|
(autoload 'devdocs-delete "devdocs" "\
|
||||||
Delete DevDocs documentation.
|
Delete DevDocs documentation.
|
||||||
DOC is a document metadata alist.
|
DOC is a document metadata alist.
|
||||||
|
|
||||||
\(fn DOC)" t nil)
|
(fn DOC)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-install "devdocs" "\
|
(autoload 'devdocs-install "devdocs" "\
|
||||||
Download and install DevDocs documentation.
|
Download and install DevDocs documentation.
|
||||||
DOC is a document metadata alist.
|
DOC is a document slug or metadata alist. If the document is
|
||||||
|
already installed, reinstall it.
|
||||||
\(fn DOC)" t nil)
|
|
||||||
|
|
||||||
|
(fn DOC)" t)
|
||||||
(autoload 'devdocs-update-all "devdocs" "\
|
(autoload 'devdocs-update-all "devdocs" "\
|
||||||
Reinstall all documents with a new version available." t nil)
|
Reinstall all documents with a new version available." t)
|
||||||
|
|
||||||
(autoload 'devdocs-lookup "devdocs" "\
|
(autoload 'devdocs-lookup "devdocs" "\
|
||||||
Look up a DevDocs documentation entry.
|
Look up a DevDocs documentation entry.
|
||||||
|
|
||||||
|
@ -34,26 +34,27 @@ and set `devdocs-current-docs' for this buffer.
|
||||||
|
|
||||||
If INITIAL-INPUT is not nil, insert it into the minibuffer.
|
If INITIAL-INPUT is not nil, insert it into the minibuffer.
|
||||||
|
|
||||||
\(fn &optional ASK-DOCS INITIAL-INPUT)" t nil)
|
(fn &optional ASK-DOCS INITIAL-INPUT)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-peruse "devdocs" "\
|
(autoload 'devdocs-peruse "devdocs" "\
|
||||||
Read a document from the first page.
|
Read a document from the first page.
|
||||||
|
|
||||||
\(fn DOC)" t nil)
|
(fn DOC)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-search "devdocs" "\
|
(autoload 'devdocs-search "devdocs" "\
|
||||||
Search for QUERY in the DevDocs website.
|
Search for QUERY in the DevDocs website.
|
||||||
|
|
||||||
\(fn QUERY)" t nil)
|
(fn QUERY)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "devdocs" '("devdocs-"))
|
(register-definition-prefixes "devdocs" '("devdocs-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'devdocs-autoloads)
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; devdocs-autoloads.el ends here
|
;;; devdocs-autoloads.el ends here
|
14
code/elpa/devdocs-20240301.1838/devdocs-pkg.el
Normal file
14
code/elpa/devdocs-20240301.1838/devdocs-pkg.el
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
(define-package "devdocs" "20240301.1838" "Emacs viewer for DevDocs"
|
||||||
|
'((emacs "27.1"))
|
||||||
|
:commit "3424436f333955b39a0803ce9781aaffaae003f5" :authors
|
||||||
|
'(("Augusto Stoffel" . "arstoffel@gmail.com"))
|
||||||
|
:maintainers
|
||||||
|
'(("Augusto Stoffel" . "arstoffel@gmail.com"))
|
||||||
|
:maintainer
|
||||||
|
'("Augusto Stoffel" . "arstoffel@gmail.com")
|
||||||
|
:keywords
|
||||||
|
'("help")
|
||||||
|
:url "https://github.com/astoff/devdocs.el")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
;; Author: Augusto Stoffel <arstoffel@gmail.com>
|
;; Author: Augusto Stoffel <arstoffel@gmail.com>
|
||||||
;; Keywords: help
|
;; Keywords: help
|
||||||
;; Package-Version: 20230220.2042
|
|
||||||
;; Package-Commit: 2988d4d201df16d72c3bea465d2b93b554dbddfc
|
|
||||||
;; URL: https://github.com/astoff/devdocs.el
|
;; URL: https://github.com/astoff/devdocs.el
|
||||||
;; Package-Requires: ((emacs "27.1"))
|
;; Package-Requires: ((emacs "27.1"))
|
||||||
;; Version: 0.5
|
;; Version: 0.5
|
||||||
|
@ -40,7 +38,8 @@
|
||||||
(require 'shr)
|
(require 'shr)
|
||||||
(require 'url-expand)
|
(require 'url-expand)
|
||||||
(eval-when-compile
|
(eval-when-compile
|
||||||
(require 'let-alist))
|
(require 'let-alist)
|
||||||
|
(require 'subr-x))
|
||||||
|
|
||||||
(unless (libxml-available-p)
|
(unless (libxml-available-p)
|
||||||
(display-warning 'devdocs "This package requires Emacs to be compiled with libxml2"))
|
(display-warning 'devdocs "This package requires Emacs to be compiled with libxml2"))
|
||||||
|
@ -131,6 +130,12 @@ its return value; take the necessary precautions."
|
||||||
|
|
||||||
;;; Documentation management
|
;;; Documentation management
|
||||||
|
|
||||||
|
(defalias 'devdocs--json-parse-buffer
|
||||||
|
(if (json-available-p)
|
||||||
|
(lambda () (json-parse-buffer :object-type 'alist))
|
||||||
|
(require 'json)
|
||||||
|
#'json-read))
|
||||||
|
|
||||||
(defun devdocs--doc-metadata (slug)
|
(defun devdocs--doc-metadata (slug)
|
||||||
"Return the metadata of an installed document named SLUG."
|
"Return the metadata of an installed document named SLUG."
|
||||||
(let ((file (expand-file-name (concat slug "/metadata") devdocs-data-dir)))
|
(let ((file (expand-file-name (concat slug "/metadata") devdocs-data-dir)))
|
||||||
|
@ -158,7 +163,7 @@ If necessary, download data from `devdocs-site-url'."
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(url-insert-file-contents
|
(url-insert-file-contents
|
||||||
(format "%s/docs.json" devdocs-site-url))
|
(format "%s/docs.json" devdocs-site-url))
|
||||||
(json-read))))
|
(devdocs--json-parse-buffer))))
|
||||||
|
|
||||||
(defun devdocs--doc-title (doc)
|
(defun devdocs--doc-title (doc)
|
||||||
"Title of document DOC.
|
"Title of document DOC.
|
||||||
|
@ -201,9 +206,14 @@ DOC is a document metadata alist."
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun devdocs-install (doc)
|
(defun devdocs-install (doc)
|
||||||
"Download and install DevDocs documentation.
|
"Download and install DevDocs documentation.
|
||||||
DOC is a document metadata alist."
|
DOC is a document slug or metadata alist. If the document is
|
||||||
|
already installed, reinstall it."
|
||||||
(interactive (list (devdocs--read-document "Install documentation: " nil t)))
|
(interactive (list (devdocs--read-document "Install documentation: " nil t)))
|
||||||
(make-directory devdocs-data-dir t)
|
(make-directory devdocs-data-dir t)
|
||||||
|
(unless (listp doc)
|
||||||
|
(setq doc (or (seq-find (lambda (it) (string= doc (alist-get 'slug it)))
|
||||||
|
(devdocs--available-docs))
|
||||||
|
(user-error "No such document: %s" doc))))
|
||||||
(let* ((slug (alist-get 'slug doc))
|
(let* ((slug (alist-get 'slug doc))
|
||||||
(mtime (alist-get 'mtime doc))
|
(mtime (alist-get 'mtime doc))
|
||||||
(temp (make-temp-file "devdocs-" t))
|
(temp (make-temp-file "devdocs-" t))
|
||||||
|
@ -211,16 +221,15 @@ DOC is a document metadata alist."
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(url-insert-file-contents (format "%s/%s/db.json?%s" devdocs-cdn-url slug mtime))
|
(url-insert-file-contents (format "%s/%s/db.json?%s" devdocs-cdn-url slug mtime))
|
||||||
(dolist-with-progress-reporter
|
(dolist-with-progress-reporter
|
||||||
(entry (let ((json-key-type 'string))
|
(entry (devdocs--json-parse-buffer))
|
||||||
(json-read)))
|
|
||||||
"Installing documentation..."
|
"Installing documentation..."
|
||||||
(with-temp-file (expand-file-name
|
(with-temp-file (expand-file-name
|
||||||
(url-hexify-string (format "%s.html" (car entry))) temp)
|
(url-hexify-string (format "%s.html" (car entry))) temp)
|
||||||
(push (car entry) pages)
|
(push (symbol-name (car entry)) pages)
|
||||||
(insert (cdr entry)))))
|
(insert (cdr entry)))))
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(url-insert-file-contents (format "%s/%s/index.json?%s" devdocs-cdn-url slug mtime))
|
(url-insert-file-contents (format "%s/%s/index.json?%s" devdocs-cdn-url slug mtime))
|
||||||
(let ((index (json-read)))
|
(let ((index (devdocs--json-parse-buffer)))
|
||||||
(push `(pages . ,(vconcat (nreverse pages))) index)
|
(push `(pages . ,(vconcat (nreverse pages))) index)
|
||||||
(with-temp-file (expand-file-name "index" temp)
|
(with-temp-file (expand-file-name "index" temp)
|
||||||
(prin1 index (current-buffer)))))
|
(prin1 index (current-buffer)))))
|
||||||
|
@ -338,7 +347,7 @@ with the order of appearance in the text."
|
||||||
(current (seq-position entries nil pred)))
|
(current (seq-position entries nil pred)))
|
||||||
(unless current (user-error "No current entry"))
|
(unless current (user-error "No current entry"))
|
||||||
(devdocs--render
|
(devdocs--render
|
||||||
(or (ignore-error 'args-out-of-range (elt entries (+ count current)))
|
(or (ignore-error args-out-of-range (elt entries (+ count current)))
|
||||||
(user-error "No %s entry" (if (< count 0) "previous" "next")))))))
|
(user-error "No %s entry" (if (< count 0) "previous" "next")))))))
|
||||||
|
|
||||||
(defun devdocs-previous-entry (count)
|
(defun devdocs-previous-entry (count)
|
||||||
|
@ -433,7 +442,8 @@ Interactively, read a page name with completion."
|
||||||
(pcase (string-to-char path)
|
(pcase (string-to-char path)
|
||||||
('?/ path)
|
('?/ path)
|
||||||
('?# (concat (devdocs--path-file base) path))
|
('?# (concat (devdocs--path-file base) path))
|
||||||
(_ (seq-rest ;; drop leading slash
|
(_ (string-remove-prefix
|
||||||
|
"/"
|
||||||
(url-expander-remove-relative-links ;; undocumented function!
|
(url-expander-remove-relative-links ;; undocumented function!
|
||||||
(concat (file-name-directory base) path))))))
|
(concat (file-name-directory base) path))))))
|
||||||
|
|
||||||
|
@ -475,7 +485,7 @@ fragment part of ENTRY.path."
|
||||||
(url-hexify-string (devdocs--path-file .path)))
|
(url-hexify-string (devdocs--path-file .path)))
|
||||||
devdocs-data-dir)))
|
devdocs-data-dir)))
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(setq-local shr-target-id (or .fragment (devdocs--path-fragment .path)))
|
(setq-local shr-target-id (url-unhex-string (or .fragment (devdocs--path-fragment .path))))
|
||||||
;; TODO: cl-progv here for shr settings?
|
;; TODO: cl-progv here for shr settings?
|
||||||
(shr-insert-document
|
(shr-insert-document
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
|
@ -1,70 +0,0 @@
|
||||||
;;; devdocs-browser-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
|
||||||
;;
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "devdocs-browser" "devdocs-browser.el" (0 0
|
|
||||||
;;;;;; 0 0))
|
|
||||||
;;; Generated autoloads from devdocs-browser.el
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-list-docs "devdocs-browser" "\
|
|
||||||
Get doc metadata lists, reload cache if REFRESH-CACHE.
|
|
||||||
|
|
||||||
\(fn &optional REFRESH-CACHE)" nil nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-update-docs "devdocs-browser" "\
|
|
||||||
Update doc metadata list.
|
|
||||||
To upgrade docs content, see `devdocs-browser-upgrade-doc'." t nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-install-doc "devdocs-browser" "\
|
|
||||||
Install doc by SLUG-OR-NAME.
|
|
||||||
When called interactively, user can choose from the list.
|
|
||||||
When called interactively with prefix, or FORCE is t, reinstall existing doc.
|
|
||||||
|
|
||||||
\(fn SLUG-OR-NAME &optional FORCE)" t nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-uninstall-doc "devdocs-browser" "\
|
|
||||||
Uninstall doc by SLUG.
|
|
||||||
When called interactively, user can choose from the list.
|
|
||||||
|
|
||||||
\(fn SLUG)" t nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-upgrade-doc "devdocs-browser" "\
|
|
||||||
Upgrade doc by SLUG, return t if upgrade success.
|
|
||||||
Also download new version of offline data if
|
|
||||||
there's offline data for current version.
|
|
||||||
When called interactively, user can choose from list.
|
|
||||||
You may need to call `devdocs-browser-update-docs' first.
|
|
||||||
|
|
||||||
\(fn SLUG)" t nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-upgrade-all-docs "devdocs-browser" "\
|
|
||||||
Upgrade all docs." t nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-open-in "devdocs-browser" "\
|
|
||||||
Open entry in specified docs SLUG-OR-NAME-LIST.
|
|
||||||
When called interactively, user can choose from the list.
|
|
||||||
|
|
||||||
\(fn SLUG-OR-NAME-LIST)" t nil)
|
|
||||||
|
|
||||||
(autoload 'devdocs-browser-open "devdocs-browser" "\
|
|
||||||
Open entry in active docs.
|
|
||||||
Active docs are specified by `devdocs-browser-active-docs',
|
|
||||||
or `devdocs-browser-major-mode-docs-alist',
|
|
||||||
or the current doc type if called in a devdocs eww buffer.
|
|
||||||
When all of them are nil, all installed docs are used." t nil)
|
|
||||||
|
|
||||||
(register-definition-prefixes "devdocs-browser" '("devdocs-browser-"))
|
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
|
||||||
;; version-control: never
|
|
||||||
;; no-byte-compile: t
|
|
||||||
;; no-update-autoloads: t
|
|
||||||
;; coding: utf-8
|
|
||||||
;; End:
|
|
||||||
;;; devdocs-browser-autoloads.el ends here
|
|
|
@ -1,2 +0,0 @@
|
||||||
;;; Generated package description from devdocs-browser.el -*- no-byte-compile: t -*-
|
|
||||||
(define-package "devdocs-browser" "20230112.1554" "Browse devdocs.io documents using EWW" '((emacs "27.1")) :commit "c316c93306527fcb4069adde94402a48605d42d5" :authors '(("blahgeek" . "i@blahgeek.com")) :maintainer '("blahgeek" . "i@blahgeek.com") :keywords '("docs" "help" "tools") :url "https://github.com/blahgeek/emacs-devdocs-browser")
|
|
|
@ -1,808 +0,0 @@
|
||||||
;;; devdocs-browser.el --- Browse devdocs.io documents using EWW -*- lexical-binding: t; -*-
|
|
||||||
|
|
||||||
;; Copyright (C) 2021
|
|
||||||
|
|
||||||
;; Author: blahgeek <i@blahgeek.com>
|
|
||||||
;; URL: https://github.com/blahgeek/emacs-devdocs-browser
|
|
||||||
;; Package-Version: 20230112.1554
|
|
||||||
;; Package-Commit: c316c93306527fcb4069adde94402a48605d42d5
|
|
||||||
;; Version: 20210525
|
|
||||||
;; Keywords: docs, help, tools
|
|
||||||
;; Package-Requires: ((emacs "27.1"))
|
|
||||||
|
|
||||||
;; This program 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.
|
|
||||||
|
|
||||||
;; This program 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
;;; Commentary:
|
|
||||||
|
|
||||||
;; Browse devdocs.io documents inside Emacs using EWW.
|
|
||||||
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
(require 'files)
|
|
||||||
(require 'shr)
|
|
||||||
(require 'eww)
|
|
||||||
(require 'eldoc)
|
|
||||||
(require 'imenu)
|
|
||||||
|
|
||||||
|
|
||||||
(defgroup devdocs-browser nil
|
|
||||||
"Browse devdocs.io."
|
|
||||||
:group 'tools
|
|
||||||
:group 'web)
|
|
||||||
|
|
||||||
(defcustom devdocs-browser-cache-directory
|
|
||||||
(expand-file-name "devdocs-browser" user-emacs-directory)
|
|
||||||
"Directory to store devdocs cache files."
|
|
||||||
:type 'directory
|
|
||||||
:group 'devdocs-browser)
|
|
||||||
|
|
||||||
(defcustom devdocs-browser-base-url "https://devdocs.io/"
|
|
||||||
"Base URL to fetch json metadata files."
|
|
||||||
:type 'string)
|
|
||||||
|
|
||||||
(defcustom devdocs-browser-doc-base-url "https://documents.devdocs.io/"
|
|
||||||
"Base URL for doc contents."
|
|
||||||
:type 'string)
|
|
||||||
|
|
||||||
(defcustom devdocs-browser-major-mode-docs-alist
|
|
||||||
'((c++-mode . ("cpp"))
|
|
||||||
(c-mode . ("c"))
|
|
||||||
(go-mode . ("go"))
|
|
||||||
(python-mode . ("Python"))
|
|
||||||
(emacs-lisp-mode . ("elisp"))
|
|
||||||
(rust-mode . ("rust"))
|
|
||||||
(cmake-mode . ("CMake")))
|
|
||||||
"Alist of MAJOR-MODE and list of docset names.
|
|
||||||
When calling `devdocs-browser-open', this variable will be used
|
|
||||||
to pick a list of docsets based on the current MAJOR-MODE.
|
|
||||||
Docset name may be SLUG (e.g. 'python~3.8') or NAME (e.g. 'Python'),
|
|
||||||
if it's a NAME and multiple choices are possible,
|
|
||||||
one of the installed docs with the NAME will be used.
|
|
||||||
Also see `devdocs-browser-active-docs'."
|
|
||||||
:type '(alist :key-type function
|
|
||||||
:value-type (list string)))
|
|
||||||
|
|
||||||
(defvar-local devdocs-browser-active-docs
|
|
||||||
nil
|
|
||||||
"List of docset names used by `devdocs-browser-open' to pick docsets.
|
|
||||||
If this var is set to non-nil,
|
|
||||||
it have higher priority than `devdocs-browser-major-mode-docs-alist'.
|
|
||||||
See `devdocs-browser-major-mode-docs-alist' for the meaning of NAME.")
|
|
||||||
|
|
||||||
(defcustom devdocs-browser-highlight-lang-mode-alist '()
|
|
||||||
"Alist of language name and MAJOR-MODE, to highlight HTML pre blocks.
|
|
||||||
If language is not found in this alist,
|
|
||||||
`devdocs-browser-highlight-lang-mode-alist-default' will be used.
|
|
||||||
See https://prismjs.com/ for list of language names."
|
|
||||||
:type '(alist :key-type string
|
|
||||||
:value-type function))
|
|
||||||
|
|
||||||
(defvar devdocs-browser-highlight-lang-mode-alist-default
|
|
||||||
'(("html" . html-mode)
|
|
||||||
("xml" . xml-mode)
|
|
||||||
("css" . css-mode)
|
|
||||||
("clike" . c-mode)
|
|
||||||
("javascript" . js-mode)
|
|
||||||
("js" . js-mode)
|
|
||||||
("jsx" . js-mode)
|
|
||||||
("bash" . sh-mode)
|
|
||||||
("shell" . sh-mode)
|
|
||||||
("c" . c-mode)
|
|
||||||
("cpp" . c++-mode)
|
|
||||||
("cmake" . cmake-mode)
|
|
||||||
("go" . go-mode)
|
|
||||||
("haskell" . haskell-mode)
|
|
||||||
("hs" . haskell-mode)
|
|
||||||
("java" . java-mode)
|
|
||||||
("json" . js-mode)
|
|
||||||
("elisp" . elisp-mode)
|
|
||||||
("emacs" . elisp-mode)
|
|
||||||
("lua" . lua-mode)
|
|
||||||
("makefile" . makefile-mode)
|
|
||||||
("markdown" . markdown-mode)
|
|
||||||
("md" . markdown-mode)
|
|
||||||
("nginx" . conf-mode)
|
|
||||||
("objectivec" . objc-mode)
|
|
||||||
("objc" . objc-mode)
|
|
||||||
("perl" . perl-mode)
|
|
||||||
("protobuf" . protobuf-mode)
|
|
||||||
("python" . python-mode)
|
|
||||||
("py" . python-mode)
|
|
||||||
("ruby" . ruby-mode)
|
|
||||||
("rust" . rust-mode)
|
|
||||||
("rb" . ruby-mode)
|
|
||||||
("sql" . sql-mode)
|
|
||||||
("typescript" . typescript-mode))
|
|
||||||
"Default value for `devdocs-browser-highlight-lang-mode-alist'.")
|
|
||||||
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-fontify-pre (dom)
|
|
||||||
"Return fontified string for pre DOM."
|
|
||||||
(with-temp-buffer
|
|
||||||
(shr-generic dom)
|
|
||||||
(when (> shr-indentation 0)
|
|
||||||
(save-excursion
|
|
||||||
(goto-char (point-min))
|
|
||||||
(while (not (eobp))
|
|
||||||
(shr-indent)
|
|
||||||
(forward-line 1))))
|
|
||||||
(let* ((language (dom-attr dom 'data-language))
|
|
||||||
(mode (cdr (or (assoc language devdocs-browser-highlight-lang-mode-alist)
|
|
||||||
(assoc language devdocs-browser-highlight-lang-mode-alist-default)))))
|
|
||||||
(when (fboundp mode)
|
|
||||||
(delay-mode-hooks (funcall mode))
|
|
||||||
(font-lock-default-function mode)
|
|
||||||
(font-lock-default-fontify-region (point-min) (point-max) nil)))
|
|
||||||
(buffer-string)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-pre (dom)
|
|
||||||
"Rendering function for pre DOM."
|
|
||||||
(let ((shr-folding-mode 'none)
|
|
||||||
(shr-current-font 'default))
|
|
||||||
(shr-ensure-newline)
|
|
||||||
(insert (devdocs-browser--eww-fontify-pre dom))
|
|
||||||
(shr-ensure-newline)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-maybe-set-title (dom)
|
|
||||||
"Maybe set DOM as title if it's not set yet."
|
|
||||||
(when (zerop (length (plist-get eww-data :title)))
|
|
||||||
(eww-tag-title dom)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-h1 (dom)
|
|
||||||
"Rendering function for h1 DOM. Maybe use it as title."
|
|
||||||
(devdocs-browser--eww-tag-maybe-set-title dom)
|
|
||||||
(shr-tag-h1 dom))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-h2 (dom)
|
|
||||||
"Rendering function for h2 DOM. Maybe use it as title."
|
|
||||||
(devdocs-browser--eww-tag-maybe-set-title dom)
|
|
||||||
(shr-heading dom (if shr-use-fonts
|
|
||||||
'(variable-pitch (:height 1.2 :weight bold))
|
|
||||||
'bold)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-h3 (dom)
|
|
||||||
"Rendering function for h2 DOM. Maybe use it as title."
|
|
||||||
(devdocs-browser--eww-tag-maybe-set-title dom)
|
|
||||||
(shr-heading dom (if shr-use-fonts
|
|
||||||
'(variable-pitch (:height 1.1 :weight bold))
|
|
||||||
'bold)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-h4 (dom)
|
|
||||||
"Rendering function for h4 DOM."
|
|
||||||
(shr-heading dom 'bold))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-h5 (dom)
|
|
||||||
"Rendering function for h5 DOM."
|
|
||||||
(shr-heading dom 'italic))
|
|
||||||
|
|
||||||
(defvar-local devdocs-browser--eww-data '()
|
|
||||||
"Plist data for current eww page, contain :doc and :path.")
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-fix-url (url)
|
|
||||||
"Fix links' URL in docs by appending suffix and mtime."
|
|
||||||
;; shr-expand-url may be call in a temp buffer
|
|
||||||
;; we need to temporary bind this buffer to access the buffer-local variable.
|
|
||||||
(with-current-buffer (window-buffer)
|
|
||||||
(let ((url-parsed (url-generic-parse-url url))
|
|
||||||
(root-url-parsed (url-generic-parse-url (plist-get eww-data :url)))
|
|
||||||
(mtime (plist-get (plist-get devdocs-browser--eww-data :doc) :mtime)))
|
|
||||||
(when (and mtime
|
|
||||||
(equal (url-type url-parsed) (url-type root-url-parsed))
|
|
||||||
(equal (url-host url-parsed) (url-host root-url-parsed))
|
|
||||||
(not (string-match-p "\\.html" url)))
|
|
||||||
(setf (url-filename url-parsed)
|
|
||||||
(if (equal (url-type url-parsed) "file")
|
|
||||||
(concat (url-filename url-parsed) ".html")
|
|
||||||
(format "%s.html?%s" (url-filename url-parsed) mtime)))
|
|
||||||
(setq url (url-recreate-url url-parsed)))))
|
|
||||||
url)
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-parse-url-path (url)
|
|
||||||
"Return URL's doc :path ('hello/world#target')."
|
|
||||||
;; see devdocs-browser--eww-open for url pattern
|
|
||||||
(when-let* ((url-parsed (url-generic-parse-url url))
|
|
||||||
(doc (plist-get devdocs-browser--eww-data :doc))
|
|
||||||
(slug (plist-get doc :slug))
|
|
||||||
(filename-suffix (if (equal (url-type url-parsed) "file")
|
|
||||||
".html"
|
|
||||||
(format ".html?%s" (plist-get doc :mtime))))
|
|
||||||
(filename-prefix (if (equal (url-type url-parsed) "file")
|
|
||||||
(devdocs-browser-offline-data-dir slug)
|
|
||||||
(concat "/" slug "/")))
|
|
||||||
(path (url-filename url-parsed)))
|
|
||||||
(when (and (string-prefix-p filename-prefix path)
|
|
||||||
(string-suffix-p filename-suffix path))
|
|
||||||
(setq path (string-remove-prefix filename-prefix path))
|
|
||||||
(setq path (string-remove-suffix filename-suffix path))
|
|
||||||
(when (url-target url-parsed)
|
|
||||||
(setq path (concat path "#" (url-target url-parsed))))
|
|
||||||
path)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-page-path ()
|
|
||||||
"Return current page's :path ('hello/world#target')."
|
|
||||||
(devdocs-browser--eww-parse-url-path (plist-get eww-data :url)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-link-eldoc (&optional _)
|
|
||||||
"Show URL link or description at current point."
|
|
||||||
(when-let ((url (get-text-property (point) 'shr-url)))
|
|
||||||
(if-let ((path (devdocs-browser--eww-parse-url-path url)))
|
|
||||||
(let* ((doc (plist-get devdocs-browser--eww-data :doc))
|
|
||||||
(index (plist-get doc :index))
|
|
||||||
(entries (plist-get index :entries))
|
|
||||||
(entry (seq-find
|
|
||||||
(lambda (x) (equal (plist-get x :path) path))
|
|
||||||
entries)))
|
|
||||||
(concat
|
|
||||||
(when entry
|
|
||||||
(propertize (plist-get entry :name) 'face 'font-lock-keyword-face))
|
|
||||||
(when entry
|
|
||||||
(format " (%s): " (plist-get entry :type)))
|
|
||||||
(propertize path 'face 'italic)))
|
|
||||||
(format "External link: %s" (propertize url 'face 'italic)))))
|
|
||||||
|
|
||||||
(defun devdocs-browser--position-by-target (target)
|
|
||||||
"Find buffer position for TARGET (url hash)."
|
|
||||||
(save-excursion
|
|
||||||
(goto-char (point-min))
|
|
||||||
(when-let ((match (text-property-search-forward 'shr-target-id target #'member)))
|
|
||||||
(prop-match-beginning match))))
|
|
||||||
|
|
||||||
(defun devdocs-browser--imenu-create-index ()
|
|
||||||
"Create index alist for current buffer for imenu.
|
|
||||||
Can be used as `imenu-create-index-function'."
|
|
||||||
(when-let* ((doc (plist-get devdocs-browser--eww-data :doc))
|
|
||||||
(entries (plist-get (plist-get doc :index) :entries))
|
|
||||||
(page-path (devdocs-browser--eww-page-path))
|
|
||||||
(page-url (url-generic-parse-url page-path)))
|
|
||||||
(seq-filter
|
|
||||||
#'identity
|
|
||||||
(mapcar
|
|
||||||
(lambda (entry)
|
|
||||||
(when-let* ((name (plist-get entry :name))
|
|
||||||
(path (plist-get entry :path))
|
|
||||||
(url (url-generic-parse-url path))
|
|
||||||
(target (url-target url))
|
|
||||||
(_ (equal (url-filename url) (url-filename page-url))))
|
|
||||||
(cons name (devdocs-browser--position-by-target target))))
|
|
||||||
entries))))
|
|
||||||
|
|
||||||
(define-obsolete-function-alias 'devdocs-browser-eww-goto-target 'imenu "20220917")
|
|
||||||
|
|
||||||
(defun devdocs-browser-eww-open-in-default-browser ()
|
|
||||||
"Open current page in devdocs.io in browser."
|
|
||||||
(interactive)
|
|
||||||
(when-let* ((doc (plist-get devdocs-browser--eww-data :doc))
|
|
||||||
(slug (plist-get doc :slug))
|
|
||||||
(path (devdocs-browser--eww-page-path))
|
|
||||||
(url (concat devdocs-browser-base-url slug "/" path)))
|
|
||||||
(browse-url-default-browser url)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-recenter-advice (res)
|
|
||||||
"Recenter current cursor for devdocs buffer, used for advice :filter-return (return `RES')."
|
|
||||||
(when devdocs-browser--eww-data
|
|
||||||
(recenter))
|
|
||||||
res)
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-browse-url-new-window-advice (args)
|
|
||||||
"Advice around `eww-browse-url' with ARGS, set NEW-WINDOW if URL is external."
|
|
||||||
(let ((url (car args))
|
|
||||||
(new-window (cadr args)))
|
|
||||||
(when (and devdocs-browser--eww-data
|
|
||||||
(not (devdocs-browser--eww-parse-url-path url)))
|
|
||||||
(setq new-window t))
|
|
||||||
(list url new-window)))
|
|
||||||
|
|
||||||
(define-minor-mode devdocs-browser-eww-mode
|
|
||||||
"Minor mode for browsing devdocs pages with eww."
|
|
||||||
:lighter " Devdocs"
|
|
||||||
:interactive nil
|
|
||||||
:group 'devdocs-browser
|
|
||||||
:keymap (let ((map (make-sparse-keymap)))
|
|
||||||
(define-key map (kbd "C-c C-o") #'devdocs-browser-eww-open-in-default-browser)
|
|
||||||
map)
|
|
||||||
(setq-local shr-external-rendering-functions
|
|
||||||
(append shr-external-rendering-functions
|
|
||||||
'((pre . devdocs-browser--eww-tag-pre)
|
|
||||||
(h1 . devdocs-browser--eww-tag-h1)
|
|
||||||
(h2 . devdocs-browser--eww-tag-h2)
|
|
||||||
(h3 . devdocs-browser--eww-tag-h3)
|
|
||||||
(h4 . devdocs-browser--eww-tag-h4)
|
|
||||||
(h5 . devdocs-browser--eww-tag-h5))))
|
|
||||||
(setq-local imenu-create-index-function
|
|
||||||
#'devdocs-browser--imenu-create-index)
|
|
||||||
(advice-add 'shr-expand-url :filter-return #'devdocs-browser--eww-fix-url)
|
|
||||||
(advice-add 'eww-display-html :filter-return #'devdocs-browser--eww-recenter-advice)
|
|
||||||
(advice-add 'eww-browse-url :filter-args #'devdocs-browser--eww-browse-url-new-window-advice)
|
|
||||||
(add-hook 'eldoc-documentation-functions #'devdocs-browser--eww-link-eldoc nil t)
|
|
||||||
(eldoc-mode))
|
|
||||||
|
|
||||||
(defvar devdocs-browser--docs-dir "docs")
|
|
||||||
(defvar devdocs-browser--index-json-filename "index.json")
|
|
||||||
(defvar devdocs-browser--metadata-filename "metadata.el")
|
|
||||||
(defvar devdocs-browser--offline-data-json-filename "content.json")
|
|
||||||
(defvar devdocs-browser--offline-data-dir-name "content")
|
|
||||||
|
|
||||||
(defun devdocs-browser--completing-read (prompt collection &optional def)
|
|
||||||
"Helper function for `completing-read'.
|
|
||||||
PROMPT: same meaning, but this function will append ';' at the end;
|
|
||||||
COLLECTION: alist of (name . props), where props is a plist with
|
|
||||||
possibly the following keys: :value, :annotation, :group;
|
|
||||||
if :group is not nil and name starts with '<group>: ', its removed.
|
|
||||||
DEF: same meaning;"
|
|
||||||
;; convert collection to hashtables for faster completion. `complete-with-action' also supports that.
|
|
||||||
(setq collection (delq nil collection))
|
|
||||||
(let* ((collection-ht (make-hash-table :test 'equal :size (length collection)))
|
|
||||||
(annotation-function
|
|
||||||
(lambda (s)
|
|
||||||
(let ((annotation (plist-get (gethash s collection-ht) :annotation)))
|
|
||||||
(if annotation
|
|
||||||
(concat " " annotation)
|
|
||||||
nil))))
|
|
||||||
(group-function
|
|
||||||
(lambda (s transform)
|
|
||||||
(let ((group (plist-get (gethash s collection-ht) :group)))
|
|
||||||
(cond
|
|
||||||
(transform (if (and group (string-match (rx bos (literal group) ": ") s))
|
|
||||||
(replace-match "" t t s)
|
|
||||||
s))
|
|
||||||
(t group))))))
|
|
||||||
(mapc (lambda (elem) (puthash (car elem) (cdr elem) collection-ht))
|
|
||||||
collection)
|
|
||||||
(setq prompt (concat prompt
|
|
||||||
(when def
|
|
||||||
(format " (default %s)" (funcall group-function def t)))
|
|
||||||
": "))
|
|
||||||
(let ((res (completing-read
|
|
||||||
prompt
|
|
||||||
(lambda (str pred action)
|
|
||||||
(if (eq action 'metadata)
|
|
||||||
`(metadata . ((annotation-function . ,annotation-function)
|
|
||||||
(group-function . ,group-function)))
|
|
||||||
(complete-with-action action collection str pred)))
|
|
||||||
nil t ;; require-match
|
|
||||||
nil nil def)))
|
|
||||||
(or (plist-get (gethash res collection-ht) :value)
|
|
||||||
res))))
|
|
||||||
|
|
||||||
(defun devdocs-browser--json-parse-buffer ()
|
|
||||||
"Same as `json-parse-buffer', with custom settings."
|
|
||||||
(json-parse-buffer :object-type 'plist :array-type 'array))
|
|
||||||
|
|
||||||
(defun devdocs-browser--read-json (file-path)
|
|
||||||
"Read json file in FILE-PATH, if it's a relative path, find it in cache dir."
|
|
||||||
(let ((filename (expand-file-name file-path devdocs-browser-cache-directory)))
|
|
||||||
(when (file-exists-p filename)
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents filename)
|
|
||||||
(devdocs-browser--json-parse-buffer)))))
|
|
||||||
|
|
||||||
(defun devdocs-browser--fetch-json (url-path file-path &optional base-url)
|
|
||||||
"Fetch json from BASE-URL / URL-PATH, also save to FILE-PATH.
|
|
||||||
BASE-URL defaults to `devdocs-browser-base-url'."
|
|
||||||
(let ((cache-filename (expand-file-name file-path devdocs-browser-cache-directory)))
|
|
||||||
(unless (file-exists-p (file-name-directory cache-filename))
|
|
||||||
(make-directory (file-name-directory cache-filename) t))
|
|
||||||
(with-temp-file cache-filename
|
|
||||||
(erase-buffer)
|
|
||||||
(url-insert-file-contents (concat (or base-url devdocs-browser-base-url) url-path))
|
|
||||||
(devdocs-browser--json-parse-buffer))))
|
|
||||||
|
|
||||||
|
|
||||||
(defvar devdocs-browser--docs-list-cache nil "Cached docs list.")
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-list-docs (&optional refresh-cache)
|
|
||||||
"Get doc metadata lists, reload cache if REFRESH-CACHE."
|
|
||||||
(setq devdocs-browser--docs-list-cache
|
|
||||||
(or (and (not refresh-cache) devdocs-browser--docs-list-cache)
|
|
||||||
(and (not refresh-cache) (devdocs-browser--read-json "docs.json"))
|
|
||||||
(devdocs-browser--fetch-json "docs.json" "docs.json"))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-update-docs ()
|
|
||||||
"Update doc metadata list.
|
|
||||||
To upgrade docs content, see `devdocs-browser-upgrade-doc'."
|
|
||||||
(interactive)
|
|
||||||
(let ((count (length (devdocs-browser-list-docs t))))
|
|
||||||
(message (concat "Doc metadata updated, found total %s docs. "
|
|
||||||
"You may want to run `devdocs-browser-install-doc' "
|
|
||||||
"or `devdocs-browser-upgrade-doc'.")
|
|
||||||
count)))
|
|
||||||
|
|
||||||
(defun devdocs-browser-find-doc (slug-or-name)
|
|
||||||
"Find doc from docs list by SLUG-OR-NAME."
|
|
||||||
(let ((docs-list (devdocs-browser-list-docs)))
|
|
||||||
(seq-find (lambda (doc)
|
|
||||||
(or (equal (plist-get doc :slug) slug-or-name)
|
|
||||||
(equal (plist-get doc :name) slug-or-name)))
|
|
||||||
docs-list)))
|
|
||||||
|
|
||||||
(defvar devdocs-browser--docs-cache '() "Cached doc indexes plist.")
|
|
||||||
|
|
||||||
(defun devdocs-browser--install-doc-internal (doc)
|
|
||||||
"(Re-)install doc identified by plist DOC. Return t if success."
|
|
||||||
(let* ((slug (plist-get doc :slug))
|
|
||||||
(mtime (plist-get doc :mtime))
|
|
||||||
(docs-dir (expand-file-name devdocs-browser--docs-dir devdocs-browser-cache-directory))
|
|
||||||
(doc-dir (expand-file-name slug docs-dir))
|
|
||||||
success)
|
|
||||||
(unless (file-exists-p docs-dir)
|
|
||||||
(make-directory docs-dir t))
|
|
||||||
(when (file-exists-p doc-dir)
|
|
||||||
(delete-directory doc-dir t))
|
|
||||||
|
|
||||||
;; do not leave empty directory
|
|
||||||
(unwind-protect
|
|
||||||
(progn
|
|
||||||
(devdocs-browser--fetch-json
|
|
||||||
(format "docs/%s/index.json?%s" slug mtime)
|
|
||||||
(expand-file-name devdocs-browser--index-json-filename doc-dir))
|
|
||||||
(with-temp-file (expand-file-name devdocs-browser--metadata-filename doc-dir)
|
|
||||||
(print doc (current-buffer)))
|
|
||||||
(setq success t))
|
|
||||||
(unless success
|
|
||||||
(delete-directory doc-dir t)))
|
|
||||||
|
|
||||||
(if success
|
|
||||||
(message "Installed devdocs doc %s version %s" slug mtime)
|
|
||||||
(message "Failed to install devdocs doc %s" slug))
|
|
||||||
;; remove cache
|
|
||||||
(setq devdocs-browser--docs-cache
|
|
||||||
(lax-plist-put devdocs-browser--docs-cache slug nil))
|
|
||||||
success))
|
|
||||||
|
|
||||||
(defun devdocs-browser--doc-readable-name (doc)
|
|
||||||
"Get human readable name for DOC."
|
|
||||||
(let ((slug (plist-get doc :slug))
|
|
||||||
(name (plist-get doc :name))
|
|
||||||
(version (plist-get doc :version))
|
|
||||||
(release (plist-get doc :release))
|
|
||||||
res)
|
|
||||||
(setq res (concat slug " (" name))
|
|
||||||
(unless (zerop (length version))
|
|
||||||
(setq res (concat res " " version)))
|
|
||||||
(unless (zerop (length release))
|
|
||||||
(setq res (concat res ", " release)))
|
|
||||||
(setq res (concat res ")"))
|
|
||||||
res))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-install-doc (slug-or-name &optional force)
|
|
||||||
"Install doc by SLUG-OR-NAME.
|
|
||||||
When called interactively, user can choose from the list.
|
|
||||||
When called interactively with prefix, or FORCE is t, reinstall existing doc."
|
|
||||||
(interactive
|
|
||||||
(let* ((force current-prefix-arg)
|
|
||||||
(installed-docs
|
|
||||||
(devdocs-browser-list-installed-slugs))
|
|
||||||
(selected-slug
|
|
||||||
(devdocs-browser--completing-read
|
|
||||||
"Install doc"
|
|
||||||
(mapcar (lambda (doc)
|
|
||||||
(let ((slug (plist-get doc :slug)))
|
|
||||||
(unless (and (not force)
|
|
||||||
(member slug installed-docs))
|
|
||||||
(cons (devdocs-browser--doc-readable-name doc)
|
|
||||||
`(:value ,slug)))))
|
|
||||||
(devdocs-browser-list-docs)))))
|
|
||||||
(list selected-slug force)))
|
|
||||||
(let ((doc (devdocs-browser-find-doc slug-or-name)))
|
|
||||||
(unless (and (not force)
|
|
||||||
(member (plist-get doc :slug) (devdocs-browser-list-installed-slugs)))
|
|
||||||
(devdocs-browser--install-doc-internal doc))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-uninstall-doc (slug)
|
|
||||||
"Uninstall doc by SLUG.
|
|
||||||
When called interactively, user can choose from the list."
|
|
||||||
(interactive (list (completing-read "Uninstall doc: "
|
|
||||||
(devdocs-browser-list-installed-slugs)
|
|
||||||
nil t)))
|
|
||||||
(let* ((docs-dir (expand-file-name devdocs-browser--docs-dir devdocs-browser-cache-directory))
|
|
||||||
(doc-dir (expand-file-name slug docs-dir)))
|
|
||||||
(when (file-exists-p doc-dir)
|
|
||||||
(delete-directory doc-dir t)))
|
|
||||||
(setq devdocs-browser--docs-cache
|
|
||||||
(lax-plist-put devdocs-browser--docs-cache slug nil)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--upgrade-readable-name (old-doc new-doc)
|
|
||||||
"Get human readable name for upgrade from OLD-DOC to NEW-DOC."
|
|
||||||
(let ((slug (plist-get old-doc :slug))
|
|
||||||
(name (plist-get old-doc :name))
|
|
||||||
(old-version (plist-get old-doc :version))
|
|
||||||
(old-release (plist-get old-doc :release))
|
|
||||||
(old-mtime (plist-get old-doc :mtime))
|
|
||||||
(new-version (plist-get new-doc :version))
|
|
||||||
(new-release (plist-get new-doc :release))
|
|
||||||
(new-mtime (plist-get new-doc :mtime))
|
|
||||||
res)
|
|
||||||
(setq res (format "%s (%s" slug name))
|
|
||||||
(unless (equal old-version new-version)
|
|
||||||
(setq res (concat res (format " %s->%s" old-version new-version))))
|
|
||||||
(unless (equal old-release new-release)
|
|
||||||
(setq res (concat res (format ", %s->%s" old-release new-release))))
|
|
||||||
(setq res (concat res (format ", %s->%s)" old-mtime new-mtime)))
|
|
||||||
res))
|
|
||||||
|
|
||||||
(defun devdocs-browser--upgrade-readable-name-or-nil (slug)
|
|
||||||
"Get human readable name for upgrading SLUG if it needs upgrade."
|
|
||||||
(let ((old-doc (devdocs-browser--load-doc slug))
|
|
||||||
(new-doc (devdocs-browser-find-doc slug)))
|
|
||||||
(when (and new-doc
|
|
||||||
(> (plist-get new-doc :mtime) (plist-get old-doc :mtime)))
|
|
||||||
(devdocs-browser--upgrade-readable-name old-doc new-doc))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-upgrade-doc (slug)
|
|
||||||
"Upgrade doc by SLUG, return t if upgrade success.
|
|
||||||
Also download new version of offline data if
|
|
||||||
there's offline data for current version.
|
|
||||||
When called interactively, user can choose from list.
|
|
||||||
You may need to call `devdocs-browser-update-docs' first."
|
|
||||||
(interactive
|
|
||||||
(let (rows)
|
|
||||||
(dolist (slug (devdocs-browser-list-installed-slugs))
|
|
||||||
(let ((desc (devdocs-browser--upgrade-readable-name-or-nil slug)))
|
|
||||||
(when desc
|
|
||||||
(push (cons desc slug) rows))))
|
|
||||||
(if (null rows)
|
|
||||||
(progn
|
|
||||||
(message "All docs up to date")
|
|
||||||
(list nil))
|
|
||||||
(list
|
|
||||||
(cdr (assoc (completing-read "Upgrade doc: " rows nil t) rows))))))
|
|
||||||
(when (and slug (devdocs-browser--upgrade-readable-name-or-nil slug))
|
|
||||||
(let* ((has-offline-data (devdocs-browser-offline-data-dir slug))
|
|
||||||
(doc (devdocs-browser-find-doc slug))
|
|
||||||
(install-success (devdocs-browser--install-doc-internal doc)))
|
|
||||||
(when (and has-offline-data install-success)
|
|
||||||
(devdocs-browser--download-offline-data-internal doc))
|
|
||||||
install-success)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-upgrade-all-docs ()
|
|
||||||
"Upgrade all docs."
|
|
||||||
(interactive)
|
|
||||||
(let ((count 0))
|
|
||||||
(dolist (slug (devdocs-browser-list-installed-slugs))
|
|
||||||
(message "Processing %s..." slug)
|
|
||||||
(when (devdocs-browser-upgrade-doc slug)
|
|
||||||
(setq count (1+ count))))
|
|
||||||
(message "Upgraded %s docs" count)))
|
|
||||||
|
|
||||||
(defun devdocs-browser-list-installed-slugs ()
|
|
||||||
"Get a list of installed docs' slug name."
|
|
||||||
(let ((dir (expand-file-name devdocs-browser--docs-dir devdocs-browser-cache-directory)))
|
|
||||||
(when (file-exists-p dir)
|
|
||||||
(directory-files dir nil
|
|
||||||
;; ignore ".", ".." and hidden files
|
|
||||||
"^[^.].*"))))
|
|
||||||
|
|
||||||
(defun devdocs-browser-find-installed-doc (slug-or-name)
|
|
||||||
"Find installed doc by SLUG-OR-NAME."
|
|
||||||
(let ((docs-list (mapcar #'devdocs-browser-installed-doc-info
|
|
||||||
(devdocs-browser-list-installed-slugs))))
|
|
||||||
(seq-find (lambda (doc)
|
|
||||||
(or (equal (plist-get doc :slug) slug-or-name)
|
|
||||||
(equal (plist-get doc :name) slug-or-name)))
|
|
||||||
docs-list)))
|
|
||||||
|
|
||||||
(defun devdocs-browser-installed-doc-info (slug)
|
|
||||||
"Get plist info of installed doc identified by SLUG."
|
|
||||||
(cddr (devdocs-browser--load-doc slug)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--load-doc (slug &optional refresh-cache)
|
|
||||||
"Load doc identified by SLUG, reload cache if REFRESH-CACHE is not nil.
|
|
||||||
Result is a plist metadata, with an extra :index field at the beginning."
|
|
||||||
(or (and (not refresh-cache) (lax-plist-get devdocs-browser--docs-cache slug))
|
|
||||||
(let* ((docs-dir (expand-file-name devdocs-browser--docs-dir
|
|
||||||
devdocs-browser-cache-directory))
|
|
||||||
(doc-dir (expand-file-name slug docs-dir))
|
|
||||||
(metadata-filename (expand-file-name devdocs-browser--metadata-filename doc-dir))
|
|
||||||
(metadata nil)
|
|
||||||
(index-filename (expand-file-name devdocs-browser--index-json-filename doc-dir))
|
|
||||||
(index (devdocs-browser--read-json index-filename))
|
|
||||||
res)
|
|
||||||
(when (file-exists-p metadata-filename)
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-file-contents metadata-filename)
|
|
||||||
(setq metadata (read (current-buffer))))
|
|
||||||
(setq res (append `(:index ,index) metadata))
|
|
||||||
(setq devdocs-browser--docs-cache
|
|
||||||
(lax-plist-put devdocs-browser--docs-cache slug res)))
|
|
||||||
res)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--download-offline-data-internal (doc)
|
|
||||||
"(re-)Download and extract offline data for DOC."
|
|
||||||
(let* ((slug (plist-get doc :slug))
|
|
||||||
(mtime (plist-get doc :mtime))
|
|
||||||
(docs-dir (expand-file-name devdocs-browser--docs-dir devdocs-browser-cache-directory))
|
|
||||||
(doc-dir (expand-file-name slug docs-dir))
|
|
||||||
(data-dir (expand-file-name devdocs-browser--offline-data-dir-name doc-dir))
|
|
||||||
success)
|
|
||||||
(unless (file-exists-p doc-dir)
|
|
||||||
(make-directory doc-dir t))
|
|
||||||
(when (file-exists-p data-dir)
|
|
||||||
(delete-directory data-dir t))
|
|
||||||
|
|
||||||
;; do not leave half-complete data directory
|
|
||||||
(unwind-protect
|
|
||||||
(let ((data (devdocs-browser--fetch-json
|
|
||||||
(format "%s/db.json?%s" slug mtime)
|
|
||||||
(expand-file-name devdocs-browser--offline-data-json-filename doc-dir)
|
|
||||||
devdocs-browser-doc-base-url)))
|
|
||||||
;; write data to files
|
|
||||||
(dolist (kv (seq-partition data 2))
|
|
||||||
(when-let* ((name (substring (symbol-name (car kv)) 1))
|
|
||||||
(value (cadr kv))
|
|
||||||
;; prepent "./" to fix paths starting with literal "~" (e.g. deno)
|
|
||||||
(path (expand-file-name (concat "./" name ".html") data-dir)))
|
|
||||||
(unless (file-exists-p (file-name-directory path))
|
|
||||||
(make-directory (file-name-directory path) t))
|
|
||||||
(write-region value nil path)))
|
|
||||||
(setq success t))
|
|
||||||
(unless success
|
|
||||||
(delete-directory data-dir t)))
|
|
||||||
|
|
||||||
(if success
|
|
||||||
(message "Installed devdocs offline data %s version %s" slug mtime)
|
|
||||||
(message "Failed to install devdocs offline data %s" slug))
|
|
||||||
|
|
||||||
success))
|
|
||||||
|
|
||||||
(defun devdocs-browser-offline-data-dir (slug)
|
|
||||||
"Return doc SLUG's offline data dir if present, return nil otherwise."
|
|
||||||
(let* ((docs-dir (expand-file-name devdocs-browser--docs-dir devdocs-browser-cache-directory))
|
|
||||||
(doc-dir (expand-file-name slug docs-dir))
|
|
||||||
(data-dir (expand-file-name devdocs-browser--offline-data-dir-name doc-dir)))
|
|
||||||
(when (file-exists-p data-dir)
|
|
||||||
(file-name-as-directory data-dir))))
|
|
||||||
|
|
||||||
(defun devdocs-browser-download-offline-data (slug)
|
|
||||||
"Download offline data for doc SLUG.
|
|
||||||
Offline data contains full content pages,
|
|
||||||
which allows you to view docs without Internet connection.
|
|
||||||
It may take some time to download offline data.
|
|
||||||
When called interactively, user can choose from the list."
|
|
||||||
(interactive (list (completing-read
|
|
||||||
"Install offline data: "
|
|
||||||
(seq-filter
|
|
||||||
(lambda (slug) (null (devdocs-browser-offline-data-dir slug)))
|
|
||||||
(devdocs-browser-list-installed-slugs))
|
|
||||||
nil t)))
|
|
||||||
(when-let* ((doc (devdocs-browser--load-doc slug)))
|
|
||||||
(devdocs-browser--download-offline-data-internal doc)))
|
|
||||||
|
|
||||||
(defun devdocs-browser-remove-offline-data (slug)
|
|
||||||
"Remove offline data for doc SLUG.
|
|
||||||
When called interactively, user can choose from the list."
|
|
||||||
(interactive (list (completing-read
|
|
||||||
"Remove offline data: "
|
|
||||||
(seq-filter
|
|
||||||
#'devdocs-browser-offline-data-dir
|
|
||||||
(devdocs-browser-list-installed-slugs))
|
|
||||||
nil t)))
|
|
||||||
(when-let* ((data-dir (devdocs-browser-offline-data-dir slug)))
|
|
||||||
(delete-directory data-dir t)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--eww-open (doc path)
|
|
||||||
"Open PATH for document DOC using eww."
|
|
||||||
(let* ((slug (plist-get doc :slug))
|
|
||||||
(mtime (plist-get doc :mtime))
|
|
||||||
base-url url)
|
|
||||||
;; cannot use format directly because `path' may contains #query
|
|
||||||
;; path: hello/world#query
|
|
||||||
;; url for offline: file:///home/path/to/devdocs/python~3.8/hello/world.html#query
|
|
||||||
;; url for online: https://documents.devdocs.io/python~3.8/hello/world.html?161818817#query
|
|
||||||
(let ((offline-data-dir (devdocs-browser-offline-data-dir slug)))
|
|
||||||
(if offline-data-dir
|
|
||||||
(progn
|
|
||||||
(setq base-url (concat "file://" offline-data-dir))
|
|
||||||
(setq url (url-generic-parse-url (concat "file://" offline-data-dir path)))
|
|
||||||
(setf (url-filename url) (concat (url-filename url) ".html")))
|
|
||||||
(setq base-url (concat devdocs-browser-doc-base-url slug "/"))
|
|
||||||
(setq url (url-generic-parse-url
|
|
||||||
(concat devdocs-browser-doc-base-url slug "/" path)))
|
|
||||||
(setf (url-filename url)
|
|
||||||
(format "%s.html?%s" (url-filename url) mtime))))
|
|
||||||
|
|
||||||
(pop-to-buffer (format "*devdocs-%s*" slug))
|
|
||||||
(if devdocs-browser-eww-mode
|
|
||||||
(eww-save-history)
|
|
||||||
(eww-mode)
|
|
||||||
(devdocs-browser-eww-mode))
|
|
||||||
(setq-local devdocs-browser--eww-data
|
|
||||||
(list :doc doc
|
|
||||||
:base-url base-url))
|
|
||||||
|
|
||||||
(eww (url-recreate-url url))
|
|
||||||
(recenter)))
|
|
||||||
|
|
||||||
(defun devdocs-browser--default-active-slugs (&optional no-fallback-all)
|
|
||||||
"Default active doc slugs for current buffer, fallback to all slugs if not NO-FALLBACK-ALL."
|
|
||||||
(if devdocs-browser--eww-data
|
|
||||||
(list (plist-get (plist-get devdocs-browser--eww-data :doc) :slug))
|
|
||||||
(let ((names (or devdocs-browser-active-docs
|
|
||||||
(alist-get major-mode devdocs-browser-major-mode-docs-alist)))
|
|
||||||
slugs)
|
|
||||||
(dolist (name names)
|
|
||||||
(when-let* ((doc (devdocs-browser-find-installed-doc name))
|
|
||||||
(slug (plist-get doc :slug)))
|
|
||||||
(setq slugs (push slug slugs))))
|
|
||||||
(or slugs
|
|
||||||
(and (not no-fallback-all) (devdocs-browser-list-installed-slugs))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-open-in (slug-or-name-list)
|
|
||||||
"Open entry in specified docs SLUG-OR-NAME-LIST.
|
|
||||||
When called interactively, user can choose from the list."
|
|
||||||
(interactive
|
|
||||||
(let ((def (devdocs-browser--default-active-slugs t)))
|
|
||||||
(list (completing-read-multiple
|
|
||||||
(concat "Select doc"
|
|
||||||
(when def (format " (default %s)" def))
|
|
||||||
": ")
|
|
||||||
(devdocs-browser-list-installed-slugs)
|
|
||||||
nil t nil nil def))))
|
|
||||||
|
|
||||||
(let ((current-word-regex
|
|
||||||
(when-let ((word (thing-at-point 'word t)))
|
|
||||||
(concat "\\<" (regexp-quote word) "\\>")))
|
|
||||||
slugs rows def)
|
|
||||||
(dolist (slug-or-name slug-or-name-list)
|
|
||||||
(when-let* ((doc-simple (devdocs-browser-find-installed-doc slug-or-name))
|
|
||||||
(slug (plist-get doc-simple :slug))
|
|
||||||
(doc (devdocs-browser--load-doc slug))
|
|
||||||
(index (plist-get doc :index))
|
|
||||||
(entries (plist-get index :entries)))
|
|
||||||
(setq slugs (push slug slugs))
|
|
||||||
(let ((new-rows
|
|
||||||
(mapcar
|
|
||||||
(lambda (entry)
|
|
||||||
(let* ((name (plist-get entry :name))
|
|
||||||
(path (plist-get entry :path))
|
|
||||||
(type (plist-get entry :type))
|
|
||||||
(title (concat slug ": " name)))
|
|
||||||
(when (and (null def) current-word-regex)
|
|
||||||
(when (string-match-p current-word-regex name)
|
|
||||||
(setq def title)))
|
|
||||||
(cons title `(:value (,doc ,path)
|
|
||||||
:group ,slug
|
|
||||||
:annotation ,type))))
|
|
||||||
entries)))
|
|
||||||
(setq rows (append new-rows rows))
|
|
||||||
(push (cons (format "%s: INDEX PAGE" slug)
|
|
||||||
`(:value (,doc "index")
|
|
||||||
:group ,slug))
|
|
||||||
rows))))
|
|
||||||
(let* ((selected-value
|
|
||||||
(devdocs-browser--completing-read
|
|
||||||
(format "Devdocs browser [%s]" (mapconcat #'identity slugs ","))
|
|
||||||
rows def)))
|
|
||||||
(when selected-value
|
|
||||||
(apply #'devdocs-browser--eww-open selected-value)))))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun devdocs-browser-open ()
|
|
||||||
"Open entry in active docs.
|
|
||||||
Active docs are specified by `devdocs-browser-active-docs',
|
|
||||||
or `devdocs-browser-major-mode-docs-alist',
|
|
||||||
or the current doc type if called in a devdocs eww buffer.
|
|
||||||
When all of them are nil, all installed docs are used."
|
|
||||||
(interactive)
|
|
||||||
(devdocs-browser-open-in (devdocs-browser--default-active-slugs)))
|
|
||||||
|
|
||||||
|
|
||||||
(provide 'devdocs-browser)
|
|
||||||
;;; devdocs-browser.el ends here
|
|
|
@ -1,37 +1,35 @@
|
||||||
;;; devdocs-browser-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; devdocs-browser-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "devdocs-browser" "devdocs-browser.el" (0 0
|
|
||||||
;;;;;; 0 0))
|
|
||||||
;;; Generated autoloads from devdocs-browser.el
|
;;; Generated autoloads from devdocs-browser.el
|
||||||
|
|
||||||
(autoload 'devdocs-browser-list-docs "devdocs-browser" "\
|
(autoload 'devdocs-browser-list-docs "devdocs-browser" "\
|
||||||
Get doc metadata lists, reload cache if REFRESH-CACHE.
|
Get doc metadata lists, reload cache if REFRESH-CACHE.
|
||||||
|
|
||||||
\(fn &optional REFRESH-CACHE)" nil nil)
|
(fn &optional REFRESH-CACHE)")
|
||||||
|
(autoload 'devdocs-browser-update-metadata "devdocs-browser" "\
|
||||||
(autoload 'devdocs-browser-update-docs "devdocs-browser" "\
|
|
||||||
Update doc metadata list.
|
Update doc metadata list.
|
||||||
To upgrade docs content, see `devdocs-browser-upgrade-doc'." t nil)
|
To upgrade docs content, see `devdocs-browser-upgrade-doc'." t)
|
||||||
|
(defalias 'devdocs-browser-update-docs 'devdocs-browser-update-metadata)
|
||||||
(autoload 'devdocs-browser-install-doc "devdocs-browser" "\
|
(autoload 'devdocs-browser-install-doc "devdocs-browser" "\
|
||||||
Install doc by SLUG-OR-NAME.
|
Install doc by SLUG-OR-NAME.
|
||||||
When called interactively, user can choose from the list.
|
When called interactively, user can choose from the list.
|
||||||
When called interactively with prefix, or FORCE is t, reinstall existing doc.
|
When called interactively with prefix, or FORCE is t, reinstall existing doc.
|
||||||
|
|
||||||
\(fn SLUG-OR-NAME &optional FORCE)" t nil)
|
(fn SLUG-OR-NAME &optional FORCE)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-browser-uninstall-doc "devdocs-browser" "\
|
(autoload 'devdocs-browser-uninstall-doc "devdocs-browser" "\
|
||||||
Uninstall doc by SLUG.
|
Uninstall doc by SLUG.
|
||||||
When called interactively, user can choose from the list.
|
When called interactively, user can choose from the list.
|
||||||
|
|
||||||
\(fn SLUG)" t nil)
|
(fn SLUG)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-browser-upgrade-doc "devdocs-browser" "\
|
(autoload 'devdocs-browser-upgrade-doc "devdocs-browser" "\
|
||||||
Upgrade doc by SLUG, return t if upgrade success.
|
Upgrade doc by SLUG, return t if upgrade success.
|
||||||
Also download new version of offline data if
|
Also download new version of offline data if
|
||||||
|
@ -39,36 +37,32 @@ there's offline data for current version.
|
||||||
When called interactively, user can choose from list.
|
When called interactively, user can choose from list.
|
||||||
You may need to call `devdocs-browser-update-docs' first.
|
You may need to call `devdocs-browser-update-docs' first.
|
||||||
|
|
||||||
\(fn SLUG)" t nil)
|
(fn SLUG)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-browser-upgrade-all-docs "devdocs-browser" "\
|
(autoload 'devdocs-browser-upgrade-all-docs "devdocs-browser" "\
|
||||||
Upgrade all docs." t nil)
|
Upgrade all docs." t)
|
||||||
|
|
||||||
(autoload 'devdocs-browser-open-in "devdocs-browser" "\
|
(autoload 'devdocs-browser-open-in "devdocs-browser" "\
|
||||||
Open entry in specified docs SLUG-OR-NAME-LIST.
|
Open entry in specified docs SLUG-OR-NAME-LIST.
|
||||||
When called interactively, user can choose from the list.
|
When called interactively, user can choose from the list.
|
||||||
|
|
||||||
\(fn SLUG-OR-NAME-LIST)" t nil)
|
(fn SLUG-OR-NAME-LIST)" t)
|
||||||
|
|
||||||
(autoload 'devdocs-browser-open "devdocs-browser" "\
|
(autoload 'devdocs-browser-open "devdocs-browser" "\
|
||||||
Open entry in active docs.
|
Open entry in active docs.
|
||||||
Active docs are specified by `devdocs-browser-active-docs',
|
Active docs are specified by `devdocs-browser-active-docs',
|
||||||
or `devdocs-browser-major-mode-docs-alist',
|
or `devdocs-browser-major-mode-docs-alist',
|
||||||
or the current doc type if called in a devdocs eww buffer.
|
or the current doc type if called in a devdocs eww buffer.
|
||||||
When all of them are nil, all installed docs are used." t nil)
|
When all of them are nil, all installed docs are used." t)
|
||||||
|
|
||||||
(register-definition-prefixes "devdocs-browser" '("devdocs-browser-"))
|
(register-definition-prefixes "devdocs-browser" '("devdocs-browser-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;;;### (autoloads nil nil ("devdocs-browser-pkg.el") (0 0 0 0))
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'devdocs-browser-autoloads)
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; devdocs-browser-autoloads.el ends here
|
;;; devdocs-browser-autoloads.el ends here
|
|
@ -1,6 +1,6 @@
|
||||||
(define-package "devdocs-browser" "20230423.444" "Browse devdocs.io documents using EWW"
|
(define-package "devdocs-browser" "20231231.1455" "Browse devdocs.io documents using EWW"
|
||||||
'((emacs "27.1"))
|
'((emacs "27.1"))
|
||||||
:commit "ef7686e4ff4ecab42e1b4a1a5d079bcf947a5b71" :authors
|
:commit "afc460e687bec4eb947ab85d207778fc3b9b3bbc" :authors
|
||||||
'(("blahgeek" . "i@blahgeek.com"))
|
'(("blahgeek" . "i@blahgeek.com"))
|
||||||
:maintainers
|
:maintainers
|
||||||
'(("blahgeek" . "i@blahgeek.com"))
|
'(("blahgeek" . "i@blahgeek.com"))
|
|
@ -125,6 +125,11 @@ See https://prismjs.com/ for list of language names."
|
||||||
"Default value for `devdocs-browser-highlight-lang-mode-alist'.")
|
"Default value for `devdocs-browser-highlight-lang-mode-alist'.")
|
||||||
|
|
||||||
|
|
||||||
|
(defun devdocs-browser--clear-dom-id-attr (dom)
|
||||||
|
"Clear id attribute for DOM and its children."
|
||||||
|
(dom-remove-attribute dom 'id)
|
||||||
|
(mapc #'devdocs-browser--clear-dom-id-attr (dom-non-text-children dom)))
|
||||||
|
|
||||||
(defun devdocs-browser--eww-fontify-pre (dom)
|
(defun devdocs-browser--eww-fontify-pre (dom)
|
||||||
"Return fontified string for pre DOM."
|
"Return fontified string for pre DOM."
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
|
@ -146,6 +151,9 @@ See https://prismjs.com/ for list of language names."
|
||||||
|
|
||||||
(defun devdocs-browser--eww-tag-pre (dom)
|
(defun devdocs-browser--eww-tag-pre (dom)
|
||||||
"Rendering function for pre DOM."
|
"Rendering function for pre DOM."
|
||||||
|
;; must clear all 'id' attributes in dom.
|
||||||
|
;; otherwise, shr would try to add text properties based on it, but since they are rendered in temp-buffer, the marker would be invalid
|
||||||
|
(devdocs-browser--clear-dom-id-attr dom)
|
||||||
(let ((shr-folding-mode 'none)
|
(let ((shr-folding-mode 'none)
|
||||||
(shr-current-font 'default))
|
(shr-current-font 'default))
|
||||||
(shr-ensure-newline)
|
(shr-ensure-newline)
|
||||||
|
@ -184,6 +192,11 @@ See https://prismjs.com/ for list of language names."
|
||||||
"Rendering function for h5 DOM."
|
"Rendering function for h5 DOM."
|
||||||
(shr-heading dom 'italic))
|
(shr-heading dom 'italic))
|
||||||
|
|
||||||
|
(defun devdocs-browser--eww-tag-generic-ensure-paragraph (dom)
|
||||||
|
"Rendering function for generic DOM while ensuring paragraph."
|
||||||
|
(shr-ensure-paragraph)
|
||||||
|
(shr-generic dom))
|
||||||
|
|
||||||
(defvar-local devdocs-browser--eww-data '()
|
(defvar-local devdocs-browser--eww-data '()
|
||||||
"Plist data for current eww page, contain :doc and :path.")
|
"Plist data for current eww page, contain :doc and :path.")
|
||||||
|
|
||||||
|
@ -316,7 +329,9 @@ Can be used as `imenu-create-index-function'."
|
||||||
(h2 . devdocs-browser--eww-tag-h2)
|
(h2 . devdocs-browser--eww-tag-h2)
|
||||||
(h3 . devdocs-browser--eww-tag-h3)
|
(h3 . devdocs-browser--eww-tag-h3)
|
||||||
(h4 . devdocs-browser--eww-tag-h4)
|
(h4 . devdocs-browser--eww-tag-h4)
|
||||||
(h5 . devdocs-browser--eww-tag-h5))))
|
(h5 . devdocs-browser--eww-tag-h5)
|
||||||
|
(summary . devdocs-browser--eww-tag-generic-ensure-paragraph)
|
||||||
|
(section . devdocs-browser--eww-tag-generic-ensure-paragraph))))
|
||||||
(setq-local imenu-create-index-function
|
(setq-local imenu-create-index-function
|
||||||
#'devdocs-browser--imenu-create-index)
|
#'devdocs-browser--imenu-create-index)
|
||||||
(when (boundp 'eww-auto-rename-buffer)
|
(when (boundp 'eww-auto-rename-buffer)
|
||||||
|
@ -410,7 +425,7 @@ BASE-URL defaults to `devdocs-browser-base-url'."
|
||||||
(devdocs-browser--fetch-json "docs.json" "docs.json"))))
|
(devdocs-browser--fetch-json "docs.json" "docs.json"))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun devdocs-browser-update-docs ()
|
(defun devdocs-browser-update-metadata ()
|
||||||
"Update doc metadata list.
|
"Update doc metadata list.
|
||||||
To upgrade docs content, see `devdocs-browser-upgrade-doc'."
|
To upgrade docs content, see `devdocs-browser-upgrade-doc'."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -420,6 +435,10 @@ To upgrade docs content, see `devdocs-browser-upgrade-doc'."
|
||||||
"or `devdocs-browser-upgrade-doc'.")
|
"or `devdocs-browser-upgrade-doc'.")
|
||||||
count)))
|
count)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defalias 'devdocs-browser-update-docs 'devdocs-browser-update-metadata)
|
||||||
|
(make-obsolete 'devdocs-browser-update-docs 'devdocs-browser-update-metadata "20231231")
|
||||||
|
|
||||||
(defun devdocs-browser-find-doc (slug-or-name)
|
(defun devdocs-browser-find-doc (slug-or-name)
|
||||||
"Find doc from docs list by SLUG-OR-NAME."
|
"Find doc from docs list by SLUG-OR-NAME."
|
||||||
(let ((docs-list (devdocs-browser-list-docs)))
|
(let ((docs-list (devdocs-browser-list-docs)))
|
|
@ -1,2 +0,0 @@
|
||||||
;;; Generated package description from dired-single.el -*- no-byte-compile: t -*-
|
|
||||||
(define-package "dired-single" "20230306.626" "Reuse the current dired buffer" '((emacs "25.1")) :commit "c781b7dcff6e7f9a5060b067d2cdb0acbc840c49" :url "https://codeberg.org/amano.kenji/dired-single")
|
|
|
@ -1,12 +1,14 @@
|
||||||
;;; dired-single-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; dired-single-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "dired-single" "dired-single.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from dired-single.el
|
;;; Generated autoloads from dired-single.el
|
||||||
|
|
||||||
(autoload 'dired-single-buffer "dired-single" "\
|
(autoload 'dired-single-buffer "dired-single" "\
|
||||||
|
@ -29,15 +31,13 @@ specified, the directory or file on the current line is used (assuming it's
|
||||||
a Dired buffer). If the current line represents a file, the file is visited
|
a Dired buffer). If the current line represents a file, the file is visited
|
||||||
in another window.
|
in another window.
|
||||||
|
|
||||||
\(fn &optional DEFAULT-DIRNAME)" t nil)
|
(fn &optional DEFAULT-DIRNAME)" t)
|
||||||
|
|
||||||
(autoload 'dired-single-buffer-mouse "dired-single" "\
|
(autoload 'dired-single-buffer-mouse "dired-single" "\
|
||||||
Mouse-initiated version of `dired-single-buffer' (which see).
|
Mouse-initiated version of `dired-single-buffer' (which see).
|
||||||
|
|
||||||
Argument CLICK is the mouse-click event.
|
Argument CLICK is the mouse-click event.
|
||||||
|
|
||||||
\(fn CLICK)" t nil)
|
(fn CLICK)" t)
|
||||||
|
|
||||||
(autoload 'dired-single-magic-buffer "dired-single" "\
|
(autoload 'dired-single-magic-buffer "dired-single" "\
|
||||||
Switch to buffer whose name is the value of `dired-single-magic-buffer-name'.
|
Switch to buffer whose name is the value of `dired-single-magic-buffer-name'.
|
||||||
|
|
||||||
|
@ -48,28 +48,29 @@ magic buffer, it will prompt for a new directory to visit.
|
||||||
Optional argument DEFAULT-DIRNAME specifies the directory to visit (defaults to
|
Optional argument DEFAULT-DIRNAME specifies the directory to visit (defaults to
|
||||||
the currently displayed directory).
|
the currently displayed directory).
|
||||||
|
|
||||||
\(fn &optional DEFAULT-DIRNAME)" t nil)
|
(fn &optional DEFAULT-DIRNAME)" t)
|
||||||
|
|
||||||
(autoload 'dired-single-toggle-buffer-name "dired-single" "\
|
(autoload 'dired-single-toggle-buffer-name "dired-single" "\
|
||||||
Toggle between the 'magic' buffer name and the 'real' Dired buffer name.
|
Toggle between the `magic' buffer name and the `real' Dired buffer name.
|
||||||
|
|
||||||
Will also seek to uniquify the 'real' buffer name." t nil)
|
|
||||||
|
|
||||||
|
Will also seek to uniquify the `real' buffer name." t)
|
||||||
(autoload 'dired-single-up-directory "dired-single" "\
|
(autoload 'dired-single-up-directory "dired-single" "\
|
||||||
Like `dired-up-directory' but with `dired-single-buffer'.
|
Like `dired-up-directory' but with `dired-single-buffer'.
|
||||||
|
|
||||||
If (as OTHER-WINDOW) is non-nil, open the parent directory in a new window.
|
If (as OTHER-WINDOW) is non-nil, open the parent directory in a new window.
|
||||||
|
|
||||||
\(fn &optional OTHER-WINDOW)" t nil)
|
(fn &optional OTHER-WINDOW)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "dired-single" '("dired-single-"))
|
(register-definition-prefixes "dired-single" '("dired-single-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'dired-single-autoloads)
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; dired-single-autoloads.el ends here
|
;;; dired-single-autoloads.el ends here
|
6
code/elpa/dired-single-20240131.1148/dired-single-pkg.el
Normal file
6
code/elpa/dired-single-20240131.1148/dired-single-pkg.el
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
(define-package "dired-single" "20240131.1148" "Reuse the current dired buffer"
|
||||||
|
'((emacs "25.1"))
|
||||||
|
:commit "60fce6599326e12cc2033c28d50b8bf6c6ba164a" :url "https://codeberg.org/amano.kenji/dired-single")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
|
@ -1,8 +1,6 @@
|
||||||
;;; dired-single.el --- Reuse the current dired buffer -*- lexical-binding: t; -*-
|
;;; dired-single.el --- Reuse the current dired buffer -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
;; Version: 0.3.1
|
;; Version: 0.3.1
|
||||||
;; Package-Version: 20230306.626
|
|
||||||
;; Package-Commit: c781b7dcff6e7f9a5060b067d2cdb0acbc840c49
|
|
||||||
;; URL: https://codeberg.org/amano.kenji/dired-single
|
;; URL: https://codeberg.org/amano.kenji/dired-single
|
||||||
;; License: 0BSD
|
;; License: 0BSD
|
||||||
;; Package-Requires: ((emacs "25.1"))
|
;; Package-Requires: ((emacs "25.1"))
|
||||||
|
@ -177,9 +175,9 @@ the currently displayed directory)."
|
||||||
;;;; ------------------------------------------------------------------------
|
;;;; ------------------------------------------------------------------------
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun dired-single-toggle-buffer-name ()
|
(defun dired-single-toggle-buffer-name ()
|
||||||
"Toggle between the 'magic' buffer name and the 'real' Dired buffer name.
|
"Toggle between the `magic' buffer name and the `real' Dired buffer name.
|
||||||
|
|
||||||
Will also seek to uniquify the 'real' buffer name."
|
Will also seek to uniquify the `real' buffer name."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
|
||||||
;; make sure it's a dired buffer
|
;; make sure it's a dired buffer
|
|
@ -1,2 +0,0 @@
|
||||||
;;; Generated package description from dockerfile-mode.el -*- no-byte-compile: t -*-
|
|
||||||
(define-package "dockerfile-mode" "20220822.2021" "Major mode for editing Docker's Dockerfiles" '((emacs "24")) :commit "52c6c00da1d31c0b6c29c74335b3af63ed6bf06c" :keywords '("docker" "languages" "processes" "tools") :url "https://github.com/spotify/dockerfile-mode")
|
|
|
@ -1,13 +1,14 @@
|
||||||
;;; dockerfile-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; dockerfile-mode-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "dockerfile-mode" "dockerfile-mode.el" (0 0
|
|
||||||
;;;;;; 0 0))
|
|
||||||
;;; Generated autoloads from dockerfile-mode.el
|
;;; Generated autoloads from dockerfile-mode.el
|
||||||
|
|
||||||
(autoload 'dockerfile-build-buffer "dockerfile-mode" "\
|
(autoload 'dockerfile-build-buffer "dockerfile-mode" "\
|
||||||
|
@ -27,31 +28,30 @@ The shell command used to build the image is:
|
||||||
-f filename \\
|
-f filename \\
|
||||||
directory
|
directory
|
||||||
|
|
||||||
\(fn IMAGE-NAME &optional NO-CACHE)" t nil)
|
(fn IMAGE-NAME &optional NO-CACHE)" t)
|
||||||
|
|
||||||
(autoload 'dockerfile-build-no-cache-buffer "dockerfile-mode" "\
|
(autoload 'dockerfile-build-no-cache-buffer "dockerfile-mode" "\
|
||||||
Build an image called IMAGE-NAME based upon the buffer without cache.
|
Build an image called IMAGE-NAME based upon the buffer without cache.
|
||||||
|
|
||||||
\(fn IMAGE-NAME)" t nil)
|
(fn IMAGE-NAME)" t)
|
||||||
|
|
||||||
(autoload 'dockerfile-mode "dockerfile-mode" "\
|
(autoload 'dockerfile-mode "dockerfile-mode" "\
|
||||||
A major mode to edit Dockerfiles.
|
A major mode to edit Dockerfiles.
|
||||||
\\{dockerfile-mode-map}
|
\\{dockerfile-mode-map}
|
||||||
|
|
||||||
\(fn)" t nil)
|
(fn)" t)
|
||||||
|
|
||||||
(add-to-list 'auto-mode-alist (cons (concat "[/\\]" "\\(?:Containerfile\\|Dockerfile\\)" "\\(?:\\.[^/\\]*\\)?\\'") 'dockerfile-mode))
|
(add-to-list 'auto-mode-alist (cons (concat "[/\\]" "\\(?:Containerfile\\|Dockerfile\\)" "\\(?:\\.[^/\\]*\\)?\\'") 'dockerfile-mode))
|
||||||
|
|
||||||
(add-to-list 'auto-mode-alist '("\\.dockerfile\\'" . dockerfile-mode))
|
(add-to-list 'auto-mode-alist '("\\.dockerfile\\'" . dockerfile-mode))
|
||||||
|
|
||||||
(register-definition-prefixes "dockerfile-mode" '("dockerfile-"))
|
(register-definition-prefixes "dockerfile-mode" '("dockerfile-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'dockerfile-mode-autoloads)
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; dockerfile-mode-autoloads.el ends here
|
;;; dockerfile-mode-autoloads.el ends here
|
|
@ -0,0 +1,9 @@
|
||||||
|
(define-package "dockerfile-mode" "20240318.24" "Major mode for editing Docker's Dockerfiles"
|
||||||
|
'((emacs "24")
|
||||||
|
(s "1.2.0"))
|
||||||
|
:commit "f6196726342b44081933597a343805db6366e7ac" :keywords
|
||||||
|
'("docker" "languages" "processes" "tools")
|
||||||
|
:url "https://github.com/spotify/dockerfile-mode")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
|
@ -1,9 +1,7 @@
|
||||||
;;; dockerfile-mode.el --- Major mode for editing Docker's Dockerfiles -*- lexical-binding: t -*-
|
;;; dockerfile-mode.el --- Major mode for editing Docker's Dockerfiles -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; Copyright (c) 2013 Spotify AB
|
;; Copyright (c) 2013 Spotify AB
|
||||||
;; Package-Requires: ((emacs "24"))
|
;; Package-Requires: ((emacs "24") (s "1.2.0"))
|
||||||
;; Package-Version: 20220822.2021
|
|
||||||
;; Package-Commit: 52c6c00da1d31c0b6c29c74335b3af63ed6bf06c
|
|
||||||
;; Homepage: https://github.com/spotify/dockerfile-mode
|
;; Homepage: https://github.com/spotify/dockerfile-mode
|
||||||
;; URL: https://github.com/spotify/dockerfile-mode
|
;; URL: https://github.com/spotify/dockerfile-mode
|
||||||
;; Version: 1.7
|
;; Version: 1.7
|
||||||
|
@ -31,6 +29,7 @@
|
||||||
|
|
||||||
(require 'sh-script)
|
(require 'sh-script)
|
||||||
(require 'rx)
|
(require 'rx)
|
||||||
|
(require 's)
|
||||||
|
|
||||||
|
|
||||||
(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p))
|
(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p))
|
||||||
|
@ -158,19 +157,16 @@ Lines beginning with a keyword are ignored, and any others are
|
||||||
indented by one `dockerfile-indent-offset'. Functionality toggled
|
indented by one `dockerfile-indent-offset'. Functionality toggled
|
||||||
by `dockerfile-enable-auto-indent'."
|
by `dockerfile-enable-auto-indent'."
|
||||||
(when dockerfile-enable-auto-indent
|
(when dockerfile-enable-auto-indent
|
||||||
(unless (member (get-text-property (point-at-bol) 'face)
|
(unless (member (get-text-property (line-beginning-position) 'face)
|
||||||
'(font-lock-comment-delimiter-face font-lock-keyword-face))
|
'(font-lock-comment-delimiter-face font-lock-keyword-face))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(beginning-of-line)
|
(beginning-of-line)
|
||||||
(skip-chars-forward "[ \t]" (point-at-eol))
|
(unless (looking-at-p "\\s-*$") ; Ignore empty lines.
|
||||||
(unless (equal (point) (point-at-eol)) ; Ignore empty lines.
|
(indent-line-to dockerfile-indent-offset))))))
|
||||||
;; Delete existing whitespace.
|
|
||||||
(delete-char (- (point-at-bol) (point)))
|
|
||||||
(indent-to dockerfile-indent-offset))))))
|
|
||||||
|
|
||||||
(defun dockerfile-build-arg-string ()
|
(defun dockerfile-build-arg-string ()
|
||||||
"Create a --build-arg string for each element in `dockerfile-build-args'."
|
"Create a --build-arg string for each element in `dockerfile-build-args'."
|
||||||
(mapconcat (lambda (arg) (concat "--build-arg " (shell-quote-argument arg)))
|
(mapconcat (lambda (arg) (concat "--build-arg=" (s-replace "\\=" "=" (shell-quote-argument arg))))
|
||||||
dockerfile-build-args " "))
|
dockerfile-build-args " "))
|
||||||
|
|
||||||
(defun dockerfile-standard-filename (file)
|
(defun dockerfile-standard-filename (file)
|
|
@ -1,68 +0,0 @@
|
||||||
;;; elisp-refs-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
|
||||||
;;
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "elisp-refs" "elisp-refs.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from elisp-refs.el
|
|
||||||
|
|
||||||
(autoload 'elisp-refs-function "elisp-refs" "\
|
|
||||||
Display all the references to function SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
|
||||||
|
|
||||||
This searches for functions, not macros. For that, see
|
|
||||||
`elisp-refs-macro'.
|
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
|
||||||
|
|
||||||
(autoload 'elisp-refs-macro "elisp-refs" "\
|
|
||||||
Display all the references to macro SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
|
||||||
|
|
||||||
This searches for macros, not functions. For that, see
|
|
||||||
`elisp-refs-function'.
|
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
|
||||||
|
|
||||||
(autoload 'elisp-refs-special "elisp-refs" "\
|
|
||||||
Display all the references to special form SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
|
||||||
|
|
||||||
(autoload 'elisp-refs-variable "elisp-refs" "\
|
|
||||||
Display all the references to variable SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
|
||||||
|
|
||||||
(autoload 'elisp-refs-symbol "elisp-refs" "\
|
|
||||||
Display all the references to SYMBOL in all loaded elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the
|
|
||||||
search.
|
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
|
||||||
|
|
||||||
(register-definition-prefixes "elisp-refs" '("elisp-"))
|
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
;; Local Variables:
|
|
||||||
;; version-control: never
|
|
||||||
;; no-byte-compile: t
|
|
||||||
;; no-update-autoloads: t
|
|
||||||
;; coding: utf-8
|
|
||||||
;; End:
|
|
||||||
;;; elisp-refs-autoloads.el ends here
|
|
|
@ -1,2 +0,0 @@
|
||||||
;;; Generated package description from elisp-refs.el -*- no-byte-compile: t -*-
|
|
||||||
(define-package "elisp-refs" "20230309.1638" "find callers of elisp functions or macros" '((dash "2.12.0") (s "1.11.0")) :commit "6973912994ade71a3e13a24425f1cc648d8b94bb" :authors '(("Wilfred Hughes" . "me@wilfred.me.uk")) :maintainer '("Wilfred Hughes" . "me@wilfred.me.uk") :keywords '("lisp"))
|
|
|
@ -1,911 +0,0 @@
|
||||||
;;; elisp-refs.el --- find callers of elisp functions or macros -*- lexical-binding: t; -*-
|
|
||||||
|
|
||||||
;; Copyright (C) 2016-2020 Wilfred Hughes <me@wilfred.me.uk>
|
|
||||||
|
|
||||||
;; Author: Wilfred Hughes <me@wilfred.me.uk>
|
|
||||||
;; Version: 1.6
|
|
||||||
;; Package-Version: 20230309.1638
|
|
||||||
;; Package-Commit: 6973912994ade71a3e13a24425f1cc648d8b94bb
|
|
||||||
;; Keywords: lisp
|
|
||||||
;; Package-Requires: ((dash "2.12.0") (s "1.11.0"))
|
|
||||||
|
|
||||||
;; This program 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.
|
|
||||||
|
|
||||||
;; This program 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:
|
|
||||||
|
|
||||||
;; elisp-refs.el is an Emacs package for finding references to
|
|
||||||
;; functions, macros or variables. Unlike a dumb text search,
|
|
||||||
;; elisp-refs.el actually parses the code, so it's never confused by
|
|
||||||
;; comments or `foo-bar' matching `foo'.
|
|
||||||
;;
|
|
||||||
;; See https://github.com/Wilfred/refs.el/blob/master/README.md for
|
|
||||||
;; more information.
|
|
||||||
|
|
||||||
;;; Code:
|
|
||||||
|
|
||||||
(require 'dash)
|
|
||||||
(require 's)
|
|
||||||
(require 'format)
|
|
||||||
(eval-when-compile (require 'cl-lib))
|
|
||||||
|
|
||||||
;;; Internal
|
|
||||||
|
|
||||||
(defvar elisp-refs-verbose t)
|
|
||||||
|
|
||||||
(defun elisp-refs--format-int (integer)
|
|
||||||
"Format INTEGER as a string, with , separating thousands."
|
|
||||||
(let ((number (abs integer))
|
|
||||||
(parts nil))
|
|
||||||
(while (> number 999)
|
|
||||||
(push (format "%03d" (mod number 1000))
|
|
||||||
parts)
|
|
||||||
(setq number (/ number 1000)))
|
|
||||||
(push (format "%d" number) parts)
|
|
||||||
(concat
|
|
||||||
(if (< integer 0) "-" "")
|
|
||||||
(s-join "," parts))))
|
|
||||||
|
|
||||||
(defsubst elisp-refs--start-pos (end-pos)
|
|
||||||
"Find the start position of form ending at END-POS
|
|
||||||
in the current buffer."
|
|
||||||
(let ((parse-sexp-ignore-comments t))
|
|
||||||
(scan-sexps end-pos -1)))
|
|
||||||
|
|
||||||
(defun elisp-refs--sexp-positions (buffer start-pos end-pos)
|
|
||||||
"Return a list of start and end positions of all the sexps
|
|
||||||
between START-POS and END-POS (inclusive) in BUFFER.
|
|
||||||
|
|
||||||
Positions exclude quote characters, so given 'foo or `foo, we
|
|
||||||
report the position of the symbol foo.
|
|
||||||
|
|
||||||
Not recursive, so we don't consider subelements of nested sexps."
|
|
||||||
(let ((positions nil))
|
|
||||||
(with-current-buffer buffer
|
|
||||||
(condition-case _err
|
|
||||||
(catch 'done
|
|
||||||
(while t
|
|
||||||
(let* ((sexp-end-pos (let ((parse-sexp-ignore-comments t))
|
|
||||||
(scan-sexps start-pos 1))))
|
|
||||||
;; If we've reached a sexp beyond the range requested,
|
|
||||||
;; or if there are no sexps left, we're done.
|
|
||||||
(when (or (null sexp-end-pos) (> sexp-end-pos end-pos))
|
|
||||||
(throw 'done nil))
|
|
||||||
;; Otherwise, this sexp is in the range requested.
|
|
||||||
(push (list (elisp-refs--start-pos sexp-end-pos) sexp-end-pos)
|
|
||||||
positions)
|
|
||||||
(setq start-pos sexp-end-pos))))
|
|
||||||
;; Terminate when we see "Containing expression ends prematurely"
|
|
||||||
(scan-error nil)))
|
|
||||||
(nreverse positions)))
|
|
||||||
|
|
||||||
(defun elisp-refs--read-buffer-form (symbols-with-pos)
|
|
||||||
"Read a form from the current buffer, starting at point.
|
|
||||||
Returns a list:
|
|
||||||
\(form form-start-pos form-end-pos symbol-positions read-start-pos)
|
|
||||||
|
|
||||||
In Emacs 28 and earlier, SYMBOL-POSITIONS is a list of 0-indexed
|
|
||||||
symbol positions relative to READ-START-POS, according to
|
|
||||||
`read-symbol-positions-list'.
|
|
||||||
|
|
||||||
In Emacs 29+, SYMBOL-POSITIONS is nil. If SYMBOLS-WITH-POS is
|
|
||||||
non-nil, forms are read with `read-positioning-symbols'."
|
|
||||||
(let* ((read-with-symbol-positions t)
|
|
||||||
(read-start-pos (point))
|
|
||||||
(form (if (and symbols-with-pos (fboundp 'read-positioning-symbols))
|
|
||||||
(read-positioning-symbols (current-buffer))
|
|
||||||
(read (current-buffer))))
|
|
||||||
(symbols (if (boundp 'read-symbol-positions-list)
|
|
||||||
read-symbol-positions-list
|
|
||||||
nil))
|
|
||||||
(end-pos (point))
|
|
||||||
(start-pos (elisp-refs--start-pos end-pos)))
|
|
||||||
(list form start-pos end-pos symbols read-start-pos)))
|
|
||||||
|
|
||||||
(defvar elisp-refs--path nil
|
|
||||||
"A buffer-local variable used by `elisp-refs--contents-buffer'.
|
|
||||||
Internal implementation detail.")
|
|
||||||
|
|
||||||
(defun elisp-refs--read-all-buffer-forms (buffer symbols-with-pos)
|
|
||||||
"Read all the forms in BUFFER, along with their positions."
|
|
||||||
(with-current-buffer buffer
|
|
||||||
(goto-char (point-min))
|
|
||||||
(let ((forms nil))
|
|
||||||
(condition-case err
|
|
||||||
(while t
|
|
||||||
(push (elisp-refs--read-buffer-form symbols-with-pos) forms))
|
|
||||||
(error
|
|
||||||
(if (or (equal (car err) 'end-of-file)
|
|
||||||
;; TODO: this shouldn't occur in valid elisp files,
|
|
||||||
;; but it's happening in helm-utils.el.
|
|
||||||
(equal (car err) 'scan-error))
|
|
||||||
;; Reached end of file, we're done.
|
|
||||||
(nreverse forms)
|
|
||||||
;; Some unexpected error, propagate.
|
|
||||||
(error "Unexpected error whilst reading %s position %s: %s"
|
|
||||||
(abbreviate-file-name elisp-refs--path) (point) err)))))))
|
|
||||||
|
|
||||||
(defun elisp-refs--proper-list-p (val)
|
|
||||||
"Is VAL a proper list?"
|
|
||||||
(if (fboundp 'proper-list-p)
|
|
||||||
;; `proper-list-p' was added in Emacs 27.1.
|
|
||||||
;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=2fde6275b69fd113e78243790bf112bbdd2fe2bf
|
|
||||||
(with-no-warnings (proper-list-p val))
|
|
||||||
;; Earlier Emacs versions only had format-proper-list-p.
|
|
||||||
(with-no-warnings (format-proper-list-p val))))
|
|
||||||
|
|
||||||
(defun elisp-refs--walk (buffer form start-pos end-pos symbol match-p &optional path)
|
|
||||||
"Walk FORM, a nested list, and return a list of sublists (with
|
|
||||||
their positions) where MATCH-P returns t. FORM is traversed
|
|
||||||
depth-first (pre-order traversal, left-to-right).
|
|
||||||
|
|
||||||
MATCH-P is called with three arguments:
|
|
||||||
\(SYMBOL CURRENT-FORM PATH).
|
|
||||||
|
|
||||||
PATH is the first element of all the enclosing forms of
|
|
||||||
CURRENT-FORM, innermost first, along with the index of the
|
|
||||||
current form.
|
|
||||||
|
|
||||||
For example if we are looking at h in (e f (g h)), PATH takes the
|
|
||||||
value ((g . 1) (e . 2)).
|
|
||||||
|
|
||||||
START-POS and END-POS should be the position of FORM within BUFFER."
|
|
||||||
(cond
|
|
||||||
((funcall match-p symbol form path)
|
|
||||||
;; If this form matches, just return it, along with the position.
|
|
||||||
(list (list form start-pos end-pos)))
|
|
||||||
;; Otherwise, recurse on the subforms.
|
|
||||||
((consp form)
|
|
||||||
(let ((matches nil)
|
|
||||||
;; Find the positions of the subforms.
|
|
||||||
(subforms-positions
|
|
||||||
(if (eq (car-safe form) '\`)
|
|
||||||
;; Kludge: `elisp-refs--sexp-positions' excludes the ` when
|
|
||||||
;; calculating positions. So, to find the inner
|
|
||||||
;; positions when walking from `(...) to (...), we
|
|
||||||
;; don't need to increment the start position.
|
|
||||||
(cons nil (elisp-refs--sexp-positions buffer start-pos end-pos))
|
|
||||||
;; Calculate the positions after the opening paren.
|
|
||||||
(elisp-refs--sexp-positions buffer (1+ start-pos) end-pos))))
|
|
||||||
;; For each subform, recurse if it's a list, or a matching symbol.
|
|
||||||
(--each (-zip form subforms-positions)
|
|
||||||
(-let [(subform subform-start subform-end) it]
|
|
||||||
(when (or
|
|
||||||
(and (consp subform) (elisp-refs--proper-list-p subform))
|
|
||||||
(and (symbolp subform) (eq subform symbol)))
|
|
||||||
(-when-let (subform-matches
|
|
||||||
(elisp-refs--walk
|
|
||||||
buffer subform
|
|
||||||
subform-start subform-end
|
|
||||||
symbol match-p
|
|
||||||
(cons (cons (car-safe form) it-index) path)))
|
|
||||||
(push subform-matches matches)))))
|
|
||||||
|
|
||||||
;; Concat the results from all the subforms.
|
|
||||||
(apply #'append (nreverse matches))))))
|
|
||||||
|
|
||||||
;; TODO: condition-case (condition-case ... (error ...)) is not a call
|
|
||||||
;; TODO: (cl-destructuring-bind (foo &rest bar) ...) is not a call
|
|
||||||
;; TODO: letf, cl-letf, -let, -let*
|
|
||||||
(defun elisp-refs--function-p (symbol form path)
|
|
||||||
"Return t if FORM looks like a function call to SYMBOL."
|
|
||||||
(cond
|
|
||||||
((not (consp form))
|
|
||||||
nil)
|
|
||||||
;; Ignore (defun _ (SYMBOL ...) ...)
|
|
||||||
((or (equal (car path) '(defsubst . 2))
|
|
||||||
(equal (car path) '(defun . 2))
|
|
||||||
(equal (car path) '(defmacro . 2))
|
|
||||||
(equal (car path) '(cl-defun . 2)))
|
|
||||||
nil)
|
|
||||||
;; Ignore (lambda (SYMBOL ...) ...)
|
|
||||||
((equal (car path) '(lambda . 1))
|
|
||||||
nil)
|
|
||||||
;; Ignore (let (SYMBOL ...) ...)
|
|
||||||
;; and (let* (SYMBOL ...) ...)
|
|
||||||
((or
|
|
||||||
(equal (car path) '(let . 1))
|
|
||||||
(equal (car path) '(let* . 1)))
|
|
||||||
nil)
|
|
||||||
;; Ignore (let ((SYMBOL ...)) ...)
|
|
||||||
((or
|
|
||||||
(equal (cl-second path) '(let . 1))
|
|
||||||
(equal (cl-second path) '(let* . 1)))
|
|
||||||
nil)
|
|
||||||
;; Ignore (declare-function NAME (ARGS...))
|
|
||||||
((equal (car path) '(declare-function . 3))
|
|
||||||
nil)
|
|
||||||
;; (SYMBOL ...)
|
|
||||||
((eq (car form) symbol)
|
|
||||||
t)
|
|
||||||
;; (foo ... #'SYMBOL ...)
|
|
||||||
((--any-p (equal it (list 'function symbol)) form)
|
|
||||||
t)
|
|
||||||
;; (funcall 'SYMBOL ...)
|
|
||||||
((and (eq (car form) 'funcall)
|
|
||||||
(equal `',symbol (cl-second form)))
|
|
||||||
t)
|
|
||||||
;; (apply 'SYMBOL ...)
|
|
||||||
((and (eq (car form) 'apply)
|
|
||||||
(equal `',symbol (cl-second form)))
|
|
||||||
t)))
|
|
||||||
|
|
||||||
(defun elisp-refs--macro-p (symbol form path)
|
|
||||||
"Return t if FORM looks like a macro call to SYMBOL."
|
|
||||||
(cond
|
|
||||||
((not (consp form))
|
|
||||||
nil)
|
|
||||||
;; Ignore (defun _ (SYMBOL ...) ...)
|
|
||||||
((or (equal (car path) '(defsubst . 2))
|
|
||||||
(equal (car path) '(defun . 2))
|
|
||||||
(equal (car path) '(defmacro . 2)))
|
|
||||||
nil)
|
|
||||||
;; Ignore (lambda (SYMBOL ...) ...)
|
|
||||||
((equal (car path) '(lambda . 1))
|
|
||||||
nil)
|
|
||||||
;; Ignore (let (SYMBOL ...) ...)
|
|
||||||
;; and (let* (SYMBOL ...) ...)
|
|
||||||
((or
|
|
||||||
(equal (car path) '(let . 1))
|
|
||||||
(equal (car path) '(let* . 1)))
|
|
||||||
nil)
|
|
||||||
;; Ignore (let ((SYMBOL ...)) ...)
|
|
||||||
((or
|
|
||||||
(equal (cl-second path) '(let . 1))
|
|
||||||
(equal (cl-second path) '(let* . 1)))
|
|
||||||
nil)
|
|
||||||
;; (SYMBOL ...)
|
|
||||||
((eq (car form) symbol)
|
|
||||||
t)))
|
|
||||||
|
|
||||||
;; Looking for a special form is exactly the same as looking for a
|
|
||||||
;; macro.
|
|
||||||
(defalias 'elisp-refs--special-p 'elisp-refs--macro-p)
|
|
||||||
|
|
||||||
(defun elisp-refs--variable-p (symbol form path)
|
|
||||||
"Return t if this looks like a variable reference to SYMBOL.
|
|
||||||
We consider parameters to be variables too."
|
|
||||||
(cond
|
|
||||||
((consp form)
|
|
||||||
nil)
|
|
||||||
;; Ignore (defun _ (SYMBOL ...) ...)
|
|
||||||
((or (equal (car path) '(defsubst . 1))
|
|
||||||
(equal (car path) '(defun . 1))
|
|
||||||
(equal (car path) '(defmacro . 1))
|
|
||||||
(equal (car path) '(cl-defun . 1)))
|
|
||||||
nil)
|
|
||||||
;; (let (SYMBOL ...) ...) is a variable, not a function call.
|
|
||||||
((or
|
|
||||||
(equal (cl-second path) '(let . 1))
|
|
||||||
(equal (cl-second path) '(let* . 1)))
|
|
||||||
t)
|
|
||||||
;; (lambda (SYMBOL ...) ...) is a variable
|
|
||||||
((equal (cl-second path) '(lambda . 1))
|
|
||||||
t)
|
|
||||||
;; (let ((SYMBOL ...)) ...) is also a variable.
|
|
||||||
((or
|
|
||||||
(equal (cl-third path) '(let . 1))
|
|
||||||
(equal (cl-third path) '(let* . 1)))
|
|
||||||
t)
|
|
||||||
;; Ignore (SYMBOL ...) otherwise, we assume it's a function/macro
|
|
||||||
;; call.
|
|
||||||
((equal (car path) (cons symbol 0))
|
|
||||||
nil)
|
|
||||||
((eq form symbol)
|
|
||||||
t)))
|
|
||||||
|
|
||||||
;; TODO: benchmark building a list with `push' rather than using
|
|
||||||
;; mapcat.
|
|
||||||
(defun elisp-refs--read-and-find (buffer symbol match-p)
|
|
||||||
"Read all the forms in BUFFER, and return a list of all forms that
|
|
||||||
contain SYMBOL where MATCH-P returns t.
|
|
||||||
|
|
||||||
For every matching form found, we return the form itself along
|
|
||||||
with its start and end position."
|
|
||||||
(-non-nil
|
|
||||||
(--mapcat
|
|
||||||
(-let [(form start-pos end-pos symbol-positions _read-start-pos) it]
|
|
||||||
;; Optimisation: if we have a list of positions for the current
|
|
||||||
;; form (Emacs 28 and earlier), and it doesn't contain the
|
|
||||||
;; symbol we're looking for, don't bother walking the form.
|
|
||||||
(when (or (null symbol-positions) (assq symbol symbol-positions))
|
|
||||||
(elisp-refs--walk buffer form start-pos end-pos symbol match-p)))
|
|
||||||
(elisp-refs--read-all-buffer-forms buffer nil))))
|
|
||||||
|
|
||||||
(defun elisp-refs--walk-positioned-symbols (forms symbol)
|
|
||||||
"Given a nested list of FORMS, return a list of all positions of SYMBOL.
|
|
||||||
Assumes `symbol-with-pos-pos' is defined (Emacs 29+)."
|
|
||||||
(cond
|
|
||||||
((symbol-with-pos-p forms)
|
|
||||||
(let ((symbols-with-pos-enabled t))
|
|
||||||
(if (eq forms symbol)
|
|
||||||
(list (list symbol
|
|
||||||
(symbol-with-pos-pos forms)
|
|
||||||
(+ (symbol-with-pos-pos forms) (length (symbol-name symbol))))))))
|
|
||||||
((elisp-refs--proper-list-p forms)
|
|
||||||
;; Proper list, use `--mapcat` to reduce how much we recurse.
|
|
||||||
(--mapcat (elisp-refs--walk-positioned-symbols it symbol) forms))
|
|
||||||
((consp forms)
|
|
||||||
;; Improper list, we have to recurse on head and tail.
|
|
||||||
(append (elisp-refs--walk-positioned-symbols (car forms) symbol)
|
|
||||||
(elisp-refs--walk-positioned-symbols (cdr forms) symbol)))
|
|
||||||
((vectorp forms)
|
|
||||||
(--mapcat (elisp-refs--walk-positioned-symbols it symbol) forms))))
|
|
||||||
|
|
||||||
(defun elisp-refs--read-and-find-symbol (buffer symbol)
|
|
||||||
"Read all the forms in BUFFER, and return a list of all
|
|
||||||
positions of SYMBOL."
|
|
||||||
(let* ((symbols-with-pos (fboundp 'symbol-with-pos-pos))
|
|
||||||
(forms (elisp-refs--read-all-buffer-forms buffer symbols-with-pos)))
|
|
||||||
|
|
||||||
(if symbols-with-pos
|
|
||||||
(elisp-refs--walk-positioned-symbols forms symbol)
|
|
||||||
(-non-nil
|
|
||||||
(--mapcat
|
|
||||||
(-let [(_ _ _ symbol-positions read-start-pos) it]
|
|
||||||
(--map
|
|
||||||
(-let [(sym . offset) it]
|
|
||||||
(when (eq sym symbol)
|
|
||||||
(-let* ((start-pos (+ read-start-pos offset))
|
|
||||||
(end-pos (+ start-pos (length (symbol-name sym)))))
|
|
||||||
(list sym start-pos end-pos))))
|
|
||||||
symbol-positions))
|
|
||||||
forms)))))
|
|
||||||
|
|
||||||
(defun elisp-refs--filter-obarray (pred)
|
|
||||||
"Return a list of all the items in `obarray' where PRED returns t."
|
|
||||||
(let (symbols)
|
|
||||||
(mapatoms (lambda (symbol)
|
|
||||||
(when (and (funcall pred symbol)
|
|
||||||
(not (equal (symbol-name symbol) "")))
|
|
||||||
(push symbol symbols))))
|
|
||||||
symbols))
|
|
||||||
|
|
||||||
(defun elisp-refs--loaded-paths ()
|
|
||||||
"Return a list of all files that have been loaded in Emacs.
|
|
||||||
Where the file was a .elc, return the path to the .el file instead."
|
|
||||||
(let ((elc-paths (-non-nil (mapcar #'-first-item load-history))))
|
|
||||||
(-non-nil
|
|
||||||
(--map
|
|
||||||
(let ((el-name (format "%s.el" (file-name-sans-extension it)))
|
|
||||||
(el-gz-name (format "%s.el.gz" (file-name-sans-extension it))))
|
|
||||||
(cond ((file-exists-p el-name) el-name)
|
|
||||||
((file-exists-p el-gz-name) el-gz-name)
|
|
||||||
;; Ignore files where we can't find a .el file.
|
|
||||||
(t nil)))
|
|
||||||
elc-paths))))
|
|
||||||
|
|
||||||
(defun elisp-refs--contents-buffer (path)
|
|
||||||
"Read PATH into a disposable buffer, and return it.
|
|
||||||
Works around the fact that Emacs won't allow multiple buffers
|
|
||||||
visiting the same file."
|
|
||||||
(let ((fresh-buffer (generate-new-buffer (format " *refs-%s*" path)))
|
|
||||||
;; Be defensive against users overriding encoding
|
|
||||||
;; configurations (Helpful bugs #75 and #147).
|
|
||||||
(coding-system-for-read nil)
|
|
||||||
(file-name-handler-alist
|
|
||||||
'(("\\(?:\\.dz\\|\\.txz\\|\\.xz\\|\\.lzma\\|\\.lz\\|\\.g?z\\|\\.\\(?:tgz\\|svgz\\|sifz\\)\\|\\.tbz2?\\|\\.bz2\\|\\.Z\\)\\(?:~\\|\\.~[-[:alnum:]:#@^._]+\\(?:~[[:digit:]]+\\)?~\\)?\\'" .
|
|
||||||
jka-compr-handler)
|
|
||||||
("\\`/:" . file-name-non-special))))
|
|
||||||
(with-current-buffer fresh-buffer
|
|
||||||
(setq-local elisp-refs--path path)
|
|
||||||
(insert-file-contents path)
|
|
||||||
;; We don't enable emacs-lisp-mode because it slows down this
|
|
||||||
;; function significantly. We just need the syntax table for
|
|
||||||
;; scan-sexps to do the right thing with comments.
|
|
||||||
(set-syntax-table emacs-lisp-mode-syntax-table))
|
|
||||||
fresh-buffer))
|
|
||||||
|
|
||||||
(defvar elisp-refs--highlighting-buffer
|
|
||||||
nil
|
|
||||||
"A temporary buffer used for highlighting.
|
|
||||||
Since `elisp-refs--syntax-highlight' is a hot function, we
|
|
||||||
don't want to create lots of temporary buffers.")
|
|
||||||
|
|
||||||
(defun elisp-refs--syntax-highlight (str)
|
|
||||||
"Apply font-lock properties to a string STR of Emacs lisp code."
|
|
||||||
;; Ensure we have a highlighting buffer to work with.
|
|
||||||
(unless (and elisp-refs--highlighting-buffer
|
|
||||||
(buffer-live-p elisp-refs--highlighting-buffer))
|
|
||||||
(setq elisp-refs--highlighting-buffer
|
|
||||||
(generate-new-buffer " *refs-highlighting*"))
|
|
||||||
(with-current-buffer elisp-refs--highlighting-buffer
|
|
||||||
(delay-mode-hooks (emacs-lisp-mode))))
|
|
||||||
|
|
||||||
(with-current-buffer elisp-refs--highlighting-buffer
|
|
||||||
(erase-buffer)
|
|
||||||
(insert str)
|
|
||||||
(if (fboundp 'font-lock-ensure)
|
|
||||||
(font-lock-ensure)
|
|
||||||
(with-no-warnings
|
|
||||||
(font-lock-fontify-buffer)))
|
|
||||||
(buffer-string)))
|
|
||||||
|
|
||||||
(defun elisp-refs--replace-tabs (string)
|
|
||||||
"Replace tabs in STRING with spaces."
|
|
||||||
;; This is important for unindenting, as we may unindent by less
|
|
||||||
;; than one whole tab.
|
|
||||||
(s-replace "\t" (s-repeat tab-width " ") string))
|
|
||||||
|
|
||||||
(defun elisp-refs--lines (string)
|
|
||||||
"Return a list of all the lines in STRING.
|
|
||||||
'a\nb' -> ('a\n' 'b')"
|
|
||||||
(let ((lines nil))
|
|
||||||
(while (> (length string) 0)
|
|
||||||
(let ((index (s-index-of "\n" string)))
|
|
||||||
(if index
|
|
||||||
(progn
|
|
||||||
(push (substring string 0 (1+ index)) lines)
|
|
||||||
(setq string (substring string (1+ index))))
|
|
||||||
(push string lines)
|
|
||||||
(setq string ""))))
|
|
||||||
(nreverse lines)))
|
|
||||||
|
|
||||||
(defun elisp-refs--map-lines (string fn)
|
|
||||||
"Execute FN for each line in string, and join the result together."
|
|
||||||
(let ((result nil))
|
|
||||||
(dolist (line (elisp-refs--lines string))
|
|
||||||
(push (funcall fn line) result))
|
|
||||||
(apply #'concat (nreverse result))))
|
|
||||||
|
|
||||||
(defun elisp-refs--unindent-rigidly (string)
|
|
||||||
"Given an indented STRING, unindent rigidly until
|
|
||||||
at least one line has no indent.
|
|
||||||
|
|
||||||
STRING should have a 'elisp-refs-start-pos property. The returned
|
|
||||||
string will have this property updated to reflect the unindent."
|
|
||||||
(let* ((lines (s-lines string))
|
|
||||||
;; Get the leading whitespace for each line.
|
|
||||||
(indents (--map (car (s-match (rx bos (+ whitespace)) it))
|
|
||||||
lines))
|
|
||||||
(min-indent (-min (--map (length it) indents))))
|
|
||||||
(propertize
|
|
||||||
(elisp-refs--map-lines
|
|
||||||
string
|
|
||||||
(lambda (line) (substring line min-indent)))
|
|
||||||
'elisp-refs-unindented min-indent)))
|
|
||||||
|
|
||||||
(defun elisp-refs--containing-lines (buffer start-pos end-pos)
|
|
||||||
"Return a string, all the lines in BUFFER that are between
|
|
||||||
START-POS and END-POS (inclusive).
|
|
||||||
|
|
||||||
For the characters that are between START-POS and END-POS,
|
|
||||||
propertize them."
|
|
||||||
(let (expanded-start-pos expanded-end-pos)
|
|
||||||
(with-current-buffer buffer
|
|
||||||
;; Expand START-POS and END-POS to line boundaries.
|
|
||||||
(goto-char start-pos)
|
|
||||||
(beginning-of-line)
|
|
||||||
(setq expanded-start-pos (point))
|
|
||||||
(goto-char end-pos)
|
|
||||||
(end-of-line)
|
|
||||||
(setq expanded-end-pos (point))
|
|
||||||
|
|
||||||
;; Extract the rest of the line before and after the section we're interested in.
|
|
||||||
(let* ((before-match (buffer-substring expanded-start-pos start-pos))
|
|
||||||
(after-match (buffer-substring end-pos expanded-end-pos))
|
|
||||||
;; Concat the extra text with the actual match, ensuring we
|
|
||||||
;; highlight the match as code, but highlight the rest as as
|
|
||||||
;; comments.
|
|
||||||
(text (concat
|
|
||||||
(propertize before-match
|
|
||||||
'face 'font-lock-comment-face)
|
|
||||||
(elisp-refs--syntax-highlight (buffer-substring start-pos end-pos))
|
|
||||||
(propertize after-match
|
|
||||||
'face 'font-lock-comment-face))))
|
|
||||||
(-> text
|
|
||||||
(elisp-refs--replace-tabs)
|
|
||||||
(elisp-refs--unindent-rigidly)
|
|
||||||
(propertize 'elisp-refs-start-pos expanded-start-pos
|
|
||||||
'elisp-refs-path elisp-refs--path))))))
|
|
||||||
|
|
||||||
(defun elisp-refs--find-file (button)
|
|
||||||
"Open the file referenced by BUTTON."
|
|
||||||
(find-file (button-get button 'path))
|
|
||||||
(goto-char (point-min)))
|
|
||||||
|
|
||||||
(define-button-type 'elisp-refs-path-button
|
|
||||||
'action 'elisp-refs--find-file
|
|
||||||
'follow-link t
|
|
||||||
'help-echo "Open file")
|
|
||||||
|
|
||||||
(defun elisp-refs--path-button (path)
|
|
||||||
"Return a button that navigates to PATH."
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert-text-button
|
|
||||||
(abbreviate-file-name path)
|
|
||||||
:type 'elisp-refs-path-button
|
|
||||||
'path path)
|
|
||||||
(buffer-string)))
|
|
||||||
|
|
||||||
(defun elisp-refs--describe (button)
|
|
||||||
"Show *Help* for the symbol referenced by BUTTON."
|
|
||||||
(let ((symbol (button-get button 'symbol))
|
|
||||||
(kind (button-get button 'kind)))
|
|
||||||
(cond ((eq kind 'symbol)
|
|
||||||
(describe-symbol symbol))
|
|
||||||
((eq kind 'variable)
|
|
||||||
(describe-variable symbol))
|
|
||||||
(t
|
|
||||||
;; Emacs uses `describe-function' for functions, macros and
|
|
||||||
;; special forms.
|
|
||||||
(describe-function symbol)))))
|
|
||||||
|
|
||||||
(define-button-type 'elisp-refs-describe-button
|
|
||||||
'action 'elisp-refs--describe
|
|
||||||
'follow-link t
|
|
||||||
'help-echo "Describe")
|
|
||||||
|
|
||||||
(defun elisp-refs--describe-button (symbol kind)
|
|
||||||
"Return a button that shows *Help* for SYMBOL.
|
|
||||||
KIND should be 'function, 'macro, 'variable, 'special or 'symbol."
|
|
||||||
(with-temp-buffer
|
|
||||||
(insert (symbol-name kind) " ")
|
|
||||||
(insert-text-button
|
|
||||||
(symbol-name symbol)
|
|
||||||
:type 'elisp-refs-describe-button
|
|
||||||
'symbol symbol
|
|
||||||
'kind kind)
|
|
||||||
(buffer-string)))
|
|
||||||
|
|
||||||
(defun elisp-refs--pluralize (number thing)
|
|
||||||
"Human-friendly description of NUMBER occurrences of THING."
|
|
||||||
(format "%s %s%s"
|
|
||||||
(elisp-refs--format-int number)
|
|
||||||
thing
|
|
||||||
(if (equal number 1) "" "s")))
|
|
||||||
|
|
||||||
(defun elisp-refs--format-count (symbol ref-count file-count
|
|
||||||
searched-file-count prefix)
|
|
||||||
(let* ((file-str (if (zerop file-count)
|
|
||||||
""
|
|
||||||
(format " in %s" (elisp-refs--pluralize file-count "file"))))
|
|
||||||
(found-str (format "Found %s to %s%s."
|
|
||||||
(elisp-refs--pluralize ref-count "reference")
|
|
||||||
symbol
|
|
||||||
file-str))
|
|
||||||
(searched-str (if prefix
|
|
||||||
(format "Searched %s in %s."
|
|
||||||
(elisp-refs--pluralize searched-file-count "loaded file")
|
|
||||||
(elisp-refs--path-button (file-name-as-directory prefix)))
|
|
||||||
(format "Searched all %s loaded in Emacs."
|
|
||||||
(elisp-refs--pluralize searched-file-count "file")))))
|
|
||||||
(s-word-wrap 70 (format "%s %s" found-str searched-str))))
|
|
||||||
|
|
||||||
;; TODO: if we have multiple matches on one line, we repeatedly show
|
|
||||||
;; that line. That's slightly confusing.
|
|
||||||
(defun elisp-refs--show-results (symbol description results
|
|
||||||
searched-file-count prefix)
|
|
||||||
"Given a RESULTS list where each element takes the form \(forms . buffer\),
|
|
||||||
render a friendly results buffer."
|
|
||||||
(let ((buf (get-buffer-create (format "*refs: %s*" symbol))))
|
|
||||||
(switch-to-buffer buf)
|
|
||||||
(let ((inhibit-read-only t))
|
|
||||||
(erase-buffer)
|
|
||||||
(save-excursion
|
|
||||||
;; Insert the header.
|
|
||||||
(insert
|
|
||||||
(elisp-refs--format-count
|
|
||||||
description
|
|
||||||
(-sum (--map (length (car it)) results))
|
|
||||||
(length results)
|
|
||||||
searched-file-count
|
|
||||||
prefix)
|
|
||||||
"\n\n")
|
|
||||||
;; Insert the results.
|
|
||||||
(--each results
|
|
||||||
(-let* (((forms . buf) it)
|
|
||||||
(path (with-current-buffer buf elisp-refs--path)))
|
|
||||||
(insert
|
|
||||||
(propertize "File: " 'face 'bold)
|
|
||||||
(elisp-refs--path-button path) "\n")
|
|
||||||
(--each forms
|
|
||||||
(-let [(_ start-pos end-pos) it]
|
|
||||||
(insert (elisp-refs--containing-lines buf start-pos end-pos)
|
|
||||||
"\n")))
|
|
||||||
(insert "\n")))
|
|
||||||
;; Prepare the buffer for the user.
|
|
||||||
(elisp-refs-mode)))
|
|
||||||
;; Cleanup buffers created when highlighting results.
|
|
||||||
(when elisp-refs--highlighting-buffer
|
|
||||||
(kill-buffer elisp-refs--highlighting-buffer))))
|
|
||||||
|
|
||||||
(defun elisp-refs--loaded-bufs ()
|
|
||||||
"Return a list of open buffers, one for each path in `load-path'."
|
|
||||||
(mapcar #'elisp-refs--contents-buffer (elisp-refs--loaded-paths)))
|
|
||||||
|
|
||||||
(defun elisp-refs--search-1 (bufs match-fn)
|
|
||||||
"Call MATCH-FN on each buffer in BUFS, reporting progress
|
|
||||||
and accumulating results.
|
|
||||||
|
|
||||||
BUFS should be disposable: we make no effort to preserve their
|
|
||||||
state during searching.
|
|
||||||
|
|
||||||
MATCH-FN should return a list where each element takes the form:
|
|
||||||
\(form start-pos end-pos)."
|
|
||||||
(let* (;; Our benchmark suggests we spend a lot of time in GC, and
|
|
||||||
;; performance improves if we GC less frequently.
|
|
||||||
(gc-cons-percentage 0.8)
|
|
||||||
(total-bufs (length bufs)))
|
|
||||||
(let ((searched 0)
|
|
||||||
(forms-and-bufs nil))
|
|
||||||
(dolist (buf bufs)
|
|
||||||
(let* ((matching-forms (funcall match-fn buf)))
|
|
||||||
;; If there were any matches in this buffer, push the
|
|
||||||
;; matches along with the buffer into our results
|
|
||||||
;; list.
|
|
||||||
(when matching-forms
|
|
||||||
(push (cons matching-forms buf) forms-and-bufs))
|
|
||||||
;; Give feedback to the user on our progress, because
|
|
||||||
;; searching takes several seconds.
|
|
||||||
(when (and (zerop (mod searched 10))
|
|
||||||
elisp-refs-verbose)
|
|
||||||
(message "Searched %s/%s files" searched total-bufs))
|
|
||||||
(cl-incf searched)))
|
|
||||||
(when elisp-refs-verbose
|
|
||||||
(message "Searched %s/%s files" total-bufs total-bufs))
|
|
||||||
forms-and-bufs)))
|
|
||||||
|
|
||||||
(defun elisp-refs--search (symbol description match-fn &optional path-prefix)
|
|
||||||
"Find references to SYMBOL in all loaded files; call MATCH-FN on each buffer.
|
|
||||||
When PATH-PREFIX, limit to loaded files whose path starts with that prefix.
|
|
||||||
|
|
||||||
Display the results in a hyperlinked buffer.
|
|
||||||
|
|
||||||
MATCH-FN should return a list where each element takes the form:
|
|
||||||
\(form start-pos end-pos)."
|
|
||||||
(let* ((loaded-paths (elisp-refs--loaded-paths))
|
|
||||||
(matching-paths (if path-prefix
|
|
||||||
(--filter (s-starts-with? path-prefix it) loaded-paths)
|
|
||||||
loaded-paths))
|
|
||||||
(loaded-src-bufs (mapcar #'elisp-refs--contents-buffer matching-paths)))
|
|
||||||
;; Use unwind-protect to ensure we always cleanup temporary
|
|
||||||
;; buffers, even if the user hits C-g.
|
|
||||||
(unwind-protect
|
|
||||||
(progn
|
|
||||||
(let ((forms-and-bufs
|
|
||||||
(elisp-refs--search-1 loaded-src-bufs match-fn)))
|
|
||||||
(elisp-refs--show-results symbol description forms-and-bufs
|
|
||||||
(length loaded-src-bufs) path-prefix)))
|
|
||||||
;; Clean up temporary buffers.
|
|
||||||
(--each loaded-src-bufs (kill-buffer it)))))
|
|
||||||
|
|
||||||
(defun elisp-refs--completing-read-symbol (prompt &optional filter)
|
|
||||||
"Read an interned symbol from the minibuffer,
|
|
||||||
defaulting to the symbol at point. PROMPT is the string to prompt
|
|
||||||
with.
|
|
||||||
|
|
||||||
If FILTER is given, only offer symbols where (FILTER sym) returns
|
|
||||||
t."
|
|
||||||
(let ((filter (or filter (lambda (_) t))))
|
|
||||||
(read
|
|
||||||
(completing-read prompt
|
|
||||||
(elisp-refs--filter-obarray filter)
|
|
||||||
nil nil nil nil
|
|
||||||
(-if-let (sym (thing-at-point 'symbol))
|
|
||||||
(when (funcall filter (read sym))
|
|
||||||
sym))))))
|
|
||||||
|
|
||||||
;;; Commands
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun elisp-refs-function (symbol &optional path-prefix)
|
|
||||||
"Display all the references to function SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
|
||||||
|
|
||||||
This searches for functions, not macros. For that, see
|
|
||||||
`elisp-refs-macro'."
|
|
||||||
(interactive
|
|
||||||
(list (elisp-refs--completing-read-symbol "Function: " #'functionp)
|
|
||||||
(when current-prefix-arg
|
|
||||||
(read-directory-name "Limit search to loaded files in: "))))
|
|
||||||
(when (not (functionp symbol))
|
|
||||||
(if (macrop symbol)
|
|
||||||
(user-error "%s is a macro. Did you mean elisp-refs-macro?"
|
|
||||||
symbol)
|
|
||||||
(user-error "%s is not a function. Did you mean elisp-refs-symbol?"
|
|
||||||
symbol)))
|
|
||||||
(elisp-refs--search symbol
|
|
||||||
(elisp-refs--describe-button symbol 'function)
|
|
||||||
(lambda (buf)
|
|
||||||
(elisp-refs--read-and-find buf symbol #'elisp-refs--function-p))
|
|
||||||
path-prefix))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun elisp-refs-macro (symbol &optional path-prefix)
|
|
||||||
"Display all the references to macro SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
|
||||||
|
|
||||||
This searches for macros, not functions. For that, see
|
|
||||||
`elisp-refs-function'."
|
|
||||||
(interactive
|
|
||||||
(list (elisp-refs--completing-read-symbol "Macro: " #'macrop)
|
|
||||||
(when current-prefix-arg
|
|
||||||
(read-directory-name "Limit search to loaded files in: "))))
|
|
||||||
(when (not (macrop symbol))
|
|
||||||
(if (functionp symbol)
|
|
||||||
(user-error "%s is a function. Did you mean elisp-refs-function?"
|
|
||||||
symbol)
|
|
||||||
(user-error "%s is not a function. Did you mean elisp-refs-symbol?"
|
|
||||||
symbol)))
|
|
||||||
(elisp-refs--search symbol
|
|
||||||
(elisp-refs--describe-button symbol 'macro)
|
|
||||||
(lambda (buf)
|
|
||||||
(elisp-refs--read-and-find buf symbol #'elisp-refs--macro-p))
|
|
||||||
path-prefix))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun elisp-refs-special (symbol &optional path-prefix)
|
|
||||||
"Display all the references to special form SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search."
|
|
||||||
(interactive
|
|
||||||
(list (elisp-refs--completing-read-symbol "Special form: " #'special-form-p)
|
|
||||||
(when current-prefix-arg
|
|
||||||
(read-directory-name "Limit search to loaded files in: "))))
|
|
||||||
(elisp-refs--search symbol
|
|
||||||
(elisp-refs--describe-button symbol 'special-form)
|
|
||||||
(lambda (buf)
|
|
||||||
(elisp-refs--read-and-find buf symbol #'elisp-refs--special-p))
|
|
||||||
path-prefix))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun elisp-refs-variable (symbol &optional path-prefix)
|
|
||||||
"Display all the references to variable SYMBOL, in all loaded
|
|
||||||
elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search."
|
|
||||||
(interactive
|
|
||||||
;; This is awkward. We don't want to just offer defvar variables,
|
|
||||||
;; because then we can't search for code which uses `let' to bind
|
|
||||||
;; symbols. There doesn't seem to be a good way to only offer
|
|
||||||
;; variables that have been bound at some point.
|
|
||||||
(list (elisp-refs--completing-read-symbol "Variable: " )
|
|
||||||
(when current-prefix-arg
|
|
||||||
(read-directory-name "Limit search to loaded files in: "))))
|
|
||||||
(elisp-refs--search symbol
|
|
||||||
(elisp-refs--describe-button symbol 'variable)
|
|
||||||
(lambda (buf)
|
|
||||||
(elisp-refs--read-and-find buf symbol #'elisp-refs--variable-p))
|
|
||||||
path-prefix))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun elisp-refs-symbol (symbol &optional path-prefix)
|
|
||||||
"Display all the references to SYMBOL in all loaded elisp files.
|
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the
|
|
||||||
search."
|
|
||||||
(interactive
|
|
||||||
(list (elisp-refs--completing-read-symbol "Symbol: " )
|
|
||||||
(when current-prefix-arg
|
|
||||||
(read-directory-name "Limit search to loaded files in: "))))
|
|
||||||
(elisp-refs--search symbol
|
|
||||||
(elisp-refs--describe-button symbol 'symbol)
|
|
||||||
(lambda (buf)
|
|
||||||
(elisp-refs--read-and-find-symbol buf symbol))
|
|
||||||
path-prefix))
|
|
||||||
|
|
||||||
;;; Mode
|
|
||||||
|
|
||||||
(defvar elisp-refs-mode-map
|
|
||||||
(let ((map (make-sparse-keymap)))
|
|
||||||
;; TODO: it would be nice for TAB to navigate to file buttons too,
|
|
||||||
;; like *Help* does.
|
|
||||||
(set-keymap-parent map special-mode-map)
|
|
||||||
(define-key map (kbd "<tab>") #'elisp-refs-next-match)
|
|
||||||
(define-key map (kbd "<backtab>") #'elisp-refs-prev-match)
|
|
||||||
(define-key map (kbd "n") #'elisp-refs-next-match)
|
|
||||||
(define-key map (kbd "p") #'elisp-refs-prev-match)
|
|
||||||
(define-key map (kbd "q") #'kill-this-buffer)
|
|
||||||
(define-key map (kbd "RET") #'elisp-refs-visit-match)
|
|
||||||
map)
|
|
||||||
"Keymap for `elisp-refs-mode'.")
|
|
||||||
|
|
||||||
(define-derived-mode elisp-refs-mode special-mode "Refs"
|
|
||||||
"Major mode for refs results buffers.")
|
|
||||||
|
|
||||||
(defun elisp--refs-visit-match (open-fn)
|
|
||||||
"Go to the search result at point.
|
|
||||||
Open file with function OPEN_FN. `find-file` or `find-file-other-window`"
|
|
||||||
(interactive)
|
|
||||||
(let* ((path (get-text-property (point) 'elisp-refs-path))
|
|
||||||
(pos (get-text-property (point) 'elisp-refs-start-pos))
|
|
||||||
(unindent (get-text-property (point) 'elisp-refs-unindented))
|
|
||||||
(column-offset (current-column))
|
|
||||||
(line-offset -1))
|
|
||||||
(when (null path)
|
|
||||||
(user-error "No match here"))
|
|
||||||
|
|
||||||
;; If point is not on the first line of the match, work out how
|
|
||||||
;; far away the first line is.
|
|
||||||
(save-excursion
|
|
||||||
(while (equal pos (get-text-property (point) 'elisp-refs-start-pos))
|
|
||||||
(forward-line -1)
|
|
||||||
(cl-incf line-offset)))
|
|
||||||
|
|
||||||
(funcall open-fn path)
|
|
||||||
(goto-char pos)
|
|
||||||
;; Move point so we're on the same char in the buffer that we were
|
|
||||||
;; on in the results buffer.
|
|
||||||
(forward-line line-offset)
|
|
||||||
(beginning-of-line)
|
|
||||||
(let ((target-offset (+ column-offset unindent))
|
|
||||||
(i 0))
|
|
||||||
(while (< i target-offset)
|
|
||||||
(if (looking-at "\t")
|
|
||||||
(cl-incf i tab-width)
|
|
||||||
(cl-incf i))
|
|
||||||
(forward-char 1)))))
|
|
||||||
|
|
||||||
(defun elisp-refs-visit-match ()
|
|
||||||
"Goto the search result at point."
|
|
||||||
(interactive)
|
|
||||||
(elisp--refs-visit-match #'find-file))
|
|
||||||
|
|
||||||
(defun elisp-refs-visit-match-other-window ()
|
|
||||||
"Goto the search result at point, opening in another window."
|
|
||||||
(interactive)
|
|
||||||
(elisp--refs-visit-match #'find-file-other-window))
|
|
||||||
|
|
||||||
|
|
||||||
(defun elisp-refs--move-to-match (direction)
|
|
||||||
"Move point one match forwards.
|
|
||||||
If DIRECTION is -1, moves backwards instead."
|
|
||||||
(let* ((start-pos (point))
|
|
||||||
(match-pos (get-text-property start-pos 'elisp-refs-start-pos))
|
|
||||||
current-match-pos)
|
|
||||||
(condition-case _err
|
|
||||||
(progn
|
|
||||||
;; Move forward/backwards until we're on the next/previous match.
|
|
||||||
(catch 'done
|
|
||||||
(while t
|
|
||||||
(setq current-match-pos
|
|
||||||
(get-text-property (point) 'elisp-refs-start-pos))
|
|
||||||
(when (and current-match-pos
|
|
||||||
(not (equal match-pos current-match-pos)))
|
|
||||||
(throw 'done nil))
|
|
||||||
(forward-char direction)))
|
|
||||||
;; Move to the beginning of that match.
|
|
||||||
(while (equal (get-text-property (point) 'elisp-refs-start-pos)
|
|
||||||
(get-text-property (1- (point)) 'elisp-refs-start-pos))
|
|
||||||
(forward-char -1))
|
|
||||||
;; Move forward until we're on the first char of match within that
|
|
||||||
;; line.
|
|
||||||
(while (or
|
|
||||||
(looking-at " ")
|
|
||||||
(eq (get-text-property (point) 'face)
|
|
||||||
'font-lock-comment-face))
|
|
||||||
(forward-char 1)))
|
|
||||||
;; If we're at the last result, don't move point.
|
|
||||||
(end-of-buffer
|
|
||||||
(progn
|
|
||||||
(goto-char start-pos)
|
|
||||||
(signal 'end-of-buffer nil))))))
|
|
||||||
|
|
||||||
(defun elisp-refs-prev-match ()
|
|
||||||
"Move to the previous search result in the Refs buffer."
|
|
||||||
(interactive)
|
|
||||||
(elisp-refs--move-to-match -1))
|
|
||||||
|
|
||||||
(defun elisp-refs-next-match ()
|
|
||||||
"Move to the next search result in the Refs buffer."
|
|
||||||
(interactive)
|
|
||||||
(elisp-refs--move-to-match 1))
|
|
||||||
|
|
||||||
(provide 'elisp-refs)
|
|
||||||
;;; elisp-refs.el ends here
|
|
|
@ -1,12 +1,14 @@
|
||||||
;;; elisp-refs-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
|
;;; elisp-refs-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
;;
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(add-to-list 'load-path (directory-file-name
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
(or (file-name-directory #$) (car load-path))))
|
|
||||||
|
|
||||||
|
|
||||||
;;;### (autoloads nil "elisp-refs" "elisp-refs.el" (0 0 0 0))
|
|
||||||
;;; Generated autoloads from elisp-refs.el
|
;;; Generated autoloads from elisp-refs.el
|
||||||
|
|
||||||
(autoload 'elisp-refs-function "elisp-refs" "\
|
(autoload 'elisp-refs-function "elisp-refs" "\
|
||||||
|
@ -18,8 +20,7 @@ If called with a prefix, prompt for a directory to limit the search.
|
||||||
This searches for functions, not macros. For that, see
|
This searches for functions, not macros. For that, see
|
||||||
`elisp-refs-macro'.
|
`elisp-refs-macro'.
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
(fn SYMBOL &optional PATH-PREFIX)" t)
|
||||||
|
|
||||||
(autoload 'elisp-refs-macro "elisp-refs" "\
|
(autoload 'elisp-refs-macro "elisp-refs" "\
|
||||||
Display all the references to macro SYMBOL, in all loaded
|
Display all the references to macro SYMBOL, in all loaded
|
||||||
elisp files.
|
elisp files.
|
||||||
|
@ -29,40 +30,40 @@ If called with a prefix, prompt for a directory to limit the search.
|
||||||
This searches for macros, not functions. For that, see
|
This searches for macros, not functions. For that, see
|
||||||
`elisp-refs-function'.
|
`elisp-refs-function'.
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
(fn SYMBOL &optional PATH-PREFIX)" t)
|
||||||
|
|
||||||
(autoload 'elisp-refs-special "elisp-refs" "\
|
(autoload 'elisp-refs-special "elisp-refs" "\
|
||||||
Display all the references to special form SYMBOL, in all loaded
|
Display all the references to special form SYMBOL, in all loaded
|
||||||
elisp files.
|
elisp files.
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
If called with a prefix, prompt for a directory to limit the search.
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
(fn SYMBOL &optional PATH-PREFIX)" t)
|
||||||
|
|
||||||
(autoload 'elisp-refs-variable "elisp-refs" "\
|
(autoload 'elisp-refs-variable "elisp-refs" "\
|
||||||
Display all the references to variable SYMBOL, in all loaded
|
Display all the references to variable SYMBOL, in all loaded
|
||||||
elisp files.
|
elisp files.
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the search.
|
If called with a prefix, prompt for a directory to limit the search.
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
(fn SYMBOL &optional PATH-PREFIX)" t)
|
||||||
|
|
||||||
(autoload 'elisp-refs-symbol "elisp-refs" "\
|
(autoload 'elisp-refs-symbol "elisp-refs" "\
|
||||||
Display all the references to SYMBOL in all loaded elisp files.
|
Display all the references to SYMBOL in all loaded elisp files.
|
||||||
|
|
||||||
If called with a prefix, prompt for a directory to limit the
|
If called with a prefix, prompt for a directory to limit the
|
||||||
search.
|
search.
|
||||||
|
|
||||||
\(fn SYMBOL &optional PATH-PREFIX)" t nil)
|
(fn SYMBOL &optional PATH-PREFIX)" t)
|
||||||
|
|
||||||
(register-definition-prefixes "elisp-refs" '("elisp-"))
|
(register-definition-prefixes "elisp-refs" '("elisp-"))
|
||||||
|
|
||||||
;;;***
|
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'elisp-refs-autoloads)
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; version-control: never
|
;; version-control: never
|
||||||
;; no-byte-compile: t
|
;; no-byte-compile: t
|
||||||
;; no-update-autoloads: t
|
;; no-update-autoloads: t
|
||||||
;; coding: utf-8
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
;; End:
|
;; End:
|
||||||
|
|
||||||
;;; elisp-refs-autoloads.el ends here
|
;;; elisp-refs-autoloads.el ends here
|
|
@ -1,7 +1,7 @@
|
||||||
(define-package "elisp-refs" "20230419.405" "find callers of elisp functions or macros"
|
(define-package "elisp-refs" "20230920.201" "find callers of elisp functions or macros"
|
||||||
'((dash "2.12.0")
|
'((dash "2.12.0")
|
||||||
(s "1.11.0"))
|
(s "1.11.0"))
|
||||||
:commit "bf3cca8f74065b1b31036f461e3a093b162311bd" :authors
|
:commit "541a064c3ce27867872cf708354a65d83baf2a6d" :authors
|
||||||
'(("Wilfred Hughes" . "me@wilfred.me.uk"))
|
'(("Wilfred Hughes" . "me@wilfred.me.uk"))
|
||||||
:maintainers
|
:maintainers
|
||||||
'(("Wilfred Hughes" . "me@wilfred.me.uk"))
|
'(("Wilfred Hughes" . "me@wilfred.me.uk"))
|
|
@ -398,6 +398,7 @@ visiting the same file."
|
||||||
(file-name-handler-alist
|
(file-name-handler-alist
|
||||||
'(("\\(?:\\.dz\\|\\.txz\\|\\.xz\\|\\.lzma\\|\\.lz\\|\\.g?z\\|\\.\\(?:tgz\\|svgz\\|sifz\\)\\|\\.tbz2?\\|\\.bz2\\|\\.Z\\)\\(?:~\\|\\.~[-[:alnum:]:#@^._]+\\(?:~[[:digit:]]+\\)?~\\)?\\'" .
|
'(("\\(?:\\.dz\\|\\.txz\\|\\.xz\\|\\.lzma\\|\\.lz\\|\\.g?z\\|\\.\\(?:tgz\\|svgz\\|sifz\\)\\|\\.tbz2?\\|\\.bz2\\|\\.Z\\)\\(?:~\\|\\.~[-[:alnum:]:#@^._]+\\(?:~[[:digit:]]+\\)?~\\)?\\'" .
|
||||||
jka-compr-handler)
|
jka-compr-handler)
|
||||||
|
("\\(?:^/\\)\\(\\(?:\\(?:\\(-\\|[[:alnum:]]\\{2,\\}\\)\\(?::\\)\\(?:\\([^/:|[:blank:]]+\\)\\(?:@\\)\\)?\\(\\(?:[%._[:alnum:]-]+\\|\\(?:\\[\\)\\(?:\\(?:[[:alnum:]]*:\\)+[.[:alnum:]]*\\)?\\(?:]\\)\\)\\(?:\\(?:#\\)\\(?:[[:digit:]]+\\)\\)?\\)?\\)\\(?:|\\)\\)+\\)?\\(?:\\(-\\|[[:alnum:]]\\{2,\\}\\)\\(?::\\)\\(?:\\([^/:|[:blank:]]+\\)\\(?:@\\)\\)?\\(\\(?:[%._[:alnum:]-]+\\|\\(?:\\[\\)\\(?:\\(?:[[:alnum:]]*:\\)+[.[:alnum:]]*\\)?\\(?:]\\)\\)\\(?:\\(?:#\\)\\(?:[[:digit:]]+\\)\\)?\\)?\\)\\(?::\\)\\([^\n
]*\\'\\)" . tramp-file-name-handler)
|
||||||
("\\`/:" . file-name-non-special))))
|
("\\`/:" . file-name-non-special))))
|
||||||
(with-current-buffer fresh-buffer
|
(with-current-buffer fresh-buffer
|
||||||
(setq-local elisp-refs--path path)
|
(setq-local elisp-refs--path path)
|
||||||
|
@ -813,7 +814,6 @@ search."
|
||||||
(define-key map (kbd "<backtab>") #'elisp-refs-prev-match)
|
(define-key map (kbd "<backtab>") #'elisp-refs-prev-match)
|
||||||
(define-key map (kbd "n") #'elisp-refs-next-match)
|
(define-key map (kbd "n") #'elisp-refs-next-match)
|
||||||
(define-key map (kbd "p") #'elisp-refs-prev-match)
|
(define-key map (kbd "p") #'elisp-refs-prev-match)
|
||||||
(define-key map (kbd "q") #'kill-this-buffer)
|
|
||||||
(define-key map (kbd "RET") #'elisp-refs-visit-match)
|
(define-key map (kbd "RET") #'elisp-refs-visit-match)
|
||||||
map)
|
map)
|
||||||
"Keymap for `elisp-refs-mode'.")
|
"Keymap for `elisp-refs-mode'.")
|
28
code/elpa/f-20240308.906/f-autoloads.el
Normal file
28
code/elpa/f-20240308.906/f-autoloads.el
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
;;; f-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from f.el
|
||||||
|
|
||||||
|
(register-definition-prefixes "f" '("f-"))
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'f-autoloads)
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
|
;; End:
|
||||||
|
|
||||||
|
;;; f-autoloads.el ends here
|
16
code/elpa/f-20240308.906/f-pkg.el
Normal file
16
code/elpa/f-20240308.906/f-pkg.el
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
(define-package "f" "20240308.906" "Modern API for working with files and directories"
|
||||||
|
'((emacs "24.1")
|
||||||
|
(s "1.7.0")
|
||||||
|
(dash "2.2.0"))
|
||||||
|
:commit "1e7020dc0d4c52d3da9bd610d431cab13aa02d8c" :authors
|
||||||
|
'(("Johan Andersson" . "johan.rejeep@gmail.com"))
|
||||||
|
:maintainers
|
||||||
|
'(("Lucien Cartier-Tilet" . "lucien@phundrak.com"))
|
||||||
|
:maintainer
|
||||||
|
'("Lucien Cartier-Tilet" . "lucien@phundrak.com")
|
||||||
|
:keywords
|
||||||
|
'("files" "directories")
|
||||||
|
:url "http://github.com/rejeep/f.el")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
438
code/elpa/f-20240308.906/f-shortdoc.el
Normal file
438
code/elpa/f-20240308.906/f-shortdoc.el
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
;;; f-shortdoc.el --- Shortdoc for f.el -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||||
|
|
||||||
|
;; Author: Lucien Cartier-Tilet <lucien@phundrak.com>
|
||||||
|
;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com>
|
||||||
|
;; Version: 0.1.0
|
||||||
|
;; Package-Requires: ((emacs "28.1"))
|
||||||
|
;; Homepage: https://github.com/rejeep/f.el
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Shortdoc implementation for f.el
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(when (version<= "28.1" emacs-version)
|
||||||
|
(require 'shortdoc)
|
||||||
|
|
||||||
|
(define-short-documentation-group f
|
||||||
|
"Paths"
|
||||||
|
(f-join
|
||||||
|
:eval (f-join "path")
|
||||||
|
:eval (f-join "path" "to")
|
||||||
|
:eval (f-join "/" "path" "to" "heaven")
|
||||||
|
:eval (f-join "path" "/to" "file"))
|
||||||
|
|
||||||
|
(f-split
|
||||||
|
:eval (f-split "path")
|
||||||
|
:eval (f-split "path/to")
|
||||||
|
:eval (f-split "/path/to/heaven")
|
||||||
|
:eval (f-split "~/back/to/earth"))
|
||||||
|
|
||||||
|
(f-expand
|
||||||
|
:no-eval (f-expand "name")
|
||||||
|
:result-string "/default/directory/name"
|
||||||
|
:no-eval (f-expand "name" "other/directory")
|
||||||
|
:result-string "other/directory/name")
|
||||||
|
|
||||||
|
(f-filename
|
||||||
|
:eval (f-filename "path/to/file.ext")
|
||||||
|
:eval (f-filename "path/to/directory"))
|
||||||
|
|
||||||
|
(f-dirname
|
||||||
|
:eval (f-dirname "path/to/file.ext")
|
||||||
|
:eval (f-dirname "path/to/directory")
|
||||||
|
:eval (f-dirname "/"))
|
||||||
|
|
||||||
|
(f-common-parent
|
||||||
|
:eval (f-common-parent '("foo/bar/baz" "foo/bar/qux" "foo/bar/mux"))
|
||||||
|
:eval (f-common-parent '("/foo/bar/baz" "/foo/bar/qux" "/foo/bax/mux"))
|
||||||
|
:eval (f-common-parent '("foo/bar/baz" "quack/bar/qux" "lack/bar/mux")))
|
||||||
|
|
||||||
|
(f-ext
|
||||||
|
:eval (f-ext "path/to/file")
|
||||||
|
:eval (f-ext "path/to/file.txt")
|
||||||
|
:eval (f-ext "path/to/file.txt.org"))
|
||||||
|
|
||||||
|
(f-no-ext
|
||||||
|
:eval (f-no-ext "path/to/file")
|
||||||
|
:eval (f-no-ext "path/to/file.txt")
|
||||||
|
:eval (f-no-ext "path/to/file.txt.org"))
|
||||||
|
|
||||||
|
(f-swap-ext
|
||||||
|
:eval (f-swap-ext "path/to/file.ext" "org"))
|
||||||
|
|
||||||
|
(f-base
|
||||||
|
:eval (f-base "path/to/file.ext")
|
||||||
|
:eval (f-base "path/to/directory"))
|
||||||
|
|
||||||
|
(f-relative
|
||||||
|
:eval (f-relative "/some/path/relative/to/my/file.txt" "/some/path/")
|
||||||
|
:eval (f-relative "/default/directory/my/file.txt"))
|
||||||
|
|
||||||
|
(f-short
|
||||||
|
:no-eval (f-short "/Users/foo/Code/on/macOS")
|
||||||
|
:result-string "~/Code/on/macOS"
|
||||||
|
:no-eval (f-short "/home/foo/Code/on/linux")
|
||||||
|
:result-string "~/Code/on/linux"
|
||||||
|
:eval (f-short "/path/to/Code/bar"))
|
||||||
|
|
||||||
|
(f-long
|
||||||
|
:eval (f-long "~/Code/bar")
|
||||||
|
:eval (f-long "/path/to/Code/bar"))
|
||||||
|
|
||||||
|
(f-canonical
|
||||||
|
:eval (f-canonical "/path/to/real/file")
|
||||||
|
:no-eval (f-canonical "/link/to/file")
|
||||||
|
:result-string "/path/to/real/file")
|
||||||
|
|
||||||
|
(f-slash
|
||||||
|
:no-eval (f-slash "/path/to/file")
|
||||||
|
:result-string "/path/to/file"
|
||||||
|
:no-eval (f-slash "/path/to/dir")
|
||||||
|
:result-string "/path/to/dir/"
|
||||||
|
:no-eval (f-slash "/path/to/dir/")
|
||||||
|
:result-string "/path/to/dir/")
|
||||||
|
|
||||||
|
(f-full
|
||||||
|
:eval (f-full "~/path/to/file")
|
||||||
|
:eval (f-full "~/path/to/dir")
|
||||||
|
:eval (f-full "~/path/to/dir/"))
|
||||||
|
|
||||||
|
(f-uniquify
|
||||||
|
:eval (f-uniquify '("/foo/bar" "/foo/baz" "/foo/quux"))
|
||||||
|
:eval (f-uniquify '("/foo/bar" "/www/bar" "/foo/quux"))
|
||||||
|
:eval (f-uniquify '("/foo/bar" "/www/bar" "/www/bar/quux"))
|
||||||
|
:eval (f-uniquify '("/foo/bar" "/foo/baz" "/home/www/bar" "/home/www/baz" "/var/foo" "/opt/foo/www/baz")))
|
||||||
|
|
||||||
|
(f-uniquify-alist
|
||||||
|
:eval (f-uniquify-alist '("/foo/bar" "/foo/baz" "/foo/quux"))
|
||||||
|
:eval (f-uniquify-alist '("/foo/bar" "/www/bar" "/foo/quux"))
|
||||||
|
:eval (f-uniquify-alist '("/foo/bar" "/www/bar" "/www/bar/quux"))
|
||||||
|
:eval (f-uniquify-alist '("/foo/bar" "/foo/baz" "/home/www/bar" "/home/www/baz" "/var/foo" "/opt/foo/www/baz")))
|
||||||
|
|
||||||
|
"I/O"
|
||||||
|
(f-read-bytes
|
||||||
|
:no-eval* (f-read-bytes "path/to/binary/data"))
|
||||||
|
|
||||||
|
(f-write-bytes
|
||||||
|
:no-eval* (f-write-bytes (unibyte-string 72 101 108 108 111 32 119 111 114 108 100) "path/to/binary/data"))
|
||||||
|
|
||||||
|
(f-append-bytes
|
||||||
|
:no-eval* (f-append-bytes "path/to/file" (unibyte-string 72 101 108 108 111 32 119 111 114 108 100)))
|
||||||
|
|
||||||
|
(f-read-text
|
||||||
|
:no-eval* (f-read-text "path/to/file.txt" 'utf-8)
|
||||||
|
:no-eval* (f-read "path/to/file.txt" 'utf-8))
|
||||||
|
|
||||||
|
(f-write-text
|
||||||
|
:no-eval* (f-write-text "Hello world" 'utf-8 "path/to/file.txt")
|
||||||
|
:no-eval* (f-write "Hello world" 'utf-8 "path/to/file.txt"))
|
||||||
|
|
||||||
|
(f-append-text
|
||||||
|
:no-eval* (f-append-text "Hello world" 'utf-8 "path/to/file.txt")
|
||||||
|
:no-eval* (f-append "Hello world" 'utf-8 "path/to/file.txt"))
|
||||||
|
|
||||||
|
"Destructive"
|
||||||
|
(f-mkdir
|
||||||
|
:no-eval (f-mkdir "dir")
|
||||||
|
:result-string "creates /default/directory/dir"
|
||||||
|
:no-eval (f-mkdir "other" "dir")
|
||||||
|
:result-string "creates /default/directory/other/dir"
|
||||||
|
:no-eval (f-mkdir "/" "some" "path")
|
||||||
|
:result-string "creates /some/path"
|
||||||
|
:no-eval (f-mkdir "~" "yet" "another" "dir")
|
||||||
|
:result-string "creates ~/yet/another/dir")
|
||||||
|
|
||||||
|
(f-mkdir-full-path
|
||||||
|
:no-eval (f-mkdir-full-path "dir")
|
||||||
|
:result-string "creates /default/directory/dir"
|
||||||
|
:no-eval (f-mkdir-full-path "other/dir")
|
||||||
|
:result-string "creates /default/directory/other/dir"
|
||||||
|
:no-eval (f-mkdir-full-path "/some/path")
|
||||||
|
:result-string "creates /some/path"
|
||||||
|
:no-eval (f-mkdir-full-path "~/yet/another/dir")
|
||||||
|
:result-string "creates ~/yet/another/dir")
|
||||||
|
|
||||||
|
(f-delete
|
||||||
|
:no-eval* (f-delete "dir")
|
||||||
|
:no-eval* (f-delete "other/dir" t)
|
||||||
|
:no-eval* (f-delete "path/to/file.txt"))
|
||||||
|
|
||||||
|
(f-symlink
|
||||||
|
:no-eval* (f-symlink "path/to/source" "path/to/link"))
|
||||||
|
|
||||||
|
(f-move
|
||||||
|
:no-eval* (f-move "path/to/file.txt" "new-file.txt")
|
||||||
|
:no-eval* (f-move "path/to/file.txt" "other/path"))
|
||||||
|
|
||||||
|
(f-copy
|
||||||
|
:no-eval* (f-copy "path/to/file.txt" "new-file.txt")
|
||||||
|
:no-eval* (f-copy "path/to/dir" "other/dir"))
|
||||||
|
|
||||||
|
(f-copy-contents
|
||||||
|
:no-eval* (f-copy-contents "path/to/dir" "path/to/other/dir"))
|
||||||
|
|
||||||
|
(f-touch
|
||||||
|
:no-eval* (f-touch "path/to/existing/file.txt")
|
||||||
|
:no-eval* (f-touch "path/to/non/existing/file.txt"))
|
||||||
|
|
||||||
|
"Predicates"
|
||||||
|
(f-exists-p
|
||||||
|
:no-eval* (f-exists-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-exists-p "path/to/dir"))
|
||||||
|
|
||||||
|
(f-directory-p
|
||||||
|
:no-eval* (f-directory-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-directory-p "path/to/dir"))
|
||||||
|
|
||||||
|
(f-file-p
|
||||||
|
:no-eval* (f-file-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-file-p "path/to/dir"))
|
||||||
|
|
||||||
|
(f-symlink-p
|
||||||
|
:no-eval* (f-symlink-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-symlink-p "path/to/dir")
|
||||||
|
:no-eval* (f-symlink-p "path/to/link"))
|
||||||
|
|
||||||
|
(f-readable-p
|
||||||
|
:no-eval* (f-readable-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-readable-p "path/to/dir"))
|
||||||
|
|
||||||
|
(f-writable-p
|
||||||
|
:no-eval* (f-writable-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-writable-p "path/to/dir"))
|
||||||
|
|
||||||
|
(f-executable-p
|
||||||
|
:no-eval* (f-executable-p "path/to/file.txt")
|
||||||
|
:no-eval* (f-executable-p "path/to/dir"))
|
||||||
|
|
||||||
|
(f-absolute-p
|
||||||
|
:eval (f-absolute-p "path/to/dir")
|
||||||
|
:eval (f-absolute-p "/full/path/to/dir"))
|
||||||
|
|
||||||
|
(f-relative-p
|
||||||
|
:eval (f-relative-p "path/to/dir")
|
||||||
|
:eval (f-relative-p "/full/path/to/dir"))
|
||||||
|
|
||||||
|
(f-root-p
|
||||||
|
:eval (f-root-p "/")
|
||||||
|
:eval (f-root-p "/not/root"))
|
||||||
|
|
||||||
|
(f-ext-p
|
||||||
|
:eval (f-ext-p "path/to/file.el" "el")
|
||||||
|
:eval (f-ext-p "path/to/file.el" "txt")
|
||||||
|
:eval (f-ext-p "path/to/file.el")
|
||||||
|
:eval (f-ext-p "path/to/file"))
|
||||||
|
|
||||||
|
(f-same-p
|
||||||
|
:eval (f-same-p "foo.txt" "foo.txt")
|
||||||
|
:eval (f-same-p "foo/bar/../baz" "foo/baz")
|
||||||
|
:eval (f-same-p "/path/to/foo.txt" "/path/to/bar.txt"))
|
||||||
|
|
||||||
|
(f-parent-of-p
|
||||||
|
:no-eval (f-parent-of-p "/path/to" "/path/to/dir")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-parent-of-p "/path/to/dir" "/path/to")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-parent-of-p "/path/to" "/path/to")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-child-of-p
|
||||||
|
:no-eval (f-child-of-p "/path/to" "/path/to/dir")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-child-of-p "/path/to/dir" "/path/to")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-child-of-p "/path/to" "/path/to")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-ancestor-of-p
|
||||||
|
:no-eval (f-ancestor-of-p "/path/to" "/path/to/dir")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-ancestor-of-p "/path" "/path/to/dir")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-ancestor-of-p "/path/to/dir" "/path/to")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-ancestor-of-p "/path/to" "/path/to")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-descendant-of-p
|
||||||
|
:no-eval (f-descendant-of-p "/path/to/dir" "/path/to")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-descendant-of-p "/path/to/dir" "/path")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-descendant-of-p "/path/to" "/path/to/dir")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-descendant-of-p "/path/to" "/path/to")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-hidden-p
|
||||||
|
:eval (f-hidden-p "path/to/foo")
|
||||||
|
:eval (f-hidden-p ".path/to/foo")
|
||||||
|
:eval (f-hidden-p "path/.to/foo")
|
||||||
|
:eval (f-hidden-p "path/to/.foo")
|
||||||
|
:eval (f-hidden-p ".path/to/foo" 'any)
|
||||||
|
:eval (f-hidden-p "path/.to/foo" 'any)
|
||||||
|
:eval (f-hidden-p "path/to/.foo" 'any)
|
||||||
|
:eval (f-hidden-p ".path/to/foo" 'last)
|
||||||
|
:eval (f-hidden-p "path/.to/foo" 'last)
|
||||||
|
:eval (f-hidden-p "path/to/.foo" 'last))
|
||||||
|
|
||||||
|
(f-empty-p
|
||||||
|
:no-eval (f-empty-p "/path/to/empty-file")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-empty-p "/path/to/file-with-contents")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-empty-p "/path/to/empty-dir/")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-empty-p "/path/to/dir-with-contents/")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-older-p
|
||||||
|
:no-eval (f-older-p "older-file.txt" "newer-file.txt")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-older-p "newer-file.txt" "older-file.txt")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-older-p "same-time1.txt" "same-time2.txt")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-newer-p
|
||||||
|
:no-eval (f-newer-p "newer-file.txt" "older-file.txt")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-newer-p "older-file.txt" "newer-file.txt")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-newer-p "same-time1.txt" "same-time2.txt")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
(f-same-time-p
|
||||||
|
:no-eval (f-same-time-p "same-time1.txt" "same-time2.txt")
|
||||||
|
:result t
|
||||||
|
:no-eval (f-same-time-p "newer-file.txt" "older-file.txt")
|
||||||
|
:result nil
|
||||||
|
:no-eval (f-same-time-p "older-file.txt" "newer-file.txt")
|
||||||
|
:result nil)
|
||||||
|
|
||||||
|
"Stats"
|
||||||
|
(f-size
|
||||||
|
:no-eval* (f-size "path/to/file.txt")
|
||||||
|
:no-eval* (f-size "path/to/dir"))
|
||||||
|
|
||||||
|
(f-depth
|
||||||
|
:eval (f-depth "/")
|
||||||
|
:eval (f-depth "/var/")
|
||||||
|
:eval (f-depth "/usr/local/bin"))
|
||||||
|
|
||||||
|
(f-change-time
|
||||||
|
:no-eval (f-change-time "path/to/file.txt")
|
||||||
|
:result (25517 48756 26337 111000)
|
||||||
|
:no-eval (f-change-time "path/to/dir")
|
||||||
|
:result (25517 57887 344657 210000)
|
||||||
|
:no-eval (f-change-time "path/to/file.txt" t)
|
||||||
|
:result (1672330868026337111 . 1000000000)
|
||||||
|
:no-eval (f-change-time "path/to/dir" t)
|
||||||
|
:result (1672339999344657210 . 1000000000)
|
||||||
|
:no-eval (f-change-time "path/to/file.txt" 'seconds)
|
||||||
|
:result 1672330868
|
||||||
|
:no-eval (f-change-time "path/to/dir" 'seconds)
|
||||||
|
:result 1672339999)
|
||||||
|
|
||||||
|
(f-modification-time
|
||||||
|
:no-eval (f-modification-time "path/to/file.txt")
|
||||||
|
:result (25517 48756 26337 111000)
|
||||||
|
:no-eval (f-modification-time "path/to/dir")
|
||||||
|
:result (25517 57887 344657 210000)
|
||||||
|
:no-eval (f-modification-time "path/to/file.txt" t)
|
||||||
|
:result (1672330868026337111 . 1000000000)
|
||||||
|
:no-eval (f-modification-time "path/to/dir" t)
|
||||||
|
:result (1672339999344657210 . 1000000000)
|
||||||
|
:no-eval (f-modification-time "path/to/file.txt" 'seconds)
|
||||||
|
:result 1672330868
|
||||||
|
:no-eval (f-modification-time "path/to/dir" 'seconds)
|
||||||
|
:result 1672339999)
|
||||||
|
|
||||||
|
(f-access-time
|
||||||
|
:no-eval (f-access-time "path/to/file.txt")
|
||||||
|
:result (25517 48756 26337 111000)
|
||||||
|
:no-eval (f-access-time "path/to/dir")
|
||||||
|
:result (25517 57887 344657 210000)
|
||||||
|
:no-eval (f-access-time "path/to/file.txt" t)
|
||||||
|
:result (1672330868026337111 . 1000000000)
|
||||||
|
:no-eval (f-access-time "path/to/dir" t)
|
||||||
|
:result (1672339999344657210 . 1000000000)
|
||||||
|
:no-eval (f-access-time "path/to/file.txt" 'seconds)
|
||||||
|
:result 1672330868
|
||||||
|
:no-eval (f-access-time "path/to/dir" 'seconds)
|
||||||
|
:result 1672339999)
|
||||||
|
|
||||||
|
"Misc"
|
||||||
|
(f-this-file
|
||||||
|
:no-eval* (f-this-file))
|
||||||
|
|
||||||
|
(f-path-separator
|
||||||
|
:eval (f-path-separator))
|
||||||
|
|
||||||
|
(f-glob
|
||||||
|
:no-eval* (f-glob "path/to/*.el")
|
||||||
|
:no-eval* (f-glob "*.el" "path/to"))
|
||||||
|
|
||||||
|
(f-entries
|
||||||
|
:no-eval* (f-entries "path/to/dir")
|
||||||
|
:no-eval* (f-entries "path/to/dir" (lambda (file) (s-matches? "test" file)))
|
||||||
|
:no-eval* (f-entries "path/to/dir" nil t)
|
||||||
|
:no-eval* (f--entries "path/to/dir" (s-matches? "test" it)))
|
||||||
|
|
||||||
|
(f-directories
|
||||||
|
:no-eval* (f-directories "path/to/dir")
|
||||||
|
:no-eval* (f-directories "path/to/dir" (lambda (dir) (equal (f-filename dir) "test")))
|
||||||
|
:no-eval* (f-directories "path/to/dir" nil t)
|
||||||
|
:no-eval* (f--directories "path/to/dir" (equal (f-filename it) "test")))
|
||||||
|
|
||||||
|
(f-files
|
||||||
|
:no-eval* (f-files "path/to/dir")
|
||||||
|
:no-eval* (f-files "path/to/dir" (lambda (file) (equal (f-ext file) "el")))
|
||||||
|
:no-eval* (f-files "path/to/dir" nil t)
|
||||||
|
:no-eval* (f--files "path/to/dir" (equal (f-ext it) "el")))
|
||||||
|
|
||||||
|
(f-root
|
||||||
|
:eval (f-root))
|
||||||
|
|
||||||
|
(f-traverse-upwards
|
||||||
|
:no-eval* (f-traverse-upwards
|
||||||
|
(lambda (path)
|
||||||
|
(f-exists? (f-expand ".git" path)))
|
||||||
|
start-path)
|
||||||
|
|
||||||
|
:no-eval* (f--traverse-upwards (f-exists? (f-expand ".git" it)) start-path))
|
||||||
|
|
||||||
|
(f-with-sandbox
|
||||||
|
:no-eval (f-with-sandbox foo-path
|
||||||
|
(f-touch (f-expand "foo" foo-path)))
|
||||||
|
:no-eval (f-with-sandbox (list foo-path bar-path)
|
||||||
|
(f-touch (f-expand "foo" foo-path))
|
||||||
|
(f-touch (f-expand "bar" bar-path)))
|
||||||
|
:no-eval (f-with-sandbox foo-path
|
||||||
|
(f-touch (f-expand "bar" bar-path)))))) ;; "Destructive operation outside sandbox"
|
||||||
|
|
||||||
|
(eval-when-compile
|
||||||
|
(when (version< emacs-version "28.1")
|
||||||
|
(warn "Emacs should not be compiling this file")))
|
||||||
|
|
||||||
|
(provide 'f-shortdoc)
|
||||||
|
|
||||||
|
;;; f-shortdoc.el ends here
|
799
code/elpa/f-20240308.906/f.el
Normal file
799
code/elpa/f-20240308.906/f.el
Normal file
|
@ -0,0 +1,799 @@
|
||||||
|
;;; f.el --- Modern API for working with files and directories -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2013 Johan Andersson
|
||||||
|
|
||||||
|
;; Author: Johan Andersson <johan.rejeep@gmail.com>
|
||||||
|
;; Maintainer: Lucien Cartier-Tilet <lucien@phundrak.com>
|
||||||
|
;; Version: 0.20.0
|
||||||
|
;; Package-Requires: ((emacs "24.1") (s "1.7.0") (dash "2.2.0"))
|
||||||
|
;; Keywords: files, directories
|
||||||
|
;; Homepage: http://github.com/rejeep/f.el
|
||||||
|
|
||||||
|
;; This file is NOT part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; License:
|
||||||
|
|
||||||
|
;; This program 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, or (at your option)
|
||||||
|
;; any later version.
|
||||||
|
|
||||||
|
;; This program 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 GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
;; Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; Much inspired by magnar's excellent s.el and dash.el, f.el is a
|
||||||
|
;; modern API for working with files and directories in Emacs.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(require 's)
|
||||||
|
(require 'dash)
|
||||||
|
(when (version<= "28.1" emacs-version)
|
||||||
|
(when (< emacs-major-version 29)
|
||||||
|
(require 'f-shortdoc nil t)))
|
||||||
|
|
||||||
|
(put 'f-guard-error 'error-conditions '(error f-guard-error))
|
||||||
|
(put 'f-guard-error 'error-message "Destructive operation outside sandbox")
|
||||||
|
|
||||||
|
(defvar f--guard-paths nil
|
||||||
|
"List of allowed paths to modify when guarded.
|
||||||
|
|
||||||
|
Do not modify this variable.")
|
||||||
|
|
||||||
|
(defmacro f--destructive (path &rest body)
|
||||||
|
"If PATH is allowed to be modified, yield BODY.
|
||||||
|
|
||||||
|
If PATH is not allowed to be modified, throw error."
|
||||||
|
(declare (indent 1))
|
||||||
|
`(if f--guard-paths
|
||||||
|
(if (--any? (or (f-same-p it ,path)
|
||||||
|
(f-ancestor-of-p it ,path)) f--guard-paths)
|
||||||
|
(progn ,@body)
|
||||||
|
(signal 'f-guard-error (list ,path f--guard-paths)))
|
||||||
|
,@body))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; Paths
|
||||||
|
|
||||||
|
(defun f-join (&rest args)
|
||||||
|
"Join ARGS to a single path.
|
||||||
|
|
||||||
|
Be aware if one of the arguments is an absolute path, `f-join'
|
||||||
|
will discard all the preceeding arguments and make this absolute
|
||||||
|
path the new root of the generated path."
|
||||||
|
(let (path
|
||||||
|
(relative (f-relative-p (car args))))
|
||||||
|
(mapc
|
||||||
|
(lambda (arg)
|
||||||
|
(setq path (cond ((not path) arg)
|
||||||
|
((f-absolute-p arg)
|
||||||
|
(progn
|
||||||
|
(setq relative nil)
|
||||||
|
arg))
|
||||||
|
(t (f-expand arg path)))))
|
||||||
|
args)
|
||||||
|
(if relative (f-relative path) path)))
|
||||||
|
|
||||||
|
(defun f-split (path)
|
||||||
|
"Split PATH and return list containing parts."
|
||||||
|
(let ((parts (split-string path (f-path-separator) 'omit-nulls)))
|
||||||
|
(if (string= (s-left 1 path) (f-path-separator))
|
||||||
|
(push (f-path-separator) parts)
|
||||||
|
parts)))
|
||||||
|
|
||||||
|
(defun f-expand (path &optional dir)
|
||||||
|
"Expand PATH relative to DIR (or `default-directory').
|
||||||
|
PATH and DIR can be either a directory names or directory file
|
||||||
|
names. Return a directory name if PATH is a directory name, and
|
||||||
|
a directory file name otherwise. File name handlers are
|
||||||
|
ignored."
|
||||||
|
(let (file-name-handler-alist)
|
||||||
|
(expand-file-name path dir)))
|
||||||
|
|
||||||
|
(defun f-filename (path)
|
||||||
|
"Return the name of PATH."
|
||||||
|
(file-name-nondirectory (directory-file-name path)))
|
||||||
|
|
||||||
|
(defalias 'f-parent 'f-dirname)
|
||||||
|
|
||||||
|
(defun f-dirname (path)
|
||||||
|
"Return the parent directory to PATH."
|
||||||
|
(let ((parent (file-name-directory
|
||||||
|
(directory-file-name (f-expand path default-directory)))))
|
||||||
|
(unless (f-same-p path parent)
|
||||||
|
(if (f-relative-p path)
|
||||||
|
(f-relative parent)
|
||||||
|
(directory-file-name parent)))))
|
||||||
|
|
||||||
|
(defun f-common-parent (paths)
|
||||||
|
"Return the deepest common parent directory of PATHS."
|
||||||
|
(cond
|
||||||
|
((not paths) nil)
|
||||||
|
((not (cdr paths)) (f-parent (car paths)))
|
||||||
|
(:otherwise
|
||||||
|
(let* ((paths (-map 'f-split paths))
|
||||||
|
(common (caar paths))
|
||||||
|
(re nil))
|
||||||
|
(while (and (not (null (car paths))) (--all? (equal (car it) common) paths))
|
||||||
|
(setq paths (-map 'cdr paths))
|
||||||
|
(push common re)
|
||||||
|
(setq common (caar paths)))
|
||||||
|
(cond
|
||||||
|
((null re) "")
|
||||||
|
((and (= (length re) 1) (f-root-p (car re)))
|
||||||
|
(f-root))
|
||||||
|
(:otherwise
|
||||||
|
(concat (apply 'f-join (nreverse re)) "/")))))))
|
||||||
|
|
||||||
|
(defalias 'f-ext 'file-name-extension)
|
||||||
|
|
||||||
|
(defalias 'f-no-ext 'file-name-sans-extension)
|
||||||
|
|
||||||
|
(defun f-swap-ext (path ext)
|
||||||
|
"Return PATH but with EXT as the new extension.
|
||||||
|
EXT must not be nil or empty."
|
||||||
|
(if (s-blank-p ext)
|
||||||
|
(error "Extension cannot be empty or nil")
|
||||||
|
(concat (f-no-ext path) "." ext)))
|
||||||
|
|
||||||
|
(defun f-base (path)
|
||||||
|
"Return the name of PATH, excluding the extension of file."
|
||||||
|
(f-no-ext (f-filename path)))
|
||||||
|
|
||||||
|
(defalias 'f-relative 'file-relative-name)
|
||||||
|
|
||||||
|
(defalias 'f-short 'abbreviate-file-name)
|
||||||
|
(defalias 'f-abbrev 'abbreviate-file-name)
|
||||||
|
|
||||||
|
(defun f-long (path)
|
||||||
|
"Return long version of PATH."
|
||||||
|
(f-expand path))
|
||||||
|
|
||||||
|
(defalias 'f-canonical 'file-truename)
|
||||||
|
|
||||||
|
(defun f-slash (path)
|
||||||
|
"Append slash to PATH unless one already.
|
||||||
|
|
||||||
|
Some functions, such as `call-process' requires there to be an
|
||||||
|
ending slash."
|
||||||
|
(if (f-dir-p path)
|
||||||
|
(file-name-as-directory path)
|
||||||
|
path))
|
||||||
|
|
||||||
|
(defun f-full (path)
|
||||||
|
"Return absolute path to PATH, with ending slash."
|
||||||
|
(f-slash (f-long path)))
|
||||||
|
|
||||||
|
(defun f--uniquify (paths)
|
||||||
|
"Helper for `f-uniquify' and `f-uniquify-alist'."
|
||||||
|
(let* ((files-length (length paths))
|
||||||
|
(uniq-filenames (--map (cons it (f-filename it)) paths))
|
||||||
|
(uniq-filenames-next (-group-by 'cdr uniq-filenames)))
|
||||||
|
(while (/= files-length (length uniq-filenames-next))
|
||||||
|
(setq uniq-filenames-next
|
||||||
|
(-group-by 'cdr
|
||||||
|
(--mapcat
|
||||||
|
(let ((conf-files (cdr it)))
|
||||||
|
(if (> (length conf-files) 1)
|
||||||
|
(--map (cons
|
||||||
|
(car it)
|
||||||
|
(concat
|
||||||
|
(f-filename (s-chop-suffix (cdr it)
|
||||||
|
(car it)))
|
||||||
|
(f-path-separator) (cdr it)))
|
||||||
|
conf-files)
|
||||||
|
conf-files))
|
||||||
|
uniq-filenames-next))))
|
||||||
|
uniq-filenames-next))
|
||||||
|
|
||||||
|
(defun f-uniquify (files)
|
||||||
|
"Return unique suffixes of FILES.
|
||||||
|
|
||||||
|
This function expects no duplicate paths."
|
||||||
|
(-map 'car (f--uniquify files)))
|
||||||
|
|
||||||
|
(defun f-uniquify-alist (files)
|
||||||
|
"Return alist mapping FILES to unique suffixes of FILES.
|
||||||
|
|
||||||
|
This function expects no duplicate paths."
|
||||||
|
(-map 'cadr (f--uniquify files)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; I/O
|
||||||
|
|
||||||
|
(defun f-read-bytes (path &optional beg end)
|
||||||
|
"Read binary data from PATH.
|
||||||
|
|
||||||
|
Return the binary data as unibyte string. The optional second
|
||||||
|
and third arguments BEG and END specify what portion of the file
|
||||||
|
to read."
|
||||||
|
(with-temp-buffer
|
||||||
|
(set-buffer-multibyte nil)
|
||||||
|
(setq buffer-file-coding-system 'binary)
|
||||||
|
(insert-file-contents-literally path nil beg end)
|
||||||
|
(buffer-substring-no-properties (point-min) (point-max))))
|
||||||
|
|
||||||
|
(defalias 'f-read 'f-read-text)
|
||||||
|
(defun f-read-text (path &optional coding)
|
||||||
|
"Read text with PATH, using CODING.
|
||||||
|
|
||||||
|
CODING defaults to `utf-8'.
|
||||||
|
|
||||||
|
Return the decoded text as multibyte string."
|
||||||
|
(decode-coding-string (f-read-bytes path) (or coding 'utf-8)))
|
||||||
|
|
||||||
|
(defalias 'f-write 'f-write-text)
|
||||||
|
(defun f-write-text (text coding path)
|
||||||
|
"Write TEXT with CODING to PATH.
|
||||||
|
|
||||||
|
TEXT is a multibyte string. CODING is a coding system to encode
|
||||||
|
TEXT with. PATH is a file name to write to."
|
||||||
|
(f-write-bytes (encode-coding-string text coding) path))
|
||||||
|
|
||||||
|
(defun f-unibyte-string-p (s)
|
||||||
|
"Determine whether S is a unibyte string."
|
||||||
|
(not (multibyte-string-p s)))
|
||||||
|
|
||||||
|
(defun f-write-bytes (data path)
|
||||||
|
"Write binary DATA to PATH.
|
||||||
|
|
||||||
|
DATA is a unibyte string. PATH is a file name to write to."
|
||||||
|
(f--write-bytes data path nil))
|
||||||
|
|
||||||
|
(defalias 'f-append 'f-append-text)
|
||||||
|
(defun f-append-text (text coding path)
|
||||||
|
"Append TEXT with CODING to PATH.
|
||||||
|
|
||||||
|
If PATH does not exist, it is created."
|
||||||
|
(f-append-bytes (encode-coding-string text coding) path))
|
||||||
|
|
||||||
|
(defun f-append-bytes (data path)
|
||||||
|
"Append binary DATA to PATH.
|
||||||
|
|
||||||
|
If PATH does not exist, it is created."
|
||||||
|
(f--write-bytes data path :append))
|
||||||
|
|
||||||
|
(defun f--write-bytes (data filename append)
|
||||||
|
"Write binary DATA to FILENAME.
|
||||||
|
If APPEND is non-nil, append the DATA to the existing contents."
|
||||||
|
(f--destructive filename
|
||||||
|
(unless (f-unibyte-string-p data)
|
||||||
|
(signal 'wrong-type-argument (list 'f-unibyte-string-p data)))
|
||||||
|
(let ((coding-system-for-write 'binary)
|
||||||
|
(write-region-annotate-functions nil)
|
||||||
|
(write-region-post-annotation-function nil))
|
||||||
|
(write-region data nil filename append :silent)
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; Destructive
|
||||||
|
|
||||||
|
(defun f-mkdir (&rest dirs)
|
||||||
|
"Create directories DIRS.
|
||||||
|
|
||||||
|
DIRS should be a successive list of directories forming together
|
||||||
|
a full path. The easiest way to call this function with a fully
|
||||||
|
formed path is using `f-split' alongside it:
|
||||||
|
|
||||||
|
(apply #\\='f-mkdir (f-split \"path/to/file\"))
|
||||||
|
|
||||||
|
Although it works sometimes, it is not recommended to use fully
|
||||||
|
formed paths in the function. In this case, it is recommended to
|
||||||
|
use `f-mkdir-full-path' instead."
|
||||||
|
(let (path)
|
||||||
|
(-each
|
||||||
|
dirs
|
||||||
|
(lambda (dir)
|
||||||
|
(setq path (f-expand dir path))
|
||||||
|
(unless (f-directory-p path)
|
||||||
|
(f--destructive path (make-directory path)))))))
|
||||||
|
|
||||||
|
(defun f-mkdir-full-path (dir)
|
||||||
|
"Create DIR from a full path.
|
||||||
|
|
||||||
|
This function is similar to `f-mkdir' except it can accept a full
|
||||||
|
path instead of requiring several successive directory names."
|
||||||
|
(apply #'f-mkdir (f-split dir)))
|
||||||
|
|
||||||
|
(defun f-delete (path &optional force)
|
||||||
|
"Delete PATH, which can be file or directory.
|
||||||
|
|
||||||
|
If FORCE is t, a directory will be deleted recursively."
|
||||||
|
(f--destructive path
|
||||||
|
(if (or (f-file-p path) (f-symlink-p path))
|
||||||
|
(delete-file path)
|
||||||
|
(delete-directory path force))))
|
||||||
|
|
||||||
|
(defun f-symlink (source path)
|
||||||
|
"Create a symlink to SOURCE from PATH."
|
||||||
|
(f--destructive path (make-symbolic-link source path)))
|
||||||
|
|
||||||
|
(defun f-move (from to)
|
||||||
|
"Move or rename FROM to TO.
|
||||||
|
If TO is a directory name, move FROM into TO."
|
||||||
|
(f--destructive to (rename-file from to t)))
|
||||||
|
|
||||||
|
(defun f-copy (from to)
|
||||||
|
"Copy file or directory FROM to TO.
|
||||||
|
If FROM names a directory and TO is a directory name, copy FROM
|
||||||
|
into TO as a subdirectory."
|
||||||
|
(f--destructive to
|
||||||
|
(if (f-file-p from)
|
||||||
|
(copy-file from to)
|
||||||
|
;; The behavior of `copy-directory' differs between Emacs 23 and
|
||||||
|
;; 24 in that in Emacs 23, the contents of `from' is copied to
|
||||||
|
;; `to', while in Emacs 24 the directory `from' is copied to
|
||||||
|
;; `to'. We want the Emacs 24 behavior.
|
||||||
|
(if (> emacs-major-version 23)
|
||||||
|
(copy-directory from to)
|
||||||
|
(if (f-dir-p to)
|
||||||
|
(progn
|
||||||
|
(apply 'f-mkdir (f-split to))
|
||||||
|
(let ((new-to (f-expand (f-filename from) to)))
|
||||||
|
(copy-directory from new-to)))
|
||||||
|
(copy-directory from to))))))
|
||||||
|
|
||||||
|
(defun f-copy-contents (from to)
|
||||||
|
"Copy contents in directory FROM, to directory TO."
|
||||||
|
(unless (f-exists-p to)
|
||||||
|
(error "Cannot copy contents to non existing directory %s" to))
|
||||||
|
(unless (f-dir-p from)
|
||||||
|
(error "Cannot copy contents as %s is a file" from))
|
||||||
|
(--each (f-entries from)
|
||||||
|
(f-copy it (file-name-as-directory to))))
|
||||||
|
|
||||||
|
(defun f-touch (path)
|
||||||
|
"Update PATH last modification date or create if it does not exist."
|
||||||
|
(f--destructive path
|
||||||
|
(if (f-file-p path)
|
||||||
|
(set-file-times path)
|
||||||
|
(f-write-bytes "" path))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; Predicates
|
||||||
|
|
||||||
|
(defalias 'f-exists-p 'file-exists-p)
|
||||||
|
(defalias 'f-exists? 'file-exists-p)
|
||||||
|
|
||||||
|
(defalias 'f-directory-p 'file-directory-p)
|
||||||
|
(defalias 'f-directory? 'file-directory-p)
|
||||||
|
(defalias 'f-dir-p 'file-directory-p)
|
||||||
|
(defalias 'f-dir? 'file-directory-p)
|
||||||
|
|
||||||
|
|
||||||
|
(defalias 'f-file-p 'file-regular-p)
|
||||||
|
(defalias 'f-file? 'file-regular-p)
|
||||||
|
|
||||||
|
(defun f-symlink-p (path)
|
||||||
|
"Return t if PATH is symlink, false otherwise."
|
||||||
|
(not (not (file-symlink-p path))))
|
||||||
|
|
||||||
|
(defalias 'f-symlink? 'f-symlink-p)
|
||||||
|
|
||||||
|
(defalias 'f-readable-p 'file-readable-p)
|
||||||
|
(defalias 'f-readable? 'file-readable-p)
|
||||||
|
|
||||||
|
(defalias 'f-writable-p 'file-writable-p)
|
||||||
|
(defalias 'f-writable? 'file-writable-p)
|
||||||
|
|
||||||
|
(defalias 'f-executable-p 'file-executable-p)
|
||||||
|
(defalias 'f-executable? 'file-executable-p)
|
||||||
|
|
||||||
|
(defalias 'f-absolute-p 'file-name-absolute-p)
|
||||||
|
(defalias 'f-absolute? 'file-name-absolute-p)
|
||||||
|
|
||||||
|
(defun f-relative-p (path)
|
||||||
|
"Return t if PATH is relative, false otherwise."
|
||||||
|
(not (f-absolute-p path)))
|
||||||
|
|
||||||
|
(defalias 'f-relative? 'f-relative-p)
|
||||||
|
|
||||||
|
(defun f-root-p (path)
|
||||||
|
"Return t if PATH is root directory, false otherwise."
|
||||||
|
(not (f-parent path)))
|
||||||
|
|
||||||
|
(defalias 'f-root? 'f-root-p)
|
||||||
|
|
||||||
|
(defun f-ext-p (path &optional ext)
|
||||||
|
"Return t if extension of PATH is EXT, false otherwise.
|
||||||
|
|
||||||
|
If EXT is nil or omitted, return t if PATH has any extension,
|
||||||
|
false otherwise.
|
||||||
|
|
||||||
|
The extension, in a file name, is the part that follows the last
|
||||||
|
'.', excluding version numbers and backup suffixes."
|
||||||
|
(if ext
|
||||||
|
(string= (f-ext path) ext)
|
||||||
|
(not (eq (f-ext path) nil))))
|
||||||
|
|
||||||
|
(defalias 'f-ext? 'f-ext-p)
|
||||||
|
|
||||||
|
(defalias 'f-equal-p 'f-same-p)
|
||||||
|
(defalias 'f-equal? 'f-same-p)
|
||||||
|
|
||||||
|
(defun f-same-p (path-a path-b)
|
||||||
|
"Return t if PATH-A and PATH-B are references to same file."
|
||||||
|
(equal
|
||||||
|
(f-canonical (directory-file-name (f-expand path-a)))
|
||||||
|
(f-canonical (directory-file-name (f-expand path-b)))))
|
||||||
|
|
||||||
|
(defalias 'f-same? 'f-same-p)
|
||||||
|
|
||||||
|
(defun f-parent-of-p (path-a path-b)
|
||||||
|
"Return t if PATH-A is parent of PATH-B."
|
||||||
|
(--when-let (f-parent path-b)
|
||||||
|
(f-same-p path-a it)))
|
||||||
|
|
||||||
|
(defalias 'f-parent-of? 'f-parent-of-p)
|
||||||
|
|
||||||
|
(defun f-child-of-p (path-a path-b)
|
||||||
|
"Return t if PATH-A is child of PATH-B."
|
||||||
|
(--when-let (f-parent path-a)
|
||||||
|
(f-same-p it path-b)))
|
||||||
|
|
||||||
|
(defalias 'f-child-of? 'f-child-of-p)
|
||||||
|
|
||||||
|
(defun f-ancestor-of-p (path-a path-b)
|
||||||
|
"Return t if PATH-A is ancestor of PATH-B."
|
||||||
|
(unless (f-same-p path-a path-b)
|
||||||
|
(string-prefix-p (f-full path-a)
|
||||||
|
(f-full path-b))))
|
||||||
|
|
||||||
|
(defalias 'f-ancestor-of? 'f-ancestor-of-p)
|
||||||
|
|
||||||
|
(defun f-descendant-of-p (path-a path-b)
|
||||||
|
"Return t if PATH-A is desendant of PATH-B."
|
||||||
|
(unless (f-same-p path-a path-b)
|
||||||
|
(let ((path-a (f-split (f-full path-a)))
|
||||||
|
(path-b (f-split (f-full path-b)))
|
||||||
|
(parent-p t))
|
||||||
|
(while (and path-b parent-p)
|
||||||
|
(if (string= (car path-a) (car path-b))
|
||||||
|
(setq path-a (cdr path-a)
|
||||||
|
path-b (cdr path-b))
|
||||||
|
(setq parent-p nil)))
|
||||||
|
parent-p)))
|
||||||
|
|
||||||
|
(defalias 'f-descendant-of? 'f-descendant-of-p)
|
||||||
|
|
||||||
|
(defun f-hidden-p (path &optional behavior)
|
||||||
|
"Return t if PATH is hidden, nil otherwise.
|
||||||
|
|
||||||
|
BEHAVIOR controls when a path should be considered as hidden
|
||||||
|
depending on its value. Beware, if PATH begins with \"./\", the
|
||||||
|
current dir \".\" will not be considered as hidden.
|
||||||
|
|
||||||
|
When BEHAVIOR is nil, it will only check if the path begins with
|
||||||
|
a dot, as in .a/b/c, and return t if there is one. This is the
|
||||||
|
old behavior of f.el left as default for backward-compatibility
|
||||||
|
purposes.
|
||||||
|
|
||||||
|
When BEHAVIOR is ANY, return t if any of the elements of PATH is
|
||||||
|
hidden, nil otherwise.
|
||||||
|
|
||||||
|
When BEHAVIOR is LAST, return t only if the last element of PATH
|
||||||
|
is hidden, nil otherwise.
|
||||||
|
|
||||||
|
TODO: Hidden directories and files on Windows are marked
|
||||||
|
differently than on *NIX systems. This should be properly
|
||||||
|
implemented."
|
||||||
|
(let ((split-path (f-split path))
|
||||||
|
(check-hidden (lambda (elt)
|
||||||
|
(and (string= (substring elt 0 1) ".")
|
||||||
|
(not (member elt '("." "..")))))))
|
||||||
|
(pcase behavior
|
||||||
|
('any (-any check-hidden split-path))
|
||||||
|
('last (apply check-hidden (last split-path)))
|
||||||
|
(otherwise (if (null otherwise)
|
||||||
|
(funcall check-hidden (car split-path))
|
||||||
|
(error "Invalid value %S for argument BEHAVIOR" otherwise))))))
|
||||||
|
|
||||||
|
(defalias 'f-hidden? 'f-hidden-p)
|
||||||
|
|
||||||
|
(defun f-empty-p (path)
|
||||||
|
"If PATH is a file, return t if the file in PATH is empty, nil otherwise.
|
||||||
|
If PATH is directory, return t if directory has no files, nil otherwise."
|
||||||
|
(if (f-directory-p path)
|
||||||
|
(equal (f-files path nil t) nil)
|
||||||
|
(= (f-size path) 0)))
|
||||||
|
|
||||||
|
(defalias 'f-empty? 'f-empty-p)
|
||||||
|
|
||||||
|
|
||||||
|
;;;; Stats
|
||||||
|
|
||||||
|
(defun f-size (path)
|
||||||
|
"Return size of PATH.
|
||||||
|
|
||||||
|
If PATH is a file, return size of that file. If PATH is
|
||||||
|
directory, return sum of all files in PATH."
|
||||||
|
(if (f-directory-p path)
|
||||||
|
(-sum (-map 'f-size (f-files path nil t)))
|
||||||
|
(nth 7 (file-attributes path))))
|
||||||
|
|
||||||
|
(defun f-depth (path)
|
||||||
|
"Return the depth of PATH.
|
||||||
|
|
||||||
|
At first, PATH is expanded with `f-expand'. Then the full path is used to
|
||||||
|
detect the depth.
|
||||||
|
'/' will be zero depth, '/usr' will be one depth. And so on."
|
||||||
|
(- (length (f-split (f-expand path))) 1))
|
||||||
|
|
||||||
|
;; For Emacs 28 and below, forward-declare ‘current-time-list’, which was
|
||||||
|
;; introduced in Emacs 29.
|
||||||
|
(defvar current-time-list)
|
||||||
|
|
||||||
|
(defun f--get-time (path timestamp-p fn)
|
||||||
|
"Helper function, get time-related information for PATH.
|
||||||
|
Helper for `f-change-time', `f-modification-time',
|
||||||
|
`f-access-time'. It is meant to be called internally, avoid
|
||||||
|
calling it manually unless you have to.
|
||||||
|
|
||||||
|
If TIMESTAMP-P is non-nil, return the date requested as a
|
||||||
|
timestamp. If the value is \\='seconds, return the timestamp as
|
||||||
|
a timestamp with a one-second precision. Otherwise, the
|
||||||
|
timestamp is returned in a (TICKS . HZ) format, see
|
||||||
|
`current-time' if using Emacs 29 or newer.
|
||||||
|
|
||||||
|
Otherwise, if TIMESTAMP-P is nil, return the default style of
|
||||||
|
`current-time'.
|
||||||
|
|
||||||
|
FN is the function specified by the caller function to retrieve
|
||||||
|
the correct data from PATH."
|
||||||
|
(let* ((current-time-list (not timestamp-p))
|
||||||
|
(date (apply fn (list (file-attributes path))))
|
||||||
|
(emacs29-or-newer-p (version<= "29" emacs-version)))
|
||||||
|
(cond
|
||||||
|
((and (eq timestamp-p 'seconds) emacs29-or-newer-p)
|
||||||
|
(/ (car date) (cdr date)))
|
||||||
|
((or (and (not (eq timestamp-p 'seconds)) emacs29-or-newer-p)
|
||||||
|
(and (not timestamp-p) (not emacs29-or-newer-p)))
|
||||||
|
date)
|
||||||
|
((and (eq timestamp-p 'seconds) (not emacs29-or-newer-p))
|
||||||
|
(+ (* (nth 0 date) (expt 2 16))
|
||||||
|
(nth 1 date)))
|
||||||
|
((and timestamp-p (not emacs29-or-newer-p))
|
||||||
|
`(,(+ (* (nth 0 date) (expt 2 16) 1000)
|
||||||
|
(* (nth 1 date) 1000)
|
||||||
|
(nth 3 date))
|
||||||
|
. 1000)))))
|
||||||
|
|
||||||
|
(defun f-change-time (path &optional timestamp-p)
|
||||||
|
"Return the last status change time of PATH.
|
||||||
|
|
||||||
|
The status change time (ctime) of PATH in the same format as
|
||||||
|
`current-time'. For details on TIMESTAMP-P and the format of the
|
||||||
|
returned value, see `f--get-time'."
|
||||||
|
(f--get-time path
|
||||||
|
timestamp-p
|
||||||
|
(if (fboundp 'file-attribute-status-change-time)
|
||||||
|
#'file-attribute-status-change-time
|
||||||
|
(lambda (f) (nth 6 f)))))
|
||||||
|
|
||||||
|
(defun f-modification-time (path &optional timestamp-p)
|
||||||
|
"Return the last modification time of PATH.
|
||||||
|
The modification time (mtime) of PATH in the same format as
|
||||||
|
`current-time'. For details on TIMESTAMP-P and the format of the
|
||||||
|
returned value, see `f--get-time'."
|
||||||
|
(f--get-time path
|
||||||
|
timestamp-p
|
||||||
|
(if (fboundp 'file-attribute-modification-time)
|
||||||
|
#'file-attribute-modification-time
|
||||||
|
(lambda (f) (nth 5 f)))))
|
||||||
|
|
||||||
|
(defun f-access-time (path &optional timestamp-p)
|
||||||
|
"Return the last access time of PATH.
|
||||||
|
The access time (atime) of PATH is in the same format as
|
||||||
|
`current-time'. For details on TIMESTAMP-P and the format of the
|
||||||
|
returned value, see `f--get-time'."
|
||||||
|
(f--get-time path
|
||||||
|
timestamp-p
|
||||||
|
(if (fboundp 'file-attribute-access-time)
|
||||||
|
#'file-attribute-access-time
|
||||||
|
(lambda (f) (nth 4 f)))))
|
||||||
|
|
||||||
|
(defun f--three-way-compare (a b)
|
||||||
|
"Three way comparison.
|
||||||
|
|
||||||
|
Return -1 if A < B.
|
||||||
|
Return 0 if A = B.
|
||||||
|
Return 1 if A > B."
|
||||||
|
(cond ((< a b) -1)
|
||||||
|
((= a b) 0)
|
||||||
|
((> a b) 1)))
|
||||||
|
|
||||||
|
;; TODO: How to properly test this function?
|
||||||
|
(defun f--date-compare (file other method)
|
||||||
|
"Three-way comparison of the date of FILE and OTHER.
|
||||||
|
|
||||||
|
This function can return three values:
|
||||||
|
* 1 means FILE is newer than OTHER
|
||||||
|
* 0 means FILE and NEWER share the same date
|
||||||
|
* -1 means FILE is older than OTHER
|
||||||
|
|
||||||
|
The statistics used for the date comparison depends on METHOD.
|
||||||
|
When METHOD is null, compare their modification time. Otherwise,
|
||||||
|
compare their change time when METHOD is \\='change, or compare
|
||||||
|
their last access time when METHOD is \\='access."
|
||||||
|
(let* ((fn-method (cond
|
||||||
|
((eq 'change method) #'f-change-time)
|
||||||
|
((eq 'access method) #'f-access-time)
|
||||||
|
((null method) #'f-modification-time)
|
||||||
|
(t (error "Unknown method %S" method))))
|
||||||
|
(date-file (apply fn-method (list file)))
|
||||||
|
(date-other (apply fn-method (list other)))
|
||||||
|
(dates (-zip-pair date-file date-other)))
|
||||||
|
(-reduce-from (lambda (acc elt)
|
||||||
|
(if (= acc 0)
|
||||||
|
(f--three-way-compare (car elt) (cdr elt))
|
||||||
|
acc))
|
||||||
|
0
|
||||||
|
dates)))
|
||||||
|
|
||||||
|
(defun f-older-p (file other &optional method)
|
||||||
|
"Compare if FILE is older than OTHER.
|
||||||
|
|
||||||
|
For more info on METHOD, see `f--date-compare'."
|
||||||
|
(< (f--date-compare file other method) 0))
|
||||||
|
|
||||||
|
(defalias 'f-older? #'f-older-p)
|
||||||
|
|
||||||
|
(defun f-newer-p (file other &optional method)
|
||||||
|
"Compare if FILE is newer than OTHER.
|
||||||
|
|
||||||
|
For more info on METHOD, see `f--date-compare'."
|
||||||
|
(> (f--date-compare file other method) 0))
|
||||||
|
|
||||||
|
(defalias 'f-newer? #'f-newer-p)
|
||||||
|
|
||||||
|
(defun f-same-time-p (file other &optional method)
|
||||||
|
"Check if FILE and OTHER share the same access or modification time.
|
||||||
|
|
||||||
|
For more info on METHOD, see `f--date-compare'."
|
||||||
|
(= (f--date-compare file other method) 0))
|
||||||
|
|
||||||
|
(defalias 'f-same-time? #'f-same-time-p)
|
||||||
|
|
||||||
|
|
||||||
|
;;;; Misc
|
||||||
|
|
||||||
|
(defun f-this-file ()
|
||||||
|
"Return path to this file."
|
||||||
|
(cond
|
||||||
|
(load-in-progress load-file-name)
|
||||||
|
((and (boundp 'byte-compile-current-file) byte-compile-current-file)
|
||||||
|
byte-compile-current-file)
|
||||||
|
(:else (buffer-file-name))))
|
||||||
|
|
||||||
|
(defvar f--path-separator nil
|
||||||
|
"A variable to cache result of `f-path-separator'.")
|
||||||
|
|
||||||
|
(defun f-path-separator ()
|
||||||
|
"Return path separator."
|
||||||
|
(or f--path-separator
|
||||||
|
(setq f--path-separator (substring (f-join "x" "y") 1 2))))
|
||||||
|
|
||||||
|
(defun f-glob (pattern &optional path)
|
||||||
|
"Find PATTERN in PATH."
|
||||||
|
(file-expand-wildcards
|
||||||
|
(f-join (or path default-directory) pattern)))
|
||||||
|
|
||||||
|
(defun f--collect-entries (path recursive)
|
||||||
|
(let (result
|
||||||
|
(entries
|
||||||
|
(-reject
|
||||||
|
(lambda (file)
|
||||||
|
(member (f-filename file) '("." "..")))
|
||||||
|
(directory-files path t))))
|
||||||
|
(cond (recursive
|
||||||
|
(mapc
|
||||||
|
(lambda (entry)
|
||||||
|
(if (f-file-p entry)
|
||||||
|
(setq result (cons entry result))
|
||||||
|
(when (f-directory-p entry)
|
||||||
|
(setq result (cons entry result))
|
||||||
|
(if (f-readable-p entry)
|
||||||
|
(setq result (append result (f--collect-entries entry recursive)))
|
||||||
|
result))))
|
||||||
|
entries))
|
||||||
|
(t (setq result entries)))
|
||||||
|
result))
|
||||||
|
|
||||||
|
(defmacro f--entries (path body &optional recursive)
|
||||||
|
"Anaphoric version of `f-entries'."
|
||||||
|
`(f-entries
|
||||||
|
,path
|
||||||
|
(lambda (path)
|
||||||
|
(let ((it path))
|
||||||
|
,body))
|
||||||
|
,recursive))
|
||||||
|
|
||||||
|
(defun f-entries (path &optional fn recursive)
|
||||||
|
"Find all files and directories in PATH.
|
||||||
|
|
||||||
|
FN - called for each found file and directory. If FN returns a thruthy
|
||||||
|
value, file or directory will be included.
|
||||||
|
RECURSIVE - Search for files and directories recursive."
|
||||||
|
(let ((entries (f--collect-entries path recursive)))
|
||||||
|
(if fn (-select fn entries) entries)))
|
||||||
|
|
||||||
|
(defmacro f--directories (path body &optional recursive)
|
||||||
|
"Anaphoric version of `f-directories'."
|
||||||
|
`(f-directories
|
||||||
|
,path
|
||||||
|
(lambda (path)
|
||||||
|
(let ((it path))
|
||||||
|
,body))
|
||||||
|
,recursive))
|
||||||
|
|
||||||
|
(defun f-directories (path &optional fn recursive)
|
||||||
|
"Find all directories in PATH. See `f-entries'."
|
||||||
|
(let ((directories (-select 'f-directory-p (f--collect-entries path recursive))))
|
||||||
|
(if fn (-select fn directories) directories)))
|
||||||
|
|
||||||
|
(defmacro f--files (path body &optional recursive)
|
||||||
|
"Anaphoric version of `f-files'."
|
||||||
|
`(f-files
|
||||||
|
,path
|
||||||
|
(lambda (path)
|
||||||
|
(let ((it path))
|
||||||
|
,body))
|
||||||
|
,recursive))
|
||||||
|
|
||||||
|
(defun f-files (path &optional fn recursive)
|
||||||
|
"Find all files in PATH. See `f-entries'."
|
||||||
|
(let ((files (-select 'f-file-p (f--collect-entries path recursive))))
|
||||||
|
(if fn (-select fn files) files)))
|
||||||
|
|
||||||
|
(defmacro f--traverse-upwards (body &optional path)
|
||||||
|
"Anaphoric version of `f-traverse-upwards'."
|
||||||
|
`(f-traverse-upwards
|
||||||
|
(lambda (dir)
|
||||||
|
(let ((it dir))
|
||||||
|
,body))
|
||||||
|
,path))
|
||||||
|
|
||||||
|
(defun f-traverse-upwards (fn &optional path)
|
||||||
|
"Traverse up as long as FN return nil, starting at PATH.
|
||||||
|
|
||||||
|
If FN returns a non-nil value, the path sent as argument to FN is
|
||||||
|
returned. If no function callback return a non-nil value, nil is
|
||||||
|
returned."
|
||||||
|
(unless path
|
||||||
|
(setq path default-directory))
|
||||||
|
(when (f-relative-p path)
|
||||||
|
(setq path (f-expand path)))
|
||||||
|
(if (funcall fn path)
|
||||||
|
path
|
||||||
|
(unless (f-root-p path)
|
||||||
|
(f-traverse-upwards fn (f-parent path)))))
|
||||||
|
|
||||||
|
(defun f-root ()
|
||||||
|
"Return absolute root."
|
||||||
|
(f-traverse-upwards 'f-root-p))
|
||||||
|
|
||||||
|
(defmacro f-with-sandbox (path-or-paths &rest body)
|
||||||
|
"Only allow PATH-OR-PATHS and descendants to be modified in BODY."
|
||||||
|
(declare (indent 1))
|
||||||
|
`(let ((paths (if (listp ,path-or-paths)
|
||||||
|
,path-or-paths
|
||||||
|
(list ,path-or-paths))))
|
||||||
|
(unwind-protect
|
||||||
|
(let ((f--guard-paths paths))
|
||||||
|
,@body)
|
||||||
|
(setq f--guard-paths nil))))
|
||||||
|
|
||||||
|
(provide 'f)
|
||||||
|
|
||||||
|
;;; f.el ends here
|
9
code/elpa/helm-20240320.541/.dir-locals.el
Normal file
9
code/elpa/helm-20240320.541/.dir-locals.el
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
;;; Directory Local Variables
|
||||||
|
;;; For more information see (info "(emacs) Directory Variables")
|
||||||
|
|
||||||
|
((nil . ((bug-reference-bug-regexp . "\\(\\b\\(?:[Ii]ssue ?#?\\|[Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z+-]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)")
|
||||||
|
(bug-reference-url-format . "https://github.com/emacs-helm/helm/issues/%s")
|
||||||
|
(byte-compile-warnings . (not obsolete docstrings docstrings-non-ascii-quotes))))
|
||||||
|
(emacs-lisp-mode . ((mode . bug-reference-prog)
|
||||||
|
(indent-tabs-mode . nil)
|
||||||
|
(fill-column . 80))))
|
265
code/elpa/helm-20240320.541/emacs-helm.sh
Normal file
265
code/elpa/helm-20240320.541/emacs-helm.sh
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
|
||||||
|
## Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
##
|
||||||
|
## This program 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.
|
||||||
|
##
|
||||||
|
## This program 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:
|
||||||
|
# Preconfigured `emacs -Q' with a basic Helm configuration.
|
||||||
|
|
||||||
|
|
||||||
|
# If TEMP env var exists, use it, otherwise declare it.
|
||||||
|
test -z "$TEMP" && TEMP="/tmp"
|
||||||
|
|
||||||
|
CONF_FILE="$TEMP/helm-cfg.el"
|
||||||
|
EMACS=emacs
|
||||||
|
QUICK=-Q
|
||||||
|
TOOLBARS=-1
|
||||||
|
LOAD_PACKAGES=
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
cat >&1 <<EOF
|
||||||
|
Usage: ${0##*/} [-P PATH] [--toolbars] [--load-packages pkgs] [-h] [EMACS-OPTIONS-OR-FILENAME]
|
||||||
|
|
||||||
|
-P --path Specify path to emacs
|
||||||
|
-B --toolbars Display Menu bar, scroll bar etc...
|
||||||
|
--load-packages Load specified M/Elpa packages (separate with ",")
|
||||||
|
-h Display this help and exit
|
||||||
|
|
||||||
|
Any other Emacs options or filename must come after.
|
||||||
|
|
||||||
|
Emacs options:
|
||||||
|
|
||||||
|
Initialization options:
|
||||||
|
|
||||||
|
--chdir DIR change to directory DIR
|
||||||
|
--daemon, --bg-daemon[=NAME] start a (named) server in the background
|
||||||
|
--fg-daemon[=NAME] start a (named) server in the foreground
|
||||||
|
--debug-init enable Emacs Lisp debugger for init file
|
||||||
|
--display, -d DISPLAY use X server DISPLAY
|
||||||
|
--no-build-details do not add build details such as time stamps
|
||||||
|
--no-loadup, -nl do not load loadup.el into bare Emacs
|
||||||
|
--no-site-file do not load site-start.el
|
||||||
|
--no-x-resources do not load X resources
|
||||||
|
--no-window-system, -nw do not communicate with X, ignoring $DISPLAY
|
||||||
|
--script FILE run FILE as an Emacs Lisp script
|
||||||
|
--terminal, -t DEVICE use DEVICE for terminal I/O
|
||||||
|
|
||||||
|
Action options:
|
||||||
|
|
||||||
|
FILE visit FILE
|
||||||
|
+LINE go to line LINE in next FILE
|
||||||
|
+LINE:COLUMN go to line LINE, column COLUMN, in next FILE
|
||||||
|
--directory, -L DIR prepend DIR to load-path (with :DIR, append DIR)
|
||||||
|
--file FILE visit FILE
|
||||||
|
--find-file FILE visit FILE
|
||||||
|
--funcall, -f FUNC call Emacs Lisp function FUNC with no arguments
|
||||||
|
--insert FILE insert contents of FILE into current buffer
|
||||||
|
--load, -l FILE load Emacs Lisp FILE using the load function
|
||||||
|
--visit FILE visit FILE
|
||||||
|
|
||||||
|
Display options:
|
||||||
|
|
||||||
|
--background-color, -bg COLOR window background color
|
||||||
|
--basic-display, -D disable many display features;
|
||||||
|
used for debugging Emacs
|
||||||
|
--border-color, -bd COLOR main border color
|
||||||
|
--border-width, -bw WIDTH width of main border
|
||||||
|
--color, --color=MODE override color mode for character terminals;
|
||||||
|
MODE defaults to \`auto', and
|
||||||
|
can also be \`never', \`always',
|
||||||
|
or a mode name like \`ansi8'
|
||||||
|
--cursor-color, -cr COLOR color of the Emacs cursor indicating point
|
||||||
|
--font, -fn FONT default font; must be fixed-width
|
||||||
|
--foreground-color, -fg COLOR window foreground color
|
||||||
|
--fullheight, -fh make the first frame high as the screen
|
||||||
|
--fullscreen, -fs make the first frame fullscreen
|
||||||
|
--fullwidth, -fw make the first frame wide as the screen
|
||||||
|
--maximized, -mm make the first frame maximized
|
||||||
|
--geometry, -g GEOMETRY window geometry
|
||||||
|
--iconic start Emacs in iconified state
|
||||||
|
--internal-border, -ib WIDTH width between text and main border
|
||||||
|
--line-spacing, -lsp PIXELS additional space to put between lines
|
||||||
|
--mouse-color, -ms COLOR mouse cursor color in Emacs window
|
||||||
|
--name NAME title for initial Emacs frame
|
||||||
|
--reverse-video, -r, -rv switch foreground and background
|
||||||
|
--title, -T TITLE title for initial Emacs frame
|
||||||
|
--vertical-scroll-bars, -vb enable vertical scroll bars
|
||||||
|
--xrm XRESOURCES set additional X resources
|
||||||
|
--parent-id XID set parent window
|
||||||
|
--help display this help and exit
|
||||||
|
--version output version information and exit
|
||||||
|
|
||||||
|
You can generally also specify long option names with a single -; for
|
||||||
|
example, -batch as well as --batch. You can use any unambiguous
|
||||||
|
abbreviation for a --option.
|
||||||
|
|
||||||
|
Various environment variables and window system resources also affect
|
||||||
|
the operation of Emacs. See the main documentation.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
for a in "$@"; do
|
||||||
|
case $a in
|
||||||
|
--path | -P)
|
||||||
|
shift 1
|
||||||
|
EMACS="$1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--toolbars | -B)
|
||||||
|
shift 1
|
||||||
|
TOOLBARS=1
|
||||||
|
;;
|
||||||
|
--load-packages)
|
||||||
|
shift 1
|
||||||
|
LOAD_PACKAGES="$1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-Q | -q)
|
||||||
|
QUICK="$a"
|
||||||
|
;;
|
||||||
|
-h)
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
LOAD_PATH=$($EMACS -q -batch --eval "(prin1 load-path)")
|
||||||
|
|
||||||
|
cd "${0%/*}" || exit 1
|
||||||
|
|
||||||
|
# Check if autoload file exists.
|
||||||
|
# It may be in a different directory if emacs-helm.sh is a symlink.
|
||||||
|
TRUENAME=$(find "${0%/*}" -path "$0" -printf "%l")
|
||||||
|
if [ -n "$TRUENAME" ]; then
|
||||||
|
AUTO_FILE="${TRUENAME%/*}/helm-autoloads.el"
|
||||||
|
else
|
||||||
|
AUTO_FILE="helm-autoloads.el"
|
||||||
|
fi
|
||||||
|
if [ ! -e "$AUTO_FILE" ]; then
|
||||||
|
echo No autoloads found, please run make first to generate autoload file
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
cat > $CONF_FILE <<EOF
|
||||||
|
(setq initial-scratch-message (concat initial-scratch-message
|
||||||
|
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\\n\
|
||||||
|
;; This Emacs is Powered by \`HELM' using\\n\
|
||||||
|
;; emacs program \"$EMACS\".\\n\
|
||||||
|
;; This is a minimal \`helm' configuration to discover \`helm' or debug it.\\n\
|
||||||
|
;; You can retrieve this minimal configuration in \"$CONF_FILE\".\\n\
|
||||||
|
;;
|
||||||
|
;; Some original Emacs commands are replaced by their \`helm' counterparts:\\n\\n\
|
||||||
|
;; - \`find-file'(C-x C-f) =>\`helm-find-files'\\n\
|
||||||
|
;; - \`occur'(M-s o) =>\`helm-occur'\\n\
|
||||||
|
;; - \`list-buffers'(C-x C-b) =>\`helm-buffers-list'\\n\
|
||||||
|
;; - \`completion-at-point'(M-tab) =>\`helm-lisp-completion-at-point'[1]\\n\
|
||||||
|
;; - \`apropos-command'(C-h a) =>\`helm-apropos'\\n\
|
||||||
|
;; - \`dabbrev-expand'(M-/) =>\`helm-dabbrev'\\n\
|
||||||
|
;; - \`execute-extended-command'(M-x) =>\`helm-M-x'\\n\\n
|
||||||
|
;; Some other Emacs commands are \"helmized\" by \`helm-mode'.\\n\
|
||||||
|
;; [1] Coming with emacs-24.4, \`completion-at-point' is \"helmized\" by \`helm-mode'\\n\
|
||||||
|
|
||||||
|
;; which provides Helm completion in many places like \`shell-mode'.\\n\
|
||||||
|
;; Find context help for most Helm commands with \`C-h m'.\\n\
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\\n\\n"))
|
||||||
|
|
||||||
|
(setq load-path (quote $LOAD_PATH))
|
||||||
|
|
||||||
|
(defvar default-package-manager nil)
|
||||||
|
;; /home/you/.emacs.d/.local/straight/build-27.1/helm
|
||||||
|
(defvar initial-package-directory (file-name-directory (file-truename "$0")))
|
||||||
|
|
||||||
|
(defvar bootstrap-version)
|
||||||
|
(let* ((packages "$LOAD_PACKAGES")
|
||||||
|
(pkg-list (and packages
|
||||||
|
(not (equal packages ""))
|
||||||
|
(split-string packages ",")))
|
||||||
|
;; /home/you/.emacs.d/.local/straight/build-27.1
|
||||||
|
(straight-path (file-name-directory (directory-file-name initial-package-directory)))
|
||||||
|
;; /home/you/.emacs.d/.local/straight/build-27.1/async
|
||||||
|
(async-path (expand-file-name "async" straight-path))
|
||||||
|
;; /home/you/.emacs.d/.local/straight/repos/straight.el/bootstrap.el
|
||||||
|
(bootstrap-file
|
||||||
|
(expand-file-name "repos/straight.el/bootstrap.el"
|
||||||
|
(file-name-directory (directory-file-name straight-path))))
|
||||||
|
(bootstrap-version 5))
|
||||||
|
(when (file-exists-p bootstrap-file)
|
||||||
|
(setq default-package-manager 'straight)
|
||||||
|
(load bootstrap-file nil 'nomessage)
|
||||||
|
(add-to-list 'load-path async-path)
|
||||||
|
(when pkg-list
|
||||||
|
(dolist (pkg pkg-list)
|
||||||
|
(let* ((pkg-path (expand-file-name pkg straight-path))
|
||||||
|
(autoload-file (expand-file-name
|
||||||
|
(format "%s-autoloads.el" pkg)
|
||||||
|
pkg-path)))
|
||||||
|
(add-to-list 'load-path pkg-path)
|
||||||
|
(if (file-exists-p autoload-file)
|
||||||
|
(load autoload-file nil 'nomessage)
|
||||||
|
(straight-use-package (intern pkg))))))))
|
||||||
|
|
||||||
|
(unless (eq default-package-manager 'straight)
|
||||||
|
(require 'package)
|
||||||
|
;; User may be using a non standard \`package-user-dir'.
|
||||||
|
;; Modify \`package-directory-list' instead of \`package-user-dir'
|
||||||
|
;; in case the user starts Helm from a non-ELPA installation.
|
||||||
|
(unless (file-equal-p package-user-dir (locate-user-emacs-file "elpa"))
|
||||||
|
;; Something like /home/you/.emacs.d/somedir/else/elpa/
|
||||||
|
;; starting from default-directory is wrong in case helm.sh is a symlink
|
||||||
|
;; or e.g. helm --chdir foo have been used.
|
||||||
|
(add-to-list 'package-directory-list (directory-file-name
|
||||||
|
(file-name-directory
|
||||||
|
(directory-file-name initial-package-directory)))))
|
||||||
|
|
||||||
|
(let* ((str-lst "$LOAD_PACKAGES")
|
||||||
|
(load-packages (and str-lst
|
||||||
|
(not (string= str-lst ""))
|
||||||
|
(split-string str-lst ","))))
|
||||||
|
(setq package-load-list
|
||||||
|
(if (equal load-packages '("all"))
|
||||||
|
'(all)
|
||||||
|
(append '((helm-core t) (helm t) (async t) (popup t) (wfnames t))
|
||||||
|
(mapcar (lambda (p) (list (intern p) t)) load-packages)))))
|
||||||
|
|
||||||
|
(package-initialize))
|
||||||
|
|
||||||
|
(add-to-list 'load-path initial-package-directory)
|
||||||
|
|
||||||
|
(unless (> $TOOLBARS 0)
|
||||||
|
(setq default-frame-alist '((vertical-scroll-bars . nil)
|
||||||
|
(tool-bar-lines . 0)
|
||||||
|
(menu-bar-lines . 0)
|
||||||
|
(fullscreen . nil))))
|
||||||
|
(blink-cursor-mode -1)
|
||||||
|
(load "helm-autoloads" nil t)
|
||||||
|
(helm-mode 1)
|
||||||
|
(with-eval-after-load 'tramp-cache (setq tramp-cache-read-persistent-data t))
|
||||||
|
(with-eval-after-load 'auth-source (setq auth-source-save-behavior nil))
|
||||||
|
(define-key global-map [remap find-file] 'helm-find-files)
|
||||||
|
(define-key global-map [remap occur] 'helm-occur)
|
||||||
|
(define-key global-map [remap list-buffers] 'helm-buffers-list)
|
||||||
|
(define-key global-map [remap dabbrev-expand] 'helm-dabbrev)
|
||||||
|
(define-key global-map [remap execute-extended-command] 'helm-M-x)
|
||||||
|
(define-key global-map [remap apropos-command] 'helm-apropos)
|
||||||
|
(unless (boundp 'completion-in-region-function)
|
||||||
|
(define-key lisp-interaction-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point)
|
||||||
|
(define-key emacs-lisp-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point))
|
||||||
|
(add-hook 'kill-emacs-hook #'(lambda () (and (file-exists-p "$CONF_FILE") (delete-file "$CONF_FILE"))))
|
||||||
|
EOF
|
||||||
|
|
||||||
|
$EMACS "$QUICK" -l "$CONF_FILE" "$@"
|
284
code/elpa/helm-20240320.541/helm-adaptive.el
Normal file
284
code/elpa/helm-20240320.541/helm-adaptive.el
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
;;; helm-adaptive.el --- Adaptive Sorting of Candidates. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Original Author: Tamas Patrovics
|
||||||
|
|
||||||
|
;; Copyright (C) 2007 Tamas Patrovics
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-adapt nil
|
||||||
|
"Adaptative sorting of candidates for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-adaptive-history-file
|
||||||
|
(locate-user-emacs-file "helm-adaptive-history")
|
||||||
|
"Path of file where history information is stored.
|
||||||
|
When nil history is not saved nor restored after Emacs restart
|
||||||
|
unless you save/restore `helm-adaptive-history' with something
|
||||||
|
else like psession or desktop."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-adaptive-history-length 50
|
||||||
|
"Maximum number of candidates stored for a source."
|
||||||
|
:type 'number)
|
||||||
|
|
||||||
|
(defcustom helm-adaptive-sort-by-frequent-recent-usage t
|
||||||
|
"Try to sort on an average of frequent and recent usage when non-nil.
|
||||||
|
|
||||||
|
When nil sort on frequency usage only.
|
||||||
|
|
||||||
|
Only frequency:
|
||||||
|
When candidate have low frequency, you have to hit on it many
|
||||||
|
times to make it going up on top.
|
||||||
|
|
||||||
|
Frequency+recent:
|
||||||
|
Even with a low frequency, candidate go up on top. If a candidate
|
||||||
|
have a high frequency but it is not used since some time, it goes
|
||||||
|
down slowly, but as soon you reuse it it go up on top quickly."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
;; Internal
|
||||||
|
(defvar helm-adaptive-done nil
|
||||||
|
"nil if history information is not yet stored for the current
|
||||||
|
selection.")
|
||||||
|
|
||||||
|
(defvar helm-adaptive-history nil
|
||||||
|
"Contains the stored history information.
|
||||||
|
Format: ((SOURCE-NAME
|
||||||
|
(SELECTED-CANDIDATE (PATTERN . NUMBER-OF-USE) ...) ...) ...)")
|
||||||
|
|
||||||
|
(defconst helm-adaptive-freq-coefficient 5)
|
||||||
|
(defconst helm-adaptive-recent-coefficient 2)
|
||||||
|
|
||||||
|
(defun helm-adaptive-done-reset ()
|
||||||
|
(setq helm-adaptive-done nil))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode helm-adaptive-mode
|
||||||
|
"Toggle adaptive sorting in all sources."
|
||||||
|
:global t
|
||||||
|
(if helm-adaptive-mode
|
||||||
|
(progn
|
||||||
|
(unless helm-adaptive-history
|
||||||
|
(helm-adaptive-maybe-load-history))
|
||||||
|
(add-hook 'kill-emacs-hook #'helm-adaptive-save-history)
|
||||||
|
;; Should run at beginning of `helm-initial-setup'.
|
||||||
|
(add-hook 'helm-before-initialize-hook #'helm-adaptive-done-reset)
|
||||||
|
;; Should run at beginning of `helm-exit-minibuffer'.
|
||||||
|
(add-hook 'helm-before-action-hook #'helm-adaptive-store-selection)
|
||||||
|
;; Should run at beginning of `helm-select-action'.
|
||||||
|
(add-hook 'helm-select-action-hook #'helm-adaptive-store-selection))
|
||||||
|
(helm-adaptive-save-history)
|
||||||
|
(setq helm-adaptive-history nil)
|
||||||
|
(remove-hook 'kill-emacs-hook #'helm-adaptive-save-history)
|
||||||
|
(remove-hook 'helm-before-initialize-hook #'helm-adaptive-done-reset)
|
||||||
|
(remove-hook 'helm-before-action-hook #'helm-adaptive-store-selection)
|
||||||
|
(remove-hook 'helm-select-action-hook #'helm-adaptive-store-selection)))
|
||||||
|
|
||||||
|
(defun helm-adapt-use-adaptive-p (&optional source-name)
|
||||||
|
"Return current source only if it use adaptive history, nil otherwise."
|
||||||
|
(when helm-adaptive-mode
|
||||||
|
(let* ((source (or source-name (helm-get-current-source)))
|
||||||
|
(adapt-source (or (assoc-default 'filtered-candidate-transformer source)
|
||||||
|
(assoc-default 'candidate-transformer source))))
|
||||||
|
(if (listp adapt-source)
|
||||||
|
(and (memq 'helm-adaptive-sort adapt-source) source)
|
||||||
|
(and (eq adapt-source 'helm-adaptive-sort) source)))))
|
||||||
|
|
||||||
|
(defun helm-adaptive-store-selection ()
|
||||||
|
"Store history information for the selected candidate."
|
||||||
|
(unless helm-adaptive-done
|
||||||
|
(setq helm-adaptive-done t)
|
||||||
|
(let ((source (helm-adapt-use-adaptive-p)))
|
||||||
|
(when source
|
||||||
|
(let* ((source-name (assoc-default 'name source))
|
||||||
|
(source-info (or (assoc source-name helm-adaptive-history)
|
||||||
|
(progn
|
||||||
|
(push (list source-name) helm-adaptive-history)
|
||||||
|
(car helm-adaptive-history))))
|
||||||
|
(selection (helm-get-selection nil t))
|
||||||
|
(selection-info (progn
|
||||||
|
(setcdr source-info
|
||||||
|
(cons
|
||||||
|
(let ((found (assoc selection (cdr source-info))))
|
||||||
|
(if (not found)
|
||||||
|
;; new entry
|
||||||
|
(list selection)
|
||||||
|
;; move entry to the beginning of the
|
||||||
|
;; list, so that it doesn't get
|
||||||
|
;; trimmed when the history is
|
||||||
|
;; truncated
|
||||||
|
(setcdr source-info
|
||||||
|
(delete found (cdr source-info)))
|
||||||
|
found))
|
||||||
|
(cdr source-info)))
|
||||||
|
(cadr source-info)))
|
||||||
|
(pattern-info (progn
|
||||||
|
(setcdr selection-info
|
||||||
|
(cons
|
||||||
|
(let ((found (assoc helm-pattern (cdr selection-info))))
|
||||||
|
(if (not found)
|
||||||
|
;; new entry
|
||||||
|
(cons helm-pattern 0)
|
||||||
|
;; move entry to the beginning of the
|
||||||
|
;; list, so if two patterns used the
|
||||||
|
;; same number of times then the one
|
||||||
|
;; used last appears first in the list
|
||||||
|
(setcdr selection-info
|
||||||
|
(delete found (cdr selection-info)))
|
||||||
|
found))
|
||||||
|
(cdr selection-info)))
|
||||||
|
(cadr selection-info)))
|
||||||
|
(timestamp-info (helm-aif (assq 'timestamp (cdr selection-info))
|
||||||
|
it
|
||||||
|
(setcdr selection-info (cons (cons 'timestamp 0) (cdr selection-info)))
|
||||||
|
(cadr selection-info))))
|
||||||
|
;; Increase usage count.
|
||||||
|
(setcdr pattern-info (1+ (cdr pattern-info)))
|
||||||
|
;; Update timestamp.
|
||||||
|
(setcdr timestamp-info (float-time))
|
||||||
|
;; Truncate history if needed.
|
||||||
|
(if (> (length (cdr selection-info)) helm-adaptive-history-length)
|
||||||
|
(setcdr selection-info
|
||||||
|
(helm-take (cdr selection-info) helm-adaptive-history-length))))))))
|
||||||
|
|
||||||
|
(defun helm-adaptive-maybe-load-history ()
|
||||||
|
"Load `helm-adaptive-history-file' which contain `helm-adaptive-history'.
|
||||||
|
Returns nil if `helm-adaptive-history-file' doesn't exist."
|
||||||
|
(when (and helm-adaptive-history-file
|
||||||
|
(file-readable-p helm-adaptive-history-file))
|
||||||
|
(load-file helm-adaptive-history-file)))
|
||||||
|
|
||||||
|
(defun helm-adaptive-save-history (&optional arg)
|
||||||
|
"Save history information to the file given by `helm-adaptive-history-file'."
|
||||||
|
(interactive "p")
|
||||||
|
(when helm-adaptive-history-file
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert
|
||||||
|
";; -*- mode: emacs-lisp -*-\n"
|
||||||
|
";; History entries used for helm adaptive display.\n")
|
||||||
|
(let (print-length print-level)
|
||||||
|
(prin1 `(setq helm-adaptive-history ',helm-adaptive-history)
|
||||||
|
(current-buffer)))
|
||||||
|
(insert ?\n)
|
||||||
|
(write-region (point-min) (point-max) helm-adaptive-history-file nil
|
||||||
|
(unless arg 'quiet)))))
|
||||||
|
|
||||||
|
(defun helm-adaptive-sort (candidates source)
|
||||||
|
"Sort the CANDIDATES for SOURCE by usage frequency.
|
||||||
|
This is a filtered candidate transformer you can use with the
|
||||||
|
`filtered-candidate-transformer' attribute."
|
||||||
|
(let* ((source-name (assoc-default 'name source))
|
||||||
|
(source-info (assoc source-name helm-adaptive-history)))
|
||||||
|
(if source-info
|
||||||
|
(let ((usage
|
||||||
|
;; Loop in the SOURCE entry of `helm-adaptive-history'
|
||||||
|
;; and assemble a list containing the (CANDIDATE
|
||||||
|
;; . USAGE-COUNT) pairs.
|
||||||
|
(cl-loop with cf = (if helm-adaptive-sort-by-frequent-recent-usage
|
||||||
|
helm-adaptive-freq-coefficient 1)
|
||||||
|
with cr = helm-adaptive-recent-coefficient
|
||||||
|
for (src-cand . infos) in (cdr source-info)
|
||||||
|
for count-freq = 0
|
||||||
|
for count-rec =
|
||||||
|
(helm-aif (and helm-adaptive-sort-by-frequent-recent-usage
|
||||||
|
(assq 'timestamp infos))
|
||||||
|
(* cr (+ (float-time) (cdr it)))
|
||||||
|
0)
|
||||||
|
do (cl-loop for (pattern . score) in
|
||||||
|
(remove (assq 'timestamp infos) infos)
|
||||||
|
;; If current pattern is equal to
|
||||||
|
;; the previously used one then
|
||||||
|
;; this candidate has priority
|
||||||
|
;; (that's why its count-freq is
|
||||||
|
;; boosted by 10000) and it only
|
||||||
|
;; has to compete with other
|
||||||
|
;; candidates which were also
|
||||||
|
;; selected with the same pattern.
|
||||||
|
if (equal pattern helm-pattern)
|
||||||
|
return (setq count-freq (+ 10000 score))
|
||||||
|
else do (cl-incf count-freq score))
|
||||||
|
and collect (cons src-cand (+ (* count-freq cf) count-rec))
|
||||||
|
into results
|
||||||
|
;; Sort the list in descending order, so
|
||||||
|
;; candidates with highest priority come
|
||||||
|
;; first.
|
||||||
|
finally return
|
||||||
|
(sort results (lambda (first second)
|
||||||
|
(> (cdr first) (cdr second)))))))
|
||||||
|
(if (consp usage)
|
||||||
|
;; Put those candidates first which have the highest usage count.
|
||||||
|
(cl-loop for (cand . _freq) in usage
|
||||||
|
for info = (or (and (assq 'multiline source)
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\n\\'" "" cand))
|
||||||
|
;; Some transformers like in
|
||||||
|
;; bookmarks may add a leading
|
||||||
|
;; space to provide additional
|
||||||
|
;; infos like an icon as a
|
||||||
|
;; display prop, strip out this
|
||||||
|
;; leading space for
|
||||||
|
;; comparison. Same for a
|
||||||
|
;; trailing space (helm
|
||||||
|
;; boookmark add bmk location as
|
||||||
|
;; a display prop when
|
||||||
|
;; displaying it).
|
||||||
|
(helm-aand (replace-regexp-in-string "\\` " "" cand)
|
||||||
|
(replace-regexp-in-string " \\'" "" it)))
|
||||||
|
when (cl-member info candidates
|
||||||
|
:test 'helm-adaptive-compare)
|
||||||
|
collect (car it) into sorted
|
||||||
|
and do (setq candidates
|
||||||
|
(cl-remove info candidates
|
||||||
|
:test 'helm-adaptive-compare))
|
||||||
|
finally return (append sorted candidates))
|
||||||
|
(message "Your `%s' is maybe corrupted or too old, \
|
||||||
|
you should reinitialize it with `helm-reset-adaptive-history'"
|
||||||
|
helm-adaptive-history-file)
|
||||||
|
(sit-for 1)
|
||||||
|
candidates))
|
||||||
|
;; if there is no information stored for this source then do nothing
|
||||||
|
candidates)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-reset-adaptive-history ()
|
||||||
|
"Delete all `helm-adaptive-history' and his file.
|
||||||
|
Useful when you have a old or corrupted
|
||||||
|
`helm-adaptive-history-file'."
|
||||||
|
(interactive)
|
||||||
|
(when (y-or-n-p "Really delete all your `helm-adaptive-history'? ")
|
||||||
|
(setq helm-adaptive-history nil)
|
||||||
|
(when (and helm-adaptive-history-file
|
||||||
|
(file-exists-p helm-adaptive-history-file))
|
||||||
|
(delete-file helm-adaptive-history-file))))
|
||||||
|
|
||||||
|
(defun helm-adaptive-compare (x y)
|
||||||
|
"Compare display parts if some of candidates X and Y.
|
||||||
|
|
||||||
|
Arguments X and Y are cons cell in (DISPLAY . REAL) format or
|
||||||
|
atoms."
|
||||||
|
(equal (if (listp x) (car x) x)
|
||||||
|
(if (listp y) (car y) y)))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'helm-adaptive)
|
||||||
|
|
||||||
|
;;; helm-adaptive.el ends here
|
990
code/elpa/helm-20240320.541/helm-autoloads.el
Normal file
990
code/elpa/helm-20240320.541/helm-autoloads.el
Normal file
|
@ -0,0 +1,990 @@
|
||||||
|
;;; helm-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
|
||||||
|
;; Generated by the `loaddefs-generate' function.
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-adaptive.el
|
||||||
|
|
||||||
|
(defvar helm-adaptive-mode nil "\
|
||||||
|
Non-nil if Helm-Adaptive mode is enabled.
|
||||||
|
See the `helm-adaptive-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-adaptive-mode'.")
|
||||||
|
(custom-autoload 'helm-adaptive-mode "helm-adaptive" nil)
|
||||||
|
(autoload 'helm-adaptive-mode "helm-adaptive" "\
|
||||||
|
Toggle adaptive sorting in all sources.
|
||||||
|
|
||||||
|
This is a global minor mode. If called interactively, toggle the
|
||||||
|
`Helm-Adaptive mode' mode. If the prefix argument is positive,
|
||||||
|
enable the mode, and if it is zero or negative, disable the mode.
|
||||||
|
|
||||||
|
If called from Lisp, toggle the mode if ARG is `toggle'. Enable
|
||||||
|
the mode if ARG is nil, omitted, or is a positive number.
|
||||||
|
Disable the mode if ARG is a negative number.
|
||||||
|
|
||||||
|
To check whether the minor mode is enabled in the current buffer,
|
||||||
|
evaluate `(default-value \\='helm-adaptive-mode)'.
|
||||||
|
|
||||||
|
The mode's hook is called both when the mode is enabled and when
|
||||||
|
it is disabled.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-reset-adaptive-history "helm-adaptive" "\
|
||||||
|
Delete all `helm-adaptive-history' and his file.
|
||||||
|
Useful when you have a old or corrupted
|
||||||
|
`helm-adaptive-history-file'." t)
|
||||||
|
(register-definition-prefixes "helm-adaptive" '("helm-adapt"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-bookmark.el
|
||||||
|
|
||||||
|
(autoload 'helm-bookmarks "helm-bookmark" "\
|
||||||
|
Preconfigured `helm' for bookmarks." t)
|
||||||
|
(autoload 'helm-filtered-bookmarks "helm-bookmark" "\
|
||||||
|
Preconfigured `helm' for bookmarks (filtered by category).
|
||||||
|
Optional source `helm-source-bookmark-addressbook' is loaded only
|
||||||
|
if external addressbook-bookmark package is installed." t)
|
||||||
|
(register-definition-prefixes "helm-bookmark" '("bmk" "bookmark" "helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-buffers.el
|
||||||
|
|
||||||
|
(autoload 'helm-buffers-quit-and-find-file-fn "helm-buffers" "\
|
||||||
|
|
||||||
|
|
||||||
|
(fn SOURCE)")
|
||||||
|
(autoload 'helm-buffers-list "helm-buffers" "\
|
||||||
|
Preconfigured `helm' to list buffers." t)
|
||||||
|
(autoload 'helm-mini "helm-buffers" "\
|
||||||
|
Preconfigured `helm' displaying `helm-mini-default-sources'." t)
|
||||||
|
(register-definition-prefixes "helm-buffers" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-color.el
|
||||||
|
|
||||||
|
(autoload 'helm-colors "helm-color" "\
|
||||||
|
Preconfigured `helm' for color." t)
|
||||||
|
(register-definition-prefixes "helm-color" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-command.el
|
||||||
|
|
||||||
|
(autoload 'helm-M-x "helm-command" "\
|
||||||
|
Preconfigured `helm' for Emacs commands.
|
||||||
|
It is `helm' replacement of regular `M-x'
|
||||||
|
`execute-extended-command'.
|
||||||
|
|
||||||
|
Unlike regular `M-x' Emacs vanilla `execute-extended-command'
|
||||||
|
command, the prefix args if needed, can be passed AFTER starting
|
||||||
|
`helm-M-x'. When a prefix arg is passed BEFORE starting
|
||||||
|
`helm-M-x', the first `C-u' while in `helm-M-x' session will
|
||||||
|
disable it.
|
||||||
|
|
||||||
|
You can get help on each command by persistent action.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-command" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-dabbrev.el
|
||||||
|
|
||||||
|
(autoload 'helm-dabbrev "helm-dabbrev" "\
|
||||||
|
Preconfigured helm for dynamic abbreviations." t)
|
||||||
|
(register-definition-prefixes "helm-dabbrev" '("helm-dabbrev-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-elisp.el
|
||||||
|
|
||||||
|
(autoload 'helm-lisp-completion-at-point "helm-elisp" "\
|
||||||
|
Preconfigured Helm for Lisp symbol completion at point." t)
|
||||||
|
(autoload 'helm-get-first-line-documentation "helm-elisp" "\
|
||||||
|
Return first line documentation of symbol SYM truncated at END-COLUMN.
|
||||||
|
If SYM is not documented, return \"Not documented\".
|
||||||
|
Argument NAME allows specifiying what function to use to display
|
||||||
|
documentation when SYM name is the same for function and variable.
|
||||||
|
|
||||||
|
(fn SYM &optional (NAME \"describe-function\") (END-COLUMN 72))")
|
||||||
|
(autoload 'helm-complete-file-name-at-point "helm-elisp" "\
|
||||||
|
Preconfigured Helm to complete file name at point.
|
||||||
|
|
||||||
|
(fn &optional FORCE)" t)
|
||||||
|
(autoload 'helm-lisp-indent "helm-elisp" nil t)
|
||||||
|
(autoload 'helm-apropos "helm-elisp" "\
|
||||||
|
Preconfigured Helm to describe commands, functions, variables and faces.
|
||||||
|
In non interactives calls DEFAULT argument should be provided as
|
||||||
|
a string, i.e. the `symbol-name' of any existing symbol.
|
||||||
|
|
||||||
|
(fn DEFAULT)" t)
|
||||||
|
(autoload 'helm-manage-advice "helm-elisp" "\
|
||||||
|
Preconfigured `helm' to disable/enable function advices." t)
|
||||||
|
(autoload 'helm-locate-library "helm-elisp" "\
|
||||||
|
Preconfigured helm to locate elisp libraries.
|
||||||
|
|
||||||
|
When `completions-detailed' or `helm-completions-detailed' is non
|
||||||
|
nil, a description of libraries is provided. The libraries are
|
||||||
|
partially cached in the variables
|
||||||
|
`helm--locate-library-doc-cache' and
|
||||||
|
`helm--locate-library-cache'. TIP: You can make these vars
|
||||||
|
persistent for faster start with the psession package, using M-x
|
||||||
|
psession-make-persistent-variable. NOTE: The caches affect as
|
||||||
|
well `find-libray' and `locate-library' when `helm-mode' is
|
||||||
|
enabled and `completions-detailed' is non nil. There is no need
|
||||||
|
to refresh the caches, they will be updated automatically if some
|
||||||
|
new libraries are found, however when a library update its
|
||||||
|
headers and the description change you can reset the caches with
|
||||||
|
a prefix arg.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-timers "helm-elisp" "\
|
||||||
|
Preconfigured `helm' for timers." t)
|
||||||
|
(autoload 'helm-complex-command-history "helm-elisp" "\
|
||||||
|
Preconfigured `helm' for complex command history." t)
|
||||||
|
(register-definition-prefixes "helm-elisp" '("helm-" "with-helm-show-completion"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-epa.el
|
||||||
|
|
||||||
|
(defvar helm-epa-mode nil "\
|
||||||
|
Non-nil if Helm-Epa mode is enabled.
|
||||||
|
See the `helm-epa-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-epa-mode'.")
|
||||||
|
(custom-autoload 'helm-epa-mode "helm-epa" nil)
|
||||||
|
(autoload 'helm-epa-mode "helm-epa" "\
|
||||||
|
Enable helm completion on gpg keys in epa functions.
|
||||||
|
|
||||||
|
This is a global minor mode. If called interactively, toggle the
|
||||||
|
`Helm-Epa mode' mode. If the prefix argument is positive, enable
|
||||||
|
the mode, and if it is zero or negative, disable the mode.
|
||||||
|
|
||||||
|
If called from Lisp, toggle the mode if ARG is `toggle'. Enable
|
||||||
|
the mode if ARG is nil, omitted, or is a positive number.
|
||||||
|
Disable the mode if ARG is a negative number.
|
||||||
|
|
||||||
|
To check whether the minor mode is enabled in the current buffer,
|
||||||
|
evaluate `(default-value \\='helm-epa-mode)'.
|
||||||
|
|
||||||
|
The mode's hook is called both when the mode is enabled and when
|
||||||
|
it is disabled.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-epa-list-keys "helm-epa" "\
|
||||||
|
List all gpg keys.
|
||||||
|
This is the helm interface for `epa-list-keys'." t)
|
||||||
|
(register-definition-prefixes "helm-epa" '("helm-epa"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-eshell.el
|
||||||
|
|
||||||
|
(autoload 'helm-esh-pcomplete "helm-eshell" "\
|
||||||
|
Preconfigured `helm' to provide Helm completion in Eshell." t)
|
||||||
|
(autoload 'helm-eshell-history "helm-eshell" "\
|
||||||
|
Preconfigured Helm for Eshell history." t)
|
||||||
|
(autoload 'helm-eshell-prompts "helm-eshell" "\
|
||||||
|
Pre-configured `helm' to browse the prompts of the current Eshell." t)
|
||||||
|
(autoload 'helm-eshell-prompts-all "helm-eshell" "\
|
||||||
|
Pre-configured `helm' to browse the prompts of all Eshell sessions." t)
|
||||||
|
(register-definition-prefixes "helm-eshell" '("helm-e"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-eval.el
|
||||||
|
|
||||||
|
(autoload 'helm-eval-expression "helm-eval" "\
|
||||||
|
Preconfigured `helm' for `helm-source-evaluation-result'.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(autoload 'helm-eval-expression-with-eldoc "helm-eval" "\
|
||||||
|
Preconfigured `helm' for `helm-source-evaluation-result' with `eldoc' support." t)
|
||||||
|
(autoload 'helm-calcul-expression "helm-eval" "\
|
||||||
|
Preconfigured `helm' for `helm-source-calculation-result'." t)
|
||||||
|
(register-definition-prefixes "helm-eval" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-external.el
|
||||||
|
|
||||||
|
(autoload 'helm-run-external-command "helm-external" "\
|
||||||
|
Preconfigured `helm' to run External PROGRAM asyncronously from Emacs.
|
||||||
|
If program is already running try to run `helm-raise-command' if
|
||||||
|
defined otherwise exit with error. You can set your own list of
|
||||||
|
commands with `helm-external-commands-list'." t)
|
||||||
|
(register-definition-prefixes "helm-external" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-fd.el
|
||||||
|
|
||||||
|
(register-definition-prefixes "helm-fd" '("helm-fd-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-files.el
|
||||||
|
|
||||||
|
(defvar helm-ff-icon-mode nil "\
|
||||||
|
Non-nil if Helm-Ff-Icon mode is enabled.
|
||||||
|
See the `helm-ff-icon-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-ff-icon-mode'.")
|
||||||
|
(custom-autoload 'helm-ff-icon-mode "helm-files" nil)
|
||||||
|
(autoload 'helm-ff-icon-mode "helm-files" "\
|
||||||
|
Display icons from `all-the-icons' package in HFF when enabled.
|
||||||
|
|
||||||
|
This is a global minor mode. If called interactively, toggle the
|
||||||
|
`Helm-Ff-Icon mode' mode. If the prefix argument is positive,
|
||||||
|
enable the mode, and if it is zero or negative, disable the mode.
|
||||||
|
|
||||||
|
If called from Lisp, toggle the mode if ARG is `toggle'. Enable
|
||||||
|
the mode if ARG is nil, omitted, or is a positive number.
|
||||||
|
Disable the mode if ARG is a negative number.
|
||||||
|
|
||||||
|
To check whether the minor mode is enabled in the current buffer,
|
||||||
|
evaluate `(default-value \\='helm-ff-icon-mode)'.
|
||||||
|
|
||||||
|
The mode's hook is called both when the mode is enabled and when
|
||||||
|
it is disabled.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-ff-clear-image-dired-thumbnails-cache "helm-files" "\
|
||||||
|
Clear `helm-ff-image-dired-thumbnails-cache'.
|
||||||
|
You may want to do this after customizing
|
||||||
|
`image-dired-thumbnail-storage' which may change the place where
|
||||||
|
thumbnail files are stored." t)
|
||||||
|
(autoload 'helm-ff-cleanup-image-dired-dir-and-cache "helm-files" "\
|
||||||
|
Cleanup `image-dired-dir' directory.
|
||||||
|
Delete all thumb files that are no more associated with an existing
|
||||||
|
image file in `helm-ff-image-dired-thumbnails-cache'." t)
|
||||||
|
(autoload 'helm-projects-history "helm-files" "\
|
||||||
|
Jump to project already visisted with `helm-browse-project'.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-browse-project "helm-files" "\
|
||||||
|
Preconfigured helm to browse projects.
|
||||||
|
Browse files and see status of project with its VCS.
|
||||||
|
Only HG and GIT are supported for now.
|
||||||
|
Fall back to `helm-browse-project-find-files' if current
|
||||||
|
directory is not under control of one of those VCS.
|
||||||
|
With a prefix ARG browse files recursively, with two prefix ARG
|
||||||
|
rebuild the cache.
|
||||||
|
If the current directory is found in the cache, start
|
||||||
|
`helm-browse-project-find-files' even with no prefix ARG.
|
||||||
|
NOTE: The prefix ARG have no effect on the VCS controlled
|
||||||
|
directories.
|
||||||
|
|
||||||
|
Needed dependencies for VCS:
|
||||||
|
<https://github.com/emacs-helm/helm-ls-git>
|
||||||
|
and
|
||||||
|
<https://github.com/emacs-helm/helm-ls-hg>.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(autoload 'helm-find-files "helm-files" "\
|
||||||
|
Preconfigured `helm' for helm implementation of `find-file'.
|
||||||
|
Called with a prefix arg show history if some.
|
||||||
|
Don't call it from programs, use `helm-find-files-1' instead.
|
||||||
|
This is the starting point for nearly all actions you can do on
|
||||||
|
files.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-files" '("eshell-command-aliases-list" "helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-find.el
|
||||||
|
|
||||||
|
(autoload 'helm-find "helm-find" "\
|
||||||
|
Preconfigured `helm' for the find shell command.
|
||||||
|
|
||||||
|
Recursively find files whose names are matched by all specified
|
||||||
|
globbing PATTERNs under the current directory using the external
|
||||||
|
program specified in `find-program' (usually \"find\"). Every
|
||||||
|
input PATTERN is silently wrapped into two stars: *PATTERN*.
|
||||||
|
|
||||||
|
With prefix argument, prompt for a directory to search.
|
||||||
|
|
||||||
|
When user option `helm-findutils-search-full-path' is non-nil,
|
||||||
|
match against complete paths, otherwise, against file names
|
||||||
|
without directory part.
|
||||||
|
|
||||||
|
The (possibly empty) list of globbing PATTERNs can be followed by
|
||||||
|
the separator \"*\" plus any number of additional arguments that
|
||||||
|
are passed to \"find\" literally.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-find" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-font.el
|
||||||
|
|
||||||
|
(autoload 'helm-select-xfont "helm-font" "\
|
||||||
|
Preconfigured `helm' to select Xfont." t)
|
||||||
|
(autoload 'helm-ucs "helm-font" "\
|
||||||
|
Preconfigured `helm' for `ucs-names'.
|
||||||
|
|
||||||
|
Called with a prefix arg force reloading cache.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-font" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-for-files.el
|
||||||
|
|
||||||
|
(autoload 'helm-for-files "helm-for-files" "\
|
||||||
|
Preconfigured `helm' for opening files.
|
||||||
|
Run all sources defined in `helm-for-files-preferred-list'." t)
|
||||||
|
(autoload 'helm-multi-files "helm-for-files" "\
|
||||||
|
Preconfigured helm like `helm-for-files' but running locate only on demand.
|
||||||
|
|
||||||
|
Allow toggling back and forth from locate to others sources with
|
||||||
|
`helm-multi-files-toggle-locate-binding' key.
|
||||||
|
This avoids launching locate needlessly when what you are
|
||||||
|
searching for is already found." t)
|
||||||
|
(autoload 'helm-recentf "helm-for-files" "\
|
||||||
|
Preconfigured `helm' for `recentf'." t)
|
||||||
|
(register-definition-prefixes "helm-for-files" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-global-bindings.el
|
||||||
|
|
||||||
|
(register-definition-prefixes "helm-global-bindings" '("helm-command-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-grep.el
|
||||||
|
|
||||||
|
(autoload 'helm-goto-precedent-file "helm-grep" "\
|
||||||
|
Go to previous file in Helm grep/etags buffers." t)
|
||||||
|
(autoload 'helm-goto-next-file "helm-grep" "\
|
||||||
|
Go to previous file in Helm grep/etags buffers." t)
|
||||||
|
(autoload 'helm-revert-next-error-last-buffer "helm-grep" "\
|
||||||
|
Revert last `next-error' buffer from `current-buffer'.
|
||||||
|
|
||||||
|
Accept to revert only `helm-grep-mode' or `helm-occur-mode' buffers.
|
||||||
|
Use this when you want to revert the `next-error' buffer after
|
||||||
|
modifications in `current-buffer'." t)
|
||||||
|
(autoload 'helm-do-grep-ag "helm-grep" "\
|
||||||
|
Preconfigured `helm' for grepping with AG in `default-directory'.
|
||||||
|
With prefix arg prompt for type if available with your AG
|
||||||
|
version.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(autoload 'helm-grep-do-git-grep "helm-grep" "\
|
||||||
|
Preconfigured `helm' for git-grepping `default-directory'.
|
||||||
|
With a prefix arg ARG git-grep the whole repository.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-grep" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-help.el
|
||||||
|
|
||||||
|
(autoload 'helm-documentation "helm-help" "\
|
||||||
|
Preconfigured `helm' for Helm documentation.
|
||||||
|
With a prefix arg refresh the documentation.
|
||||||
|
|
||||||
|
Find here the documentation of all documented sources." t)
|
||||||
|
(defvar helm-comp-read-mode-line "\\<helm-comp-read-map>C/\\[helm-cr-empty-string]:Empty \\<helm-map>\\[helm-help]:Help \\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend \\[helm-customize-group]:Conf")
|
||||||
|
(defvar helm-read-file-name-mode-line-string "\\<helm-read-file-map>\\[helm-help]:Help C/\\[helm-cr-empty-string]:Empty \\<helm-map>\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend \\[helm-customize-group]:Conf" "\
|
||||||
|
String displayed in mode-line in `helm-source-find-files'.")
|
||||||
|
(defvar helm-top-mode-line "\\<helm-top-map>\\[helm-help]:Help \\<helm-map>\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend \\[helm-customize-group]:Conf")
|
||||||
|
(register-definition-prefixes "helm-help" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-id-utils.el
|
||||||
|
|
||||||
|
(autoload 'helm-gid "helm-id-utils" "\
|
||||||
|
Preconfigured `helm' for `gid' command line of `ID-Utils'.
|
||||||
|
Need A database created with the command `mkid' above
|
||||||
|
`default-directory'.
|
||||||
|
Need id-utils as dependency which provide `mkid', `gid' etc..
|
||||||
|
See <https://www.gnu.org/software/idutils/>." t)
|
||||||
|
(register-definition-prefixes "helm-id-utils" '("helm-gid-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-imenu.el
|
||||||
|
|
||||||
|
(autoload 'helm-imenu "helm-imenu" "\
|
||||||
|
Preconfigured `helm' for `imenu'." t)
|
||||||
|
(autoload 'helm-imenu-in-all-buffers "helm-imenu" "\
|
||||||
|
Fetch Imenu entries in all buffers with similar mode as current.
|
||||||
|
A mode is similar as current if it is the same, it is derived
|
||||||
|
i.e. `derived-mode-p' or it have an association in
|
||||||
|
`helm-imenu-all-buffer-assoc'." t)
|
||||||
|
(register-definition-prefixes "helm-imenu" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-info.el
|
||||||
|
|
||||||
|
(autoload 'helm-info "helm-info" "\
|
||||||
|
Preconfigured `helm' for searching Info files' indices.
|
||||||
|
|
||||||
|
With a prefix argument \\[universal-argument], set REFRESH to
|
||||||
|
non-nil.
|
||||||
|
|
||||||
|
Optional parameter REFRESH, when non-nil, re-evaluates
|
||||||
|
`helm-default-info-index-list'. If the variable has been
|
||||||
|
customized, set it to its saved value. If not, set it to its
|
||||||
|
standard value. See `custom-reevaluate-setting' for more.
|
||||||
|
|
||||||
|
REFRESH is useful when new Info files are installed. If
|
||||||
|
`helm-default-info-index-list' has not been customized, the new
|
||||||
|
Info files are made available.
|
||||||
|
|
||||||
|
(fn &optional REFRESH)" t)
|
||||||
|
(autoload 'helm-info-at-point "helm-info" "\
|
||||||
|
Preconfigured `helm' for searching info at point." t)
|
||||||
|
(register-definition-prefixes "helm-info" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-locate.el
|
||||||
|
|
||||||
|
(autoload 'helm-projects-find-files "helm-locate" "\
|
||||||
|
Find files with locate in `helm-locate-project-list'.
|
||||||
|
With a prefix arg refresh the database in each project.
|
||||||
|
|
||||||
|
(fn UPDATE)" t)
|
||||||
|
(autoload 'helm-locate "helm-locate" "\
|
||||||
|
Preconfigured `helm' for Locate.
|
||||||
|
Note: you can add locate options after entering pattern.
|
||||||
|
See \\='man locate' for valid options and also `helm-locate-command'.
|
||||||
|
|
||||||
|
You can specify a local database with prefix argument ARG.
|
||||||
|
With two prefix arg, refresh the current local db or create it if
|
||||||
|
it doesn't exists.
|
||||||
|
|
||||||
|
To create a user specific db, use
|
||||||
|
\"updatedb -l 0 -o db_path -U directory\".
|
||||||
|
Where db_path is a filename matched by
|
||||||
|
`helm-locate-db-file-regexp'.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-locate" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-man.el
|
||||||
|
|
||||||
|
(autoload 'helm-man-woman "helm-man" "\
|
||||||
|
Preconfigured `helm' for Man and Woman pages.
|
||||||
|
With a prefix arg reinitialize the cache.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-man" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-misc.el
|
||||||
|
|
||||||
|
(defvar helm-minibuffer-history-mode nil "\
|
||||||
|
Non-nil if Helm-Minibuffer-History mode is enabled.
|
||||||
|
See the `helm-minibuffer-history-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-minibuffer-history-mode'.")
|
||||||
|
(custom-autoload 'helm-minibuffer-history-mode "helm-misc" nil)
|
||||||
|
(autoload 'helm-minibuffer-history-mode "helm-misc" "\
|
||||||
|
Bind `helm-minibuffer-history-key' in al minibuffer maps.
|
||||||
|
|
||||||
|
This mode is enabled by `helm-mode', so there is no need to enable it directly.
|
||||||
|
|
||||||
|
This is a global minor mode. If called interactively, toggle the
|
||||||
|
`Helm-Minibuffer-History mode' mode. If the prefix argument is
|
||||||
|
positive, enable the mode, and if it is zero or negative, disable
|
||||||
|
the mode.
|
||||||
|
|
||||||
|
If called from Lisp, toggle the mode if ARG is `toggle'. Enable
|
||||||
|
the mode if ARG is nil, omitted, or is a positive number.
|
||||||
|
Disable the mode if ARG is a negative number.
|
||||||
|
|
||||||
|
To check whether the minor mode is enabled in the current buffer,
|
||||||
|
evaluate `(default-value \\='helm-minibuffer-history-mode)'.
|
||||||
|
|
||||||
|
The mode's hook is called both when the mode is enabled and when
|
||||||
|
it is disabled.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-world-time "helm-misc" "\
|
||||||
|
Preconfigured `helm' to show world time.
|
||||||
|
Default action change TZ environment variable locally to emacs." t)
|
||||||
|
(autoload 'helm-insert-latex-math "helm-misc" "\
|
||||||
|
Preconfigured helm for latex math symbols completion." t)
|
||||||
|
(autoload 'helm-ratpoison-commands "helm-misc" "\
|
||||||
|
Preconfigured `helm' to execute ratpoison commands." t)
|
||||||
|
(autoload 'helm-stumpwm-commands "helm-misc" "\
|
||||||
|
Preconfigured helm for stumpwm commands." t)
|
||||||
|
(autoload 'helm-minibuffer-history "helm-misc" "\
|
||||||
|
Preconfigured `helm' for `minibuffer-history'." t)
|
||||||
|
(register-definition-prefixes "helm-misc" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-mode.el
|
||||||
|
|
||||||
|
(autoload 'helm-comp-read "helm-mode" "\
|
||||||
|
Read a string in the minibuffer, with helm completion.
|
||||||
|
|
||||||
|
It is helm `completing-read' equivalent.
|
||||||
|
|
||||||
|
- PROMPT is the prompt name to use.
|
||||||
|
|
||||||
|
- COLLECTION can be a list, alist, vector, obarray or hash-table.
|
||||||
|
For alists and hash-tables their car are use as real value of
|
||||||
|
candidate unless ALISTP is non-nil.
|
||||||
|
It can be also a function that receives three arguments:
|
||||||
|
the values string, predicate and t. See `all-completions' for more details.
|
||||||
|
|
||||||
|
Keys description:
|
||||||
|
|
||||||
|
- TEST: A predicate called with one arg i.e candidate.
|
||||||
|
|
||||||
|
- INITIAL-INPUT: Same as input arg in `helm'.
|
||||||
|
|
||||||
|
- PRESELECT: See preselect arg of `helm'.
|
||||||
|
|
||||||
|
- DEFAULT: This option is used only for compatibility with regular
|
||||||
|
Emacs `completing-read' (Same as DEFAULT arg of `completing-read').
|
||||||
|
|
||||||
|
- BUFFER: Name of helm-buffer.
|
||||||
|
|
||||||
|
- MUST-MATCH: Candidate selected must be one of COLLECTION.
|
||||||
|
|
||||||
|
- FUZZY: Enable fuzzy matching.
|
||||||
|
|
||||||
|
- REVERSE-HISTORY: When non--nil display history source after current
|
||||||
|
source completion.
|
||||||
|
|
||||||
|
- REQUIRES-PATTERN: Same as helm attribute, default is 0.
|
||||||
|
|
||||||
|
- HISTORY: A symbol where each result will be saved.
|
||||||
|
If not specified as a symbol an error will popup.
|
||||||
|
When specified, all elements of HISTORY are displayed in
|
||||||
|
a special source before or after COLLECTION according to REVERSE-HISTORY.
|
||||||
|
The main difference with INPUT-HISTORY is that the result of the
|
||||||
|
completion is saved whereas in INPUT-HISTORY it is the minibuffer
|
||||||
|
contents which is saved when you exit.
|
||||||
|
Don't use the same symbol for INPUT-HISTORY and HISTORY.
|
||||||
|
NOTE: As mentionned above this has nothing to do with
|
||||||
|
`minibuffer-history-variable', therefore if you want to save this
|
||||||
|
history persistently, you will have to add this variable to the
|
||||||
|
relevant variable of your favorite tool for persistent emacs session
|
||||||
|
i.e. psession, desktop etc...
|
||||||
|
|
||||||
|
- RAW-HISTORY: When non-nil do not remove backslashs if some in
|
||||||
|
HISTORY candidates.
|
||||||
|
|
||||||
|
- INPUT-HISTORY: A symbol. The minibuffer input history will be
|
||||||
|
stored there, if nil or not provided, `minibuffer-history'
|
||||||
|
will be used instead. You can navigate in this history with
|
||||||
|
`M-p' and `M-n'.
|
||||||
|
Don't use the same symbol for INPUT-HISTORY and HISTORY.
|
||||||
|
|
||||||
|
- CASE-FOLD: Same as `helm-case-fold-search'.
|
||||||
|
|
||||||
|
- PERSISTENT-ACTION: A function called with one arg i.e candidate.
|
||||||
|
|
||||||
|
- PERSISTENT-HELP: A string to document PERSISTENT-ACTION.
|
||||||
|
|
||||||
|
- MODE-LINE: A string or list to display in mode line.
|
||||||
|
Default is `helm-comp-read-mode-line'.
|
||||||
|
|
||||||
|
- KEYMAP: A keymap to use in this `helm-comp-read'.
|
||||||
|
(the keymap will be shared with history source)
|
||||||
|
|
||||||
|
- NAME: The name related to this local source.
|
||||||
|
|
||||||
|
- HEADER-NAME: A function to alter NAME, see `helm'.
|
||||||
|
|
||||||
|
- EXEC-WHEN-ONLY-ONE: Bound `helm-execute-action-at-once-if-one'
|
||||||
|
to non--nil. (possibles values are t or nil).
|
||||||
|
|
||||||
|
- VOLATILE: Use volatile attribute.
|
||||||
|
|
||||||
|
- SORT: A predicate to give to `sort' e.g `string-lessp'
|
||||||
|
Use this only on small data as it is inefficient.
|
||||||
|
If you want to sort faster add a sort function to
|
||||||
|
FC-TRANSFORMER.
|
||||||
|
Note that FUZZY when enabled is already providing a sort function.
|
||||||
|
|
||||||
|
- FC-TRANSFORMER: A `filtered-candidate-transformer' function
|
||||||
|
or a list of functions.
|
||||||
|
|
||||||
|
- HIST-FC-TRANSFORMER: A `filtered-candidate-transformer'
|
||||||
|
function for the history source.
|
||||||
|
|
||||||
|
- MARKED-CANDIDATES: If non-nil return candidate or marked candidates as a list.
|
||||||
|
|
||||||
|
- NOMARK: When non--nil don't allow marking candidates.
|
||||||
|
|
||||||
|
- ALISTP:
|
||||||
|
When non-nil (default) pass the value of (DISPLAY . REAL)
|
||||||
|
candidate in COLLECTION to action when COLLECTION is an alist or a
|
||||||
|
hash-table, otherwise DISPLAY is always returned as result on exit,
|
||||||
|
which is the default when using `completing-read'.
|
||||||
|
See `helm-comp-read-get-candidates'.
|
||||||
|
|
||||||
|
- CANDIDATES-IN-BUFFER: when non--nil use a source build with
|
||||||
|
`helm-source-in-buffer' which is much faster.
|
||||||
|
Argument VOLATILE have no effect when CANDIDATES-IN-BUFFER is non--nil.
|
||||||
|
|
||||||
|
- GET-LINE: Specify the :get-line slot of `helm-source-in-buffer', has no effect
|
||||||
|
when CANDIDATES-IN-BUFFER is nil.
|
||||||
|
|
||||||
|
- MATCH-PART: Allow matching only one part of candidate.
|
||||||
|
See match-part documentation in `helm-source'.
|
||||||
|
|
||||||
|
- MATCH-DYNAMIC: See match-dynamic in `helm-source-sync'
|
||||||
|
It has no effect when used with CANDIDATES-IN-BUFFER.
|
||||||
|
|
||||||
|
- ALLOW-NEST: Allow nesting this `helm-comp-read' in a helm session.
|
||||||
|
See `helm'.
|
||||||
|
|
||||||
|
- MULTILINE: See multiline in `helm-source'.
|
||||||
|
|
||||||
|
- COERCE: See coerce in `helm-source'.
|
||||||
|
|
||||||
|
- GROUP: See group in `helm-source'.
|
||||||
|
|
||||||
|
Any prefix args passed during `helm-comp-read' invocation will be recorded
|
||||||
|
in `helm-current-prefix-arg', otherwise if prefix args were given before
|
||||||
|
`helm-comp-read' invocation, the value of `current-prefix-arg' will be used.
|
||||||
|
That means you can pass prefix args before or after calling a command
|
||||||
|
that use `helm-comp-read'. See `helm-M-x' for example.
|
||||||
|
|
||||||
|
(fn PROMPT COLLECTION &key TEST INITIAL-INPUT DEFAULT PRESELECT (BUFFER \"*Helm Completions*\") MUST-MATCH FUZZY REVERSE-HISTORY (REQUIRES-PATTERN 0) (HISTORY nil SHISTORY) RAW-HISTORY INPUT-HISTORY (CASE-FOLD helm-comp-read-case-fold-search) (PERSISTENT-ACTION nil) (PERSISTENT-HELP \"DoNothing\") (MODE-LINE helm-comp-read-mode-line) HELP-MESSAGE (KEYMAP helm-comp-read-map) (NAME \"Helm Completions\") HEADER-NAME CANDIDATES-IN-BUFFER (GET-LINE #\\='buffer-substring) DIACRITICS MATCH-PART MATCH-DYNAMIC EXEC-WHEN-ONLY-ONE QUIT-WHEN-NO-CAND (VOLATILE t) SORT FC-TRANSFORMER HIST-FC-TRANSFORMER (MARKED-CANDIDATES helm-comp-read-use-marked) NOMARK (ALISTP t) (CANDIDATE-NUMBER-LIMIT helm-candidate-number-limit) MULTILINE ALLOW-NEST COERCE (GROUP \\='helm))")
|
||||||
|
(autoload 'helm-read-file-name "helm-mode" "\
|
||||||
|
Read a file name with helm completion.
|
||||||
|
|
||||||
|
It is helm `read-file-name' emulation.
|
||||||
|
|
||||||
|
Argument PROMPT is the default prompt to use.
|
||||||
|
|
||||||
|
Keys description:
|
||||||
|
|
||||||
|
- NAME: Source name, default to \"Read File Name\".
|
||||||
|
|
||||||
|
- INITIAL-INPUT: Where to start reading file name,
|
||||||
|
default to `default-directory' or $HOME.
|
||||||
|
|
||||||
|
- BUFFER: `helm-buffer' name, defaults to \"*Helm Completions*\".
|
||||||
|
|
||||||
|
- TEST: A predicate called with one arg \\='candidate'.
|
||||||
|
|
||||||
|
- NORET: Allow disabling helm-ff-RET (have no effect if helm-ff-RET
|
||||||
|
isn't bound to RET).
|
||||||
|
|
||||||
|
- CASE-FOLD: Same as `helm-case-fold-search'.
|
||||||
|
|
||||||
|
- PRESELECT: helm preselection.
|
||||||
|
|
||||||
|
- HISTORY: Display HISTORY in a special source.
|
||||||
|
|
||||||
|
- MUST-MATCH: Can be \\='confirm, nil, or t.
|
||||||
|
|
||||||
|
- FUZZY: Enable fuzzy matching when non-nil (Enabled by default).
|
||||||
|
|
||||||
|
- MARKED-CANDIDATES: When non--nil return a list of marked candidates.
|
||||||
|
|
||||||
|
- NOMARK: When non--nil don't allow marking candidates.
|
||||||
|
|
||||||
|
- ALISTP: Don't use `all-completions' in history
|
||||||
|
(take effect only on history).
|
||||||
|
|
||||||
|
- PERSISTENT-ACTION-IF: a persistent if action function.
|
||||||
|
|
||||||
|
- PERSISTENT-HELP: persistent help message.
|
||||||
|
|
||||||
|
- MODE-LINE: A mode line message, default is
|
||||||
|
`helm-read-file-name-mode-line-string'.
|
||||||
|
|
||||||
|
(fn PROMPT &key (NAME \"Read File Name\") INITIAL-INPUT (BUFFER \"*Helm file completions*\") TEST NORET (CASE-FOLD helm-file-name-case-fold-search) PRESELECT HISTORY MUST-MATCH (FUZZY t) DEFAULT MARKED-CANDIDATES (CANDIDATE-NUMBER-LIMIT helm-ff-candidate-number-limit) NOMARK (ALISTP t) (PERSISTENT-ACTION-IF \\='helm-find-files-persistent-action-if) (PERSISTENT-HELP \"Hit1 Expand Candidate, Hit2 or (C-u) Find file\") (MODE-LINE helm-read-file-name-mode-line-string))")
|
||||||
|
(defvar helm-mode nil "\
|
||||||
|
Non-nil if Helm mode is enabled.
|
||||||
|
See the `helm-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-mode'.")
|
||||||
|
(custom-autoload 'helm-mode "helm-mode" nil)
|
||||||
|
(autoload 'helm-mode "helm-mode" "\
|
||||||
|
Toggle generic helm completion.
|
||||||
|
|
||||||
|
All functions in Emacs that use `completing-read',
|
||||||
|
`read-file-name', `completion-in-region' and friends will use helm
|
||||||
|
interface when this mode is turned on.
|
||||||
|
|
||||||
|
However you can modify this behavior for functions of your choice
|
||||||
|
with `helm-completing-read-handlers-alist'.
|
||||||
|
|
||||||
|
Called with a positive arg, turn on unconditionally, with a
|
||||||
|
negative arg turn off.
|
||||||
|
You can toggle it with M-x `helm-mode'.
|
||||||
|
|
||||||
|
About `ido-mode':
|
||||||
|
DO NOT enable `ido-everywhere' when using `helm-mode'. Instead of
|
||||||
|
using `ido-mode', add the commands where you want to use ido to
|
||||||
|
`helm-completing-read-handlers-alist' with `ido' as value.
|
||||||
|
|
||||||
|
Note: This mode is incompatible with Emacs23.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-mode" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-net.el
|
||||||
|
|
||||||
|
(autoload 'helm-browse-url-firefox "helm-net" "\
|
||||||
|
Same as `browse-url-firefox' but detach from Emacs.
|
||||||
|
|
||||||
|
So when you quit Emacs you can keep your Firefox session open and
|
||||||
|
not be prompted to kill the Firefox process.
|
||||||
|
|
||||||
|
NOTE: Probably not supported on some systems (e.g., Windows).
|
||||||
|
|
||||||
|
(fn URL &optional IGNORE)" t)
|
||||||
|
(autoload 'helm-browse-url-opera "helm-net" "\
|
||||||
|
Browse URL with Opera browser and detach from Emacs.
|
||||||
|
|
||||||
|
So when you quit Emacs you can keep your Opera session open and
|
||||||
|
not be prompted to kill the Opera process.
|
||||||
|
|
||||||
|
NOTE: Probably not supported on some systems (e.g., Windows).
|
||||||
|
|
||||||
|
(fn URL &optional IGNORE)" t)
|
||||||
|
(autoload 'helm-browse-url-chromium "helm-net" "\
|
||||||
|
Browse URL with Google Chrome browser.
|
||||||
|
|
||||||
|
(fn URL &optional IGNORE)" t)
|
||||||
|
(autoload 'helm-browse-url-uzbl "helm-net" "\
|
||||||
|
Browse URL with uzbl browser.
|
||||||
|
|
||||||
|
(fn URL &optional IGNORE)" t)
|
||||||
|
(autoload 'helm-browse-url-conkeror "helm-net" "\
|
||||||
|
Browse URL with conkeror browser.
|
||||||
|
|
||||||
|
(fn URL &optional IGNORE)" t)
|
||||||
|
(autoload 'helm-browse-url-nyxt "helm-net" "\
|
||||||
|
Browse URL with nyxt browser.
|
||||||
|
|
||||||
|
(fn URL &optional IGNORE)" t)
|
||||||
|
(autoload 'helm-surfraw "helm-net" "\
|
||||||
|
Preconfigured `helm' to search PATTERN with search ENGINE.
|
||||||
|
|
||||||
|
(fn PATTERN ENGINE)" t)
|
||||||
|
(autoload 'helm-google-suggest "helm-net" "\
|
||||||
|
Preconfigured `helm' for Google search with Google suggest." t)
|
||||||
|
(register-definition-prefixes "helm-net" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-occur.el
|
||||||
|
|
||||||
|
(autoload 'helm-occur "helm-occur" "\
|
||||||
|
Preconfigured helm for searching lines matching pattern in `current-buffer'.
|
||||||
|
|
||||||
|
When `helm-source-occur' is member of
|
||||||
|
`helm-sources-using-default-as-input' which is the default,
|
||||||
|
symbol at point is searched at startup.
|
||||||
|
|
||||||
|
When a region is marked search only in this region by narrowing.
|
||||||
|
|
||||||
|
To search in multiples buffers start from one of the commands listing
|
||||||
|
buffers (i.e. a helm command using `helm-source-buffers-list' like
|
||||||
|
`helm-mini') and use the multi occur buffers action.
|
||||||
|
|
||||||
|
This is the helm implementation that collect lines matching pattern
|
||||||
|
like vanilla Emacs `occur' but have nothing to do with it, the search
|
||||||
|
engine beeing completely different and also much faster." t)
|
||||||
|
(autoload 'helm-occur-visible-buffers "helm-occur" "\
|
||||||
|
Run helm-occur on all visible buffers in frame." t)
|
||||||
|
(autoload 'helm-occur-from-isearch "helm-occur" "\
|
||||||
|
Invoke `helm-occur' from isearch.
|
||||||
|
|
||||||
|
To use this bind it to a key in `isearch-mode-map'." t)
|
||||||
|
(autoload 'helm-multi-occur-from-isearch "helm-occur" "\
|
||||||
|
Invoke `helm-multi-occur' from isearch.
|
||||||
|
|
||||||
|
With a prefix arg, reverse the behavior of
|
||||||
|
`helm-moccur-always-search-in-current'.
|
||||||
|
The prefix arg can be set before calling
|
||||||
|
`helm-multi-occur-from-isearch' or during the buffer selection.
|
||||||
|
|
||||||
|
To use this bind it to a key in `isearch-mode-map'." t)
|
||||||
|
(register-definition-prefixes "helm-occur" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-packages.el
|
||||||
|
|
||||||
|
(autoload 'helm-packages "helm-packages" "\
|
||||||
|
Helm interface to manage packages.
|
||||||
|
|
||||||
|
With a prefix arg ARG refresh package list.
|
||||||
|
|
||||||
|
When installing or upgrading ensure to refresh the package list
|
||||||
|
to avoid errors with outdated packages no more availables.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-packages" '("helm-packages-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-regexp.el
|
||||||
|
|
||||||
|
(autoload 'helm-regexp "helm-regexp" "\
|
||||||
|
Preconfigured helm to build regexps.
|
||||||
|
`query-replace-regexp' can be run from there against found regexp." t)
|
||||||
|
(register-definition-prefixes "helm-regexp" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-ring.el
|
||||||
|
|
||||||
|
(autoload 'helm-mark-ring "helm-ring" "\
|
||||||
|
Preconfigured `helm' for `helm-source-mark-ring'." t)
|
||||||
|
(autoload 'helm-global-mark-ring "helm-ring" "\
|
||||||
|
Preconfigured `helm' for `helm-source-global-mark-ring'." t)
|
||||||
|
(autoload 'helm-all-mark-rings "helm-ring" "\
|
||||||
|
Preconfigured `helm' for mark rings.
|
||||||
|
Source used are `helm-source-global-mark-ring' and
|
||||||
|
`helm-source-mark-ring'." t)
|
||||||
|
(autoload 'helm-register "helm-ring" "\
|
||||||
|
Preconfigured `helm' for Emacs registers." t)
|
||||||
|
(autoload 'helm-show-kill-ring "helm-ring" "\
|
||||||
|
Preconfigured `helm' for `kill-ring'.
|
||||||
|
It is drop-in replacement of `yank-pop'.
|
||||||
|
|
||||||
|
First call open the kill-ring browser, next calls move to next line." t)
|
||||||
|
(autoload 'helm-execute-kmacro "helm-ring" "\
|
||||||
|
Preconfigured helm for keyboard macros.
|
||||||
|
Define your macros with `f3' and `f4'.
|
||||||
|
See (info \"(emacs) Keyboard Macros\") for detailed infos." t)
|
||||||
|
(register-definition-prefixes "helm-ring" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-semantic.el
|
||||||
|
|
||||||
|
(autoload 'helm-semantic "helm-semantic" "\
|
||||||
|
Preconfigured `helm' for `semantic'.
|
||||||
|
If ARG is supplied, pre-select symbol at point instead of current.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(autoload 'helm-semantic-or-imenu "helm-semantic" "\
|
||||||
|
Preconfigured helm for `semantic' or `imenu'.
|
||||||
|
If ARG is supplied, pre-select symbol at point instead of current
|
||||||
|
semantic tag in scope.
|
||||||
|
|
||||||
|
If `semantic-mode' is active in the current buffer, then use
|
||||||
|
semantic for generating tags, otherwise fall back to `imenu'.
|
||||||
|
Fill in the symbol at point by default.
|
||||||
|
|
||||||
|
(fn ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-semantic" '("helm-s"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-sys.el
|
||||||
|
|
||||||
|
(defvar helm-top-poll-mode nil "\
|
||||||
|
Non-nil if Helm-Top-Poll mode is enabled.
|
||||||
|
See the `helm-top-poll-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-top-poll-mode'.")
|
||||||
|
(custom-autoload 'helm-top-poll-mode "helm-sys" nil)
|
||||||
|
(autoload 'helm-top-poll-mode "helm-sys" "\
|
||||||
|
Refresh automatically helm top buffer once enabled.
|
||||||
|
|
||||||
|
This is a global minor mode. If called interactively, toggle the
|
||||||
|
`Helm-Top-Poll mode' mode. If the prefix argument is positive,
|
||||||
|
enable the mode, and if it is zero or negative, disable the mode.
|
||||||
|
|
||||||
|
If called from Lisp, toggle the mode if ARG is `toggle'. Enable
|
||||||
|
the mode if ARG is nil, omitted, or is a positive number.
|
||||||
|
Disable the mode if ARG is a negative number.
|
||||||
|
|
||||||
|
To check whether the minor mode is enabled in the current buffer,
|
||||||
|
evaluate `(default-value \\='helm-top-poll-mode)'.
|
||||||
|
|
||||||
|
The mode's hook is called both when the mode is enabled and when
|
||||||
|
it is disabled.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(autoload 'helm-top "helm-sys" "\
|
||||||
|
Preconfigured `helm' for top command." t)
|
||||||
|
(autoload 'helm-list-emacs-process "helm-sys" "\
|
||||||
|
Preconfigured `helm' for Emacs process." t)
|
||||||
|
(autoload 'helm-xrandr-set "helm-sys" "\
|
||||||
|
Preconfigured helm for xrandr." t)
|
||||||
|
(register-definition-prefixes "helm-sys" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-tags.el
|
||||||
|
|
||||||
|
(autoload 'helm-etags-select "helm-tags" "\
|
||||||
|
Preconfigured helm for etags.
|
||||||
|
If called with a prefix argument REINIT
|
||||||
|
or if any of the tag files have been modified, reinitialize cache.
|
||||||
|
|
||||||
|
This function aggregates three sources of tag files:
|
||||||
|
|
||||||
|
1) An automatically located file in the parent directories,
|
||||||
|
by `helm-etags-get-tag-file'.
|
||||||
|
2) `tags-file-name', which is commonly set by `find-tag' command.
|
||||||
|
3) `tags-table-list' which is commonly set by `visit-tags-table' command.
|
||||||
|
|
||||||
|
(fn REINIT)" t)
|
||||||
|
(register-definition-prefixes "helm-tags" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-types.el
|
||||||
|
|
||||||
|
(register-definition-prefixes "helm-types" '("helm-"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-utils.el
|
||||||
|
|
||||||
|
(defvar helm-popup-tip-mode nil "\
|
||||||
|
Non-nil if Helm-Popup-Tip mode is enabled.
|
||||||
|
See the `helm-popup-tip-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `helm-popup-tip-mode'.")
|
||||||
|
(custom-autoload 'helm-popup-tip-mode "helm-utils" nil)
|
||||||
|
(autoload 'helm-popup-tip-mode "helm-utils" "\
|
||||||
|
Show help-echo informations in a popup tip at end of line.
|
||||||
|
|
||||||
|
This is a global minor mode. If called interactively, toggle the
|
||||||
|
`Helm-Popup-Tip mode' mode. If the prefix argument is positive,
|
||||||
|
enable the mode, and if it is zero or negative, disable the mode.
|
||||||
|
|
||||||
|
If called from Lisp, toggle the mode if ARG is `toggle'. Enable
|
||||||
|
the mode if ARG is nil, omitted, or is a positive number.
|
||||||
|
Disable the mode if ARG is a negative number.
|
||||||
|
|
||||||
|
To check whether the minor mode is enabled in the current buffer,
|
||||||
|
evaluate `(default-value \\='helm-popup-tip-mode)'.
|
||||||
|
|
||||||
|
The mode's hook is called both when the mode is enabled and when
|
||||||
|
it is disabled.
|
||||||
|
|
||||||
|
(fn &optional ARG)" t)
|
||||||
|
(register-definition-prefixes "helm-utils" '("helm-" "with-helm-display-marked-candidates"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Generated autoloads from helm-x-files.el
|
||||||
|
|
||||||
|
(register-definition-prefixes "helm-x-files" '("helm-"))
|
||||||
|
|
||||||
|
;;; End of scraped data
|
||||||
|
|
||||||
|
(provide 'helm-autoloads)
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; no-native-compile: t
|
||||||
|
;; coding: utf-8-emacs-unix
|
||||||
|
;; End:
|
||||||
|
|
||||||
|
;;; helm-autoloads.el ends here
|
846
code/elpa/helm-20240320.541/helm-bookmark.el
Normal file
846
code/elpa/helm-20240320.541/helm-bookmark.el
Normal file
|
@ -0,0 +1,846 @@
|
||||||
|
;;; helm-bookmark.el --- Helm for Emacs regular Bookmarks. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'bookmark)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-lib)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-types)
|
||||||
|
(require 'helm-utils)
|
||||||
|
(require 'helm-info)
|
||||||
|
(require 'helm-adaptive)
|
||||||
|
(require 'helm-net)
|
||||||
|
|
||||||
|
(declare-function helm-browse-project "helm-files" (arg))
|
||||||
|
(declare-function addressbook-bookmark-edit "ext:addressbook-bookmark.el" (bookmark))
|
||||||
|
(declare-function all-the-icons-fileicon "ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-icon-for-file"ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-octicon "ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-match-to-alist "ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-faicon "ext:all-the-icons.el")
|
||||||
|
|
||||||
|
(defvar all-the-icons-dir-icon-alist)
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-bookmark nil
|
||||||
|
"Predefined configurations for `helm.el'."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-bookmark-show-location nil
|
||||||
|
"Show location of bookmark on display."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-bookmark-default-filtered-sources
|
||||||
|
(append '(helm-source-bookmark-org
|
||||||
|
helm-source-bookmark-files&dirs
|
||||||
|
helm-source-bookmark-helm-find-files
|
||||||
|
helm-source-bookmark-info
|
||||||
|
helm-source-bookmark-gnus
|
||||||
|
helm-source-bookmark-mu4e
|
||||||
|
helm-source-bookmark-man
|
||||||
|
helm-source-bookmark-images
|
||||||
|
helm-source-bookmark-w3m)
|
||||||
|
(list 'helm-source-bookmark-uncategorized
|
||||||
|
'helm-source-bookmark-set))
|
||||||
|
"List of sources to use in `helm-filtered-bookmarks'."
|
||||||
|
:type '(repeat (choice symbol)))
|
||||||
|
|
||||||
|
(defcustom helm-bookmark-use-icon nil
|
||||||
|
"Display candidates with an icon with `all-the-icons' when non nil.
|
||||||
|
Don't use `setq' to set this."
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(if (require 'all-the-icons nil t)
|
||||||
|
(set var val)
|
||||||
|
(set var nil))))
|
||||||
|
|
||||||
|
(defcustom helm-bookmark-default-sort-method 'adaptive
|
||||||
|
"Sort method for `helm-filtered-bookmarks'.
|
||||||
|
|
||||||
|
Value can be either \\='native' or \\='adaptive'.
|
||||||
|
|
||||||
|
Once you use \\='native' the bookmark variable `bookmark-sort-flag'
|
||||||
|
will be honored."
|
||||||
|
:type '(choice
|
||||||
|
(symbol :tag "Helm adaptive sort method" adaptive)
|
||||||
|
(symbol :tag "Native bookmark sort method" native))
|
||||||
|
;; Don't use the :set function until functions and variables below
|
||||||
|
;; are not loaded i.e. use set-default only for now.
|
||||||
|
:initialize 'custom-initialize-changed
|
||||||
|
:set (lambda (var val)
|
||||||
|
(set var val)
|
||||||
|
(cl-loop for s in (remove 'helm-source-bookmark-set
|
||||||
|
helm-bookmark-default-filtered-sources)
|
||||||
|
for fn = (intern (format "%s-builder" s))
|
||||||
|
do (set s (funcall fn)))))
|
||||||
|
|
||||||
|
(defgroup helm-bookmark-faces nil
|
||||||
|
"Customize the appearance of helm-bookmark."
|
||||||
|
:prefix "helm-"
|
||||||
|
:group 'helm-bookmark
|
||||||
|
:group 'helm-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-info
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "green"))
|
||||||
|
"Face used for W3m Emacs bookmarks (not w3m bookmarks)."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-w3m
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "yellow"))
|
||||||
|
"Face used for W3m Emacs bookmarks (not w3m bookmarks)."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-gnus
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "magenta"))
|
||||||
|
"Face used for Gnus bookmarks."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-man
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "Orange4"))
|
||||||
|
"Face used for Woman/man bookmarks."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-file
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "Deepskyblue2"))
|
||||||
|
"Face used for file bookmarks."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-file-not-found
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "Slategray4"))
|
||||||
|
"Face used for file bookmarks."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-directory
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:inherit helm-ff-directory))
|
||||||
|
"Face used for file bookmarks."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
(defface helm-bookmark-addressbook
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "tomato"))
|
||||||
|
"Face used for addressbook bookmarks."
|
||||||
|
:group 'helm-bookmark-faces)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar helm-bookmark-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "C-c o") #'helm-bookmark-run-jump-other-window)
|
||||||
|
(define-key map (kbd "C-c C-o") #'helm-bookmark-run-jump-other-frame)
|
||||||
|
(define-key map (kbd "C-c C-t") #'helm-bookmark-run-jump-other-tab)
|
||||||
|
(define-key map (kbd "C-d") #'helm-bookmark-run-delete)
|
||||||
|
(define-key map (kbd "C-]") #'helm-bookmark-toggle-filename)
|
||||||
|
(define-key map (kbd "M-e") #'helm-bookmark-run-edit)
|
||||||
|
map)
|
||||||
|
"Generic Keymap for Emacs bookmark sources.")
|
||||||
|
|
||||||
|
(defclass helm-source-basic-bookmarks (helm-source-in-buffer helm-type-bookmark)
|
||||||
|
((init :initform (lambda ()
|
||||||
|
(bookmark-maybe-load-default-file)
|
||||||
|
(helm-init-candidates-in-buffer
|
||||||
|
'global
|
||||||
|
(if (and (fboundp 'bookmark-maybe-sort-alist)
|
||||||
|
(fboundp 'bookmark-name-from-full-record))
|
||||||
|
(mapcar 'bookmark-name-from-full-record
|
||||||
|
(bookmark-maybe-sort-alist))
|
||||||
|
(bookmark-all-names)))))
|
||||||
|
(filtered-candidate-transformer :initform 'helm-bookmark-transformer)
|
||||||
|
(find-file-target :initform #'helm-bookmarks-quit-an-find-file-fn)))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmarks
|
||||||
|
(helm-make-source "Bookmarks" 'helm-source-basic-bookmarks)
|
||||||
|
"See (info \"(emacs)Bookmarks\").")
|
||||||
|
|
||||||
|
(defun helm-bookmark-transformer (candidates _source)
|
||||||
|
(cl-loop for i in candidates
|
||||||
|
for loc = (bookmark-location i)
|
||||||
|
for len = (string-width i)
|
||||||
|
for trunc = (if (> len bookmark-bmenu-file-column)
|
||||||
|
(helm-substring i bookmark-bmenu-file-column)
|
||||||
|
i)
|
||||||
|
for sep = (make-string (- (+ bookmark-bmenu-file-column 2)
|
||||||
|
(length trunc))
|
||||||
|
? )
|
||||||
|
if helm-bookmark-show-location
|
||||||
|
collect (cons (concat trunc sep (if (listp loc) (car loc) loc)) i)
|
||||||
|
else collect i))
|
||||||
|
|
||||||
|
(defun helm-bookmark-toggle-filename-1 (_candidate)
|
||||||
|
(let* ((real (helm-get-selection helm-buffer))
|
||||||
|
(trunc (if (> (string-width real) bookmark-bmenu-file-column)
|
||||||
|
(helm-substring real bookmark-bmenu-file-column)
|
||||||
|
real)))
|
||||||
|
(setq helm-bookmark-show-location (not helm-bookmark-show-location))
|
||||||
|
(helm-update (if helm-bookmark-show-location
|
||||||
|
(regexp-quote trunc)
|
||||||
|
(regexp-quote real)))))
|
||||||
|
|
||||||
|
(helm-make-persistent-command-from-action helm-bookmark-toggle-filename
|
||||||
|
"Toggle bookmark location visibility."
|
||||||
|
'toggle-filename 'helm-bookmark-toggle-filename-1)
|
||||||
|
|
||||||
|
(defun helm-bookmark-jump-1 (candidate &optional fn)
|
||||||
|
(let (;; FIXME Why is prefarg necessary here?
|
||||||
|
(current-prefix-arg helm-current-prefix-arg)
|
||||||
|
non-essential)
|
||||||
|
(bookmark-jump candidate fn)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-jump (candidate)
|
||||||
|
"Jump to bookmark action."
|
||||||
|
(helm-bookmark-jump-1 candidate))
|
||||||
|
|
||||||
|
(defun helm-bookmark-jump-other-frame (candidate)
|
||||||
|
"Jump to bookmark in other frame action."
|
||||||
|
(helm-bookmark-jump-1 candidate #'switch-to-buffer-other-frame))
|
||||||
|
|
||||||
|
(defun helm-bookmark-jump-other-window (candidate)
|
||||||
|
"Jump to bookmark in other window action."
|
||||||
|
(helm-bookmark-jump-1 candidate #'switch-to-buffer-other-window))
|
||||||
|
|
||||||
|
(defun helm-bookmark-jump-other-tab (candidate)
|
||||||
|
"Jump to bookmark action."
|
||||||
|
(cl-assert (fboundp 'tab-bar-mode) nil "Tab-bar-mode not available")
|
||||||
|
(helm-bookmark-jump-1 candidate #'switch-to-buffer-other-tab))
|
||||||
|
|
||||||
|
;;; bookmark-set
|
||||||
|
;;
|
||||||
|
(defvar helm-source-bookmark-set
|
||||||
|
(helm-build-dummy-source "Set Bookmark"
|
||||||
|
:filtered-candidate-transformer
|
||||||
|
(lambda (_candidates _source)
|
||||||
|
(list (or (and (not (string= helm-pattern ""))
|
||||||
|
helm-pattern)
|
||||||
|
"Enter a bookmark name to record")))
|
||||||
|
:action '(("Set bookmark" . (lambda (candidate)
|
||||||
|
(if (string= helm-pattern "")
|
||||||
|
(message "No bookmark name given for record")
|
||||||
|
(bookmark-set candidate))))))
|
||||||
|
"See (info \"(emacs)Bookmarks\").")
|
||||||
|
|
||||||
|
|
||||||
|
;;; Predicates
|
||||||
|
;;
|
||||||
|
(defconst helm-bookmark--non-file-filename " - no file -"
|
||||||
|
"Name to use for `filename' entry, for non-file bookmarks.")
|
||||||
|
|
||||||
|
(defun helm-bookmark-gnus-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK is a Gnus bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(or (eq (bookmark-get-handler bookmark) 'bmkext-jump-gnus)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'gnus-summary-bookmark-jump)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bookmarkp-jump-gnus)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bmkp-jump-gnus)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-mu4e-bookmark-p (bookmark)
|
||||||
|
"Return non nil if BOOKMARK is a mu4e bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(memq (bookmark-get-handler bookmark)
|
||||||
|
'(mu4e-bookmark-jump mu4e--jump-to-bookmark)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-w3m-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK is a W3m bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(or (eq (bookmark-get-handler bookmark) 'bmkext-jump-w3m)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bookmark-w3m-bookmark-jump)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bookmarkp-jump-w3m)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bmkp-jump-w3m)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-woman-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK is a Woman bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(or (eq (bookmark-get-handler bookmark) 'bmkext-jump-woman)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'woman-bookmark-jump)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bookmarkp-jump-woman)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bmkp-jump-woman)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-man-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK is a Man bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(or (eq (bookmark-get-handler bookmark) 'bmkext-jump-man)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'Man-bookmark-jump)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bookmarkp-jump-man)
|
||||||
|
(eq (bookmark-get-handler bookmark) 'bmkp-jump-man)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-woman-man-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK is a Man or Woman bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(or (helm-bookmark-man-bookmark-p bookmark)
|
||||||
|
(helm-bookmark-woman-bookmark-p bookmark)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-info-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK is an Info bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(eq (bookmark-get-handler bookmark) 'Info-bookmark-jump))
|
||||||
|
|
||||||
|
(defun helm-bookmark-image-bookmark-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK bookmarks an image file."
|
||||||
|
(if (stringp bookmark)
|
||||||
|
(assq 'image-type (assq bookmark bookmark-alist))
|
||||||
|
(assq 'image-type bookmark)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-file-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK bookmarks a file or directory.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record.
|
||||||
|
This excludes bookmarks of a more specific kind (Info, Gnus, and W3m)."
|
||||||
|
(let* ((filename (bookmark-get-filename bookmark))
|
||||||
|
(isnonfile (equal filename helm-bookmark--non-file-filename)))
|
||||||
|
(and filename (not isnonfile) (not (bookmark-get-handler bookmark)))))
|
||||||
|
|
||||||
|
(defun helm-bookmark-org-file-p (bookmark)
|
||||||
|
(let* ((filename (bookmark-get-filename bookmark)))
|
||||||
|
(or (string-suffix-p ".org" filename t)
|
||||||
|
(string-suffix-p ".org_archive" filename t))))
|
||||||
|
|
||||||
|
(defun helm-bookmark-helm-find-files-p (bookmark)
|
||||||
|
"Return non-nil if BOOKMARK bookmarks a `helm-find-files' session.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(eq (bookmark-get-handler bookmark) 'helm-ff-bookmark-jump))
|
||||||
|
|
||||||
|
(defun helm-bookmark-addressbook-p (bookmark)
|
||||||
|
"Return non--nil if BOOKMARK is a contact recorded with addressbook-bookmark.
|
||||||
|
BOOKMARK is a bookmark name or a bookmark record."
|
||||||
|
(if (listp bookmark)
|
||||||
|
(string= (assoc-default 'type bookmark) "addressbook")
|
||||||
|
(string= (assoc-default
|
||||||
|
'type (assoc bookmark bookmark-alist)) "addressbook")))
|
||||||
|
|
||||||
|
(defun helm-bookmark-uncategorized-bookmark-p (bookmark)
|
||||||
|
"Return non--nil if BOOKMARK match no known category."
|
||||||
|
(cl-loop for pred in '(helm-bookmark-org-file-p
|
||||||
|
helm-bookmark-addressbook-p
|
||||||
|
helm-bookmark-gnus-bookmark-p
|
||||||
|
helm-bookmark-mu4e-bookmark-p
|
||||||
|
helm-bookmark-w3m-bookmark-p
|
||||||
|
helm-bookmark-woman-man-bookmark-p
|
||||||
|
helm-bookmark-info-bookmark-p
|
||||||
|
helm-bookmark-image-bookmark-p
|
||||||
|
helm-bookmark-file-p
|
||||||
|
helm-bookmark-helm-find-files-p
|
||||||
|
helm-bookmark-addressbook-p)
|
||||||
|
never (funcall pred bookmark)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-filter-setup-alist (fn)
|
||||||
|
"Return a filtered `bookmark-alist' sorted alphabetically."
|
||||||
|
(cl-loop for b in (if (and (fboundp 'bookmark-maybe-sort-alist)
|
||||||
|
(eq helm-bookmark-default-sort-method 'native))
|
||||||
|
(bookmark-maybe-sort-alist)
|
||||||
|
bookmark-alist)
|
||||||
|
for name = (car b)
|
||||||
|
when (funcall fn b) collect
|
||||||
|
(propertize name 'location (bookmark-location name))))
|
||||||
|
|
||||||
|
;;; Bookmark handlers
|
||||||
|
;;
|
||||||
|
(defvar w3m-async-exec)
|
||||||
|
(defun helm-bookmark-jump-w3m (bookmark)
|
||||||
|
"Jump to W3m bookmark BOOKMARK, setting a new tab.
|
||||||
|
If `browse-url-browser-function' is set to something else than
|
||||||
|
`w3m-browse-url' use it."
|
||||||
|
(require 'helm-net)
|
||||||
|
(let* ((file (or (bookmark-prop-get bookmark 'filename)
|
||||||
|
(bookmark-prop-get bookmark 'url)))
|
||||||
|
(buf (generate-new-buffer-name "*w3m*"))
|
||||||
|
(w3m-async-exec nil)
|
||||||
|
;; If user don't have anymore w3m installed let it browse its
|
||||||
|
;; bookmarks with default browser otherwise assume bookmark
|
||||||
|
;; have been bookmarked from w3m and use w3m.
|
||||||
|
(browse-url-browser-function (or (and (fboundp 'w3m-browse-url)
|
||||||
|
(executable-find "w3m")
|
||||||
|
'w3m-browse-url)
|
||||||
|
browse-url-browser-function))
|
||||||
|
(really-use-w3m (equal browse-url-browser-function 'w3m-browse-url)))
|
||||||
|
(helm-browse-url file really-use-w3m)
|
||||||
|
(when really-use-w3m
|
||||||
|
(bookmark-default-handler
|
||||||
|
`("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark))))))
|
||||||
|
|
||||||
|
;; All bookmarks recorded with the handler provided with w3m
|
||||||
|
;; (`bookmark-w3m-bookmark-jump') will use our handler which open
|
||||||
|
;; the bookmark in a new tab or in an external browser depending
|
||||||
|
;; on `browse-url-browser-function'.
|
||||||
|
(defalias 'bookmark-w3m-bookmark-jump #'helm-bookmark-jump-w3m)
|
||||||
|
|
||||||
|
;; Provide compatibility with old handlers provided in external
|
||||||
|
;; packages bookmark-extensions.el and bookmark+.
|
||||||
|
(defalias 'bmkext-jump-woman #'woman-bookmark-jump)
|
||||||
|
(defalias 'bmkext-jump-man #'Man-bookmark-jump)
|
||||||
|
(defalias 'bmkext-jump-w3m #'helm-bookmark-jump-w3m)
|
||||||
|
(defalias 'bmkext-jump-gnus #'gnus-summary-bookmark-jump)
|
||||||
|
(defalias 'bookmarkp-jump-gnus #'gnus-summary-bookmark-jump)
|
||||||
|
(defalias 'bookmarkp-jump-w3m #'helm-bookmark-jump-w3m)
|
||||||
|
(defalias 'bookmarkp-jump-woman #'woman-bookmark-jump)
|
||||||
|
(defalias 'bookmarkp-jump-man #'Man-bookmark-jump)
|
||||||
|
(defalias 'bmkp-jump-gnus #'gnus-summary-bookmark-jump)
|
||||||
|
(defalias 'bmkp-jump-w3m #'helm-bookmark-jump-w3m)
|
||||||
|
(defalias 'bmkp-jump-woman #'woman-bookmark-jump)
|
||||||
|
(defalias 'bmkp-jump-man #'Man-bookmark-jump)
|
||||||
|
|
||||||
|
|
||||||
|
;;;; Filtered bookmark sources
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defclass helm-source-filtered-bookmarks (helm-source-in-buffer helm-type-bookmark)
|
||||||
|
((filtered-candidate-transformer
|
||||||
|
:initform (delq nil
|
||||||
|
`(,(and (eq helm-bookmark-default-sort-method 'adaptive)
|
||||||
|
'helm-adaptive-sort)
|
||||||
|
helm-highlight-bookmark)))
|
||||||
|
(find-file-target :initform #'helm-bookmarks-quit-an-find-file-fn)))
|
||||||
|
|
||||||
|
(defun helm-bookmarks-quit-an-find-file-fn (source)
|
||||||
|
(let* ((sel (helm-get-selection nil nil source))
|
||||||
|
(bmk (assoc (replace-regexp-in-string "\\`\\*" "" sel)
|
||||||
|
bookmark-alist)))
|
||||||
|
(helm-aif (bookmark-get-filename bmk)
|
||||||
|
(if (and helm--url-regexp
|
||||||
|
(string-match helm--url-regexp it))
|
||||||
|
it (expand-file-name it))
|
||||||
|
(expand-file-name default-directory))))
|
||||||
|
|
||||||
|
(defun helm-bookmark-build-source (name buildfn &optional class &rest args)
|
||||||
|
(apply #'helm-make-source name
|
||||||
|
(or class 'helm-source-filtered-bookmarks)
|
||||||
|
:init (lambda ()
|
||||||
|
(bookmark-maybe-load-default-file)
|
||||||
|
(helm-init-candidates-in-buffer
|
||||||
|
'global (funcall buildfn)))
|
||||||
|
args))
|
||||||
|
|
||||||
|
;;; W3m bookmarks.
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-w3m-setup-alist ()
|
||||||
|
"Specialized filter function for bookmarks w3m."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-w3m-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-w3m-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark W3m" #'helm-bookmark-w3m-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-w3m (helm-source-bookmark-w3m-builder))
|
||||||
|
|
||||||
|
;;; Images
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-images-setup-alist ()
|
||||||
|
"Specialized filter function for images bookmarks."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-image-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-images-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark Images" #'helm-bookmark-images-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-images (helm-source-bookmark-images-builder))
|
||||||
|
|
||||||
|
;;; Woman Man
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-man-setup-alist ()
|
||||||
|
"Specialized filter function for bookmarks w3m."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-woman-man-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-man-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark Woman&Man" #'helm-bookmark-man-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-man (helm-source-bookmark-man-builder))
|
||||||
|
|
||||||
|
;;; Org files
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-org-setup-alist ()
|
||||||
|
"Specialized filter function for Org file bookmarks."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-org-file-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-org-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark Org files" #'helm-bookmark-org-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-org (helm-source-bookmark-org-builder))
|
||||||
|
|
||||||
|
;;; Gnus
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-gnus-setup-alist ()
|
||||||
|
"Specialized filter function for bookmarks gnus."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-gnus-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-gnus-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark Gnus" #'helm-bookmark-gnus-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-gnus (helm-source-bookmark-gnus-builder))
|
||||||
|
|
||||||
|
;;; Mu4e
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-mu4e-setup-alist ()
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-mu4e-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-mu4e-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark Mu4e" #'helm-bookmark-mu4e-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-mu4e (helm-source-bookmark-mu4e-builder))
|
||||||
|
|
||||||
|
;;; Info
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-info-setup-alist ()
|
||||||
|
"Specialized filter function for bookmarks info."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-info-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-info-builder ()
|
||||||
|
(helm-bookmark-build-source "Bookmark Info" #'helm-bookmark-info-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-info (helm-source-bookmark-info-builder))
|
||||||
|
|
||||||
|
;;; Files and directories
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-local-files-setup-alist ()
|
||||||
|
"Specialized filter function for bookmarks locals files."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-file-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-files&dirs-builder ()
|
||||||
|
(helm-bookmark-build-source
|
||||||
|
"Bookmark Files&Directories" #'helm-bookmark-local-files-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-files&dirs
|
||||||
|
(helm-source-bookmark-files&dirs-builder))
|
||||||
|
|
||||||
|
;;; Helm find files sessions.
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-helm-find-files-setup-alist ()
|
||||||
|
"Specialized filter function for `helm-find-files' bookmarks."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-helm-find-files-p))
|
||||||
|
|
||||||
|
(defun helm-bookmark-browse-project (candidate)
|
||||||
|
"Run `helm-browse-project' from action."
|
||||||
|
(with-helm-default-directory
|
||||||
|
(bookmark-get-filename candidate)
|
||||||
|
(helm-browse-project nil)))
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-bookmark-run-browse-project
|
||||||
|
"Run `helm-bookmark-browse-project' from keyboard."
|
||||||
|
'helm-bookmark-browse-project)
|
||||||
|
|
||||||
|
(defvar helm-bookmark-find-files-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-bookmark-map)
|
||||||
|
(define-key map (kbd "C-x C-d") #'helm-bookmark-run-browse-project)
|
||||||
|
map))
|
||||||
|
|
||||||
|
;; Same as `helm-source-filtered-bookmarks' but override actions and keymap
|
||||||
|
;; specifically for helm-find-files bookmarks.
|
||||||
|
(defclass helm-bookmark-override-inheritor (helm-source) ())
|
||||||
|
|
||||||
|
(cl-defmethod helm--setup-source ((source helm-bookmark-override-inheritor))
|
||||||
|
;; Ensure `helm-source-in-buffer' method is called.
|
||||||
|
(cl-call-next-method)
|
||||||
|
(setf (slot-value source 'action)
|
||||||
|
(helm-append-at-nth
|
||||||
|
(cl-loop for (name . action) in helm-type-bookmark-actions
|
||||||
|
;; We don't want those actions in helm-find-files bookmarks.
|
||||||
|
unless (memq action '(helm-bookmark-jump-other-frame
|
||||||
|
helm-bookmark-jump-other-window
|
||||||
|
helm-bookmark-jump-other-tab))
|
||||||
|
collect (cons name action))
|
||||||
|
'(("Browse project" . helm-bookmark-browse-project)) 1))
|
||||||
|
(setf (slot-value source 'keymap) helm-bookmark-find-files-map))
|
||||||
|
|
||||||
|
(defclass helm-bookmark-find-files-class (helm-source-filtered-bookmarks
|
||||||
|
helm-bookmark-override-inheritor)
|
||||||
|
())
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-helm-find-files-builder ()
|
||||||
|
(helm-bookmark-build-source
|
||||||
|
"Bookmark helm-find-files sessions"
|
||||||
|
#'helm-bookmark-helm-find-files-setup-alist
|
||||||
|
'helm-bookmark-find-files-class
|
||||||
|
:persistent-action (lambda (_candidate) (ignore))
|
||||||
|
:persistent-help "Do nothing"))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-helm-find-files
|
||||||
|
(helm-source-bookmark-helm-find-files-builder))
|
||||||
|
|
||||||
|
;;; Uncategorized bookmarks
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-uncategorized-setup-alist ()
|
||||||
|
"Specialized filter function for uncategorized bookmarks."
|
||||||
|
(helm-bookmark-filter-setup-alist 'helm-bookmark-uncategorized-bookmark-p))
|
||||||
|
|
||||||
|
(defun helm-source-bookmark-uncategorized-builder ()
|
||||||
|
(helm-bookmark-build-source
|
||||||
|
"Bookmark uncategorized" #'helm-bookmark-uncategorized-setup-alist))
|
||||||
|
|
||||||
|
(defvar helm-source-bookmark-uncategorized
|
||||||
|
(helm-source-bookmark-uncategorized-builder))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Transformer
|
||||||
|
;;
|
||||||
|
(defun helm-highlight-bookmark (bookmarks _source)
|
||||||
|
"Used as `filtered-candidate-transformer' to colorize bookmarks."
|
||||||
|
(let ((non-essential t))
|
||||||
|
(cl-loop for i in bookmarks
|
||||||
|
for isfile = (bookmark-get-filename i)
|
||||||
|
for hff = (helm-bookmark-helm-find-files-p i)
|
||||||
|
for handlerp = (and (fboundp 'bookmark-get-handler)
|
||||||
|
(bookmark-get-handler i))
|
||||||
|
for isw3m = (and (fboundp 'helm-bookmark-w3m-bookmark-p)
|
||||||
|
(helm-bookmark-w3m-bookmark-p i))
|
||||||
|
for isgnus = (and (fboundp 'helm-bookmark-gnus-bookmark-p)
|
||||||
|
(helm-bookmark-gnus-bookmark-p i))
|
||||||
|
for ismu4e = (and (fboundp 'helm-bookmark-mu4e-bookmark-p)
|
||||||
|
(helm-bookmark-mu4e-bookmark-p i))
|
||||||
|
for isman = (and (fboundp 'helm-bookmark-man-bookmark-p) ; Man
|
||||||
|
(helm-bookmark-man-bookmark-p i))
|
||||||
|
for iswoman = (and (fboundp 'helm-bookmark-woman-bookmark-p) ; Woman
|
||||||
|
(helm-bookmark-woman-bookmark-p i))
|
||||||
|
for isannotation = (bookmark-get-annotation i)
|
||||||
|
for isabook = (string= (bookmark-prop-get i 'type)
|
||||||
|
"addressbook")
|
||||||
|
for isinfo = (eq handlerp 'Info-bookmark-jump)
|
||||||
|
for loc = (bookmark-location i)
|
||||||
|
for len = (string-width i)
|
||||||
|
for trunc = (if (and helm-bookmark-show-location
|
||||||
|
(> len bookmark-bmenu-file-column))
|
||||||
|
(helm-substring
|
||||||
|
i bookmark-bmenu-file-column)
|
||||||
|
i)
|
||||||
|
for icon = (when helm-bookmark-use-icon
|
||||||
|
(cond ((and isfile hff)
|
||||||
|
(helm-aif (or (all-the-icons-match-to-alist
|
||||||
|
(helm-basename (helm-basedir isfile t))
|
||||||
|
all-the-icons-dir-icon-alist)
|
||||||
|
(all-the-icons-match-to-alist
|
||||||
|
(helm-basename isfile)
|
||||||
|
all-the-icons-dir-icon-alist))
|
||||||
|
(apply (car it) (cdr it))
|
||||||
|
(all-the-icons-octicon "file-directory")))
|
||||||
|
(isw3m (all-the-icons-faicon "firefox"))
|
||||||
|
((and isfile isinfo) (all-the-icons-octicon "info"))
|
||||||
|
((or iswoman isman)
|
||||||
|
(all-the-icons-fileicon "man-page"))
|
||||||
|
((or isgnus ismu4e)
|
||||||
|
(all-the-icons-octicon "mail-read"))
|
||||||
|
(isfile (all-the-icons-icon-for-file (helm-basename isfile)))))
|
||||||
|
;; Add a * if bookmark have annotation
|
||||||
|
if (and isannotation (not (string-equal isannotation "")))
|
||||||
|
do (setq trunc (concat "*" (if helm-bookmark-show-location trunc i)))
|
||||||
|
for sep = (and helm-bookmark-show-location
|
||||||
|
(make-string (- (+ bookmark-bmenu-file-column 2)
|
||||||
|
(string-width trunc))
|
||||||
|
? ))
|
||||||
|
for bmk = (cond ( ;; info buffers
|
||||||
|
isinfo
|
||||||
|
(propertize trunc 'face 'helm-bookmark-info
|
||||||
|
'help-echo isfile))
|
||||||
|
( ;; w3m buffers
|
||||||
|
isw3m
|
||||||
|
(propertize trunc 'face 'helm-bookmark-w3m
|
||||||
|
'help-echo isfile))
|
||||||
|
( ;; gnus buffers
|
||||||
|
isgnus
|
||||||
|
(propertize trunc 'face 'helm-bookmark-gnus
|
||||||
|
'help-echo isfile))
|
||||||
|
( ;; Man Woman
|
||||||
|
(or iswoman isman)
|
||||||
|
(propertize trunc 'face 'helm-bookmark-man
|
||||||
|
'help-echo isfile))
|
||||||
|
( ;; Addressbook
|
||||||
|
isabook
|
||||||
|
(propertize trunc 'face 'helm-bookmark-addressbook))
|
||||||
|
(;; Directories (helm-find-files)
|
||||||
|
hff
|
||||||
|
(if (and (file-remote-p isfile)
|
||||||
|
(not (file-remote-p isfile nil t)))
|
||||||
|
(propertize trunc 'face 'helm-bookmark-file-not-found
|
||||||
|
'help-echo isfile)
|
||||||
|
(propertize trunc 'face 'helm-bookmark-directory
|
||||||
|
'help-echo isfile)))
|
||||||
|
( ;; Directories (dired)
|
||||||
|
(and isfile
|
||||||
|
;; This is needed because `non-essential'
|
||||||
|
;; is not working on Emacs-24.2 and the behavior
|
||||||
|
;; of tramp seems to have changed since previous
|
||||||
|
;; versions (Need to reenter password even if a
|
||||||
|
;; first connection have been established,
|
||||||
|
;; probably when host is named differently
|
||||||
|
;; i.e machine/localhost)
|
||||||
|
(and (not (file-remote-p isfile))
|
||||||
|
(file-directory-p isfile)))
|
||||||
|
(propertize trunc 'face 'helm-bookmark-directory
|
||||||
|
'help-echo isfile))
|
||||||
|
( ;; Non existing files.
|
||||||
|
(and isfile
|
||||||
|
;; Be safe and call `file-exists-p'
|
||||||
|
;; only if file is not remote or
|
||||||
|
;; remote but connected.
|
||||||
|
(or (and (file-remote-p isfile)
|
||||||
|
(not (file-remote-p isfile nil t)))
|
||||||
|
(not (file-exists-p isfile))))
|
||||||
|
(propertize trunc 'face 'helm-bookmark-file-not-found
|
||||||
|
'help-echo isfile))
|
||||||
|
( ;; regular files
|
||||||
|
t
|
||||||
|
(propertize trunc 'face 'helm-bookmark-file
|
||||||
|
'help-echo isfile)))
|
||||||
|
collect (if helm-bookmark-show-location
|
||||||
|
(cons (concat (and icon (propertize " " 'display (concat icon " ")))
|
||||||
|
bmk
|
||||||
|
(propertize
|
||||||
|
" " 'display
|
||||||
|
(concat sep (if (listp loc) (car loc) loc))))
|
||||||
|
i)
|
||||||
|
(cons (concat (and icon (propertize " " 'display (concat icon " ")))
|
||||||
|
bmk)
|
||||||
|
i)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Edit/rename/save bookmarks.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-bookmark-edit-bookmark (bookmark-name)
|
||||||
|
"Edit bookmark's name and file name, and maybe save them.
|
||||||
|
BOOKMARK-NAME is the current (old) name of the bookmark to be
|
||||||
|
renamed."
|
||||||
|
(let ((bmk (helm-bookmark-get-bookmark-from-name bookmark-name))
|
||||||
|
(handler (bookmark-prop-get bookmark-name 'handler)))
|
||||||
|
(if (eq handler 'addressbook-bookmark-jump)
|
||||||
|
(addressbook-bookmark-edit
|
||||||
|
(assoc bmk bookmark-alist))
|
||||||
|
(helm-bookmark-edit-bookmark-1 bookmark-name handler))))
|
||||||
|
|
||||||
|
(defun helm-bookmark-edit-bookmark-1 (bookmark-name handler)
|
||||||
|
(let* ((helm--reading-passwd-or-string t)
|
||||||
|
(bookmark-fname (bookmark-get-filename bookmark-name))
|
||||||
|
(bookmark-loc (bookmark-prop-get bookmark-name 'location))
|
||||||
|
(message-id (bookmark-prop-get bookmark-name 'message-id))
|
||||||
|
(new-name (read-from-minibuffer "Name: " bookmark-name))
|
||||||
|
(new-loc (and (or bookmark-fname bookmark-loc)
|
||||||
|
(read-from-minibuffer "FileName or Location: "
|
||||||
|
(or bookmark-fname
|
||||||
|
(if (consp bookmark-loc)
|
||||||
|
(car bookmark-loc)
|
||||||
|
bookmark-loc)))))
|
||||||
|
(new-message-id (and (memq handler '(mu4e--jump-to-bookmark
|
||||||
|
mu4e-bookmark-jump))
|
||||||
|
(read-string "Message-id: " message-id))))
|
||||||
|
(when (and (not (equal new-name ""))
|
||||||
|
(or (not (equal new-loc ""))
|
||||||
|
(not (equal new-message-id "")))
|
||||||
|
(y-or-n-p "Save changes? "))
|
||||||
|
(if bookmark-fname
|
||||||
|
(progn
|
||||||
|
(helm-bookmark-rename bookmark-name new-name 'batch)
|
||||||
|
(bookmark-set-filename new-name new-loc))
|
||||||
|
(bookmark-prop-set
|
||||||
|
(bookmark-get-bookmark bookmark-name)
|
||||||
|
(cond (new-loc 'location)
|
||||||
|
(new-message-id 'message-id))
|
||||||
|
(or new-loc new-message-id))
|
||||||
|
(helm-bookmark-rename bookmark-name new-name 'batch))
|
||||||
|
(helm-bookmark-maybe-save-bookmark)
|
||||||
|
(list new-name new-loc))))
|
||||||
|
|
||||||
|
(defun helm-bookmark-maybe-save-bookmark ()
|
||||||
|
"Increment save counter and maybe save `bookmark-alist'."
|
||||||
|
(setq bookmark-alist-modification-count (1+ bookmark-alist-modification-count))
|
||||||
|
(when (bookmark-time-to-save-p) (bookmark-save)))
|
||||||
|
|
||||||
|
(defun helm-bookmark-rename (old &optional new batch)
|
||||||
|
"Change bookmark's name from OLD to NEW.
|
||||||
|
Interactively:
|
||||||
|
If called from the keyboard, then prompt for OLD.
|
||||||
|
If called from the menubar, select OLD from a menu.
|
||||||
|
If NEW is nil, then prompt for its string value.
|
||||||
|
|
||||||
|
If BATCH is non-nil, then do not rebuild the menu list.
|
||||||
|
|
||||||
|
While the user enters the new name, repeated `C-w' inserts
|
||||||
|
consecutive words from the buffer into the new bookmark name."
|
||||||
|
(interactive (list (bookmark-completing-read "Old bookmark name")))
|
||||||
|
(bookmark-maybe-historicize-string old)
|
||||||
|
(bookmark-maybe-load-default-file)
|
||||||
|
(save-excursion (skip-chars-forward " ") (setq bookmark-yank-point (point)))
|
||||||
|
(setq bookmark-current-buffer (current-buffer))
|
||||||
|
(let ((newname (or new (read-from-minibuffer
|
||||||
|
"New name: " nil
|
||||||
|
(let ((now-map (copy-keymap minibuffer-local-map)))
|
||||||
|
(define-key now-map "\C-w" #'bookmark-yank-word)
|
||||||
|
now-map)
|
||||||
|
nil 'bookmark-history))))
|
||||||
|
(bookmark-set-name old newname)
|
||||||
|
(setq bookmark-current-bookmark newname)
|
||||||
|
(unless batch (bookmark-bmenu-surreptitiously-rebuild-list))
|
||||||
|
(helm-bookmark-maybe-save-bookmark) newname))
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-bookmark-run-edit
|
||||||
|
"Run `helm-bookmark-edit-bookmark' from keyboard."
|
||||||
|
'helm-bookmark-edit-bookmark)
|
||||||
|
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-bookmark-run-jump-other-frame
|
||||||
|
"Jump to bookmark other frame from keyboard."
|
||||||
|
'helm-bookmark-jump-other-frame)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-bookmark-run-jump-other-window
|
||||||
|
"Jump to bookmark other window from keyboard."
|
||||||
|
'helm-bookmark-jump-other-window)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-bookmark-run-jump-other-tab
|
||||||
|
"Jump to bookmark other tab from keyboard."
|
||||||
|
'helm-bookmark-jump-other-tab)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-bookmark-run-delete
|
||||||
|
"Delete bookmark from keyboard."
|
||||||
|
'helm-delete-marked-bookmarks)
|
||||||
|
|
||||||
|
(defun helm-bookmark-get-bookmark-from-name (bmk)
|
||||||
|
"Return bookmark name even if it is a bookmark with annotation.
|
||||||
|
E.g. prepended with *."
|
||||||
|
(let ((bookmark (replace-regexp-in-string "\\`\\*" "" bmk)))
|
||||||
|
(if (assoc bookmark bookmark-alist) bookmark bmk)))
|
||||||
|
|
||||||
|
(defun helm-delete-marked-bookmarks (_ignore)
|
||||||
|
"Delete this bookmark or all marked bookmarks."
|
||||||
|
(dolist (i (helm-marked-candidates))
|
||||||
|
(bookmark-delete (helm-bookmark-get-bookmark-from-name i)
|
||||||
|
'batch)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-bookmarks ()
|
||||||
|
"Preconfigured `helm' for bookmarks."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources '(helm-source-bookmarks
|
||||||
|
helm-source-bookmark-set)
|
||||||
|
:buffer "*helm bookmarks*"
|
||||||
|
:default (buffer-name helm-current-buffer)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-filtered-bookmarks ()
|
||||||
|
"Preconfigured `helm' for bookmarks (filtered by category).
|
||||||
|
Optional source `helm-source-bookmark-addressbook' is loaded only
|
||||||
|
if external addressbook-bookmark package is installed."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources helm-bookmark-default-filtered-sources
|
||||||
|
:prompt "Search Bookmark: "
|
||||||
|
:buffer "*helm filtered bookmarks*"
|
||||||
|
:default (list (thing-at-point 'symbol)
|
||||||
|
(buffer-name helm-current-buffer))))
|
||||||
|
|
||||||
|
(provide 'helm-bookmark)
|
||||||
|
|
||||||
|
;;; helm-bookmark.el ends here
|
1181
code/elpa/helm-20240320.541/helm-buffers.el
Normal file
1181
code/elpa/helm-20240320.541/helm-buffers.el
Normal file
File diff suppressed because it is too large
Load diff
159
code/elpa/helm-20240320.541/helm-color.el
Normal file
159
code/elpa/helm-20240320.541/helm-color.el
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
;;; helm-color.el --- colors and faces -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-elisp)
|
||||||
|
|
||||||
|
(declare-function list-colors-display "facemenu")
|
||||||
|
|
||||||
|
;;; Customize Face
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-custom-faces-init ()
|
||||||
|
"Initialize buffer for `helm-source-customize-face'."
|
||||||
|
(unless (helm-candidate-buffer)
|
||||||
|
(save-selected-window
|
||||||
|
(list-faces-display)
|
||||||
|
(message nil))
|
||||||
|
(helm-init-candidates-in-buffer
|
||||||
|
'global
|
||||||
|
(with-current-buffer (get-buffer "*Faces*")
|
||||||
|
(buffer-substring
|
||||||
|
(next-single-char-property-change (point-min) 'category)
|
||||||
|
(point-max))))
|
||||||
|
(kill-buffer "*Faces*")))
|
||||||
|
|
||||||
|
(defvar helm-source-customize-face
|
||||||
|
(helm-build-in-buffer-source "Customize Face"
|
||||||
|
:init 'helm-custom-faces-init
|
||||||
|
:get-line 'buffer-substring
|
||||||
|
:persistent-action (lambda (candidate)
|
||||||
|
(helm-elisp--persistent-help
|
||||||
|
(intern (car (split-string candidate)))
|
||||||
|
'helm-describe-face))
|
||||||
|
:persistent-help "Describe face"
|
||||||
|
:action '(("Customize"
|
||||||
|
. (lambda (line)
|
||||||
|
(customize-face (intern (car (split-string line))))))
|
||||||
|
("Copy name"
|
||||||
|
. (lambda (line)
|
||||||
|
(kill-new (car (split-string line " " t)))))))
|
||||||
|
"See (info \"(emacs)Faces\")")
|
||||||
|
|
||||||
|
;;; Colors browser
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-colors-init ()
|
||||||
|
(require 'facemenu)
|
||||||
|
(unless (helm-candidate-buffer)
|
||||||
|
(save-selected-window
|
||||||
|
(list-colors-display)
|
||||||
|
(message nil))
|
||||||
|
(helm-init-candidates-in-buffer
|
||||||
|
'global
|
||||||
|
(with-current-buffer (get-buffer "*Colors*")
|
||||||
|
(buffer-string)))
|
||||||
|
(kill-buffer "*Colors*")))
|
||||||
|
|
||||||
|
(defun helm-color-insert-name (candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(insert (helm-colors-get-name candidate))))
|
||||||
|
|
||||||
|
(defun helm-color-kill-name (candidate)
|
||||||
|
(kill-new (helm-colors-get-name candidate)))
|
||||||
|
|
||||||
|
(defun helm-color-insert-rgb (candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(insert (helm-colors-get-rgb candidate))))
|
||||||
|
|
||||||
|
(defun helm-color-kill-rgb (candidate)
|
||||||
|
(kill-new (helm-colors-get-rgb candidate)))
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-color-run-insert-name
|
||||||
|
"Insert name of color from `helm-source-colors'."
|
||||||
|
'helm-color-insert-name)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-color-run-kill-name
|
||||||
|
"Kill name of color from `helm-source-colors'."
|
||||||
|
'helm-color-kill-name)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-color-run-insert-rgb
|
||||||
|
"Insert RGB of color from `helm-source-colors'."
|
||||||
|
'helm-color-insert-rgb)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-color-run-kill-rgb
|
||||||
|
"Kill RGB of color from `helm-source-colors'."
|
||||||
|
'helm-color-kill-rgb)
|
||||||
|
|
||||||
|
(defvar helm-color-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "C-c n") #'helm-color-run-insert-name)
|
||||||
|
(define-key map (kbd "C-c N") #'helm-color-run-kill-name)
|
||||||
|
(define-key map (kbd "C-c r") #'helm-color-run-insert-rgb)
|
||||||
|
(define-key map (kbd "C-c R") #'helm-color-run-kill-rgb)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defvar helm-source-colors
|
||||||
|
(helm-build-in-buffer-source "Colors"
|
||||||
|
:init 'helm-colors-init
|
||||||
|
:get-line 'buffer-substring
|
||||||
|
:keymap helm-color-map
|
||||||
|
:persistent-help "Kill entry in RGB format."
|
||||||
|
:persistent-action 'helm-color-kill-rgb
|
||||||
|
:help-message 'helm-colors-help-message
|
||||||
|
:action
|
||||||
|
'(("Copy Name (C-c N)" . helm-color-kill-name)
|
||||||
|
("Copy RGB (C-c R)" . helm-color-kill-rgb)
|
||||||
|
("Insert Name (C-c n)" . helm-color-insert-name)
|
||||||
|
("Insert RGB (C-c r)" . helm-color-insert-rgb))))
|
||||||
|
|
||||||
|
(defun helm-colors-get-name (candidate)
|
||||||
|
"Get color name."
|
||||||
|
(replace-regexp-in-string
|
||||||
|
" " ""
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert (capitalize candidate))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(search-forward-regexp "\\s-\\{2,\\}")
|
||||||
|
(delete-region (point) (point-max))
|
||||||
|
(buffer-string))))
|
||||||
|
|
||||||
|
(defun helm-colors-get-rgb (candidate)
|
||||||
|
"Get color RGB."
|
||||||
|
(replace-regexp-in-string
|
||||||
|
" " ""
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert (capitalize candidate))
|
||||||
|
(goto-char (point-max))
|
||||||
|
(search-backward-regexp "\\s-\\{2,\\}")
|
||||||
|
(delete-region (point) (point-min))
|
||||||
|
(buffer-string))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-colors ()
|
||||||
|
"Preconfigured `helm' for color."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources '(helm-source-colors helm-source-customize-face)
|
||||||
|
:buffer "*helm colors*"))
|
||||||
|
|
||||||
|
(provide 'helm-color)
|
||||||
|
|
||||||
|
;;; helm-color.el ends here
|
417
code/elpa/helm-20240320.541/helm-command.el
Normal file
417
code/elpa/helm-20240320.541/helm-command.el
Normal file
|
@ -0,0 +1,417 @@
|
||||||
|
;;; helm-command.el --- Helm execute-exended-command. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-mode)
|
||||||
|
(require 'helm-elisp)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar helm-M-x-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-comp-read-map)
|
||||||
|
(define-key map (kbd "C-u") nil)
|
||||||
|
(define-key map (kbd "C-u") #'helm-M-x-universal-argument)
|
||||||
|
(define-key map (kbd "C-]") #'helm-M-x-toggle-short-doc)
|
||||||
|
map))
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-command nil
|
||||||
|
"Emacs command related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-M-x-always-save-history nil
|
||||||
|
"`helm-M-x' save command in `extended-command-history' even when it fails."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-M-x-reverse-history nil
|
||||||
|
"The history source of `helm-M-x' appear in second position when non-nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-M-x-fuzzy-match t
|
||||||
|
"Helm-M-x fuzzy matching when non nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-M-x-show-short-doc nil
|
||||||
|
"Show short docstring of command when non nil.
|
||||||
|
This value can be toggled with
|
||||||
|
\\<helm-M-x-map>\\[helm-M-x-toggle-short-doc] while in helm-M-x session."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Faces
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defgroup helm-command-faces nil
|
||||||
|
"Customize the appearance of helm-command."
|
||||||
|
:prefix "helm-"
|
||||||
|
:group 'helm-command
|
||||||
|
:group 'helm-faces)
|
||||||
|
|
||||||
|
(defface helm-M-x-key
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "orange" :box (:line-width -1)))
|
||||||
|
"Face used in helm-M-x to show keybinding."
|
||||||
|
:group 'helm-command-faces)
|
||||||
|
|
||||||
|
(defface helm-command-active-mode
|
||||||
|
'((t :inherit font-lock-builtin-face))
|
||||||
|
"Face used by `helm-M-x' for activated modes."
|
||||||
|
:group 'helm-command-faces)
|
||||||
|
|
||||||
|
(defface helm-M-x-short-doc
|
||||||
|
'((t :box (:line-width -1) :foreground "DimGray"))
|
||||||
|
"Face used by `helm-M-x' for short docstring."
|
||||||
|
:group 'helm-command-faces)
|
||||||
|
|
||||||
|
(defvar helm-M-x-input-history nil)
|
||||||
|
(defvar helm-M-x-prefix-argument nil
|
||||||
|
"Prefix argument before calling `helm-M-x'.")
|
||||||
|
(defvar helm-M-x--timer nil)
|
||||||
|
(defvar helm-M-x--unwind-forms-done nil)
|
||||||
|
|
||||||
|
(defun helm-M-x-get-major-mode-command-alist (mode-map)
|
||||||
|
"Return alist of MODE-MAP."
|
||||||
|
(when mode-map
|
||||||
|
(cl-loop for key being the key-seqs of mode-map using (key-bindings com)
|
||||||
|
for str-key = (key-description key)
|
||||||
|
for ismenu = (string-match "<menu-bar>" str-key)
|
||||||
|
unless ismenu collect (cons str-key com))))
|
||||||
|
|
||||||
|
(defun helm-get-mode-map-from-mode (mode)
|
||||||
|
"Guess the mode-map name according to MODE.
|
||||||
|
Some modes don't use conventional mode-map name so we need to
|
||||||
|
guess mode-map name. E.g. `python-mode' ==> py-mode-map.
|
||||||
|
Return nil if no mode-map found."
|
||||||
|
(cl-loop ;; Start with a conventional mode-map name.
|
||||||
|
with mode-map = (intern-soft (format "%s-map" mode))
|
||||||
|
with mode-string = (symbol-name mode)
|
||||||
|
with mode-name = (replace-regexp-in-string "-mode" "" mode-string)
|
||||||
|
while (not mode-map)
|
||||||
|
for count downfrom (length mode-name)
|
||||||
|
;; Return when no result after parsing entire string.
|
||||||
|
when (eq count 0) return nil
|
||||||
|
for sub-name = (substring mode-name 0 count)
|
||||||
|
do (setq mode-map (intern-soft (format "%s-map" (concat sub-name "-mode"))))
|
||||||
|
finally return mode-map))
|
||||||
|
|
||||||
|
(defun helm-M-x-current-mode-map-alist ()
|
||||||
|
"Return mode-map alist of current `major-mode'."
|
||||||
|
(let ((map-sym (helm-get-mode-map-from-mode major-mode)))
|
||||||
|
(when (and map-sym (boundp map-sym))
|
||||||
|
(helm-M-x-get-major-mode-command-alist (symbol-value map-sym)))))
|
||||||
|
|
||||||
|
(defun helm-M-x-toggle-short-doc ()
|
||||||
|
"Toggle short doc display in helm-M-x."
|
||||||
|
(interactive)
|
||||||
|
(setq helm-M-x-show-short-doc (not helm-M-x-show-short-doc))
|
||||||
|
(helm-force-update (concat "^" (helm-get-selection)) (helm-get-current-source)))
|
||||||
|
(put 'helm-M-x-toggle-short-doc 'no-helm-mx t)
|
||||||
|
|
||||||
|
(defun helm-M-x-transformer-1 (candidates &optional sort ignore-props)
|
||||||
|
"Transformer function to show bindings in emacs commands.
|
||||||
|
Show global bindings and local bindings according to current
|
||||||
|
`major-mode'.
|
||||||
|
If SORT is non nil sort list with `helm-generic-sort-fn'.
|
||||||
|
Note that SORT should not be used when fuzzy matching because
|
||||||
|
fuzzy matching is running its own sort function with a different
|
||||||
|
algorithm."
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(cl-loop with local-map = (helm-M-x-current-mode-map-alist)
|
||||||
|
for cand in candidates
|
||||||
|
for local-key = (car (rassq cand local-map))
|
||||||
|
for key = (substitute-command-keys (format "\\[%s]" cand))
|
||||||
|
for sym = (intern (if (consp cand) (car cand) cand))
|
||||||
|
for doc = (when helm-M-x-show-short-doc
|
||||||
|
(helm-get-first-line-documentation (intern-soft cand)))
|
||||||
|
for disp = (if (or (eq sym major-mode)
|
||||||
|
(and (memq sym minor-mode-list)
|
||||||
|
(boundp sym)
|
||||||
|
(buffer-local-value
|
||||||
|
sym helm-current-buffer)))
|
||||||
|
(propertize cand 'face 'helm-command-active-mode)
|
||||||
|
cand)
|
||||||
|
unless (and (null ignore-props)
|
||||||
|
(or (get sym 'helm-only) (get sym 'no-helm-mx)))
|
||||||
|
collect
|
||||||
|
(cons (cond ((and (string-match "^M-x" key) local-key)
|
||||||
|
(propertize
|
||||||
|
(format "%s%s%s %s"
|
||||||
|
disp
|
||||||
|
(if doc (helm-make-separator cand) "")
|
||||||
|
(if doc
|
||||||
|
(propertize
|
||||||
|
doc 'face 'helm-M-x-short-doc)
|
||||||
|
"")
|
||||||
|
(propertize
|
||||||
|
" " 'display
|
||||||
|
(propertize local-key 'face 'helm-M-x-key)))
|
||||||
|
'match-part disp))
|
||||||
|
((and (string-match "^M-x" key)
|
||||||
|
(not (string= key "M-x")))
|
||||||
|
(propertize
|
||||||
|
(format "%s%s%s"
|
||||||
|
disp
|
||||||
|
(if doc (helm-make-separator cand) "")
|
||||||
|
(if doc
|
||||||
|
(propertize
|
||||||
|
doc 'face 'helm-M-x-short-doc)
|
||||||
|
""))
|
||||||
|
'match-part disp))
|
||||||
|
(t (propertize
|
||||||
|
(format "%s%s%s %s"
|
||||||
|
disp
|
||||||
|
(if doc (helm-make-separator cand) "")
|
||||||
|
(if doc
|
||||||
|
(propertize
|
||||||
|
doc 'face 'helm-M-x-short-doc)
|
||||||
|
"")
|
||||||
|
(propertize
|
||||||
|
" " 'display
|
||||||
|
(propertize key 'face 'helm-M-x-key)))
|
||||||
|
'match-part disp)))
|
||||||
|
cand)
|
||||||
|
into ls
|
||||||
|
finally return
|
||||||
|
(if sort (sort ls #'helm-generic-sort-fn) ls))))
|
||||||
|
|
||||||
|
(defun helm-M-x-transformer (candidates _source)
|
||||||
|
"Transformer function for `helm-M-x' candidates."
|
||||||
|
;; Generic sort function is handling helm-flex.
|
||||||
|
(helm-M-x-transformer-1 candidates (null helm--in-fuzzy)))
|
||||||
|
|
||||||
|
(defun helm-M-x-transformer-no-sort (candidates _source)
|
||||||
|
"Transformer function for `helm-M-x' candidates."
|
||||||
|
(helm-M-x-transformer-1 candidates))
|
||||||
|
|
||||||
|
(defun helm-M-x-transformer-no-sort-no-props (candidates _source)
|
||||||
|
"Transformer function for `helm-M-x' candidates."
|
||||||
|
(helm-M-x-transformer-1 candidates nil t))
|
||||||
|
|
||||||
|
(defun helm-M-x--notify-prefix-arg ()
|
||||||
|
;; Notify a prefix-arg set AFTER calling M-x.
|
||||||
|
(when prefix-arg
|
||||||
|
(with-helm-window
|
||||||
|
(helm-display-mode-line (helm-get-current-source) 'force))))
|
||||||
|
|
||||||
|
(defun helm-cmd--get-current-function-name ()
|
||||||
|
(save-excursion
|
||||||
|
(beginning-of-defun)
|
||||||
|
(cadr (split-string (buffer-substring-no-properties
|
||||||
|
(pos-bol) (pos-eol))))))
|
||||||
|
|
||||||
|
(defun helm-cmd--get-preconfigured-commands (&optional dir)
|
||||||
|
(let* ((helm-dir (or dir (helm-basedir (locate-library "helm"))))
|
||||||
|
(helm-autoload-file (expand-file-name "helm-autoloads.el" helm-dir))
|
||||||
|
results)
|
||||||
|
(when (file-exists-p helm-autoload-file)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents helm-autoload-file)
|
||||||
|
(while (re-search-forward "Preconfigured" nil t)
|
||||||
|
(push (substring (helm-cmd--get-current-function-name) 1) results))))
|
||||||
|
results))
|
||||||
|
|
||||||
|
(defun helm-M-x-universal-argument ()
|
||||||
|
"Same as `universal-argument' but for `helm-M-x'."
|
||||||
|
(interactive)
|
||||||
|
(if helm-M-x-prefix-argument
|
||||||
|
(progn (setq helm-M-x-prefix-argument nil)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(with-selected-window (minibuffer-window)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(delete-char (- (minibuffer-prompt-width) (length "M-x "))))))
|
||||||
|
(message "Initial prefix arg disabled"))
|
||||||
|
(setq prefix-arg (list 4))
|
||||||
|
(universal-argument--mode)))
|
||||||
|
(put 'helm-M-x-universal-argument 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-M-x-persistent-action (candidate)
|
||||||
|
(helm-elisp--persistent-help
|
||||||
|
candidate 'helm-describe-function))
|
||||||
|
|
||||||
|
(defun helm-M-x--move-selection-after-hook ()
|
||||||
|
(setq current-prefix-arg nil))
|
||||||
|
|
||||||
|
(defun helm-M-x--before-action-hook ()
|
||||||
|
(remove-hook 'helm-move-selection-after-hook
|
||||||
|
#'helm-M-x--move-selection-after-hook))
|
||||||
|
|
||||||
|
(defclass helm-M-x-class (helm-source-in-buffer helm-type-command)
|
||||||
|
((requires-pattern :initform 0)
|
||||||
|
(must-match :initform t)
|
||||||
|
(filtered-candidate-transformer :initform 'helm-M-x-transformer)
|
||||||
|
(persistent-help :initform "Describe this command")
|
||||||
|
(help-message :initform 'helm-M-x-help-message)
|
||||||
|
(nomark :initform t)
|
||||||
|
(cleanup :initform #'helm-M-x--unwind-forms)
|
||||||
|
(keymap :initform 'helm-M-x-map)
|
||||||
|
(resume :initform 'helm-M-x-resume-fn)))
|
||||||
|
|
||||||
|
(defun helm-M-x-resume-fn ()
|
||||||
|
(when (and helm-M-x--timer (timerp helm-M-x--timer))
|
||||||
|
(cancel-timer helm-M-x--timer)
|
||||||
|
(setq helm-M-x--timer nil))
|
||||||
|
(setq helm-M-x--timer (run-at-time 1 0.1 #'helm-M-x--notify-prefix-arg))
|
||||||
|
(setq helm--mode-line-display-prefarg t)
|
||||||
|
;; Prevent displaying a wrong prefix arg when helm-resume is called
|
||||||
|
;; from prefix arg.
|
||||||
|
(setq current-prefix-arg nil))
|
||||||
|
|
||||||
|
(defun helm-M-x-read-extended-command (collection &optional predicate history)
|
||||||
|
"Read or execute action on command name in COLLECTION or HISTORY.
|
||||||
|
|
||||||
|
Helm completion is not provided when executing or defining kbd macros.
|
||||||
|
|
||||||
|
Arg COLLECTION should be an `obarray'.
|
||||||
|
Arg PREDICATE is a function that default to `commandp'.
|
||||||
|
Arg HISTORY default to `extended-command-history'."
|
||||||
|
(setq helm--mode-line-display-prefarg t)
|
||||||
|
(let* ((pred (or predicate #'commandp))
|
||||||
|
(helm-fuzzy-sort-fn (lambda (candidates _source)
|
||||||
|
;; Sort on real candidate otherwise
|
||||||
|
;; "symbol (<binding>)" is used when sorting.
|
||||||
|
(helm-fuzzy-matching-default-sort-fn-1 candidates t)))
|
||||||
|
(sources `(,(helm-make-source "Emacs Commands history" 'helm-M-x-class
|
||||||
|
:data (lambda ()
|
||||||
|
(helm-comp-read-get-candidates
|
||||||
|
;; History should be quoted to
|
||||||
|
;; force `helm-comp-read-get-candidates'
|
||||||
|
;; to use predicate against
|
||||||
|
;; symbol and not string.
|
||||||
|
(or history 'extended-command-history)
|
||||||
|
;; Ensure using empty string to
|
||||||
|
;; not defeat helm matching fns [1]
|
||||||
|
pred nil nil ""))
|
||||||
|
:fuzzy-match helm-M-x-fuzzy-match)
|
||||||
|
,(helm-make-source "Emacs Commands" 'helm-M-x-class
|
||||||
|
:data (lambda ()
|
||||||
|
(helm-comp-read-get-candidates
|
||||||
|
;; [1] Same comment as above.
|
||||||
|
collection pred nil nil ""))
|
||||||
|
:fuzzy-match helm-M-x-fuzzy-match)))
|
||||||
|
(prompt (concat (helm-acase helm-M-x-prefix-argument
|
||||||
|
(- "-")
|
||||||
|
((guard (and (consp it) (car it)))
|
||||||
|
(if (eq guard 4) "C-u " (format "%d " guard)))
|
||||||
|
((guard (integerp it)) (format "%d " it)))
|
||||||
|
"M-x ")))
|
||||||
|
(setq helm-M-x--timer (run-at-time 1 0.1 #'helm-M-x--notify-prefix-arg))
|
||||||
|
;; Fix Bug#2250, add `helm-move-selection-after-hook' which
|
||||||
|
;; reset prefix arg to nil only for this helm session.
|
||||||
|
(add-hook 'helm-move-selection-after-hook
|
||||||
|
#'helm-M-x--move-selection-after-hook)
|
||||||
|
(add-hook 'helm-before-action-hook
|
||||||
|
#'helm-M-x--before-action-hook)
|
||||||
|
(when (and sources helm-M-x-reverse-history)
|
||||||
|
(setq sources (nreverse sources)))
|
||||||
|
(unwind-protect
|
||||||
|
(progn
|
||||||
|
(setq current-prefix-arg nil)
|
||||||
|
(helm :sources sources
|
||||||
|
:prompt prompt
|
||||||
|
:buffer "*helm M-x*"
|
||||||
|
:history 'helm-M-x-input-history
|
||||||
|
:truncate-lines t))
|
||||||
|
(helm-M-x--unwind-forms))))
|
||||||
|
|
||||||
|
;; When running a command involving again helm from helm-M-x, the
|
||||||
|
;; unwind-protect UNWINDS forms are executed only once this helm
|
||||||
|
;; command exit leaving the helm-M-x timer running and other variables
|
||||||
|
;; and hooks not unset, so the timer is now in a global var and all
|
||||||
|
;; the forms that should normally run in unwind-protect are running as
|
||||||
|
;; well as soon as helm-M-x-execute-command is called.
|
||||||
|
(defun helm-M-x--unwind-forms (&optional done)
|
||||||
|
;; helm-M-x--unwind-forms-done is non nil when it have been called
|
||||||
|
;; once from helm-M-x-execute-command.
|
||||||
|
(unless helm-M-x--unwind-forms-done
|
||||||
|
(when (timerp helm-M-x--timer)
|
||||||
|
(cancel-timer helm-M-x--timer)
|
||||||
|
(setq helm-M-x--timer nil))
|
||||||
|
(setq helm--mode-line-display-prefarg nil
|
||||||
|
helm-fuzzy-sort-fn (default-toplevel-value 'helm-fuzzy-sort-fn))
|
||||||
|
;; Be sure to remove it here as well in case of quit.
|
||||||
|
(remove-hook 'helm-move-selection-after-hook
|
||||||
|
#'helm-M-x--move-selection-after-hook)
|
||||||
|
(remove-hook 'helm-before-action-hook
|
||||||
|
#'helm-M-x--before-action-hook))
|
||||||
|
;; Reset helm-M-x--unwind-forms-done to nil when DONE is
|
||||||
|
;; unspecified.
|
||||||
|
(setq helm-M-x--unwind-forms-done done))
|
||||||
|
|
||||||
|
(defun helm-M-x-execute-command (command)
|
||||||
|
"Execute COMMAND as an editor command.
|
||||||
|
COMMAND must be a symbol that satisfies the `commandp' predicate.
|
||||||
|
Save COMMAND to `extended-command-history'."
|
||||||
|
(helm-M-x--unwind-forms t)
|
||||||
|
(when command
|
||||||
|
;; Avoid having `this-command' set to *exit-minibuffer.
|
||||||
|
(setq this-command command
|
||||||
|
;; Handle C-x z (repeat) Bug#322
|
||||||
|
real-this-command command)
|
||||||
|
;; If helm-M-x is called with regular emacs completion (kmacro)
|
||||||
|
;; use the value of arg otherwise use helm-current-prefix-arg.
|
||||||
|
(let ((prefix-arg (or helm-current-prefix-arg helm-M-x-prefix-argument))
|
||||||
|
(command-name (symbol-name command)))
|
||||||
|
(condition-case-unless-debug err
|
||||||
|
(progn
|
||||||
|
(command-execute command 'record)
|
||||||
|
(add-to-history 'extended-command-history command-name))
|
||||||
|
(error
|
||||||
|
(when helm-M-x-always-save-history
|
||||||
|
(add-to-history 'extended-command-history command-name))
|
||||||
|
(signal (car err) (cdr err)))))))
|
||||||
|
|
||||||
|
(defun helm-M-x--vanilla-M-x ()
|
||||||
|
(helm-M-x-execute-command
|
||||||
|
(intern-soft
|
||||||
|
(if helm-mode
|
||||||
|
(unwind-protect
|
||||||
|
(progn
|
||||||
|
(helm-mode -1)
|
||||||
|
(read-extended-command))
|
||||||
|
(helm-mode 1))
|
||||||
|
(read-extended-command)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-M-x (_arg)
|
||||||
|
"Preconfigured `helm' for Emacs commands.
|
||||||
|
It is `helm' replacement of regular `M-x'
|
||||||
|
`execute-extended-command'.
|
||||||
|
|
||||||
|
Unlike regular `M-x' Emacs vanilla `execute-extended-command'
|
||||||
|
command, the prefix args if needed, can be passed AFTER starting
|
||||||
|
`helm-M-x'. When a prefix arg is passed BEFORE starting
|
||||||
|
`helm-M-x', the first `C-u' while in `helm-M-x' session will
|
||||||
|
disable it.
|
||||||
|
|
||||||
|
You can get help on each command by persistent action."
|
||||||
|
(interactive
|
||||||
|
(progn
|
||||||
|
(setq helm-M-x-prefix-argument current-prefix-arg)
|
||||||
|
(list current-prefix-arg)))
|
||||||
|
(if (or defining-kbd-macro executing-kbd-macro)
|
||||||
|
(helm-M-x--vanilla-M-x)
|
||||||
|
(helm-M-x-read-extended-command obarray)))
|
||||||
|
(put 'helm-M-x 'interactive-only 'command-execute)
|
||||||
|
|
||||||
|
(provide 'helm-command)
|
||||||
|
|
||||||
|
;;; helm-command.el ends here
|
388
code/elpa/helm-20240320.541/helm-dabbrev.el
Normal file
388
code/elpa/helm-20240320.541/helm-dabbrev.el
Normal file
|
@ -0,0 +1,388 @@
|
||||||
|
;;; helm-dabbrev.el --- Helm implementation of dabbrev. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-lib)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-elisp) ; For show-completion.
|
||||||
|
|
||||||
|
(defgroup helm-dabbrev nil
|
||||||
|
"Dabbrev related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-always-search-all t
|
||||||
|
"Always search in all buffers when non--nil.
|
||||||
|
Note that even if nil, a search in all buffers will occur if the
|
||||||
|
length of candidates is <= than
|
||||||
|
`helm-dabbrev-max-length-result'."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-candidates-number-limit 1000
|
||||||
|
"Maximum number of candidates to collect.
|
||||||
|
|
||||||
|
The higher this number is, the slower the computation of
|
||||||
|
candidates will be. You can use safely a higher value with
|
||||||
|
emacs-26+.
|
||||||
|
Note that this have nothing to do with
|
||||||
|
`helm-candidate-number-limit', this means that computation of
|
||||||
|
candidates stop when this value is reached but only
|
||||||
|
`helm-candidate-number-limit' candidates are displayed in the
|
||||||
|
Helm buffer."
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-ignored-buffers-regexps
|
||||||
|
'("\\*helm" "\\*Messages" "\\*Echo Area" "\\*Buffer List")
|
||||||
|
"List of regexps matching names of buffers that `helm-dabbrev' should not check."
|
||||||
|
:type '(repeat regexp))
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-related-buffer-fn #'helm-dabbrev--same-major-mode-p
|
||||||
|
"A function that decide if a buffer to search in its related to `current-buffer'.
|
||||||
|
|
||||||
|
This is actually determined by comparing `major-mode' of the
|
||||||
|
buffer to search and the `current-buffer'.
|
||||||
|
|
||||||
|
The function take one arg, the buffer which is current, look at
|
||||||
|
`helm-dabbrev--same-major-mode-p' for an example.
|
||||||
|
|
||||||
|
When nil all buffers are considered related to `current-buffer'."
|
||||||
|
:type 'function)
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-major-mode-assoc nil
|
||||||
|
"Major mode association alist.
|
||||||
|
|
||||||
|
This allow helm-dabbrev searching in buffers with the associated
|
||||||
|
`major-mode'.
|
||||||
|
E.g. (emacs-lisp-mode . lisp-interaction-mode)
|
||||||
|
|
||||||
|
will allow searching in the lisp-interaction-mode buffer when
|
||||||
|
`current-buffer' is an `emacs-lisp-mode' buffer and vice versa
|
||||||
|
i.e. no need to provide (lisp-interaction-mode .
|
||||||
|
emacs-lisp-mode) association.
|
||||||
|
|
||||||
|
When nil check is the searched buffer has same `major-mode' than
|
||||||
|
the `current-buffer'.
|
||||||
|
|
||||||
|
This has no effect when `helm-dabbrev-related-buffer-fn' is nil
|
||||||
|
or of course bound to a function that doesn't handle this var."
|
||||||
|
:type '(alist :key-type symbol :value-type symbol))
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-lineno-around 30
|
||||||
|
"Search first in this number of lines before and after point."
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-cycle-threshold 5
|
||||||
|
"Number of time helm-dabbrev cycle before displaying helm completion.
|
||||||
|
When nil or 0 disable cycling."
|
||||||
|
:type '(choice (const :tag "Cycling disabled" nil) integer))
|
||||||
|
|
||||||
|
(defcustom helm-dabbrev-case-fold-search 'smart
|
||||||
|
"Set `case-fold-search' in `helm-dabbrev'.
|
||||||
|
Same as `helm-case-fold-search' but for `helm-dabbrev'.
|
||||||
|
Note that this is not affecting searching in Helm buffer, but the
|
||||||
|
initial search for all candidates in buffer(s)."
|
||||||
|
:type '(choice (const :tag "Ignore case" t)
|
||||||
|
(const :tag "Respect case" nil)
|
||||||
|
(other :tag "Smart" smart)))
|
||||||
|
|
||||||
|
(defvaralias 'helm-dabbrev--regexp 'helm-dabbrev-separator-regexp)
|
||||||
|
(make-obsolete-variable 'helm-dabbrev--regexp
|
||||||
|
'helm-dabbrev-separator-regexp "2.8.3")
|
||||||
|
;; Check for beginning of line should happen last (^\n\\|^).
|
||||||
|
(defvar helm-dabbrev-separator-regexp
|
||||||
|
"\\s-\\|\t\\|[(\\[\\{\"'`=<>$;,@.#+]\\|\\s\\\\|^\n\\|^"
|
||||||
|
"Regexp matching the start of a dabbrev candidate.")
|
||||||
|
|
||||||
|
|
||||||
|
(defvar helm-dabbrev-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "M-/") #'helm-next-line)
|
||||||
|
(define-key map (kbd "M-:") #'helm-previous-line)
|
||||||
|
map))
|
||||||
|
|
||||||
|
;; Internal
|
||||||
|
(defvar helm-dabbrev--cache nil)
|
||||||
|
(defvar helm-dabbrev--data nil)
|
||||||
|
(cl-defstruct helm-dabbrev-info dabbrev limits iterator)
|
||||||
|
(defvar helm-dabbrev--already-tried nil)
|
||||||
|
(defvar helm-dabbrev--computing-cache nil
|
||||||
|
"[INTERNAL] Flag to notify helm-dabbrev is blocked.
|
||||||
|
Do nothing when non nil.")
|
||||||
|
|
||||||
|
(defun helm-dabbrev--buffer-list ()
|
||||||
|
(cl-loop for buf in (buffer-list)
|
||||||
|
unless (cl-loop for r in helm-dabbrev-ignored-buffers-regexps
|
||||||
|
thereis (string-match r (buffer-name buf)))
|
||||||
|
collect buf))
|
||||||
|
|
||||||
|
(defun helm-dabbrev--same-major-mode-p (start-buffer)
|
||||||
|
"Decide if current-buffer is related to START-BUFFER."
|
||||||
|
(helm-same-major-mode-p start-buffer helm-dabbrev-major-mode-assoc))
|
||||||
|
|
||||||
|
(defun helm-dabbrev--collect (str limit ignore-case all)
|
||||||
|
(let* ((case-fold-search ignore-case)
|
||||||
|
(buffer1 (current-buffer)) ; start buffer.
|
||||||
|
(minibuf (minibufferp buffer1))
|
||||||
|
results pos-before pos-after)
|
||||||
|
(catch 'break
|
||||||
|
(dolist (buf (if all (helm-dabbrev--buffer-list)
|
||||||
|
(list (current-buffer))))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(when (or minibuf ; check against all buffers when in minibuffer.
|
||||||
|
(if helm-dabbrev-related-buffer-fn
|
||||||
|
(funcall helm-dabbrev-related-buffer-fn buffer1)
|
||||||
|
t))
|
||||||
|
(save-excursion
|
||||||
|
;; Start searching before thing before point.
|
||||||
|
(goto-char (- (point) (length str)))
|
||||||
|
;; Search the last 30 lines BEFORE point and set POS-BEFORE.
|
||||||
|
(cl-multiple-value-bind (res _pa pb)
|
||||||
|
(helm-dabbrev--search-and-store str -2 limit results)
|
||||||
|
(setq results res
|
||||||
|
;; No need to set POS-AFTER here.
|
||||||
|
pos-before pb)))
|
||||||
|
(save-excursion
|
||||||
|
;; Search the next 30 lines AFTER point and set POS-AFTER.
|
||||||
|
(cl-multiple-value-bind (res pa _pb)
|
||||||
|
(helm-dabbrev--search-and-store str 2 limit results)
|
||||||
|
(setq results res
|
||||||
|
;; No need to set POS-BEFORE, we keep the last
|
||||||
|
;; value found.
|
||||||
|
pos-after pa)))
|
||||||
|
(save-excursion
|
||||||
|
;; Search all BEFORE point maybe starting from
|
||||||
|
;; POS-BEFORE to not search again what previously found.
|
||||||
|
;; If limit is reached in previous call of
|
||||||
|
;; `helm-dabbrev--search-and-store' POS-BEFORE is nil and
|
||||||
|
;; goto-char will fail, so check it.
|
||||||
|
(when pos-before (goto-char pos-before))
|
||||||
|
(cl-multiple-value-bind (res _pa _pb)
|
||||||
|
(helm-dabbrev--search-and-store str -1 limit results)
|
||||||
|
;; No need to set POS-BEFORE and POS-AFTER here.
|
||||||
|
(setq results res)))
|
||||||
|
(save-excursion
|
||||||
|
;; Search all AFTER point maybe starting from POS-AFTER.
|
||||||
|
;; Same comment as above for POS-AFTER.
|
||||||
|
(when pos-after (goto-char pos-after))
|
||||||
|
(cl-multiple-value-bind (res _pa _pb)
|
||||||
|
(helm-dabbrev--search-and-store str 1 limit results)
|
||||||
|
;; No need to set POS-BEFORE and POS-AFTER here.
|
||||||
|
(setq results res)))))
|
||||||
|
(when (>= (length results) limit) (throw 'break nil))))
|
||||||
|
(nreverse results)))
|
||||||
|
|
||||||
|
(defun helm-dabbrev--search-and-store (pattern direction limit results)
|
||||||
|
"Search words or symbols matching PATTERN in DIRECTION up to LIMIT.
|
||||||
|
Finally returns all matched candidates appended to RESULTS.
|
||||||
|
Argument DIRECTION can be:
|
||||||
|
- (1): Search forward from point.
|
||||||
|
- (-1): Search backward from point.
|
||||||
|
- (2): Search forward from the
|
||||||
|
`helm-dabbrev-lineno-around'
|
||||||
|
lines after point.
|
||||||
|
- (-2): Search backward from the
|
||||||
|
`helm-dabbrev-lineno-around'
|
||||||
|
lines before point."
|
||||||
|
(let ((res results)
|
||||||
|
after before)
|
||||||
|
(while (and (<= (length res) limit)
|
||||||
|
(cl-case direction
|
||||||
|
(1 (search-forward pattern nil t))
|
||||||
|
(-1 (search-backward pattern nil t))
|
||||||
|
(2 (let ((pos
|
||||||
|
(save-excursion
|
||||||
|
(forward-line
|
||||||
|
helm-dabbrev-lineno-around)
|
||||||
|
(point))))
|
||||||
|
(setq after pos)
|
||||||
|
(search-forward pattern pos t)))
|
||||||
|
(-2 (let ((pos
|
||||||
|
(save-excursion
|
||||||
|
(forward-line
|
||||||
|
(- helm-dabbrev-lineno-around))
|
||||||
|
(point))))
|
||||||
|
(setq before pos)
|
||||||
|
(search-backward pattern pos t)))))
|
||||||
|
(let* ((mb (match-beginning 0))
|
||||||
|
(replace-regexp (concat "\\(" helm-dabbrev-separator-regexp
|
||||||
|
"\\)\\'"))
|
||||||
|
(match-word (helm-dabbrev--search
|
||||||
|
pattern mb replace-regexp)))
|
||||||
|
(when (and match-word (not (member match-word res)))
|
||||||
|
(push match-word res))))
|
||||||
|
(list res after before)))
|
||||||
|
|
||||||
|
(defun helm-dabbrev--search (pattern beg sep-regexp)
|
||||||
|
"Search word or symbol at point matching PATTERN.
|
||||||
|
Argument BEG is corresponding to the previous `match-beginning'
|
||||||
|
search.
|
||||||
|
The search starts at (1- BEG) with a regexp starting with
|
||||||
|
`helm-dabbrev-separator-regexp' followed by PATTERN followed by a
|
||||||
|
regexp matching syntactically any word or symbol.
|
||||||
|
The possible false positives matching SEP-REGEXP at end are
|
||||||
|
finally removed."
|
||||||
|
(let ((eol (pos-eol)))
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (1- beg))
|
||||||
|
(when (re-search-forward
|
||||||
|
(concat "\\("
|
||||||
|
helm-dabbrev-separator-regexp
|
||||||
|
"\\)"
|
||||||
|
"\\(?99:\\("
|
||||||
|
(regexp-quote pattern)
|
||||||
|
"\\(\\sw\\|\\s_\\)+\\)\\)")
|
||||||
|
eol t)
|
||||||
|
(replace-regexp-in-string
|
||||||
|
sep-regexp ""
|
||||||
|
(match-string-no-properties 99))))))
|
||||||
|
|
||||||
|
(defun helm-dabbrev--get-candidates (dabbrev &optional limit)
|
||||||
|
(cl-assert dabbrev nil "[No Match]")
|
||||||
|
(helm-dabbrev--collect
|
||||||
|
dabbrev (or limit helm-dabbrev-candidates-number-limit)
|
||||||
|
(cl-case helm-dabbrev-case-fold-search
|
||||||
|
(smart (helm-set-case-fold-search-1 dabbrev))
|
||||||
|
(t helm-dabbrev-case-fold-search))
|
||||||
|
helm-dabbrev-always-search-all))
|
||||||
|
|
||||||
|
(defun helm-dabbrev-default-action (candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(let* ((limits (helm-bounds-of-thing-before-point
|
||||||
|
helm-dabbrev-separator-regexp))
|
||||||
|
(beg (car limits))
|
||||||
|
(end (point)))
|
||||||
|
(run-with-timer
|
||||||
|
0.01 nil
|
||||||
|
#'helm-insert-completion-at-point
|
||||||
|
beg end candidate))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(cl-defun helm-dabbrev ()
|
||||||
|
"Preconfigured helm for dynamic abbreviations."
|
||||||
|
(interactive)
|
||||||
|
(unless helm-dabbrev--computing-cache
|
||||||
|
(let ((dabbrev (helm-thing-before-point
|
||||||
|
nil helm-dabbrev-separator-regexp))
|
||||||
|
(limits (helm-bounds-of-thing-before-point
|
||||||
|
helm-dabbrev-separator-regexp))
|
||||||
|
(enable-recursive-minibuffers t)
|
||||||
|
(cycling-disabled-p (or (null helm-dabbrev-cycle-threshold)
|
||||||
|
(zerop helm-dabbrev-cycle-threshold)))
|
||||||
|
(helm-execute-action-at-once-if-one t)
|
||||||
|
(helm-quit-if-no-candidate
|
||||||
|
(lambda ()
|
||||||
|
(message "[Helm-dabbrev: No expansion found]"))))
|
||||||
|
(cl-assert (and (stringp dabbrev) (not (string= dabbrev "")))
|
||||||
|
nil "[Helm-dabbrev: Nothing found before point]")
|
||||||
|
(when (and
|
||||||
|
;; have been called at least once.
|
||||||
|
(helm-dabbrev-info-p helm-dabbrev--data)
|
||||||
|
;; But user have moved with some other command
|
||||||
|
;; in the meaning time.
|
||||||
|
(not (eq last-command 'helm-dabbrev)))
|
||||||
|
(setq helm-dabbrev--data nil))
|
||||||
|
;; When candidates are requested in helm directly without cycling,
|
||||||
|
;; we need them right now before running helm.
|
||||||
|
(when cycling-disabled-p
|
||||||
|
(message "Waiting for helm-dabbrev candidates...")
|
||||||
|
(setq helm-dabbrev--cache (helm-dabbrev--get-candidates dabbrev)))
|
||||||
|
(unless (or cycling-disabled-p
|
||||||
|
(helm-dabbrev-info-p helm-dabbrev--data))
|
||||||
|
(setq helm-dabbrev--data
|
||||||
|
(make-helm-dabbrev-info
|
||||||
|
:dabbrev dabbrev
|
||||||
|
:limits limits
|
||||||
|
:iterator
|
||||||
|
(helm-iter-list
|
||||||
|
(cl-loop for i in (helm-dabbrev--get-candidates
|
||||||
|
dabbrev helm-dabbrev-cycle-threshold)
|
||||||
|
when (string-match-p
|
||||||
|
(concat "^" (regexp-quote dabbrev)) i)
|
||||||
|
collect i)))))
|
||||||
|
(let ((iter (and (helm-dabbrev-info-p helm-dabbrev--data)
|
||||||
|
(helm-dabbrev-info-iterator helm-dabbrev--data)))
|
||||||
|
deactivate-mark)
|
||||||
|
;; Cycle until iterator is consumed.
|
||||||
|
(helm-aif (and iter (helm-iter-next iter))
|
||||||
|
(progn
|
||||||
|
(helm-insert-completion-at-point
|
||||||
|
(car (helm-dabbrev-info-limits helm-dabbrev--data))
|
||||||
|
;; END is the end of the previous inserted string, not
|
||||||
|
;; the end (apart for first insertion) of the initial string.
|
||||||
|
(cdr limits) it)
|
||||||
|
;; Move already tried candidates to end of list.
|
||||||
|
(push it helm-dabbrev--already-tried))
|
||||||
|
;; Iterator is now empty, or cycling was disabled, maybe
|
||||||
|
;; reset dabbrev to initial value and start helm completion.
|
||||||
|
(let* ((old-dabbrev (if (helm-dabbrev-info-p helm-dabbrev--data)
|
||||||
|
(helm-dabbrev-info-dabbrev helm-dabbrev--data)
|
||||||
|
dabbrev))
|
||||||
|
(only-one (eq (length helm-dabbrev--already-tried) 1)))
|
||||||
|
(unless helm-dabbrev--cache ; Already computed when
|
||||||
|
; cycling is disabled.
|
||||||
|
(message "Waiting for helm-dabbrev candidates...")
|
||||||
|
(setq helm-dabbrev--computing-cache t)
|
||||||
|
(setq helm-dabbrev--cache
|
||||||
|
(helm-dabbrev--get-candidates old-dabbrev))
|
||||||
|
;; If user continues typing M-/ while display is blocked by
|
||||||
|
;; helm-dabbrev--get-candidates delete these events.
|
||||||
|
(setq unread-command-events nil))
|
||||||
|
;; If the length of candidates is only one when computed
|
||||||
|
;; that's mean the unique matched item have already been
|
||||||
|
;; inserted by the iterator, so no need to reinsert the old dabbrev,
|
||||||
|
;; just let helm exiting with "No expansion found".
|
||||||
|
(unless (or only-one cycling-disabled-p)
|
||||||
|
(setq dabbrev old-dabbrev
|
||||||
|
limits (helm-dabbrev-info-limits helm-dabbrev--data))
|
||||||
|
(setq helm-dabbrev--data nil)
|
||||||
|
(delete-region (car limits) (point))
|
||||||
|
(insert dabbrev))
|
||||||
|
(when (and (null cycling-disabled-p) only-one)
|
||||||
|
(setq helm-dabbrev--cache nil
|
||||||
|
helm-dabbrev--already-tried nil
|
||||||
|
helm-dabbrev--computing-cache nil)
|
||||||
|
(cl-return-from helm-dabbrev
|
||||||
|
(message "[Helm-dabbrev: No expansion found]")))
|
||||||
|
(with-helm-show-completion (car limits) (cdr limits)
|
||||||
|
(unwind-protect
|
||||||
|
(helm :sources
|
||||||
|
(helm-build-in-buffer-source "Dabbrev Expand"
|
||||||
|
:data
|
||||||
|
(append
|
||||||
|
(cl-loop with lst = helm-dabbrev--cache
|
||||||
|
for cand in helm-dabbrev--already-tried
|
||||||
|
do (setq lst (delete cand lst))
|
||||||
|
finally return lst)
|
||||||
|
helm-dabbrev--already-tried)
|
||||||
|
:persistent-action 'ignore
|
||||||
|
:persistent-help "DoNothing"
|
||||||
|
:keymap helm-dabbrev-map
|
||||||
|
:action 'helm-dabbrev-default-action
|
||||||
|
:group 'helm-dabbrev)
|
||||||
|
:buffer "*helm dabbrev*"
|
||||||
|
:input (concat "^" dabbrev " ")
|
||||||
|
:resume 'noresume
|
||||||
|
:allow-nest t)
|
||||||
|
(setq helm-dabbrev--computing-cache nil
|
||||||
|
helm-dabbrev--already-tried nil
|
||||||
|
helm-dabbrev--cache nil)))))))))
|
||||||
|
|
||||||
|
(provide 'helm-dabbrev)
|
||||||
|
|
||||||
|
;;; helm-dabbrev.el ends here
|
84
code/elpa/helm-20240320.541/helm-easymenu.el
Normal file
84
code/elpa/helm-20240320.541/helm-easymenu.el
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
;;; helm-easymenu.el --- Helm easymenu definitions. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'easymenu)
|
||||||
|
|
||||||
|
(easy-menu-add-item
|
||||||
|
nil '("Tools")
|
||||||
|
'("Helm"
|
||||||
|
["Find any Files/Buffers" helm-multi-files t]
|
||||||
|
["Helm Everywhere (Toggle)" helm-mode t]
|
||||||
|
["Helm resume" helm-resume t]
|
||||||
|
"----"
|
||||||
|
("Files"
|
||||||
|
["Find files" helm-find-files t]
|
||||||
|
["Recent Files" helm-recentf t]
|
||||||
|
["Locate" helm-locate t]
|
||||||
|
["Search Files with find" helm-find t]
|
||||||
|
["Bookmarks" helm-filtered-bookmarks t]
|
||||||
|
["Locate library" helm-locate-library t])
|
||||||
|
("Buffers"
|
||||||
|
["Find buffers" helm-buffers-list t])
|
||||||
|
("Projects"
|
||||||
|
["Browse project" helm-browse-project]
|
||||||
|
["Projects history" helm-projects-history])
|
||||||
|
("Commands"
|
||||||
|
["Emacs Commands" helm-M-x t]
|
||||||
|
["Externals Commands" helm-run-external-command t])
|
||||||
|
("Help"
|
||||||
|
["Helm Apropos" helm-apropos t])
|
||||||
|
("Info"
|
||||||
|
["Info at point" helm-info-at-point t]
|
||||||
|
["Emacs Manual index" helm-info-emacs t]
|
||||||
|
["Gnus Manual index" helm-info-gnus t]
|
||||||
|
["Helm documentation" helm-documentation t])
|
||||||
|
("Elpa"
|
||||||
|
["Elisp packages" helm-packages t])
|
||||||
|
("Tools"
|
||||||
|
["Occur" helm-occur t]
|
||||||
|
["Grep current directory with AG" helm-do-grep-ag t]
|
||||||
|
["Gid" helm-gid t]
|
||||||
|
["Etags" helm-etags-select t]
|
||||||
|
["Lisp complete at point" helm-lisp-completion-at-point t]
|
||||||
|
["Browse Kill ring" helm-show-kill-ring t]
|
||||||
|
["Browse register" helm-register t]
|
||||||
|
["Mark Ring" helm-all-mark-rings t]
|
||||||
|
["Regexp handler" helm-regexp t]
|
||||||
|
["Colors & Faces" helm-colors t]
|
||||||
|
["Show xfonts" helm-select-xfont t]
|
||||||
|
["Ucs Symbols" helm-ucs t]
|
||||||
|
["Imenu" helm-imenu t]
|
||||||
|
["Imenu all" helm-imenu-in-all-buffers t]
|
||||||
|
["Semantic or Imenu" helm-semantic-or-imenu t]
|
||||||
|
["Google Suggest" helm-google-suggest t]
|
||||||
|
["Eval expression" helm-eval-expression-with-eldoc t]
|
||||||
|
["Calcul expression" helm-calcul-expression t]
|
||||||
|
["Man pages" helm-man-woman t]
|
||||||
|
["Top externals process" helm-top t]
|
||||||
|
["Emacs internals process" helm-list-emacs-process t])
|
||||||
|
"----"
|
||||||
|
["Preferred Options" helm-configuration t])
|
||||||
|
"Spell Checking")
|
||||||
|
|
||||||
|
(easy-menu-add-item nil '("Tools") '("----") "Spell Checking")
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'helm-easymenu)
|
||||||
|
|
||||||
|
;;; helm-easymenu.el ends here
|
1167
code/elpa/helm-20240320.541/helm-elisp.el
Normal file
1167
code/elpa/helm-20240320.541/helm-elisp.el
Normal file
File diff suppressed because it is too large
Load diff
258
code/elpa/helm-20240320.541/helm-epa.el
Normal file
258
code/elpa/helm-20240320.541/helm-epa.el
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
;;; helm-epa.el --- helm interface for epa/epg -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto <thievol@posteo.net>
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm)
|
||||||
|
|
||||||
|
(eval-when-compile (require 'epg))
|
||||||
|
(defvar epa-protocol)
|
||||||
|
(defvar epa-last-coding-system-specified)
|
||||||
|
(defvar epg-key-validity-alist)
|
||||||
|
(defvar mail-header-separator)
|
||||||
|
(declare-function epg-list-keys "epg")
|
||||||
|
(declare-function epg-make-context "epg")
|
||||||
|
(declare-function epg-key-sub-key-list "epg")
|
||||||
|
(declare-function epg-sub-key-id "epg")
|
||||||
|
(declare-function epg-key-user-id-list "epg")
|
||||||
|
(declare-function epg-user-id-string "epg")
|
||||||
|
(declare-function epg-user-id-validity "epg")
|
||||||
|
(declare-function epa-sign-region "epa")
|
||||||
|
(declare-function epa--read-signature-type "epa")
|
||||||
|
(declare-function epa-display-error "epa")
|
||||||
|
(declare-function epg-export-keys-to-string "epg")
|
||||||
|
(declare-function epg-context-armor "epg")
|
||||||
|
(declare-function epg-context-set-armor "epg")
|
||||||
|
(declare-function epg-delete-keys "epg")
|
||||||
|
(declare-function helm-read-file-name "helm-mode")
|
||||||
|
|
||||||
|
(defvar helm-epa--list-only-secrets nil
|
||||||
|
"[INTERNAL] Used to pass MODE argument to `epg-list-keys'.")
|
||||||
|
|
||||||
|
(defcustom helm-epa-actions '(("Show key" . epa--show-key)
|
||||||
|
("encrypt file with key" . helm-epa-encrypt-file)
|
||||||
|
("Copy keys to kill ring" . helm-epa-kill-keys-armor)
|
||||||
|
("Delete keys" . helm-epa-delete-keys))
|
||||||
|
"Actions for `helm-epa-list-keys'."
|
||||||
|
:type '(alist :key-type string :value-type symbol)
|
||||||
|
:group 'helm-misc)
|
||||||
|
|
||||||
|
(defclass helm-epa (helm-source-sync)
|
||||||
|
((init :initform (lambda ()
|
||||||
|
(require 'epg)
|
||||||
|
(require 'epa)))
|
||||||
|
(candidates :initform 'helm-epa-get-key-list)
|
||||||
|
(keymap :initform 'helm-comp-read-map)
|
||||||
|
(mode-line :initform 'helm-comp-read-mode-line))
|
||||||
|
"Allow building helm sources for GPG keys.")
|
||||||
|
|
||||||
|
(defun helm-epa-get-key-list (&optional keys)
|
||||||
|
"Build candidate list for `helm-epa-list-keys'."
|
||||||
|
(cl-loop with all-keys = (or keys (epg-list-keys (epg-make-context epa-protocol)
|
||||||
|
nil helm-epa--list-only-secrets))
|
||||||
|
for key in all-keys
|
||||||
|
for sublist = (car (epg-key-sub-key-list key))
|
||||||
|
for subkey-id = (epg-sub-key-id sublist)
|
||||||
|
for uid-list = (epg-key-user-id-list key)
|
||||||
|
for uid = (epg-user-id-string (car uid-list))
|
||||||
|
for validity = (epg-user-id-validity (car uid-list))
|
||||||
|
collect (cons (format " %s %s %s"
|
||||||
|
(helm-aif (rassq validity epg-key-validity-alist)
|
||||||
|
(string (car it))
|
||||||
|
"?")
|
||||||
|
(propertize
|
||||||
|
subkey-id
|
||||||
|
'face (cl-case validity
|
||||||
|
(none 'epa-validity-medium)
|
||||||
|
((revoked expired)
|
||||||
|
'epa-validity-disabled)
|
||||||
|
(t 'epa-validity-high)))
|
||||||
|
(propertize
|
||||||
|
uid 'face 'font-lock-warning-face))
|
||||||
|
key)))
|
||||||
|
|
||||||
|
(cl-defun helm-epa--select-keys (prompt keys)
|
||||||
|
"A helm replacement for `epa--select-keys'."
|
||||||
|
(let ((result (helm :sources (helm-make-source "Epa select keys" 'helm-epa
|
||||||
|
:candidates (lambda ()
|
||||||
|
(helm-epa-get-key-list keys))
|
||||||
|
:action (lambda (_candidate)
|
||||||
|
(helm-marked-candidates)))
|
||||||
|
:prompt (and prompt (helm-epa--format-prompt prompt))
|
||||||
|
:buffer "*helm epa*")))
|
||||||
|
(if (or (equal result "") (null result))
|
||||||
|
(cl-return-from helm-epa--select-keys
|
||||||
|
(error "No keys selected, aborting"))
|
||||||
|
result)))
|
||||||
|
|
||||||
|
(defun helm-epa--format-prompt (prompt)
|
||||||
|
(let ((split (split-string prompt "\n")))
|
||||||
|
(if (cdr split)
|
||||||
|
(format "%s\n(%s): "
|
||||||
|
(replace-regexp-in-string "\\.[\t ]*\\'" "" (car split))
|
||||||
|
(replace-regexp-in-string "\\.[\t ]*\\'" "" (cadr split)))
|
||||||
|
(format "%s: " (replace-regexp-in-string "\\.[\t ]*\\'" "" (car split))))))
|
||||||
|
|
||||||
|
(defun helm-epa--read-signature-type ()
|
||||||
|
"A helm replacement for `epa--read-signature-type'."
|
||||||
|
(let ((answer (helm-read-answer "Signature type:
|
||||||
|
(n - Create a normal signature)
|
||||||
|
(c - Create a cleartext signature)
|
||||||
|
(d - Create a detached signature)"
|
||||||
|
'("n" "c" "d"))))
|
||||||
|
(helm-acase answer
|
||||||
|
("n" 'normal)
|
||||||
|
("c" 'clear)
|
||||||
|
("d" 'detached))))
|
||||||
|
|
||||||
|
(defun helm-epa-collect-keys-from-candidates (candidates)
|
||||||
|
(cl-loop for c in candidates
|
||||||
|
collect (epg-sub-key-id
|
||||||
|
(car (epg-key-sub-key-list c)))))
|
||||||
|
|
||||||
|
(defun helm-epa-collect-id-from-candidates (candidates)
|
||||||
|
(cl-loop for c in candidates
|
||||||
|
collect (epg-user-id-string
|
||||||
|
(car (epg-key-user-id-list c)))))
|
||||||
|
|
||||||
|
(defun helm-epa-success-message (str keys ids)
|
||||||
|
(message str
|
||||||
|
(mapconcat (lambda (pair)
|
||||||
|
(concat (car pair) " " (cdr pair)))
|
||||||
|
(cl-loop for k in keys
|
||||||
|
for i in ids
|
||||||
|
collect (cons k i))
|
||||||
|
"\n")))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode helm-epa-mode
|
||||||
|
"Enable helm completion on gpg keys in epa functions."
|
||||||
|
:group 'helm-misc
|
||||||
|
:global t
|
||||||
|
(require 'epa)
|
||||||
|
(if helm-epa-mode
|
||||||
|
(progn
|
||||||
|
(advice-add 'epa--select-keys :override #'helm-epa--select-keys)
|
||||||
|
(advice-add 'epa--read-signature-type :override #'helm-epa--read-signature-type))
|
||||||
|
(advice-remove 'epa--select-keys #'helm-epa--select-keys)
|
||||||
|
(advice-remove 'epa--read-signature-type #'helm-epa--read-signature-type)))
|
||||||
|
|
||||||
|
(defun helm-epa-action-transformer (actions _candidate)
|
||||||
|
"Helm epa action transformer function."
|
||||||
|
(cond ((with-helm-current-buffer
|
||||||
|
(derived-mode-p 'message-mode 'mail-mode))
|
||||||
|
(helm-append-at-nth
|
||||||
|
actions '(("Sign mail with key" . helm-epa-mail-sign)
|
||||||
|
("Encrypt mail with key" . helm-epa-mail-encrypt))
|
||||||
|
3))
|
||||||
|
(t actions)))
|
||||||
|
|
||||||
|
(defun helm-epa-delete-keys (_candidate)
|
||||||
|
"Delete gpg marked keys from helm-epa."
|
||||||
|
(let ((context (epg-make-context epa-protocol))
|
||||||
|
(keys (helm-marked-candidates)))
|
||||||
|
(message "Deleting gpg keys..")
|
||||||
|
(condition-case error
|
||||||
|
(epg-delete-keys context keys)
|
||||||
|
(error
|
||||||
|
(epa-display-error context)
|
||||||
|
(signal (car error) (cdr error))))
|
||||||
|
(message "Deleting gpg keys done")))
|
||||||
|
|
||||||
|
(defun helm-epa-encrypt-file (_candidate)
|
||||||
|
"Select a file to encrypt with key CANDIDATE."
|
||||||
|
(let* ((file (helm-read-file-name "Encrypt file: "))
|
||||||
|
(cands (helm-marked-candidates))
|
||||||
|
(keys (helm-epa-collect-keys-from-candidates cands))
|
||||||
|
(ids (helm-epa-collect-id-from-candidates cands)))
|
||||||
|
(epa-encrypt-file file cands)
|
||||||
|
(helm-epa-success-message "File encrypted with key(s):\n %s"
|
||||||
|
keys ids)))
|
||||||
|
|
||||||
|
(defun helm-epa-kill-keys-armor (_candidate)
|
||||||
|
"Copy marked keys to kill ring."
|
||||||
|
(let ((keys (helm-marked-candidates))
|
||||||
|
(context (epg-make-context epa-protocol)))
|
||||||
|
(with-no-warnings
|
||||||
|
(setf (epg-context-armor context) t))
|
||||||
|
(condition-case error
|
||||||
|
(kill-new (epg-export-keys-to-string context keys))
|
||||||
|
(error
|
||||||
|
(epa-display-error context)
|
||||||
|
(signal (car error) (cdr error))))))
|
||||||
|
|
||||||
|
(defun helm-epa-mail-sign (candidate)
|
||||||
|
"Sign email with key CANDIDATE."
|
||||||
|
(let ((key (epg-sub-key-id (car (epg-key-sub-key-list candidate))))
|
||||||
|
(id (epg-user-id-string (car (epg-key-user-id-list candidate))))
|
||||||
|
start end mode)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(if (search-forward mail-header-separator nil t)
|
||||||
|
(forward-line))
|
||||||
|
(setq epa-last-coding-system-specified
|
||||||
|
(or coding-system-for-write
|
||||||
|
(select-safe-coding-system (point) (point-max))))
|
||||||
|
(let ((verbose current-prefix-arg))
|
||||||
|
(setq start (point)
|
||||||
|
end (point-max)
|
||||||
|
mode (if verbose
|
||||||
|
(epa--read-signature-type)
|
||||||
|
'clear))))
|
||||||
|
;; TODO Make non-interactive functions to replace epa-sign-region
|
||||||
|
;; and epa-encrypt-region and inline them.
|
||||||
|
(with-no-warnings
|
||||||
|
(epa-sign-region start end candidate mode))
|
||||||
|
(message "Mail signed with key `%s %s'" key id)))
|
||||||
|
|
||||||
|
(defun helm-epa-mail-encrypt (_candidate)
|
||||||
|
"Encrypt email with key CANDIDATE."
|
||||||
|
(let ((cands (helm-marked-candidates))
|
||||||
|
start end)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(when (search-forward mail-header-separator nil t)
|
||||||
|
(forward-line))
|
||||||
|
(setq start (point)
|
||||||
|
end (point-max))
|
||||||
|
(setq epa-last-coding-system-specified
|
||||||
|
(or coding-system-for-write
|
||||||
|
(select-safe-coding-system start end))))
|
||||||
|
;; Don't let some read-only text stop us from encrypting.
|
||||||
|
(let ((inhibit-read-only t)
|
||||||
|
(keys (helm-epa-collect-keys-from-candidates cands))
|
||||||
|
(ids (helm-epa-collect-id-from-candidates cands)))
|
||||||
|
(with-no-warnings
|
||||||
|
(epa-encrypt-region start end cands nil nil))
|
||||||
|
(helm-epa-success-message "Mail encrypted with key(s):\n %s"
|
||||||
|
keys ids))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-epa-list-keys ()
|
||||||
|
"List all gpg keys.
|
||||||
|
This is the helm interface for `epa-list-keys'."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources
|
||||||
|
(helm-make-source "Epg list keys" 'helm-epa
|
||||||
|
:action-transformer 'helm-epa-action-transformer
|
||||||
|
:action 'helm-epa-actions)
|
||||||
|
:buffer "*helm epg list keys*"))
|
||||||
|
|
||||||
|
(provide 'helm-epa)
|
||||||
|
|
||||||
|
;;; helm-epa.el ends here
|
494
code/elpa/helm-20240320.541/helm-eshell.el
Normal file
494
code/elpa/helm-20240320.541/helm-eshell.el
Normal file
|
@ -0,0 +1,494 @@
|
||||||
|
;;; helm-eshell.el --- pcomplete and eshell completion for helm. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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:
|
||||||
|
;;
|
||||||
|
;; Enable like this in .emacs:
|
||||||
|
;; (add-hook 'eshell-mode-hook
|
||||||
|
;; (lambda ()
|
||||||
|
;; (eshell-cmpl-initialize)
|
||||||
|
;; (define-key eshell-mode-map [remap eshell-pcomplete] 'helm-esh-pcomplete)
|
||||||
|
;; (define-key eshell-mode-map (kbd "M-s f") 'helm-eshell-prompts-all)))
|
||||||
|
;; (define-key eshell-mode-map (kbd "M-r") 'helm-eshell-history)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-lib)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-elisp)
|
||||||
|
|
||||||
|
(declare-function eshell-read-aliases-list "em-alias")
|
||||||
|
(declare-function eshell-send-input "esh-mode" (&optional use-region queue-p no-newline))
|
||||||
|
(declare-function eshell-bol "esh-mode")
|
||||||
|
(declare-function eshell-parse-arguments "esh-arg" (beg end))
|
||||||
|
(declare-function eshell-backward-argument "esh-mode" (&optional arg))
|
||||||
|
(declare-function helm-quote-whitespace "helm-lib")
|
||||||
|
(declare-function eshell-skip-prompt "em-prompt")
|
||||||
|
(defvar eshell-special-chars-outside-quoting)
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-eshell nil
|
||||||
|
"Helm completion and history for Eshell."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom helm-eshell-fuzzy-match nil
|
||||||
|
"Enable fuzzy matching in `helm-esh-pcomplete' when non-nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar helm-eshell-history-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "M-p") #'helm-next-line)
|
||||||
|
map)
|
||||||
|
"Keymap for `helm-eshell-history'.")
|
||||||
|
|
||||||
|
(defvar helm-esh-completion-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "TAB") #'helm-next-line)
|
||||||
|
map)
|
||||||
|
"Keymap for `helm-esh-pcomplete'.")
|
||||||
|
|
||||||
|
(defvar helm-eshell--quit-flag nil)
|
||||||
|
|
||||||
|
|
||||||
|
;; Internal.
|
||||||
|
(defvar helm-ec-target "")
|
||||||
|
(defun helm-ec-insert (_candidate)
|
||||||
|
"Replace text at point with CANDIDATE.
|
||||||
|
The function that call this should set `helm-ec-target' to thing
|
||||||
|
at point."
|
||||||
|
(set (make-local-variable 'comint-file-name-quote-list)
|
||||||
|
eshell-special-chars-outside-quoting)
|
||||||
|
(let ((pt (point)))
|
||||||
|
(when (and helm-ec-target
|
||||||
|
(search-backward helm-ec-target nil t)
|
||||||
|
(string= (buffer-substring (point) pt) helm-ec-target))
|
||||||
|
(delete-region (point) pt)))
|
||||||
|
(when (string-match "\\`\\*" helm-ec-target) (insert "*"))
|
||||||
|
(let ((marked (helm-marked-candidates)))
|
||||||
|
(prog1 t ;; Makes helm returns t on action.
|
||||||
|
(insert
|
||||||
|
(mapconcat
|
||||||
|
(lambda (x)
|
||||||
|
(cond ((string-match "\\`~/" helm-ec-target)
|
||||||
|
;; Strip out the first escape char added by
|
||||||
|
;; `comint-quote-filename' before "~" (Bug#1803).
|
||||||
|
(substring (comint-quote-filename (abbreviate-file-name x)) 1))
|
||||||
|
((string-match "\\`/" helm-ec-target)
|
||||||
|
(comint-quote-filename x))
|
||||||
|
(t
|
||||||
|
(concat (and (string-match "\\`[.]/" helm-ec-target) "./")
|
||||||
|
(comint-quote-filename
|
||||||
|
(file-relative-name x))))))
|
||||||
|
marked " ")
|
||||||
|
(or (helm-aand (car (last marked))
|
||||||
|
(string-match-p "/\\'" it)
|
||||||
|
"")
|
||||||
|
" ")))))
|
||||||
|
|
||||||
|
(defun helm-esh-transformer (candidates _sources)
|
||||||
|
(cl-loop
|
||||||
|
for i in candidates
|
||||||
|
collect
|
||||||
|
(cond ((string-match "\\`~/?" helm-ec-target)
|
||||||
|
(abbreviate-file-name i))
|
||||||
|
((string-match "\\`/" helm-ec-target) i)
|
||||||
|
(t
|
||||||
|
(file-relative-name i)))
|
||||||
|
into lst
|
||||||
|
finally return (sort lst #'helm-generic-sort-fn)))
|
||||||
|
|
||||||
|
(defclass helm-esh-source (helm-source-sync)
|
||||||
|
((init :initform (lambda ()
|
||||||
|
(setq pcomplete-current-completions nil
|
||||||
|
pcomplete-last-completion-raw nil)
|
||||||
|
;; Eshell-command add this hook in all minibuffers
|
||||||
|
;; Remove it for the helm one. (Fixed in Emacs24)
|
||||||
|
(remove-hook 'minibuffer-setup-hook 'eshell-mode)))
|
||||||
|
(candidates :initform 'helm-esh-get-candidates)
|
||||||
|
;(nomark :initform t)
|
||||||
|
(persistent-action :initform 'ignore)
|
||||||
|
(nohighlight :initform t)
|
||||||
|
(filtered-candidate-transformer :initform #'helm-esh-transformer)
|
||||||
|
(action :initform 'helm-ec-insert))
|
||||||
|
"Helm class to define source for Eshell completion.")
|
||||||
|
|
||||||
|
(defun helm-esh-get-candidates ()
|
||||||
|
"Get candidates for Eshell completion using `pcomplete'."
|
||||||
|
(catch 'pcompleted
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(let* ((pcomplete-stub)
|
||||||
|
pcomplete-seen pcomplete-norm-func
|
||||||
|
pcomplete-args pcomplete-last pcomplete-index
|
||||||
|
(pcomplete-autolist pcomplete-autolist)
|
||||||
|
(pcomplete-suffix-list pcomplete-suffix-list)
|
||||||
|
(table (pcomplete-completions))
|
||||||
|
(entry (or (try-completion helm-pattern
|
||||||
|
(pcomplete-entries))
|
||||||
|
helm-pattern)))
|
||||||
|
(cl-loop ;; expand entry too to be able to compare it with file-cand.
|
||||||
|
with exp-entry = (and (stringp entry)
|
||||||
|
(not (string= entry ""))
|
||||||
|
(file-name-as-directory
|
||||||
|
(expand-file-name entry default-directory)))
|
||||||
|
with comps = (all-completions pcomplete-stub table)
|
||||||
|
unless comps return (prog1 nil
|
||||||
|
;; Don't add final space when
|
||||||
|
;; there is no completion (Bug#1990).
|
||||||
|
(setq helm-eshell--quit-flag t)
|
||||||
|
(message "No completions of %s" pcomplete-stub))
|
||||||
|
for i in comps
|
||||||
|
;; Transform the relative names to abs names.
|
||||||
|
for file-cand = (and exp-entry
|
||||||
|
(if (file-remote-p i) i
|
||||||
|
(expand-file-name
|
||||||
|
i (file-name-directory
|
||||||
|
(if (directory-name-p pcomplete-stub)
|
||||||
|
entry
|
||||||
|
(directory-file-name entry))))))
|
||||||
|
;; Compare them to avoid dups.
|
||||||
|
for file-entry-p = (and (stringp exp-entry)
|
||||||
|
(stringp file-cand)
|
||||||
|
;; Fix :/tmp/foo/ $ cd foo
|
||||||
|
(not (file-directory-p file-cand))
|
||||||
|
(file-equal-p exp-entry file-cand))
|
||||||
|
if (and file-cand (or (file-remote-p file-cand)
|
||||||
|
(file-exists-p file-cand))
|
||||||
|
(not file-entry-p))
|
||||||
|
collect file-cand into ls
|
||||||
|
else
|
||||||
|
;; Avoid adding entry here.
|
||||||
|
unless file-entry-p collect i into ls
|
||||||
|
finally return
|
||||||
|
(if (and exp-entry
|
||||||
|
(file-directory-p exp-entry)
|
||||||
|
;; If the car of completion list is
|
||||||
|
;; an executable, probably we are in
|
||||||
|
;; command completion, so don't add a
|
||||||
|
;; possible file related entry here.
|
||||||
|
(and ls (not (executable-find (car ls))))
|
||||||
|
;; Don't add entry if already in prompt.
|
||||||
|
(not (file-equal-p exp-entry pcomplete-stub)))
|
||||||
|
(append (list exp-entry)
|
||||||
|
;; Entry should not be here now but double check.
|
||||||
|
(remove entry ls))
|
||||||
|
ls))))))
|
||||||
|
|
||||||
|
;;; Eshell history.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defclass helm-eshell-history-source (helm-source-sync)
|
||||||
|
((init :initform
|
||||||
|
(lambda ()
|
||||||
|
;; Same comment as in `helm-source-esh'.
|
||||||
|
(remove-hook 'minibuffer-setup-hook 'eshell-mode)))
|
||||||
|
(candidates
|
||||||
|
:initform
|
||||||
|
(lambda ()
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(cl-loop for c from 0 to (ring-length eshell-history-ring)
|
||||||
|
for elm = (eshell-get-history c)
|
||||||
|
unless (and (member elm lst)
|
||||||
|
eshell-hist-ignoredups)
|
||||||
|
collect elm into lst
|
||||||
|
finally return lst))))
|
||||||
|
(nomark :initform t)
|
||||||
|
(multiline :initform t)
|
||||||
|
(keymap :initform 'helm-eshell-history-map)
|
||||||
|
(candidate-number-limit :initform 9999)
|
||||||
|
(action :initform (lambda (candidate)
|
||||||
|
(eshell-kill-input)
|
||||||
|
(insert candidate))))
|
||||||
|
"Helm class to define source for Eshell history.")
|
||||||
|
|
||||||
|
|
||||||
|
(defun helm-esh-pcomplete-input (target users-comp last)
|
||||||
|
(if (and (stringp last)
|
||||||
|
(not (string= last ""))
|
||||||
|
(not users-comp)
|
||||||
|
;; Fix completion on "../" see Bug#1832.
|
||||||
|
(or (file-exists-p last)
|
||||||
|
(helm-aand
|
||||||
|
(file-name-directory last)
|
||||||
|
(file-directory-p it))))
|
||||||
|
(if (and (file-directory-p last)
|
||||||
|
(string-match "\\`[~.]*.*/[.]\\'" target))
|
||||||
|
;; Fix completion on "~/.", "~/[...]/.", and "../."
|
||||||
|
(expand-file-name
|
||||||
|
(concat (helm-basedir (file-name-as-directory last))
|
||||||
|
(regexp-quote (helm-basename target))))
|
||||||
|
(expand-file-name last))
|
||||||
|
;; Don't add "~" to input to provide completion on all users instead of only
|
||||||
|
;; on current $HOME (#1832).
|
||||||
|
(unless users-comp last)))
|
||||||
|
|
||||||
|
(defun helm-esh-pcomplete-default-source ()
|
||||||
|
"Make and return the default source for Eshell completion."
|
||||||
|
(helm-make-source "Eshell completions" 'helm-esh-source
|
||||||
|
:fuzzy-match helm-eshell-fuzzy-match
|
||||||
|
:keymap helm-esh-completion-map))
|
||||||
|
|
||||||
|
(defvar helm-esh-pcomplete-build-source-fn #'helm-esh-pcomplete-default-source
|
||||||
|
"Function that builds a source or a list of sources.")
|
||||||
|
|
||||||
|
(defun helm-esh-pcomplete--make-helm (&optional input)
|
||||||
|
(helm :sources (funcall helm-esh-pcomplete-build-source-fn)
|
||||||
|
:buffer "*helm pcomplete*"
|
||||||
|
:resume 'noresume
|
||||||
|
:input input))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-esh-pcomplete ()
|
||||||
|
"Preconfigured `helm' to provide Helm completion in Eshell."
|
||||||
|
(interactive)
|
||||||
|
(let* ((helm-quit-if-no-candidate t)
|
||||||
|
(helm-execute-action-at-once-if-one t)
|
||||||
|
(end (point-marker))
|
||||||
|
(beg (save-excursion (eshell-bol) (point)))
|
||||||
|
(args (catch 'eshell-incomplete
|
||||||
|
(eshell-parse-arguments beg end)))
|
||||||
|
(target
|
||||||
|
(or (and (looking-back " " (1- (point))) " ")
|
||||||
|
(buffer-substring-no-properties
|
||||||
|
(save-excursion
|
||||||
|
(eshell-backward-argument 1) (point))
|
||||||
|
end)))
|
||||||
|
(users-comp (string= target "~"))
|
||||||
|
(first (car args)) ; Maybe lisp delimiter "(".
|
||||||
|
last ; Will be the last but parsed by pcomplete.
|
||||||
|
del-space
|
||||||
|
del-dot)
|
||||||
|
(setq helm-ec-target (or target " ")
|
||||||
|
end (point)
|
||||||
|
;; Reset beg for `with-helm-show-completion'.
|
||||||
|
beg (or (and target (not (string= target " "))
|
||||||
|
(- end (length target)))
|
||||||
|
;; Nothing at point.
|
||||||
|
(progn (insert " ") (setq del-space t) (point))))
|
||||||
|
(when (string-match "\\`[~.]*.*/[.]\\'" target)
|
||||||
|
;; Fix completion on
|
||||||
|
;; "~/.", "~/[...]/.", and "../."
|
||||||
|
(delete-char -1) (setq del-dot t)
|
||||||
|
(setq helm-ec-target (substring helm-ec-target 0 (1- (length helm-ec-target)))))
|
||||||
|
(cond ((eq first ?\()
|
||||||
|
(helm-lisp-completion-at-point))
|
||||||
|
;; In eshell `pcomplete-parse-arguments' is called
|
||||||
|
;; with `pcomplete-parse-arguments-function'
|
||||||
|
;; locally bound to `eshell-complete-parse-arguments'
|
||||||
|
;; which is calling `lisp-complete-symbol',
|
||||||
|
;; calling it before would popup the
|
||||||
|
;; *completions* buffer.
|
||||||
|
(t (setq last (replace-regexp-in-string
|
||||||
|
"\\`\\*" ""
|
||||||
|
(car (last (ignore-errors
|
||||||
|
(pcomplete-parse-arguments))))))
|
||||||
|
;; Set helm-eshell--quit-flag to non-nil only on
|
||||||
|
;; quit, this tells to not add final suffix when quitting
|
||||||
|
;; helm.
|
||||||
|
(add-hook 'helm-quit-hook #'helm-eshell--quit-hook-fn)
|
||||||
|
(with-helm-show-completion beg end
|
||||||
|
(unwind-protect
|
||||||
|
(or (helm-esh-pcomplete--make-helm
|
||||||
|
(helm-esh-pcomplete-input target users-comp last))
|
||||||
|
;; Delete removed dot on quit
|
||||||
|
(and del-dot (prog1 t (insert ".")))
|
||||||
|
;; A space is needed to have completion, remove
|
||||||
|
;; it when nothing found.
|
||||||
|
(and del-space (looking-back "\\s-" (1- (point)))
|
||||||
|
(delete-char -1))
|
||||||
|
(if (and (null helm-eshell--quit-flag)
|
||||||
|
(and (stringp last) (file-directory-p last))
|
||||||
|
(looking-back "\\([.]\\{1,2\\}\\|[^/]\\)\\'"
|
||||||
|
(1- (point))))
|
||||||
|
(prog1 t (insert "/"))
|
||||||
|
;; We need another flag for space here, but
|
||||||
|
;; global to pass it to `helm-quit-hook', this
|
||||||
|
;; space is added when point is just after
|
||||||
|
;; previous completion and there is no
|
||||||
|
;; more completion, see Bug#1832.
|
||||||
|
(unless (or helm-eshell--quit-flag
|
||||||
|
(looking-back "/\\'" (1- (point))))
|
||||||
|
(prog1 t (insert " ")))
|
||||||
|
(when (and helm-eshell--quit-flag
|
||||||
|
(string-match-p "[.]\\{2\\}\\'" last))
|
||||||
|
(insert "/"))))
|
||||||
|
(remove-hook 'helm-quit-hook #'helm-eshell--quit-hook-fn)
|
||||||
|
(setq helm-eshell--quit-flag nil)))))))
|
||||||
|
|
||||||
|
(defun helm-eshell--quit-hook-fn ()
|
||||||
|
(setq helm-eshell--quit-flag t))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-eshell-history ()
|
||||||
|
"Preconfigured Helm for Eshell history."
|
||||||
|
(interactive)
|
||||||
|
(let* ((end (point))
|
||||||
|
(beg (save-excursion (eshell-bol) (point)))
|
||||||
|
(input (buffer-substring beg end))
|
||||||
|
flag-empty)
|
||||||
|
(when (eq beg end)
|
||||||
|
(insert " ")
|
||||||
|
(setq flag-empty t)
|
||||||
|
(setq end (point)))
|
||||||
|
(unwind-protect
|
||||||
|
(with-helm-show-completion beg end
|
||||||
|
(helm :sources (helm-make-source "Eshell history"
|
||||||
|
'helm-eshell-history-source
|
||||||
|
:fuzzy-match helm-eshell-fuzzy-match)
|
||||||
|
:buffer "*helm eshell history*"
|
||||||
|
:resume 'noresume
|
||||||
|
:input input))
|
||||||
|
(when (and flag-empty
|
||||||
|
(looking-back " " (1- (point))))
|
||||||
|
(delete-char -1)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Eshell prompts
|
||||||
|
;;
|
||||||
|
(defface helm-eshell-prompts-promptidx
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "cyan"))
|
||||||
|
"Face used to highlight Eshell prompt index.")
|
||||||
|
|
||||||
|
(defface helm-eshell-prompts-buffer-name
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "green"))
|
||||||
|
"Face used to highlight Eshell buffer name.")
|
||||||
|
|
||||||
|
(defcustom helm-eshell-prompts-promptidx-p t
|
||||||
|
"Show prompt number."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defvar helm-eshell-prompts-keymap
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "C-c o") #'helm-eshell-prompts-other-window)
|
||||||
|
(define-key map (kbd "C-c C-o") #'helm-eshell-prompts-other-frame)
|
||||||
|
map)
|
||||||
|
"Keymap for `helm-eshell-prompt-all'.")
|
||||||
|
|
||||||
|
(defvar eshell-prompt-regexp)
|
||||||
|
(defvar eshell-highlight-prompt)
|
||||||
|
|
||||||
|
(defun helm-eshell-prompts-list (&optional buffer)
|
||||||
|
"List the prompts in Eshell BUFFER.
|
||||||
|
|
||||||
|
Return a list of (\"prompt\" (point) (buffer-name) prompt-index))
|
||||||
|
E.g. (\"ls\" 162 \"*eshell*\" 3).
|
||||||
|
If BUFFER is nil, use current buffer."
|
||||||
|
(with-current-buffer (or buffer (current-buffer))
|
||||||
|
(when (eq major-mode 'eshell-mode)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(let (result (count 1))
|
||||||
|
(helm-awhile (re-search-forward eshell-prompt-regexp nil t)
|
||||||
|
(when (or (and eshell-highlight-prompt
|
||||||
|
(get-text-property (match-beginning 0) 'read-only))
|
||||||
|
(null eshell-highlight-prompt))
|
||||||
|
(push (list (buffer-substring-no-properties
|
||||||
|
it (pos-eol))
|
||||||
|
it (buffer-name) count)
|
||||||
|
result)
|
||||||
|
(setq count (1+ count))))
|
||||||
|
(nreverse result))))))
|
||||||
|
|
||||||
|
(defun helm-eshell-prompts-list-all ()
|
||||||
|
"List the prompts of all Eshell buffers.
|
||||||
|
See `helm-eshell-prompts-list'."
|
||||||
|
(cl-loop for b in (buffer-list)
|
||||||
|
append (helm-eshell-prompts-list b)))
|
||||||
|
|
||||||
|
(defun helm-eshell-prompts-transformer (candidates &optional all)
|
||||||
|
;; ("ls" 162 "*eshell*" 3) => ("*eshell*:3:ls" . ("ls" 162 "*eshell*" 3))
|
||||||
|
(cl-loop for (prt pos buf id) in candidates
|
||||||
|
collect `(,(concat
|
||||||
|
(when all
|
||||||
|
(concat (propertize
|
||||||
|
buf
|
||||||
|
'face 'helm-eshell-prompts-buffer-name)
|
||||||
|
":"))
|
||||||
|
(when helm-eshell-prompts-promptidx-p
|
||||||
|
(concat (propertize
|
||||||
|
(number-to-string id)
|
||||||
|
'face 'helm-eshell-prompts-promptidx)
|
||||||
|
":"))
|
||||||
|
prt)
|
||||||
|
. ,(list prt pos buf id))))
|
||||||
|
|
||||||
|
(defun helm-eshell-prompts-all-transformer (candidates)
|
||||||
|
(helm-eshell-prompts-transformer candidates t))
|
||||||
|
|
||||||
|
(cl-defun helm-eshell-prompts-goto (candidate &optional (action 'switch-to-buffer))
|
||||||
|
;; Candidate format: ("ls" 162 "*eshell*" 3)
|
||||||
|
(let ((buf (nth 2 candidate)))
|
||||||
|
(unless (and (string= (buffer-name) buf)
|
||||||
|
(eq action 'switch-to-buffer))
|
||||||
|
(funcall action buf))
|
||||||
|
(goto-char (nth 1 candidate))
|
||||||
|
(recenter)))
|
||||||
|
|
||||||
|
(defun helm-eshell-prompts-goto-other-window (candidate)
|
||||||
|
(helm-eshell-prompts-goto candidate 'switch-to-buffer-other-window))
|
||||||
|
|
||||||
|
(defun helm-eshell-prompts-goto-other-frame (candidate)
|
||||||
|
(helm-eshell-prompts-goto candidate 'switch-to-buffer-other-frame))
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-eshell-prompts-other-window
|
||||||
|
"Switch to eshell prompt in other window."
|
||||||
|
'helm-eshell-prompts-goto-other-window)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-eshell-prompts-other-frame
|
||||||
|
"Switch to eshell prompt in other frame."
|
||||||
|
'helm-eshell-prompts-goto-other-frame)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-eshell-prompts ()
|
||||||
|
"Pre-configured `helm' to browse the prompts of the current Eshell."
|
||||||
|
(interactive)
|
||||||
|
(if (eq major-mode 'eshell-mode)
|
||||||
|
(helm :sources
|
||||||
|
(helm-build-sync-source "Eshell prompts"
|
||||||
|
:candidates (helm-eshell-prompts-list)
|
||||||
|
:candidate-transformer 'helm-eshell-prompts-transformer
|
||||||
|
:action '(("Go to prompt" . helm-eshell-prompts-goto)))
|
||||||
|
:buffer "*helm Eshell prompts*")
|
||||||
|
(message "Current buffer is not an Eshell buffer")))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-eshell-prompts-all ()
|
||||||
|
"Pre-configured `helm' to browse the prompts of all Eshell sessions."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources
|
||||||
|
(helm-build-sync-source "All Eshell prompts"
|
||||||
|
:candidates (helm-eshell-prompts-list-all)
|
||||||
|
:candidate-transformer 'helm-eshell-prompts-all-transformer
|
||||||
|
:action '(("Go to prompt" . helm-eshell-prompts-goto)
|
||||||
|
("Go to prompt in other window `C-c o`" .
|
||||||
|
helm-eshell-prompts-goto-other-window)
|
||||||
|
("Go to prompt in other frame `C-c C-o`" .
|
||||||
|
helm-eshell-prompts-goto-other-frame))
|
||||||
|
:keymap helm-eshell-prompts-keymap)
|
||||||
|
:buffer "*helm Eshell all prompts*"))
|
||||||
|
|
||||||
|
(provide 'helm-eshell)
|
||||||
|
|
||||||
|
;;; helm-eshell ends here
|
221
code/elpa/helm-20240320.541/helm-eval.el
Normal file
221
code/elpa/helm-20240320.541/helm-eval.el
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
;;; helm-eval.el --- eval expressions from helm. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'eldoc)
|
||||||
|
(require 'edebug)
|
||||||
|
|
||||||
|
(declare-function helm-lisp-completion-at-point "helm-elisp.el")
|
||||||
|
(declare-function helm-elisp-show-doc-modeline "helm-elisp.el")
|
||||||
|
(defvar helm-elisp-help-function)
|
||||||
|
|
||||||
|
(defgroup helm-eval nil
|
||||||
|
"Eval related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-eldoc-in-minibuffer-show-fn
|
||||||
|
'helm-show-info-in-mode-line
|
||||||
|
"A function to display eldoc info.
|
||||||
|
Should take one arg: the string to display."
|
||||||
|
:group 'helm-eval
|
||||||
|
:type 'symbol)
|
||||||
|
|
||||||
|
(defcustom helm-show-info-in-mode-line-delay 12
|
||||||
|
"Eldoc will show info in mode-line during this delay if user is idle."
|
||||||
|
:type 'integer
|
||||||
|
:group 'helm-eval)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Eldoc compatibility between emacs-24 and emacs-25
|
||||||
|
;;
|
||||||
|
(if (require 'elisp-mode nil t) ; emacs-25
|
||||||
|
;; Maybe the eldoc functions have been
|
||||||
|
;; already aliased by eldoc-eval.
|
||||||
|
(cl-loop for (f . a) in '((eldoc-current-symbol .
|
||||||
|
elisp--current-symbol)
|
||||||
|
(eldoc-fnsym-in-current-sexp .
|
||||||
|
elisp--fnsym-in-current-sexp)
|
||||||
|
(eldoc-get-fnsym-args-string .
|
||||||
|
elisp-get-fnsym-args-string)
|
||||||
|
(eldoc-get-var-docstring .
|
||||||
|
elisp-get-var-docstring))
|
||||||
|
unless (fboundp f)
|
||||||
|
do (defalias f a))
|
||||||
|
;; Emacs-24.
|
||||||
|
(declare-function eldoc-current-symbol "eldoc")
|
||||||
|
(declare-function eldoc-get-fnsym-args-string "eldoc" (sym &optional index))
|
||||||
|
(declare-function eldoc-get-var-docstring "eldoc" (sym))
|
||||||
|
(declare-function eldoc-fnsym-in-current-sexp "eldoc"))
|
||||||
|
|
||||||
|
;;; Evaluation Result
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;; Internal
|
||||||
|
(defvar helm-eldoc-active-minibuffers-list nil)
|
||||||
|
|
||||||
|
(defvar helm-eval-expression-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "<C-return>") #'helm-eval-new-line-and-indent)
|
||||||
|
(define-key map (kbd "<M-tab>") #'lisp-indent-line)
|
||||||
|
(define-key map (kbd "<C-tab>") #'helm-lisp-completion-at-point)
|
||||||
|
(define-key map (kbd "C-p") #'previous-line)
|
||||||
|
(define-key map (kbd "C-n") #'next-line)
|
||||||
|
(define-key map (kbd "<up>") #'previous-line)
|
||||||
|
(define-key map (kbd "<down>") #'next-line)
|
||||||
|
(define-key map (kbd "<right>") #'forward-char)
|
||||||
|
(define-key map (kbd "<left>") #'backward-char)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defclass helm-evaluation-result-class (helm-source-dummy)
|
||||||
|
((echo-input-in-header-line
|
||||||
|
:initarg :echo-input-in-header-line
|
||||||
|
:initform 'never)))
|
||||||
|
|
||||||
|
(defun helm-build-evaluation-result-source ()
|
||||||
|
(helm-make-source "Evaluation Result" 'helm-evaluation-result-class
|
||||||
|
:multiline t
|
||||||
|
:mode-line "C-RET: nl-and-indent, M-tab: reindent, C-tab:complete, C-p/n: next/prec-line."
|
||||||
|
:filtered-candidate-transformer
|
||||||
|
(lambda (_candidates _source)
|
||||||
|
(list
|
||||||
|
(condition-case nil
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(pp-to-string
|
||||||
|
(if edebug-active
|
||||||
|
(edebug-eval-expression
|
||||||
|
(read helm-pattern))
|
||||||
|
(eval (read helm-pattern) t))))
|
||||||
|
(error "Error"))))
|
||||||
|
:nohighlight t
|
||||||
|
:keymap helm-eval-expression-map
|
||||||
|
:action '(("Copy result to kill-ring" . (lambda (candidate)
|
||||||
|
(kill-new
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\n" "" candidate))
|
||||||
|
(message "Result copied to kill-ring")))
|
||||||
|
("copy sexp to kill-ring" . (lambda (_candidate)
|
||||||
|
(kill-new helm-input)
|
||||||
|
(message "Sexp copied to kill-ring"))))))
|
||||||
|
|
||||||
|
(defun helm-eval-new-line-and-indent ()
|
||||||
|
(interactive)
|
||||||
|
(newline) (lisp-indent-line))
|
||||||
|
|
||||||
|
(defun helm-eldoc-store-minibuffer ()
|
||||||
|
"Store minibuffer buffer name in `helm-eldoc-active-minibuffers-list'."
|
||||||
|
(with-selected-window (minibuffer-window)
|
||||||
|
(push (current-buffer) helm-eldoc-active-minibuffers-list)))
|
||||||
|
|
||||||
|
;; From emacs-28.1: As the eldoc API is nowaday a pain to use, try to
|
||||||
|
;; provide some eldoc in mode-line the best as possible (may break at
|
||||||
|
;; some point).
|
||||||
|
(defun helm-eldoc-show-in-eval ()
|
||||||
|
"Return eldoc in mode-line for current minibuffer input."
|
||||||
|
(let ((buf (window-buffer (active-minibuffer-window))))
|
||||||
|
(condition-case err
|
||||||
|
(when (member buf helm-eldoc-active-minibuffers-list)
|
||||||
|
(with-current-buffer buf
|
||||||
|
(let* ((info-fn (eldoc-fnsym-in-current-sexp))
|
||||||
|
(vsym (eldoc-current-symbol))
|
||||||
|
(sym (car info-fn))
|
||||||
|
(vardoc (eldoc-get-var-docstring vsym))
|
||||||
|
(doc (or vardoc
|
||||||
|
(eldoc-get-fnsym-args-string
|
||||||
|
sym (cadr info-fn))))
|
||||||
|
(all (format "%s: %s"
|
||||||
|
(propertize
|
||||||
|
(symbol-name (if vardoc vsym sym))
|
||||||
|
'face (if vardoc
|
||||||
|
'font-lock-variable-name-face
|
||||||
|
'font-lock-function-name-face))
|
||||||
|
doc)))
|
||||||
|
(when doc (funcall helm-eldoc-in-minibuffer-show-fn all)))))
|
||||||
|
(error (message "Eldoc in minibuffer error: %S" err) nil))))
|
||||||
|
|
||||||
|
(defun helm-show-info-in-mode-line (str)
|
||||||
|
"Display string STR in mode-line."
|
||||||
|
(save-selected-window
|
||||||
|
(with-helm-window
|
||||||
|
(let ((mode-line-format (concat " " str)))
|
||||||
|
(force-mode-line-update)
|
||||||
|
(sit-for helm-show-info-in-mode-line-delay))
|
||||||
|
(force-mode-line-update))))
|
||||||
|
|
||||||
|
;;; Calculation Result
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-source-calculation-result
|
||||||
|
(helm-build-dummy-source "Calculation Result"
|
||||||
|
:filtered-candidate-transformer (lambda (_candidates _source)
|
||||||
|
(list
|
||||||
|
(condition-case err
|
||||||
|
(let ((result (calc-eval helm-pattern)))
|
||||||
|
(if (listp result)
|
||||||
|
(error "At pos %s: %s"
|
||||||
|
(car result) (cadr result))
|
||||||
|
result))
|
||||||
|
(error (cdr err)))))
|
||||||
|
:nohighlight t
|
||||||
|
:action '(("Copy result to kill-ring" . (lambda (candidate)
|
||||||
|
(kill-new candidate)
|
||||||
|
(message "Result \"%s\" copied to kill-ring"
|
||||||
|
candidate)))
|
||||||
|
("Copy operation to kill-ring" . (lambda (_candidate)
|
||||||
|
(kill-new helm-input)
|
||||||
|
(message "Calculation copied to kill-ring"))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-eval-expression (arg)
|
||||||
|
"Preconfigured `helm' for `helm-source-evaluation-result'."
|
||||||
|
(interactive "P")
|
||||||
|
(let ((helm-elisp-help-function #'helm-elisp-show-doc-modeline))
|
||||||
|
(helm :sources (helm-build-evaluation-result-source)
|
||||||
|
:input (when arg (thing-at-point 'sexp))
|
||||||
|
:buffer "*helm eval*"
|
||||||
|
:echo-input-in-header-line nil
|
||||||
|
:history 'read-expression-history)))
|
||||||
|
|
||||||
|
(defvar eldoc-idle-delay)
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-eval-expression-with-eldoc ()
|
||||||
|
"Preconfigured `helm' for `helm-source-evaluation-result' with `eldoc' support."
|
||||||
|
(interactive)
|
||||||
|
(let ((timer (run-with-idle-timer
|
||||||
|
eldoc-idle-delay 'repeat
|
||||||
|
#'helm-eldoc-show-in-eval)))
|
||||||
|
(unwind-protect
|
||||||
|
(minibuffer-with-setup-hook
|
||||||
|
#'helm-eldoc-store-minibuffer
|
||||||
|
(call-interactively 'helm-eval-expression))
|
||||||
|
(and timer (cancel-timer timer))
|
||||||
|
(setq helm-eldoc-active-minibuffers-list
|
||||||
|
(cdr helm-eldoc-active-minibuffers-list)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-calcul-expression ()
|
||||||
|
"Preconfigured `helm' for `helm-source-calculation-result'."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources 'helm-source-calculation-result
|
||||||
|
:buffer "*helm calcul*"))
|
||||||
|
|
||||||
|
(provide 'helm-eval)
|
||||||
|
|
||||||
|
;;; helm-eval.el ends here
|
264
code/elpa/helm-20240320.541/helm-external.el
Normal file
264
code/elpa/helm-20240320.541/helm-external.el
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
;;; helm-external.el --- Run Externals commands within Emacs with helm completion. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-net)
|
||||||
|
|
||||||
|
(declare-function helm-comp-read "helm-mode")
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-external nil
|
||||||
|
"External related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-raise-command nil
|
||||||
|
"A shell command to jump to a window running specific program.
|
||||||
|
Need external program wmctrl.
|
||||||
|
This will be use with `format', so use something like \"wmctrl -xa %s\"."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-external)
|
||||||
|
|
||||||
|
(defcustom helm-external-programs-associations nil
|
||||||
|
"Alist to store externals programs associated with file extension.
|
||||||
|
This variable overhide setting in .mailcap file.
|
||||||
|
E.g.: \\='((\"jpg\" . \"gqview\") (\"pdf\" . \"xpdf\")) "
|
||||||
|
:type '(alist :key-type string :value-type string)
|
||||||
|
:group 'helm-external)
|
||||||
|
|
||||||
|
(defcustom helm-default-external-file-browser "nautilus"
|
||||||
|
"Default external file browser for your system.
|
||||||
|
Directories will be opened externally with it when opening file
|
||||||
|
externally in `helm-find-files'.
|
||||||
|
Set to nil if you do not have an external file browser or do not
|
||||||
|
want to use it.
|
||||||
|
Windows users should set that to \"explorer.exe\"."
|
||||||
|
:group 'helm-external
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defvar helm-open-file-externally-after-hook nil
|
||||||
|
"Hook that run after opening a file with external program.")
|
||||||
|
|
||||||
|
(defvar helm-open-file-externally-after-finish-hook nil
|
||||||
|
"Hook that run after external program finish.")
|
||||||
|
|
||||||
|
;;; Internals
|
||||||
|
(defvar helm-external-command-history nil)
|
||||||
|
(defvar helm-external-commands-list nil
|
||||||
|
"A list of all external commands the user can execute.
|
||||||
|
If this variable is not set by the user, it will be calculated
|
||||||
|
automatically.")
|
||||||
|
|
||||||
|
(defun helm-external-commands-list-1 (&optional sort)
|
||||||
|
"Return a list of all external commands the user can execute.
|
||||||
|
If `helm-external-commands-list' is non-nil it will return its
|
||||||
|
contents. Else it calculates all external commands and sets
|
||||||
|
`helm-external-commands-list'."
|
||||||
|
(or helm-external-commands-list
|
||||||
|
(setq helm-external-commands-list
|
||||||
|
(cl-loop for dir in (split-string (getenv "PATH") path-separator)
|
||||||
|
when (and (file-exists-p dir)
|
||||||
|
(file-accessible-directory-p dir))
|
||||||
|
for lsdir = (cl-loop for i in (directory-files dir t)
|
||||||
|
for bn = (file-name-nondirectory i)
|
||||||
|
when (and (not (member bn completions))
|
||||||
|
(not (file-directory-p i))
|
||||||
|
(file-executable-p i))
|
||||||
|
collect bn)
|
||||||
|
append lsdir into completions
|
||||||
|
finally return
|
||||||
|
(if sort (sort completions 'string-lessp) completions)))))
|
||||||
|
|
||||||
|
(defun helm-run-or-raise (exe &optional files detached)
|
||||||
|
"Run asynchronously EXE or jump to the application window.
|
||||||
|
If EXE is already running just jump to his window if
|
||||||
|
`helm-raise-command' is non-nil.
|
||||||
|
When FILES argument is provided run EXE with FILES.
|
||||||
|
When argument DETACHED is non nil, detach process from Emacs."
|
||||||
|
(let* ((proc-name (replace-regexp-in-string
|
||||||
|
"(" "" (car (split-string exe))))
|
||||||
|
(fmt-file (lambda (file)
|
||||||
|
(shell-quote-argument
|
||||||
|
(if (eq system-type 'windows-nt)
|
||||||
|
(helm-w32-prepare-filename file)
|
||||||
|
(expand-file-name file)))))
|
||||||
|
(file-arg (and files (mapconcat fmt-file files " ")))
|
||||||
|
process-connection-type proc)
|
||||||
|
(when (and files detached (not (string-match "%s &)\\'" exe)))
|
||||||
|
(setq exe (format "(%s &)" exe)))
|
||||||
|
(when (member proc-name helm-external-commands-list)
|
||||||
|
;; Allow adding more files to the current process if it is
|
||||||
|
;; already running (i.e. Don't just raise it without sending
|
||||||
|
;; files) we assume program doesn't start a new
|
||||||
|
;; process (like firefox, transmission etc...).
|
||||||
|
(if files
|
||||||
|
(cond ((string-match "%s &)\\'" exe)
|
||||||
|
(message "Starting and detaching `%s' from Emacs" proc-name)
|
||||||
|
(call-process-shell-command (format exe file-arg)))
|
||||||
|
(t
|
||||||
|
(message "Starting %s..." proc-name)
|
||||||
|
(setq proc
|
||||||
|
(start-process-shell-command
|
||||||
|
proc-name nil (if (string-match "%s" exe)
|
||||||
|
(format exe file-arg)
|
||||||
|
(format "%s %s" exe file-arg))))))
|
||||||
|
;; Just jump to the already running program instance or start
|
||||||
|
;; a new process.
|
||||||
|
(if (get-process proc-name)
|
||||||
|
(if helm-raise-command
|
||||||
|
(run-at-time 0.1 nil #'shell-command
|
||||||
|
(format helm-raise-command proc-name))
|
||||||
|
(error "Error: %s is already running" proc-name))
|
||||||
|
(if (and detached (not (memq system-type '(windows-nt ms-dos))))
|
||||||
|
(progn
|
||||||
|
(message "Starting and detaching `%s' from Emacs" proc-name)
|
||||||
|
(call-process-shell-command (format "(%s &)" exe)))
|
||||||
|
(when detached
|
||||||
|
(user-error "Detaching programs not supported on `%s'" system-type))
|
||||||
|
(setq proc (start-process-shell-command proc-name nil exe)))))
|
||||||
|
(when proc
|
||||||
|
(set-process-sentinel
|
||||||
|
proc
|
||||||
|
(lambda (process event)
|
||||||
|
(when (and (string= event "finished\n")
|
||||||
|
helm-raise-command
|
||||||
|
(not (helm-get-pid-from-process-name proc-name)))
|
||||||
|
(run-hooks 'helm-open-file-externally-after-finish-hook)
|
||||||
|
(shell-command (format helm-raise-command "emacs")))
|
||||||
|
(message "%s process...Finished." process))))
|
||||||
|
;; Move command on top list.
|
||||||
|
(setq helm-external-commands-list
|
||||||
|
(cons proc-name
|
||||||
|
(delete proc-name helm-external-commands-list))))))
|
||||||
|
|
||||||
|
(defun helm-get-mailcap-for-file (filename)
|
||||||
|
"Get the command to use for FILENAME from mailcap files."
|
||||||
|
(mailcap-parse-mailcaps)
|
||||||
|
(let* ((ext (file-name-extension filename))
|
||||||
|
(mime (when ext (mailcap-extension-to-mime ext)))
|
||||||
|
(result (when mime (mailcap-mime-info mime))))
|
||||||
|
;; If elisp file have no associations in .mailcap
|
||||||
|
;; `mailcap-maybe-eval' is returned, in this case just return nil.
|
||||||
|
(when (stringp result) (helm-basename result))))
|
||||||
|
|
||||||
|
(defun helm-get-default-program-for-file (filename)
|
||||||
|
"Try to find a default program to open FILENAME.
|
||||||
|
Try first in `helm-external-programs-associations' and then in
|
||||||
|
mailcap file. If nothing found return nil."
|
||||||
|
(let* ((ext (file-name-extension filename))
|
||||||
|
(def-prog (assoc-default ext helm-external-programs-associations)))
|
||||||
|
(cond ((and def-prog (not (string= def-prog ""))) def-prog)
|
||||||
|
((and helm-default-external-file-browser (file-directory-p filename))
|
||||||
|
helm-default-external-file-browser)
|
||||||
|
(t (helm-get-mailcap-for-file filename)))))
|
||||||
|
|
||||||
|
(defun helm-open-file-externally (_file)
|
||||||
|
"Open FILE with an external program.
|
||||||
|
Try to guess which program to use with
|
||||||
|
`helm-get-default-program-for-file'.
|
||||||
|
If not found or a prefix arg is given query the user which tool
|
||||||
|
to use."
|
||||||
|
(let* ((files (helm-marked-candidates :with-wildcard t))
|
||||||
|
(fname (expand-file-name (car files)))
|
||||||
|
(collection (helm-external-commands-list-1 'sort))
|
||||||
|
(def-prog (helm-get-default-program-for-file fname))
|
||||||
|
(program (if (or helm-current-prefix-arg (not def-prog))
|
||||||
|
;; Prefix arg or no default program.
|
||||||
|
(prog1
|
||||||
|
(helm-comp-read
|
||||||
|
"Program: " collection
|
||||||
|
:must-match t
|
||||||
|
:name "Open file Externally"
|
||||||
|
:history 'helm-external-command-history)
|
||||||
|
;; Always prompt to set this program as default.
|
||||||
|
(setq def-prog nil))
|
||||||
|
;; No prefix arg or default program exists.
|
||||||
|
def-prog)))
|
||||||
|
(unless (or def-prog ; Association exists, no need to record it.
|
||||||
|
;; Don't try to record non--filenames associations (e.g urls).
|
||||||
|
(not (file-exists-p fname)))
|
||||||
|
(when
|
||||||
|
(y-or-n-p
|
||||||
|
(format
|
||||||
|
"Do you want to make `%s' the default program for this kind of files? "
|
||||||
|
program))
|
||||||
|
(helm-aif (assoc (file-name-extension fname)
|
||||||
|
helm-external-programs-associations)
|
||||||
|
(setq helm-external-programs-associations
|
||||||
|
(delete it helm-external-programs-associations)))
|
||||||
|
(push (cons (file-name-extension fname)
|
||||||
|
(helm-read-string
|
||||||
|
"Program (Add args maybe and confirm): " program))
|
||||||
|
helm-external-programs-associations)
|
||||||
|
(customize-save-variable 'helm-external-programs-associations
|
||||||
|
helm-external-programs-associations)))
|
||||||
|
(helm-run-or-raise program files)
|
||||||
|
(run-hooks 'helm-open-file-externally-after-hook)
|
||||||
|
(setq helm-external-command-history
|
||||||
|
(cl-loop for i in helm-external-command-history
|
||||||
|
when (executable-find i) collect i))))
|
||||||
|
|
||||||
|
(defun helm-run-external-command-action (candidate &optional detached)
|
||||||
|
(helm-run-or-raise candidate nil detached)
|
||||||
|
(setq helm-external-command-history
|
||||||
|
(cons candidate
|
||||||
|
(delete candidate
|
||||||
|
helm-external-command-history))))
|
||||||
|
|
||||||
|
(defclass helm-external-commands (helm-source-in-buffer)
|
||||||
|
((filtered-candidate-transformer
|
||||||
|
:initform (lambda (candidates _source)
|
||||||
|
(cl-loop for c in candidates
|
||||||
|
if (get-process c)
|
||||||
|
collect (propertize c 'face 'font-lock-type-face)
|
||||||
|
else collect c)))
|
||||||
|
(must-match :initform t)
|
||||||
|
(nomark :initform t)
|
||||||
|
(action :initform
|
||||||
|
(helm-make-actions
|
||||||
|
"Run program" 'helm-run-external-command-action
|
||||||
|
(lambda ()
|
||||||
|
(unless (memq system-type '(windows-nt ms-dos))
|
||||||
|
"Run program detached"))
|
||||||
|
(lambda (candidate)
|
||||||
|
(helm-run-external-command-action candidate 'detached))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-run-external-command ()
|
||||||
|
"Preconfigured `helm' to run External PROGRAM asyncronously from Emacs.
|
||||||
|
If program is already running try to run `helm-raise-command' if
|
||||||
|
defined otherwise exit with error. You can set your own list of
|
||||||
|
commands with `helm-external-commands-list'."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources `(,(helm-make-source "External Commands history" 'helm-external-commands
|
||||||
|
:data helm-external-command-history)
|
||||||
|
,(helm-make-source "External Commands" 'helm-external-commands
|
||||||
|
:data (helm-external-commands-list-1 'sort)))
|
||||||
|
:buffer "*helm externals commands*"
|
||||||
|
:prompt "RunProgram: ")
|
||||||
|
;; Remove from history no more valid executables.
|
||||||
|
(setq helm-external-command-history
|
||||||
|
(cl-loop for i in helm-external-command-history
|
||||||
|
when (executable-find i) collect i)))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'helm-external)
|
||||||
|
|
||||||
|
;;; helm-external ends here
|
144
code/elpa/helm-20240320.541/helm-fd.el
Normal file
144
code/elpa/helm-20240320.541/helm-fd.el
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
;;; helm-fd.el --- helm interface for fd command line tool. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-types)
|
||||||
|
|
||||||
|
(declare-function ansi-color-apply "ansi-color.el")
|
||||||
|
(declare-function split-string-shell-command "shell.el")
|
||||||
|
|
||||||
|
(defvar helm-fd-executable "fd"
|
||||||
|
"The fd shell command executable.")
|
||||||
|
|
||||||
|
(defcustom helm-fd-switches '("--no-ignore" "--hidden" "--type" "f" "--type" "d" "--color" "always")
|
||||||
|
"A list of options to pass to fd shell command."
|
||||||
|
:type '(repeat string)
|
||||||
|
:group 'helm-files)
|
||||||
|
|
||||||
|
(defcustom helm-fd-mode-line-function 'helm-fd-default-mode-line
|
||||||
|
"Function called when `fd' process is finished to format mode-line."
|
||||||
|
:type 'function
|
||||||
|
:group 'helm-files)
|
||||||
|
|
||||||
|
(defface helm-fd-finish
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "Green"))
|
||||||
|
"Face used in mode line when fd process ends."
|
||||||
|
:group 'helm-grep-faces)
|
||||||
|
|
||||||
|
(defvar helm-fd-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-generic-files-map)
|
||||||
|
(define-key map (kbd "C-]") 'undefined)
|
||||||
|
(define-key map (kbd "DEL") 'helm-delete-backward-no-update)
|
||||||
|
(define-key map (kbd "M-<down>") 'helm-fd-next-directory)
|
||||||
|
(define-key map (kbd "M-<up>") 'helm-fd-previous-directory)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defun helm-fd-next-directory-1 (arg)
|
||||||
|
(with-helm-window
|
||||||
|
(let ((cur-dir (helm-basedir (helm-get-selection))))
|
||||||
|
(while (equal cur-dir (helm-basedir (helm-get-selection)))
|
||||||
|
(if (> arg 0)
|
||||||
|
(helm-next-line)
|
||||||
|
(helm-previous-line))))))
|
||||||
|
|
||||||
|
(defun helm-fd-next-directory ()
|
||||||
|
"Move to next directory in a helm-fd source."
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(helm-fd-next-directory-1 1)))
|
||||||
|
|
||||||
|
(defun helm-fd-previous-directory ()
|
||||||
|
"Move to previous directory in a helm-fd source."
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(helm-fd-next-directory-1 -1)))
|
||||||
|
|
||||||
|
(defclass helm-fd-class (helm-source-async)
|
||||||
|
((candidates-process :initform 'helm-fd-process)
|
||||||
|
(requires-pattern :initform 2)
|
||||||
|
(candidate-number-limit :initform 20000)
|
||||||
|
(nohighlight :initform t)
|
||||||
|
(help-message :initform 'helm-fd-help-message)
|
||||||
|
(filtered-candidate-transformer :initform 'helm-fd-fct)
|
||||||
|
(action :initform 'helm-type-file-actions)
|
||||||
|
(keymap :initform 'helm-fd-map)))
|
||||||
|
|
||||||
|
(defun helm-fd-process ()
|
||||||
|
"Initialize fd process in an helm async source."
|
||||||
|
(let* (process-connection-type
|
||||||
|
(cmd (append helm-fd-switches
|
||||||
|
(or (and (fboundp #'split-string-shell-command)
|
||||||
|
(split-string-shell-command helm-pattern))
|
||||||
|
(split-string helm-pattern))))
|
||||||
|
(proc (apply #'start-process "fd" nil helm-fd-executable cmd))
|
||||||
|
(start-time (float-time))
|
||||||
|
(fd-version (replace-regexp-in-string
|
||||||
|
"\n" ""
|
||||||
|
(shell-command-to-string
|
||||||
|
(concat helm-fd-executable " --version")))))
|
||||||
|
(helm-log "helm-fd-process" "Fd command:\nfd %s"
|
||||||
|
(mapconcat 'identity cmd " "))
|
||||||
|
(helm-log "helm-fd-process" "VERSION: %s" fd-version)
|
||||||
|
(prog1
|
||||||
|
proc
|
||||||
|
(set-process-sentinel
|
||||||
|
proc (lambda (_process event)
|
||||||
|
(if (string= event "finished\n")
|
||||||
|
(with-helm-window
|
||||||
|
(when helm-fd-mode-line-function
|
||||||
|
(funcall helm-fd-mode-line-function start-time fd-version)
|
||||||
|
(force-mode-line-update)))
|
||||||
|
(helm-log "helm-fd-process sentinel" "Error: Fd %s"
|
||||||
|
(replace-regexp-in-string "\n" "" event))))))))
|
||||||
|
|
||||||
|
(defun helm-fd-default-mode-line (start-time fd-version)
|
||||||
|
"Format mode-line with START-TIME and FD-VERSION, as well as `fd' results."
|
||||||
|
(setq mode-line-format
|
||||||
|
`(" " mode-line-buffer-identification " "
|
||||||
|
(:eval (format "L%s" (helm-candidate-number-at-point))) " "
|
||||||
|
(:eval (propertize
|
||||||
|
(format
|
||||||
|
"[%s process finished in %.2fs - (%s results)] "
|
||||||
|
,fd-version
|
||||||
|
,(- (float-time) start-time)
|
||||||
|
(helm-get-candidate-number))
|
||||||
|
'face 'helm-fd-finish)))))
|
||||||
|
|
||||||
|
(defun helm-fd-fct (candidates _source)
|
||||||
|
"The filtered-candidate-transformer function for helm-fd."
|
||||||
|
(cl-loop for i in candidates
|
||||||
|
collect (ansi-color-apply i)))
|
||||||
|
|
||||||
|
(defun helm-fd-1 (directory)
|
||||||
|
"Run fd shell command on DIRECTORY with helm interface."
|
||||||
|
(cl-assert (executable-find helm-fd-executable) nil "Could not find fd executable")
|
||||||
|
(cl-assert (not (file-remote-p directory)) nil "Fd not supported on remote directories")
|
||||||
|
(let ((default-directory directory))
|
||||||
|
(helm :sources (helm-make-source
|
||||||
|
(format "fd (%s)"
|
||||||
|
(abbreviate-file-name default-directory))
|
||||||
|
'helm-fd-class)
|
||||||
|
:buffer "*helm fd*")))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'helm-fd)
|
||||||
|
|
||||||
|
;;; helm-fd.el ends here
|
7014
code/elpa/helm-20240320.541/helm-files.el
Normal file
7014
code/elpa/helm-20240320.541/helm-files.el
Normal file
File diff suppressed because it is too large
Load diff
170
code/elpa/helm-20240320.541/helm-find.el
Normal file
170
code/elpa/helm-20240320.541/helm-find.el
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
;;; helm-find.el --- helm interface for find command. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm-files)
|
||||||
|
(require 'helm-external)
|
||||||
|
|
||||||
|
(defcustom helm-findutils-skip-boring-files t
|
||||||
|
"Ignore boring files in find command results."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-findutils-search-full-path nil
|
||||||
|
"Search in full path with shell command find when non-nil.
|
||||||
|
I.e. use the -path/ipath arguments of find instead of
|
||||||
|
-name/iname."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-find-noerrors nil
|
||||||
|
"Prevent showing error messages in helm buffer when non nil."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defvar helm-find-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-generic-files-map)
|
||||||
|
(define-key map (kbd "DEL") 'helm-delete-backward-no-update)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defvar helm-source-findutils
|
||||||
|
(helm-build-async-source "Find"
|
||||||
|
:header-name (lambda (name)
|
||||||
|
(concat name " in [" (helm-default-directory) "]"))
|
||||||
|
:candidates-process 'helm-find-shell-command-fn
|
||||||
|
:filtered-candidate-transformer 'helm-findutils-transformer
|
||||||
|
:action-transformer 'helm-transform-file-load-el
|
||||||
|
:persistent-action 'helm-ff-kill-or-find-buffer-fname
|
||||||
|
:action 'helm-type-file-actions
|
||||||
|
:help-message 'helm-generic-file-help-message
|
||||||
|
:keymap helm-find-map
|
||||||
|
:candidate-number-limit 9999
|
||||||
|
:requires-pattern 3))
|
||||||
|
|
||||||
|
(defun helm-findutils-transformer (candidates _source)
|
||||||
|
(let (non-essential
|
||||||
|
(default-directory (helm-default-directory)))
|
||||||
|
(cl-loop for i in candidates
|
||||||
|
for abs = (expand-file-name
|
||||||
|
(helm-aif (file-remote-p default-directory)
|
||||||
|
(concat it i) i))
|
||||||
|
for type = (car (file-attributes abs))
|
||||||
|
for disp = (if (and helm-ff-transformer-show-only-basename
|
||||||
|
(not (string-match "[.]\\{1,2\\}$" i)))
|
||||||
|
(helm-basename abs) abs)
|
||||||
|
collect (cond ((eq t type)
|
||||||
|
(cons (propertize disp 'face 'helm-ff-directory)
|
||||||
|
abs))
|
||||||
|
((stringp type)
|
||||||
|
(cons (propertize disp 'face 'helm-ff-symlink)
|
||||||
|
abs))
|
||||||
|
(t (cons (propertize disp 'face 'helm-ff-file)
|
||||||
|
abs))))))
|
||||||
|
|
||||||
|
(defun helm-find--build-cmd-line ()
|
||||||
|
(require 'find-cmd)
|
||||||
|
(let* ((default-directory (or (file-remote-p default-directory 'localname)
|
||||||
|
default-directory))
|
||||||
|
(patterns+options (split-string helm-pattern "\\(\\`\\| +\\)\\* +"))
|
||||||
|
(fold-case (helm-set-case-fold-search (car patterns+options)))
|
||||||
|
(patterns (split-string (car patterns+options)))
|
||||||
|
(additional-options (and (cdr patterns+options)
|
||||||
|
(list (concat (cadr patterns+options) " "))))
|
||||||
|
(ignored-dirs ())
|
||||||
|
(ignored-files (when helm-findutils-skip-boring-files
|
||||||
|
(cl-loop for f in completion-ignored-extensions
|
||||||
|
if (string-match "/$" f)
|
||||||
|
do (push (replace-match "" nil t f)
|
||||||
|
ignored-dirs)
|
||||||
|
else collect (concat "*" f))))
|
||||||
|
(path-or-name (if helm-findutils-search-full-path
|
||||||
|
'(ipath path) '(iname name)))
|
||||||
|
(name-or-iname (if fold-case
|
||||||
|
(car path-or-name) (cadr path-or-name))))
|
||||||
|
(find-cmd (and ignored-dirs
|
||||||
|
`(prune (name ,@ignored-dirs)))
|
||||||
|
(and ignored-files
|
||||||
|
`(not (name ,@ignored-files)))
|
||||||
|
`(and ,@(mapcar
|
||||||
|
(lambda (pattern)
|
||||||
|
`(,name-or-iname ,(concat "*" pattern "*")))
|
||||||
|
patterns)
|
||||||
|
,@additional-options))))
|
||||||
|
|
||||||
|
(defun helm-find-shell-command-fn ()
|
||||||
|
"Asynchronously fetch candidates for `helm-find'.
|
||||||
|
Additional find options can be specified after a \"*\"
|
||||||
|
separator."
|
||||||
|
(let* (process-connection-type
|
||||||
|
non-essential
|
||||||
|
(cmd (concat (helm-find--build-cmd-line)
|
||||||
|
(if helm-find-noerrors "2> /dev/null" "")))
|
||||||
|
(proc (start-file-process-shell-command "hfind" helm-buffer cmd)))
|
||||||
|
(helm-log "helm-find-shell-command-fn" "Find command:\n%s" cmd)
|
||||||
|
(prog1 proc
|
||||||
|
(set-process-sentinel
|
||||||
|
proc
|
||||||
|
(lambda (process event)
|
||||||
|
(helm-process-deferred-sentinel-hook
|
||||||
|
process event (helm-default-directory))
|
||||||
|
(if (string= event "finished\n")
|
||||||
|
(helm-locate-update-mode-line "Find")
|
||||||
|
(helm-log "helm-find-shell-command-fn sentinel" "Error: Find %s"
|
||||||
|
(replace-regexp-in-string "\n" "" event))))))))
|
||||||
|
|
||||||
|
(defun helm-find-1 (dir)
|
||||||
|
(let ((default-directory (file-name-as-directory dir)))
|
||||||
|
(helm :sources 'helm-source-findutils
|
||||||
|
:buffer "*helm find*"
|
||||||
|
:ff-transformer-show-only-basename nil
|
||||||
|
:case-fold-search helm-file-name-case-fold-search)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Preconfigured commands
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-find (arg)
|
||||||
|
"Preconfigured `helm' for the find shell command.
|
||||||
|
|
||||||
|
Recursively find files whose names are matched by all specified
|
||||||
|
globbing PATTERNs under the current directory using the external
|
||||||
|
program specified in `find-program' (usually \"find\"). Every
|
||||||
|
input PATTERN is silently wrapped into two stars: *PATTERN*.
|
||||||
|
|
||||||
|
With prefix argument, prompt for a directory to search.
|
||||||
|
|
||||||
|
When user option `helm-findutils-search-full-path' is non-nil,
|
||||||
|
match against complete paths, otherwise, against file names
|
||||||
|
without directory part.
|
||||||
|
|
||||||
|
The (possibly empty) list of globbing PATTERNs can be followed by
|
||||||
|
the separator \"*\" plus any number of additional arguments that
|
||||||
|
are passed to \"find\" literally."
|
||||||
|
(interactive "P")
|
||||||
|
(let ((directory
|
||||||
|
(if arg
|
||||||
|
(file-name-as-directory
|
||||||
|
(read-directory-name "DefaultDirectory: "))
|
||||||
|
default-directory)))
|
||||||
|
(helm-find-1 directory)))
|
||||||
|
|
||||||
|
(provide 'helm-find)
|
||||||
|
|
||||||
|
;;; helm-find.el ends here
|
344
code/elpa/helm-20240320.541/helm-font.el
Normal file
344
code/elpa/helm-20240320.541/helm-font.el
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
;;; helm-font --- Font and ucs selection for Helm -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
|
||||||
|
;; No warnings in Emacs built --without-x
|
||||||
|
(declare-function x-list-fonts "xfaces.c")
|
||||||
|
|
||||||
|
(declare-function helm-generic-sort-fn "helm-utils")
|
||||||
|
|
||||||
|
(defgroup helm-font nil
|
||||||
|
"Related applications to display fonts in Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-ucs-recent-size 10
|
||||||
|
"Number of recent chars to keep."
|
||||||
|
:type 'integer
|
||||||
|
:group 'helm-font)
|
||||||
|
|
||||||
|
(defcustom helm-ucs-actions
|
||||||
|
'(("Insert character" . helm-ucs-insert-char)
|
||||||
|
("Insert character name" . helm-ucs-insert-name)
|
||||||
|
("Insert character code in hex" . helm-ucs-insert-code)
|
||||||
|
("Kill marked characters" . helm-ucs-kill-char)
|
||||||
|
("Kill name" . helm-ucs-kill-name)
|
||||||
|
("Kill code" . helm-ucs-kill-code)
|
||||||
|
("Describe char" . helm-ucs-describe-char))
|
||||||
|
"Actions for `helm-source-ucs'."
|
||||||
|
:group 'helm-font
|
||||||
|
:type '(alist :key-type string :value-type function))
|
||||||
|
|
||||||
|
(defvar helm-ucs-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "<C-backspace>") 'helm-ucs-persistent-delete)
|
||||||
|
(define-key map (kbd "<C-left>") 'helm-ucs-persistent-backward)
|
||||||
|
(define-key map (kbd "<C-right>") 'helm-ucs-persistent-forward)
|
||||||
|
(define-key map (kbd "C-c SPC") 'helm-ucs-persistent-insert-space)
|
||||||
|
map)
|
||||||
|
"Keymap for `helm-ucs'.")
|
||||||
|
|
||||||
|
(defface helm-ucs-char
|
||||||
|
`((((class color) (background dark))
|
||||||
|
,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "Gold"))
|
||||||
|
"Face used to display ucs characters."
|
||||||
|
:group 'helm-font)
|
||||||
|
|
||||||
|
;;; Xfont selection
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-xfonts-cache nil)
|
||||||
|
(defvar helm-previous-font nil)
|
||||||
|
(defvar helm-source-xfonts
|
||||||
|
(helm-build-sync-source "X Fonts"
|
||||||
|
:init (lambda ()
|
||||||
|
(unless helm-xfonts-cache
|
||||||
|
(setq helm-xfonts-cache
|
||||||
|
(x-list-fonts "*")))
|
||||||
|
;; Save current font so it can be restored in cleanup
|
||||||
|
(setq helm-previous-font (cdr (assq 'font (frame-parameters)))))
|
||||||
|
:candidates 'helm-xfonts-cache
|
||||||
|
:action '(("Copy font to kill ring" . (lambda (elm)
|
||||||
|
(kill-new elm)))
|
||||||
|
("Set font" . (lambda (elm)
|
||||||
|
(kill-new elm)
|
||||||
|
(set-frame-font elm 'keep-size)
|
||||||
|
(message "Font copied to kill ring"))))
|
||||||
|
:cleanup (lambda ()
|
||||||
|
;; Restore previous font
|
||||||
|
(set-frame-font helm-previous-font 'keep-size))
|
||||||
|
:persistent-action (lambda (new-font)
|
||||||
|
(set-frame-font new-font 'keep-size)
|
||||||
|
(kill-new new-font))
|
||||||
|
:persistent-help "Preview font and copy to kill-ring"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; 𝕌𝕔𝕤 𝕊𝕪𝕞𝕓𝕠𝕝 𝕔𝕠𝕞𝕡𝕝𝕖𝕥𝕚𝕠𝕟
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-ucs--max-len nil)
|
||||||
|
(defvar helm-ucs--names nil)
|
||||||
|
(defvar helm-ucs-history nil)
|
||||||
|
(defvar helm-ucs-recent nil
|
||||||
|
"Ring of recent `helm-ucs' selections.")
|
||||||
|
|
||||||
|
(defun helm-calculate-ucs-alist-max-len (names)
|
||||||
|
"Calculate the length of the longest NAMES list candidate."
|
||||||
|
(cl-loop for (_n . v) in names
|
||||||
|
maximize (length (format "#x%x:" v)) into code
|
||||||
|
maximize (max 1 (string-width (format "%c" v))) into char
|
||||||
|
finally return (cons code char)))
|
||||||
|
|
||||||
|
(defun helm-calculate-ucs-hash-table-max-len (names)
|
||||||
|
"Calculate the length of the longest NAMES hash table candidate."
|
||||||
|
(cl-loop for _n being the hash-keys of names
|
||||||
|
using (hash-values v)
|
||||||
|
maximize (length (format "#x%x:" v)) into code
|
||||||
|
maximize (max 1 (string-width (format "%c" v))) into char
|
||||||
|
finally return (cons code char)))
|
||||||
|
|
||||||
|
(defun helm-calculate-ucs-max-len ()
|
||||||
|
"Calculate the length of the longest `ucs-names' candidate."
|
||||||
|
(let ((ucs-struct (ucs-names)))
|
||||||
|
(if (hash-table-p ucs-struct)
|
||||||
|
(helm-calculate-ucs-hash-table-max-len ucs-struct)
|
||||||
|
(helm-calculate-ucs-alist-max-len ucs-struct))))
|
||||||
|
|
||||||
|
(defun helm-ucs-collect-symbols-alist (names)
|
||||||
|
"Collect ucs symbols from the NAMES list."
|
||||||
|
(cl-loop with pr = (make-progress-reporter
|
||||||
|
"collecting ucs names"
|
||||||
|
0 (length names))
|
||||||
|
for (n . v) in names
|
||||||
|
for count from 1
|
||||||
|
for xcode = (format "#x%x:" v)
|
||||||
|
for len = (length xcode)
|
||||||
|
for diff = (- (car helm-ucs--max-len) len)
|
||||||
|
for code = (format "(#x%x): " v)
|
||||||
|
for char = (propertize (format "%c" v)
|
||||||
|
'face 'helm-ucs-char)
|
||||||
|
unless (or (string= "" n)
|
||||||
|
;; `char-displayable-p' return a font object or
|
||||||
|
;; t for some char that are displayable but have
|
||||||
|
;; no special font (e.g 10) so filter out char
|
||||||
|
;; with no font.
|
||||||
|
(not (fontp (char-displayable-p (read xcode)))))
|
||||||
|
collect
|
||||||
|
(concat code (make-string diff ? )
|
||||||
|
char " " n)
|
||||||
|
and do (progress-reporter-update pr count)))
|
||||||
|
|
||||||
|
(defun helm-ucs-collect-symbols-hash-table (names)
|
||||||
|
"Collect ucs symbols from the NAMES hash-table."
|
||||||
|
(cl-loop with pr = (make-progress-reporter
|
||||||
|
"collecting ucs names"
|
||||||
|
0 (hash-table-count names))
|
||||||
|
for n being the hash-keys of names
|
||||||
|
using (hash-values v)
|
||||||
|
for count from 1
|
||||||
|
for xcode = (format "#x%x:" v)
|
||||||
|
for len = (length xcode)
|
||||||
|
for diff = (- (car helm-ucs--max-len) len)
|
||||||
|
for code = (format "(#x%x): " v)
|
||||||
|
for char = (propertize (format "%c" v)
|
||||||
|
'face 'helm-ucs-char)
|
||||||
|
unless (or (string= "" n)
|
||||||
|
(not (fontp (char-displayable-p (read xcode)))))
|
||||||
|
collect
|
||||||
|
(concat code (make-string diff ? )
|
||||||
|
char " " n)
|
||||||
|
and do (progress-reporter-update pr count)))
|
||||||
|
|
||||||
|
(defun helm-ucs-collect-symbols (ucs-struct)
|
||||||
|
"Collect ucs symbols from UCS-STRUCT.
|
||||||
|
|
||||||
|
Depending on the Emacs version, the variable `ucs-names' can
|
||||||
|
either be an alist or a hash-table."
|
||||||
|
(if (hash-table-p ucs-struct)
|
||||||
|
(helm-ucs-collect-symbols-hash-table ucs-struct)
|
||||||
|
(helm-ucs-collect-symbols-alist ucs-struct)))
|
||||||
|
|
||||||
|
(defun helm-ucs-init ()
|
||||||
|
"Initialize a Helm buffer with ucs symbols.
|
||||||
|
Only math* symbols are collected."
|
||||||
|
(unless helm-ucs--max-len
|
||||||
|
(setq helm-ucs--max-len
|
||||||
|
(helm-calculate-ucs-max-len)))
|
||||||
|
(or helm-ucs--names
|
||||||
|
(setq helm-ucs--names
|
||||||
|
(helm-ucs-collect-symbols (ucs-names)))))
|
||||||
|
|
||||||
|
;; Actions (insertion)
|
||||||
|
|
||||||
|
(defun helm-ucs-match (candidate n)
|
||||||
|
"Return the N part of an ucs CANDIDATE.
|
||||||
|
Where N=1 is the ucs code, N=2 the ucs char and N=3 the ucs
|
||||||
|
name."
|
||||||
|
(when (string-match
|
||||||
|
"^(\\(#x[a-f0-9]+\\)): *\\(.\\) *\\([^:]+\\)+"
|
||||||
|
candidate)
|
||||||
|
(match-string n candidate)))
|
||||||
|
|
||||||
|
(defun helm-ucs-save-recentest (candidate)
|
||||||
|
(let ((lst (cons candidate (delete candidate helm-ucs-recent))))
|
||||||
|
(setq helm-ucs-recent
|
||||||
|
(if (> (length lst) helm-ucs-recent-size)
|
||||||
|
(nbutlast lst 1)
|
||||||
|
lst))))
|
||||||
|
|
||||||
|
(defun helm-ucs-insert (candidate n)
|
||||||
|
"Insert the N part of CANDIDATE."
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(helm-ucs-save-recentest candidate)
|
||||||
|
(insert (helm-ucs-match candidate n))))
|
||||||
|
|
||||||
|
(defun helm-ucs-insert-char (candidate)
|
||||||
|
"Insert ucs char part of CANDIDATE at point."
|
||||||
|
(helm-ucs-insert candidate 2))
|
||||||
|
|
||||||
|
(defun helm-ucs-insert-code (candidate)
|
||||||
|
"Insert ucs code part of CANDIDATE at point."
|
||||||
|
(helm-ucs-insert candidate 1))
|
||||||
|
|
||||||
|
(defun helm-ucs-insert-name (candidate)
|
||||||
|
"Insert ucs name part of CANDIDATE at point."
|
||||||
|
(helm-ucs-insert candidate 3))
|
||||||
|
|
||||||
|
;; Kill actions
|
||||||
|
(defun helm-ucs-kill-char (_candidate)
|
||||||
|
"Action that concatenate ucs marked chars."
|
||||||
|
(let ((marked (helm-marked-candidates)))
|
||||||
|
(cl-loop for candidate in marked
|
||||||
|
do (helm-ucs-save-recentest candidate))
|
||||||
|
(kill-new (mapconcat (lambda (x)
|
||||||
|
(helm-ucs-match x 2))
|
||||||
|
marked ""))))
|
||||||
|
|
||||||
|
(defun helm-ucs-kill-code (candidate)
|
||||||
|
(helm-ucs-save-recentest candidate)
|
||||||
|
(kill-new (helm-ucs-match candidate 1)))
|
||||||
|
|
||||||
|
(defun helm-ucs-kill-name (candidate)
|
||||||
|
(helm-ucs-save-recentest candidate)
|
||||||
|
(kill-new (helm-ucs-match candidate 3)))
|
||||||
|
|
||||||
|
;; Describe char
|
||||||
|
(defun helm-ucs-describe-char (candidate)
|
||||||
|
"Describe char CANDIDATE."
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert (helm-ucs-match candidate 2))
|
||||||
|
(describe-char (point-min))))
|
||||||
|
|
||||||
|
;; Navigation in current-buffer (persistent)
|
||||||
|
|
||||||
|
(defun helm-ucs-forward-char (_candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(forward-char 1)))
|
||||||
|
|
||||||
|
(defun helm-ucs-backward-char (_candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(forward-char -1)))
|
||||||
|
|
||||||
|
(defun helm-ucs-delete-backward (_candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(delete-char -1)))
|
||||||
|
|
||||||
|
(defun helm-ucs-insert-space (_candidate)
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(insert " ")))
|
||||||
|
|
||||||
|
(defun helm-ucs-persistent-forward ()
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(helm-set-attr 'action-forward 'helm-ucs-forward-char)
|
||||||
|
(helm-execute-persistent-action 'action-forward)))
|
||||||
|
(put 'helm-ucs-persistent-forward 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-ucs-persistent-backward ()
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(helm-set-attr 'action-back 'helm-ucs-backward-char)
|
||||||
|
(helm-execute-persistent-action 'action-back)))
|
||||||
|
(put 'helm-ucs-persistent-backward 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-ucs-persistent-delete ()
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(helm-set-attr 'action-delete 'helm-ucs-delete-backward)
|
||||||
|
(helm-execute-persistent-action 'action-delete)))
|
||||||
|
(put 'helm-ucs-persistent-delete 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-ucs-persistent-insert-space ()
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(helm-set-attr 'action-insert-space 'helm-ucs-insert-space)
|
||||||
|
(helm-execute-persistent-action 'action-insert-space)))
|
||||||
|
|
||||||
|
(defvar helm-source-ucs-recent
|
||||||
|
(helm-build-sync-source "Recent UCS"
|
||||||
|
:action 'helm-ucs-actions
|
||||||
|
:candidates (lambda () helm-ucs-recent)
|
||||||
|
:help-message helm-ucs-help-message
|
||||||
|
:keymap helm-ucs-map
|
||||||
|
:volatile t))
|
||||||
|
|
||||||
|
(defvar helm-source-ucs
|
||||||
|
(helm-build-in-buffer-source "UCS names"
|
||||||
|
:data #'helm-ucs-init
|
||||||
|
:get-line #'buffer-substring
|
||||||
|
:help-message 'helm-ucs-help-message
|
||||||
|
:filtered-candidate-transformer
|
||||||
|
(lambda (candidates _source) (sort candidates #'helm-generic-sort-fn))
|
||||||
|
:action 'helm-ucs-actions
|
||||||
|
:persistent-action (lambda (candidate)
|
||||||
|
(helm-ucs-insert-char candidate)
|
||||||
|
(helm-force-update))
|
||||||
|
:keymap helm-ucs-map)
|
||||||
|
"Source for collecting `ucs-names' math symbols.")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-select-xfont ()
|
||||||
|
"Preconfigured `helm' to select Xfont."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources 'helm-source-xfonts
|
||||||
|
:buffer "*helm select xfont*"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-ucs (arg)
|
||||||
|
"Preconfigured `helm' for `ucs-names'.
|
||||||
|
|
||||||
|
Called with a prefix arg force reloading cache."
|
||||||
|
(interactive "P")
|
||||||
|
(when arg
|
||||||
|
(setq helm-ucs--names nil
|
||||||
|
helm-ucs--max-len nil
|
||||||
|
ucs-names nil))
|
||||||
|
(let ((char (helm-aif (char-after) (string it))))
|
||||||
|
(helm :sources (list helm-source-ucs-recent helm-source-ucs)
|
||||||
|
:history 'helm-ucs-history
|
||||||
|
:input (and char (multibyte-string-p char) char)
|
||||||
|
:buffer "*helm ucs*")))
|
||||||
|
|
||||||
|
(provide 'helm-font)
|
||||||
|
|
||||||
|
;;; helm-font.el ends here
|
310
code/elpa/helm-20240320.541/helm-for-files.el
Normal file
310
code/elpa/helm-20240320.541/helm-for-files.el
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
;;; helm-for-files.el --- helm-for-files and related. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm-files)
|
||||||
|
(require 'helm-external)
|
||||||
|
(require 'helm-bookmark)
|
||||||
|
|
||||||
|
(defcustom helm-multi-files-toggle-locate-binding "C-c p"
|
||||||
|
"Default binding to switch back and forth locate in `helm-multi-files'."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-for-files-preferred-list
|
||||||
|
'(helm-source-buffers-list
|
||||||
|
helm-source-recentf
|
||||||
|
helm-source-bookmarks
|
||||||
|
helm-source-file-cache
|
||||||
|
helm-source-files-in-current-dir
|
||||||
|
helm-source-locate)
|
||||||
|
"Your preferred sources for `helm-for-files' and `helm-multi-files'.
|
||||||
|
|
||||||
|
When adding a source here it is up to you to ensure the library
|
||||||
|
of this source is accessible and properly loaded."
|
||||||
|
:type '(repeat (choice symbol))
|
||||||
|
:group 'helm-files)
|
||||||
|
|
||||||
|
(defcustom helm-for-files-tramp-not-fancy t
|
||||||
|
"Colorize remote files when non nil.
|
||||||
|
|
||||||
|
Be aware that a nil value will make tramp display very slow."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
;;; File Cache
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar file-cache-alist)
|
||||||
|
|
||||||
|
(defclass helm-file-cache (helm-source-in-buffer helm-type-file)
|
||||||
|
((init :initform (lambda () (require 'filecache)))))
|
||||||
|
|
||||||
|
(defun helm-file-cache-get-candidates ()
|
||||||
|
(cl-loop for item in file-cache-alist append
|
||||||
|
(cl-destructuring-bind (base &rest dirs) item
|
||||||
|
(cl-loop for dir in dirs collect
|
||||||
|
(concat dir base)))))
|
||||||
|
|
||||||
|
(defvar helm-source-file-cache nil)
|
||||||
|
|
||||||
|
(defcustom helm-file-cache-fuzzy-match nil
|
||||||
|
"Enable fuzzy matching in `helm-source-file-cache' when non--nil."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(set var val)
|
||||||
|
(setq helm-source-file-cache
|
||||||
|
(helm-make-source "File Cache" 'helm-file-cache
|
||||||
|
:fuzzy-match helm-file-cache-fuzzy-match
|
||||||
|
:data 'helm-file-cache-get-candidates))))
|
||||||
|
|
||||||
|
(cl-defun helm-file-cache-add-directory-recursively
|
||||||
|
(dir &optional match (ignore-dirs t))
|
||||||
|
(require 'filecache)
|
||||||
|
(cl-loop for f in (helm-walk-directory
|
||||||
|
dir
|
||||||
|
:path 'full
|
||||||
|
:directories nil
|
||||||
|
:match match
|
||||||
|
:skip-subdirs ignore-dirs)
|
||||||
|
do (file-cache-add-file f)))
|
||||||
|
|
||||||
|
(defun helm-transform-file-cache (actions _candidate)
|
||||||
|
(let ((source (helm-get-current-source)))
|
||||||
|
(if (string= (assoc-default 'name source) "File Cache")
|
||||||
|
(append actions
|
||||||
|
'(("Remove marked files from file-cache"
|
||||||
|
. helm-ff-file-cache-remove-file)))
|
||||||
|
actions)))
|
||||||
|
|
||||||
|
;;; Recentf files
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-recentf--basename-flag nil)
|
||||||
|
|
||||||
|
(defun helm-recentf-pattern-transformer (pattern)
|
||||||
|
(let ((pattern-no-flag (replace-regexp-in-string " -b" "" pattern)))
|
||||||
|
(cond ((and (string-match " " pattern-no-flag)
|
||||||
|
(string-match " -b\\'" pattern))
|
||||||
|
(setq helm-recentf--basename-flag t)
|
||||||
|
pattern-no-flag)
|
||||||
|
((string-match "\\([^ ]*\\) -b\\'" pattern)
|
||||||
|
(prog1 (match-string 1 pattern)
|
||||||
|
(setq helm-recentf--basename-flag t)))
|
||||||
|
(t (setq helm-recentf--basename-flag nil)
|
||||||
|
pattern))))
|
||||||
|
|
||||||
|
(defcustom helm-turn-on-recentf t
|
||||||
|
"Automatically turn on `recentf-mode' when non-nil."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defclass helm-recentf-source (helm-source-sync helm-type-file)
|
||||||
|
((init :initform (lambda ()
|
||||||
|
(require 'recentf)
|
||||||
|
(when helm-turn-on-recentf (recentf-mode 1))))
|
||||||
|
(candidates :initform (lambda () recentf-list))
|
||||||
|
(pattern-transformer :initform 'helm-recentf-pattern-transformer)
|
||||||
|
(match-part :initform (lambda (candidate)
|
||||||
|
(if (or helm-ff-transformer-show-only-basename
|
||||||
|
helm-recentf--basename-flag)
|
||||||
|
(helm-basename candidate) candidate)))
|
||||||
|
(migemo :initform t)
|
||||||
|
(persistent-action :initform 'helm-ff-kill-or-find-buffer-fname)))
|
||||||
|
|
||||||
|
(cl-defmethod helm--setup-source :after ((source helm-recentf-source))
|
||||||
|
(setf (slot-value source 'action)
|
||||||
|
(append (symbol-value (helm-actions-from-type-file))
|
||||||
|
'(("Delete file(s) from recentf" .
|
||||||
|
(lambda (_candidate)
|
||||||
|
(cl-loop for file in (helm-marked-candidates)
|
||||||
|
do (setq recentf-list (delete file recentf-list)))))))))
|
||||||
|
|
||||||
|
(defvar helm-source-recentf nil
|
||||||
|
"See (info \"(emacs)File Conveniences\").
|
||||||
|
Set `recentf-max-saved-items' to a bigger value if default is too
|
||||||
|
small.")
|
||||||
|
|
||||||
|
(defcustom helm-recentf-fuzzy-match nil
|
||||||
|
"Enable fuzzy matching in `helm-source-recentf' when non-nil."
|
||||||
|
:group 'helm-files
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(set var val)
|
||||||
|
(let ((helm-fuzzy-sort-fn 'helm-fuzzy-matching-sort-fn-preserve-ties-order))
|
||||||
|
(setq helm-source-recentf
|
||||||
|
(helm-make-source "Recentf" 'helm-recentf-source
|
||||||
|
:fuzzy-match val)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Files in current dir
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-highlight-files (files _source)
|
||||||
|
"A basic transformer for helm files sources.
|
||||||
|
Colorize only symlinks, directories and files."
|
||||||
|
(cl-loop with mp-fn = (or (assoc-default
|
||||||
|
'match-part (helm-get-current-source))
|
||||||
|
'identity)
|
||||||
|
for i in files
|
||||||
|
for disp = (if (and helm-ff-transformer-show-only-basename
|
||||||
|
(not (helm-ff-dot-file-p i))
|
||||||
|
(not (and helm--url-regexp
|
||||||
|
(string-match helm--url-regexp i)))
|
||||||
|
(not (string-match helm-ff-url-regexp i)))
|
||||||
|
(helm-basename i) (abbreviate-file-name i))
|
||||||
|
for isremote = (or (file-remote-p i)
|
||||||
|
(helm-file-on-mounted-network-p i))
|
||||||
|
;; Call file-attributes only if:
|
||||||
|
;; - file is not remote
|
||||||
|
;; - helm-for-files--tramp-not-fancy is nil and file is remote AND
|
||||||
|
;; connected. (Bug#1679)
|
||||||
|
for type = (and (or (null isremote)
|
||||||
|
(and (null helm-for-files-tramp-not-fancy)
|
||||||
|
(file-remote-p i nil t)))
|
||||||
|
(car (file-attributes i)))
|
||||||
|
collect
|
||||||
|
(cond ((and (null type) isremote) (cons disp i))
|
||||||
|
((stringp type)
|
||||||
|
(cons (propertize disp
|
||||||
|
'face 'helm-ff-symlink
|
||||||
|
'match-part (funcall mp-fn disp)
|
||||||
|
'help-echo (expand-file-name i))
|
||||||
|
i))
|
||||||
|
((eq type t)
|
||||||
|
(cons (propertize disp
|
||||||
|
'face 'helm-ff-directory
|
||||||
|
'match-part (funcall mp-fn disp)
|
||||||
|
'help-echo (expand-file-name i))
|
||||||
|
i))
|
||||||
|
(t (let* ((ext (helm-file-name-extension disp))
|
||||||
|
(disp (propertize disp
|
||||||
|
'face 'helm-ff-file
|
||||||
|
'match-part (funcall mp-fn disp)
|
||||||
|
'help-echo (expand-file-name i))))
|
||||||
|
(when (condition-case _err
|
||||||
|
(string-match (format "\\.\\(%s\\)$" ext) disp)
|
||||||
|
(invalid-regexp nil))
|
||||||
|
(add-face-text-property
|
||||||
|
(match-beginning 1) (match-end 1)
|
||||||
|
'helm-ff-file-extension nil disp))
|
||||||
|
(cons disp i))))))
|
||||||
|
|
||||||
|
(defclass helm-files-in-current-dir-source (helm-source-sync helm-type-file)
|
||||||
|
((candidates :initform (lambda ()
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(let ((dir (helm-current-directory)))
|
||||||
|
(when (file-accessible-directory-p dir)
|
||||||
|
(directory-files dir t))))))
|
||||||
|
(pattern-transformer :initform 'helm-recentf-pattern-transformer)
|
||||||
|
(match-part :initform (lambda (candidate)
|
||||||
|
(if (or helm-ff-transformer-show-only-basename
|
||||||
|
helm-recentf--basename-flag)
|
||||||
|
(helm-basename candidate) candidate)))
|
||||||
|
(fuzzy-match :initform t)
|
||||||
|
(migemo :initform t)))
|
||||||
|
|
||||||
|
(defvar helm-source-files-in-current-dir
|
||||||
|
(helm-make-source "Files from Current Directory"
|
||||||
|
'helm-files-in-current-dir-source))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-for-files ()
|
||||||
|
"Preconfigured `helm' for opening files.
|
||||||
|
Run all sources defined in `helm-for-files-preferred-list'."
|
||||||
|
(interactive)
|
||||||
|
(require 'helm-x-files)
|
||||||
|
(unless helm-source-buffers-list
|
||||||
|
(setq helm-source-buffers-list
|
||||||
|
(helm-make-source "Buffers" 'helm-source-buffers)))
|
||||||
|
(helm :sources helm-for-files-preferred-list
|
||||||
|
:ff-transformer-show-only-basename nil
|
||||||
|
:buffer "*helm for files*"
|
||||||
|
:truncate-lines helm-buffers-truncate-lines))
|
||||||
|
|
||||||
|
(defun helm-multi-files-toggle-to-locate ()
|
||||||
|
(interactive)
|
||||||
|
(with-helm-alive-p
|
||||||
|
(with-helm-buffer
|
||||||
|
(if (setq helm-multi-files--toggle-locate
|
||||||
|
(not helm-multi-files--toggle-locate))
|
||||||
|
(progn
|
||||||
|
(helm-set-sources (unless (memq 'helm-source-locate
|
||||||
|
helm-sources)
|
||||||
|
(cons 'helm-source-locate helm-sources)))
|
||||||
|
(helm-set-source-filter '(helm-source-locate)))
|
||||||
|
(helm-kill-async-processes)
|
||||||
|
(helm-set-sources (remove 'helm-source-locate
|
||||||
|
helm-for-files-preferred-list))
|
||||||
|
(helm-set-source-filter nil)))))
|
||||||
|
(put 'helm-multi-files-toggle-to-locate 'helm-only t)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-multi-files ()
|
||||||
|
"Preconfigured helm like `helm-for-files' but running locate only on demand.
|
||||||
|
|
||||||
|
Allow toggling back and forth from locate to others sources with
|
||||||
|
`helm-multi-files-toggle-locate-binding' key.
|
||||||
|
This avoids launching locate needlessly when what you are
|
||||||
|
searching for is already found."
|
||||||
|
(interactive)
|
||||||
|
(require 'helm-x-files)
|
||||||
|
(unless helm-source-buffers-list
|
||||||
|
(setq helm-source-buffers-list
|
||||||
|
(helm-make-source "Buffers" 'helm-source-buffers)))
|
||||||
|
(setq helm-multi-files--toggle-locate nil)
|
||||||
|
(helm-locate-set-command)
|
||||||
|
(helm-set-local-variable 'helm-async-outer-limit-hook
|
||||||
|
(list (lambda ()
|
||||||
|
(when (and helm-locate-fuzzy-match
|
||||||
|
(not (string-match-p
|
||||||
|
"\\s-" helm-pattern)))
|
||||||
|
(helm-redisplay-buffer)))))
|
||||||
|
(let ((sources (remove 'helm-source-locate helm-for-files-preferred-list))
|
||||||
|
(helm-locate-command
|
||||||
|
(if helm-locate-fuzzy-match
|
||||||
|
(unless (string-match-p "\\`locate -b" helm-locate-command)
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\\`locate" "locate -b" helm-locate-command))
|
||||||
|
helm-locate-command))
|
||||||
|
(old-key (lookup-key
|
||||||
|
helm-map
|
||||||
|
(read-kbd-macro helm-multi-files-toggle-locate-binding))))
|
||||||
|
(with-helm-temp-hook 'helm-after-initialize-hook
|
||||||
|
(define-key helm-map (kbd helm-multi-files-toggle-locate-binding)
|
||||||
|
'helm-multi-files-toggle-to-locate))
|
||||||
|
(unwind-protect
|
||||||
|
(helm :sources sources
|
||||||
|
:ff-transformer-show-only-basename nil
|
||||||
|
:buffer "*helm multi files*"
|
||||||
|
:truncate-lines helm-buffers-truncate-lines)
|
||||||
|
(define-key helm-map (kbd helm-multi-files-toggle-locate-binding)
|
||||||
|
old-key))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-recentf ()
|
||||||
|
"Preconfigured `helm' for `recentf'."
|
||||||
|
(interactive)
|
||||||
|
(helm :sources 'helm-source-recentf
|
||||||
|
:ff-transformer-show-only-basename nil
|
||||||
|
:buffer "*helm recentf*"))
|
||||||
|
|
||||||
|
(provide 'helm-for-files)
|
||||||
|
|
||||||
|
;;; helm-for-files.el ends here
|
104
code/elpa/helm-20240320.541/helm-global-bindings.el
Normal file
104
code/elpa/helm-20240320.541/helm-global-bindings.el
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
;;; helm-global-bindings.el --- Bind global helm commands -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm-lib) ; For helm-aif (bug #2520).
|
||||||
|
|
||||||
|
|
||||||
|
;;; Command Keymap
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defgroup helm-global-bindings nil
|
||||||
|
"Global bindings for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-command-prefix-key
|
||||||
|
(helm-aif (car (where-is-internal 'Control-X-prefix (list global-map)))
|
||||||
|
(concat it [?c]))
|
||||||
|
"The prefix key used to call Helm commands from the `global-map'.
|
||||||
|
|
||||||
|
Its default value is `C-x c'.
|
||||||
|
This key is bound to the function `helm-command-prefix' in the global map.
|
||||||
|
The definition of `helm-command-prefix' is the keymap `helm-command-map'.
|
||||||
|
Using `setq' to modify this variable will have no effect."
|
||||||
|
:type '(choice (string :tag "Key") (const :tag "no binding"))
|
||||||
|
:set
|
||||||
|
(lambda (var key)
|
||||||
|
(helm-aif (and (boundp var) (symbol-value var))
|
||||||
|
(global-unset-key (read-kbd-macro it)))
|
||||||
|
(when key
|
||||||
|
(global-set-key (read-kbd-macro key) 'helm-command-prefix))
|
||||||
|
(set var key)))
|
||||||
|
|
||||||
|
(defvar helm-command-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map (kbd "a") 'helm-apropos)
|
||||||
|
(define-key map (kbd "e") 'helm-etags-select)
|
||||||
|
(define-key map (kbd "l") 'helm-locate)
|
||||||
|
(define-key map (kbd "L") 'helm-locate-library)
|
||||||
|
(define-key map (kbd "s") 'helm-surfraw)
|
||||||
|
(define-key map (kbd "r") 'helm-regexp)
|
||||||
|
(define-key map (kbd "m") 'helm-man-woman)
|
||||||
|
(define-key map (kbd "t") 'helm-top)
|
||||||
|
(define-key map (kbd "/") 'helm-find)
|
||||||
|
(define-key map (kbd "i") 'helm-imenu)
|
||||||
|
(define-key map (kbd "I") 'helm-imenu-in-all-buffers)
|
||||||
|
(define-key map (kbd "<tab>") 'helm-lisp-completion-at-point)
|
||||||
|
(define-key map (kbd "p") 'helm-list-emacs-process)
|
||||||
|
(define-key map (kbd "C-x r b") 'helm-filtered-bookmarks)
|
||||||
|
(define-key map (kbd "M-y") 'helm-show-kill-ring)
|
||||||
|
(define-key map (kbd "C-c <SPC>") 'helm-all-mark-rings)
|
||||||
|
(define-key map (kbd "C-x C-f") 'helm-find-files)
|
||||||
|
(define-key map (kbd "f") 'helm-multi-files)
|
||||||
|
(define-key map (kbd "C-:") 'helm-eval-expression-with-eldoc)
|
||||||
|
(define-key map (kbd "C-,") 'helm-calcul-expression)
|
||||||
|
(define-key map (kbd "M-x") 'helm-M-x)
|
||||||
|
(define-key map (kbd "M-s o") 'helm-occur)
|
||||||
|
(define-key map (kbd "M-g a") 'helm-do-grep-ag)
|
||||||
|
(define-key map (kbd "c") 'helm-colors)
|
||||||
|
(define-key map (kbd "F") 'helm-select-xfont)
|
||||||
|
(define-key map (kbd "8") 'helm-ucs)
|
||||||
|
(define-key map (kbd "C-c f") 'helm-recentf)
|
||||||
|
(define-key map (kbd "C-c g") 'helm-google-suggest)
|
||||||
|
(define-key map (kbd "h i") 'helm-info-at-point)
|
||||||
|
(define-key map (kbd "h r") 'helm-info-emacs)
|
||||||
|
(define-key map (kbd "h g") 'helm-info-gnus)
|
||||||
|
(define-key map (kbd "h h") 'helm-documentation)
|
||||||
|
(define-key map (kbd "C-x C-b") 'helm-buffers-list)
|
||||||
|
(define-key map (kbd "C-x r i") 'helm-register)
|
||||||
|
(define-key map (kbd "C-c C-x") 'helm-run-external-command)
|
||||||
|
(define-key map (kbd "b") 'helm-resume)
|
||||||
|
(define-key map (kbd "M-g i") 'helm-gid)
|
||||||
|
(define-key map (kbd "@") 'helm-packages)
|
||||||
|
map)
|
||||||
|
"Default keymap for \\[helm-command-prefix] commands.
|
||||||
|
The normal global definition of the character \\[helm-command-prefix] indirects to this keymap.")
|
||||||
|
|
||||||
|
(fset 'helm-command-prefix helm-command-map)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Menu
|
||||||
|
|
||||||
|
(require 'helm-easymenu)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Provide
|
||||||
|
|
||||||
|
(provide 'helm-global-bindings)
|
||||||
|
|
||||||
|
;;; helm-global-bindings.el ends here
|
1800
code/elpa/helm-20240320.541/helm-grep.el
Normal file
1800
code/elpa/helm-20240320.541/helm-grep.el
Normal file
File diff suppressed because it is too large
Load diff
2552
code/elpa/helm-20240320.541/helm-help.el
Normal file
2552
code/elpa/helm-20240320.541/helm-help.el
Normal file
File diff suppressed because it is too large
Load diff
125
code/elpa/helm-20240320.541/helm-id-utils.el
Normal file
125
code/elpa/helm-20240320.541/helm-id-utils.el
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
;;; helm-id-utils.el --- Helm interface for id-utils. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'helm-grep)
|
||||||
|
(require 'helm-help)
|
||||||
|
|
||||||
|
(defgroup helm-id-utils nil
|
||||||
|
"ID-Utils related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-gid-program "gid"
|
||||||
|
"Name of gid command (usually `gid').
|
||||||
|
For Mac OS X users, if you install GNU coreutils, the name `gid'
|
||||||
|
might be occupied by `id' from GNU coreutils, and you should set
|
||||||
|
it to correct name (or absolute path). For example, if using
|
||||||
|
MacPorts to install id-utils, it should be `gid32'."
|
||||||
|
:group 'helm-id-utils
|
||||||
|
:type 'file)
|
||||||
|
|
||||||
|
(defcustom helm-gid-db-file-name "ID"
|
||||||
|
"Name of a database file created by `mkid' command from `ID-utils'."
|
||||||
|
:group 'helm-id-utils
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defun helm-gid-candidates-process ()
|
||||||
|
(let* ((patterns (helm-mm-split-pattern helm-pattern))
|
||||||
|
(default-com (format "%s -r %s" helm-gid-program
|
||||||
|
(shell-quote-argument (car patterns))))
|
||||||
|
(cmd (helm-aif (cdr patterns)
|
||||||
|
(concat default-com
|
||||||
|
(cl-loop for p in it
|
||||||
|
concat (format " | grep --color=always %s"
|
||||||
|
(shell-quote-argument p))))
|
||||||
|
default-com))
|
||||||
|
(proc (start-process-shell-command
|
||||||
|
"gid" helm-buffer cmd)))
|
||||||
|
(set (make-local-variable 'helm-grep-last-cmd-line) cmd)
|
||||||
|
(prog1 proc
|
||||||
|
(set-process-sentinel
|
||||||
|
proc (lambda (_process event)
|
||||||
|
(when (string= event "finished\n")
|
||||||
|
(helm-maybe-show-help-echo)
|
||||||
|
(with-helm-window
|
||||||
|
(setq mode-line-format
|
||||||
|
'(" " mode-line-buffer-identification " "
|
||||||
|
(:eval (format "L%s" (helm-candidate-number-at-point))) " "
|
||||||
|
(:eval (propertize
|
||||||
|
(format "[Helm Gid process finished - (%s results)]"
|
||||||
|
(max (1- (count-lines
|
||||||
|
(point-min) (point-max)))
|
||||||
|
0))
|
||||||
|
'face 'helm-locate-finish))))
|
||||||
|
(force-mode-line-update))
|
||||||
|
(helm-log "helm-gid-candidates-process" "Error: Gid %s"
|
||||||
|
(replace-regexp-in-string "\n" "" event))))))))
|
||||||
|
|
||||||
|
(defun helm-gid-filtered-candidate-transformer (candidates _source)
|
||||||
|
;; "gid -r" may add dups in some rare cases.
|
||||||
|
(cl-loop for c in (helm-fast-remove-dups candidates :test 'equal)
|
||||||
|
collect (helm-grep--filter-candidate-1 c)))
|
||||||
|
|
||||||
|
(defclass helm-gid-source (helm-source-async)
|
||||||
|
((header-name
|
||||||
|
:initform
|
||||||
|
(lambda (name)
|
||||||
|
(concat name " [" (helm-get-attr 'db-dir) "]")))
|
||||||
|
(db-dir :initarg :db-dir
|
||||||
|
:initform nil
|
||||||
|
:custom string
|
||||||
|
:documentation " Location of ID file.")
|
||||||
|
(candidates-process :initform #'helm-gid-candidates-process)
|
||||||
|
(filtered-candidate-transformer
|
||||||
|
:initform #'helm-gid-filtered-candidate-transformer)
|
||||||
|
(candidate-number-limit :initform 99999)
|
||||||
|
(action :initform (helm-make-actions
|
||||||
|
"Find File" 'helm-grep-action
|
||||||
|
"Find file other frame" 'helm-grep-other-frame
|
||||||
|
"Save results in grep buffer" 'helm-grep-save-results
|
||||||
|
"Find file other window" 'helm-grep-other-window))
|
||||||
|
(persistent-action :initform 'helm-grep-persistent-action)
|
||||||
|
(history :initform 'helm-grep-history)
|
||||||
|
(nohighlight :initform t)
|
||||||
|
(help-message :initform 'helm-grep-help-message)
|
||||||
|
(requires-pattern :initform 2)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-gid ()
|
||||||
|
"Preconfigured `helm' for `gid' command line of `ID-Utils'.
|
||||||
|
Need A database created with the command `mkid' above
|
||||||
|
`default-directory'.
|
||||||
|
Need id-utils as dependency which provide `mkid', `gid' etc..
|
||||||
|
See <https://www.gnu.org/software/idutils/>."
|
||||||
|
(interactive)
|
||||||
|
(let* ((db (locate-dominating-file
|
||||||
|
default-directory
|
||||||
|
helm-gid-db-file-name))
|
||||||
|
(helm-grep-default-directory-fn
|
||||||
|
(lambda () default-directory))
|
||||||
|
(helm-maybe-use-default-as-input t))
|
||||||
|
(cl-assert db nil "No DataBase found, create one with `mkid'")
|
||||||
|
(helm :sources (helm-make-source "Gid" 'helm-gid-source
|
||||||
|
:db-dir db)
|
||||||
|
:buffer "*helm gid*"
|
||||||
|
:keymap helm-grep-map
|
||||||
|
:truncate-lines helm-grep-truncate-lines)))
|
||||||
|
|
||||||
|
(provide 'helm-id-utils)
|
||||||
|
|
||||||
|
;;; helm-id-utils ends here
|
542
code/elpa/helm-20240320.541/helm-imenu.el
Normal file
542
code/elpa/helm-20240320.541/helm-imenu.el
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
;;; helm-imenu.el --- Helm interface for Imenu -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-lib)
|
||||||
|
(require 'imenu)
|
||||||
|
(require 'helm-utils)
|
||||||
|
(require 'helm-help)
|
||||||
|
|
||||||
|
(defvar all-the-icons-default-adjust)
|
||||||
|
(defvar all-the-icons-scale-factor)
|
||||||
|
|
||||||
|
(declare-function which-function "which-func")
|
||||||
|
(declare-function all-the-icons-material "ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-octicon "ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-faicon "ext:all-the-icons.el")
|
||||||
|
(declare-function all-the-icons-wicon "ext:all-the-icons.el")
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-imenu nil
|
||||||
|
"Imenu related libraries and applications for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-delimiter " / "
|
||||||
|
"Delimit types of candidates and their value in `helm-buffer'."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-execute-action-at-once-if-one
|
||||||
|
#'helm-imenu--execute-action-at-once-p
|
||||||
|
"Goto the candidate when only one is remaining."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type 'function)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-all-buffer-assoc nil
|
||||||
|
"Major mode association alist for `helm-imenu-in-all-buffers'.
|
||||||
|
Allow `helm-imenu-in-all-buffers' searching in these associated
|
||||||
|
buffers even if they are not derived from each other. The alist
|
||||||
|
is bidirectional, i.e. no need to add \\='((foo . bar) (bar . foo)),
|
||||||
|
only \\='((foo . bar)) is needed."
|
||||||
|
:type '(alist :key-type symbol :value-type symbol)
|
||||||
|
:group 'helm-imenu)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-in-all-buffers-separate-sources t
|
||||||
|
"Display imenu index of each buffer in its own source when non-nil.
|
||||||
|
|
||||||
|
When nil all candidates are displayed in a single source.
|
||||||
|
|
||||||
|
NOTE: Each source will have as name \"Imenu <buffer-name>\".
|
||||||
|
`helm-source-imenu-all' will not be set, however it will continue
|
||||||
|
to be used as a flag for using default as input. If you do not
|
||||||
|
want this behavior, remove it from
|
||||||
|
`helm-sources-using-default-as-input' even if not using a single
|
||||||
|
source to display imenu in all buffers."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'helm-imenu)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-type-faces
|
||||||
|
'(("^Variables$" . font-lock-variable-name-face)
|
||||||
|
("^\\(Function\\|Functions\\|Defuns\\)$" . font-lock-function-name-face)
|
||||||
|
("^\\(Types\\|Provides\\|Requires\\|Classes\\|Class\\|Includes\\|Imports\\|Misc\\|Code\\)$" . font-lock-type-face))
|
||||||
|
"Faces for showing type in helm-imenu.
|
||||||
|
This is a list of cons cells. The cdr of each cell is a face to
|
||||||
|
be used, and it can also just be like \\='(:foreground
|
||||||
|
\"yellow\"). Each car is a regexp match pattern of the imenu type
|
||||||
|
string."
|
||||||
|
:group 'helm-faces
|
||||||
|
:type '(repeat
|
||||||
|
(cons
|
||||||
|
(regexp :tag "Imenu type regexp pattern")
|
||||||
|
(sexp :tag "Face"))))
|
||||||
|
|
||||||
|
(defcustom helm-imenu-extra-modes nil
|
||||||
|
"Extra modes where `helm-imenu-in-all-buffers' should look into."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type '(repeat symbol))
|
||||||
|
|
||||||
|
(defcustom helm-imenu-hide-item-type-name nil
|
||||||
|
"Hide display name of imenu item type along with the icon when non nil.
|
||||||
|
|
||||||
|
This value can be toggled with \\<helm-imenu-map>\\[helm-imenu-toggle-type-view].
|
||||||
|
Don't use `setq' to set this."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(if (require 'all-the-icons nil t)
|
||||||
|
(set var val)
|
||||||
|
(set var nil))))
|
||||||
|
|
||||||
|
(defcustom helm-imenu-use-icon nil
|
||||||
|
"Display an icon from all-the-icons package when non nil.
|
||||||
|
|
||||||
|
Don't use `setq' to set this."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(if (require 'all-the-icons nil t)
|
||||||
|
(set var val)
|
||||||
|
(set var nil))))
|
||||||
|
|
||||||
|
(defcustom helm-imenu-icon-type-alist
|
||||||
|
'(("Array" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Array" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Boolean" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Boolean" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Class" . (all-the-icons-octicon "package" :face font-lock-type-face))
|
||||||
|
("Class" . (all-the-icons-octicon "package" :face font-lock-type-face))
|
||||||
|
("Color" . (all-the-icons-material "color_lens" :face font-lock-builtin-face))
|
||||||
|
("Colors" . (all-the-icons-material "color_lens" :face font-lock-builtin-face))
|
||||||
|
("Constant" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Constants" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Constructor" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Constructors" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Enum Member" . (all-the-icons-octicon "three-bars" :face font-lock-type-face))
|
||||||
|
("Enum Members" . (all-the-icons-octicon "three-bars" :face font-lock-type-face))
|
||||||
|
("Enum" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Enums" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Event" . (all-the-icons-wicon "lightning" :face font-lock-builtin-face))
|
||||||
|
("Events" . (all-the-icons-wicon "lightning" :face font-lock-builtin-face))
|
||||||
|
("Field" . (all-the-icons-octicon "three-bars" :face font-lock-type-face))
|
||||||
|
("Fields" . (all-the-icons-octicon "three-bars" :face font-lock-type-face))
|
||||||
|
("File" . (all-the-icons-faicon "file" :face font-lock-variable-name-face))
|
||||||
|
("Files" . (all-the-icons-faicon "file" :face font-lock-variable-name-face))
|
||||||
|
("Folder" . (all-the-icons-faicon "folder" :face font-lock-variable-name-face))
|
||||||
|
("Folders" . (all-the-icons-faicon "folder" :face font-lock-variable-name-face))
|
||||||
|
("Interface" . (all-the-icons-octicon "package" :face font-lock-builtin-face))
|
||||||
|
("Interfaces" . (all-the-icons-octicon "package" :face font-lock-builtin-face))
|
||||||
|
("Keyword" . (all-the-icons-octicon "key" :face font-lock-builtin-face))
|
||||||
|
("Keywords" . (all-the-icons-octicon "key" :face font-lock-builtin-face))
|
||||||
|
("Method" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Methods" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Defun" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Defuns" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Fn" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Fns" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Function" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Functions" . (all-the-icons-faicon "cube" :face font-lock-function-name-face))
|
||||||
|
("Misc" . (all-the-icons-faicon "globe" :face font-lock-function-name-face))
|
||||||
|
("Miscs" . (all-the-icons-faicon "globe" :face font-lock-function-name-face))
|
||||||
|
("Module" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face))
|
||||||
|
("Modules" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face))
|
||||||
|
("Numeric" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Numeric" . (all-the-icons-material "crop" :face font-lock-builtin-face))
|
||||||
|
("Object" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face))
|
||||||
|
("Objects" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face))
|
||||||
|
("Operator" . (all-the-icons-faicon "calculator" :face font-lock-builtin-face))
|
||||||
|
("Operators" . (all-the-icons-faicon "calculator" :face font-lock-builtin-face))
|
||||||
|
("Property" . (all-the-icons-octicon "book" :face font-lock-variable-name-face))
|
||||||
|
("Properties" . (all-the-icons-octicon "book" :face font-lock-variable-name-face))
|
||||||
|
("Reference" . (all-the-icons-octicon "book" :face font-lock-variable-name-face))
|
||||||
|
("References" . (all-the-icons-octicon "book" :face font-lock-variable-name-face))
|
||||||
|
("Snippet" . (all-the-icons-material "border_style" :face font-lock-variable-name-face))
|
||||||
|
("Snippet" . (all-the-icons-material "border_style" :face font-lock-variable-name-face))
|
||||||
|
("String" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face))
|
||||||
|
("Strings" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face))
|
||||||
|
("Struct" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Structs" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Text" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face))
|
||||||
|
("Texts" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face))
|
||||||
|
("Top level" . (all-the-icons-faicon "globe" :face font-lock-function-name-face))
|
||||||
|
("Trait" . (all-the-icons-octicon "package" :face font-lock-builtin-face))
|
||||||
|
("Traits" . (all-the-icons-octicon "package" :face font-lock-builtin-face))
|
||||||
|
("Type" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Types" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Type Parameter" . (all-the-icons-material "code" :face font-lock-type-face))
|
||||||
|
("Type Parameters" . (all-the-icons-material "code" :face font-lock-type-face))
|
||||||
|
("Unit" . (all-the-icons-faicon "bar-chart" :face font-lock-builtin-face))
|
||||||
|
("Units" . (all-the-icons-faicon "bar-chart" :face font-lock-builtin-face))
|
||||||
|
("Value" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Values" . (all-the-icons-faicon "cog" :face font-lock-type-face))
|
||||||
|
("Variable" . (all-the-icons-octicon "book" :face font-lock-variable-name-face))
|
||||||
|
("Variables" . (all-the-icons-octicon "book":face font-lock-variable-name-face)))
|
||||||
|
"An alist of types associated with a sexp returning an icon.
|
||||||
|
The sexp should be an `all-the-icons' function with its args."
|
||||||
|
:type '(alist :key-type string :value-type sexp)
|
||||||
|
:group 'helm-imenu)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-default-type-sexp
|
||||||
|
'(all-the-icons-faicon "globe" :face font-lock-function-name-face)
|
||||||
|
"Default sexp to use when no type for an object is found."
|
||||||
|
:type 'sexp
|
||||||
|
:group 'helm-imenu)
|
||||||
|
|
||||||
|
;;; keymap
|
||||||
|
(defvar helm-imenu-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "M-<down>") 'helm-imenu-next-section)
|
||||||
|
(define-key map (kbd "M-<up>") 'helm-imenu-previous-section)
|
||||||
|
(define-key map (kbd "C-]") 'helm-imenu-toggle-type-view)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defun helm-imenu-toggle-type-view ()
|
||||||
|
"Toggle candidate type view."
|
||||||
|
(interactive)
|
||||||
|
(with-helm-window
|
||||||
|
(setq helm-imenu-hide-item-type-name (not helm-imenu-hide-item-type-name))
|
||||||
|
(let* ((sel (substring (helm-get-selection nil 'withprop)
|
||||||
|
(if helm-imenu-use-icon 2 0)))
|
||||||
|
(type (get-text-property 1 'type-name sel)))
|
||||||
|
(setq sel (substring-no-properties sel))
|
||||||
|
(helm-force-update (if helm-imenu-hide-item-type-name
|
||||||
|
(format "^[ ]*%s$"
|
||||||
|
(car (last (split-string
|
||||||
|
sel helm-imenu-delimiter t))))
|
||||||
|
(format "^[ ]*%s / %s$"
|
||||||
|
type sel))))))
|
||||||
|
(put 'helm-imenu-toggle-type-view 'no-helm-mx t)
|
||||||
|
|
||||||
|
(defcustom helm-imenu-lynx-style-map nil
|
||||||
|
"Use Arrow keys to jump to occurences."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(set var val)
|
||||||
|
(if val
|
||||||
|
(progn
|
||||||
|
(define-key helm-imenu-map (kbd "<right>") 'helm-execute-persistent-action)
|
||||||
|
(define-key helm-imenu-map (kbd "<left>") 'helm-maybe-exit-minibuffer))
|
||||||
|
(define-key helm-imenu-map (kbd "<right>") nil)
|
||||||
|
(define-key helm-imenu-map (kbd "<left>") nil))))
|
||||||
|
|
||||||
|
(defun helm-imenu-next-or-previous-section (n)
|
||||||
|
(with-helm-window
|
||||||
|
(let* ((fn (lambda ()
|
||||||
|
(let ((str (buffer-substring
|
||||||
|
(pos-bol) (pos-eol))))
|
||||||
|
(if helm-imenu-hide-item-type-name
|
||||||
|
(get-text-property 1 'type-name str)
|
||||||
|
(car (split-string str helm-imenu-delimiter))))))
|
||||||
|
(curtype (funcall fn))
|
||||||
|
(stop-fn (if (> n 0)
|
||||||
|
#'helm-end-of-source-p
|
||||||
|
#'helm-beginning-of-source-p)))
|
||||||
|
(while (and (not (funcall stop-fn))
|
||||||
|
(string= curtype (funcall fn)))
|
||||||
|
(forward-line n))
|
||||||
|
(helm-mark-current-line)
|
||||||
|
(helm-follow-execute-persistent-action-maybe))))
|
||||||
|
|
||||||
|
(defun helm-imenu-next-section ()
|
||||||
|
(interactive)
|
||||||
|
(helm-imenu-next-or-previous-section 1))
|
||||||
|
|
||||||
|
(defun helm-imenu-previous-section ()
|
||||||
|
(interactive)
|
||||||
|
(helm-imenu-next-or-previous-section -1))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Internals
|
||||||
|
(defvar helm-cached-imenu-alist nil)
|
||||||
|
(make-variable-buffer-local 'helm-cached-imenu-alist)
|
||||||
|
|
||||||
|
(defvar helm-cached-imenu-candidates nil)
|
||||||
|
(make-variable-buffer-local 'helm-cached-imenu-candidates)
|
||||||
|
|
||||||
|
(defvar helm-cached-imenu-tick nil)
|
||||||
|
(make-variable-buffer-local 'helm-cached-imenu-tick)
|
||||||
|
|
||||||
|
(defvar helm-imenu--in-all-buffers-cache nil)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar helm-source-imenu nil "See (info \"(emacs)Imenu\")")
|
||||||
|
(defvar helm-source-imenu-all nil)
|
||||||
|
|
||||||
|
(defclass helm-imenu-source (helm-source-sync)
|
||||||
|
((candidates :initform 'helm-imenu-candidates)
|
||||||
|
(candidate-transformer :initform 'helm-imenu-transformer)
|
||||||
|
(persistent-action :initform 'helm-imenu-persistent-action)
|
||||||
|
(persistent-help :initform "Show this entry")
|
||||||
|
(nomark :initform t)
|
||||||
|
(keymap :initform 'helm-imenu-map)
|
||||||
|
(help-message :initform 'helm-imenu-help-message)
|
||||||
|
(action :initform 'helm-imenu-action)
|
||||||
|
(find-file-target :initform #'helm-imenu-quit-and-find-file-fn)
|
||||||
|
(group :initform 'helm-imenu)))
|
||||||
|
|
||||||
|
(defcustom helm-imenu-fuzzy-match nil
|
||||||
|
"Enable fuzzy matching in `helm-source-imenu'."
|
||||||
|
:group 'helm-imenu
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(set var val)
|
||||||
|
(setq helm-source-imenu
|
||||||
|
(helm-make-source "Imenu" 'helm-imenu-source
|
||||||
|
:fuzzy-match helm-imenu-fuzzy-match))))
|
||||||
|
|
||||||
|
(defun helm-imenu--maybe-switch-to-buffer (candidate)
|
||||||
|
(let ((cand (cdr candidate)))
|
||||||
|
(helm-aif (and (markerp cand) (marker-buffer cand))
|
||||||
|
(switch-to-buffer it))))
|
||||||
|
|
||||||
|
(defun helm-imenu--execute-action-at-once-p ()
|
||||||
|
(let ((cur (helm-get-selection))
|
||||||
|
(mb (with-helm-current-buffer
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (pos-bol))
|
||||||
|
(point-marker)))))
|
||||||
|
;; Happen when cursor is on the line where a definition is. This
|
||||||
|
;; prevent jumping to the definition where we are already, instead
|
||||||
|
;; display helm with all definitions and preselection to the place
|
||||||
|
;; we already are.
|
||||||
|
(if (equal (cdr cur) mb)
|
||||||
|
(prog1 nil
|
||||||
|
(helm-set-pattern "")
|
||||||
|
(helm-force-update (concat "\\_<" (car cur) "\\_>")))
|
||||||
|
t)))
|
||||||
|
|
||||||
|
(defun helm-imenu-quit-and-find-file-fn (source)
|
||||||
|
(let ((sel (helm-get-selection nil nil source)))
|
||||||
|
(when (and (consp sel) (markerp (cdr sel)))
|
||||||
|
(buffer-file-name (marker-buffer (cdr sel))))))
|
||||||
|
|
||||||
|
(defun helm-imenu-action (candidate)
|
||||||
|
"Default action for `helm-source-imenu'."
|
||||||
|
(helm-log-run-hook "helm-imenu-action" 'helm-goto-line-before-hook)
|
||||||
|
(helm-imenu--maybe-switch-to-buffer candidate)
|
||||||
|
(imenu candidate)
|
||||||
|
;; If semantic is supported in this buffer
|
||||||
|
;; imenu used `semantic-imenu-goto-function'
|
||||||
|
;; and position have been highlighted,
|
||||||
|
;; no need to highlight again.
|
||||||
|
(unless (eq imenu-default-goto-function
|
||||||
|
'semantic-imenu-goto-function)
|
||||||
|
(helm-highlight-current-line)))
|
||||||
|
|
||||||
|
(defun helm-imenu-persistent-action (candidate)
|
||||||
|
"Default persistent action for `helm-source-imenu'."
|
||||||
|
(helm-imenu--maybe-switch-to-buffer candidate)
|
||||||
|
(imenu candidate)
|
||||||
|
(helm-highlight-current-line))
|
||||||
|
|
||||||
|
(defun helm-imenu-candidates (&optional buffer)
|
||||||
|
(with-current-buffer (or buffer helm-current-buffer)
|
||||||
|
(let ((tick (buffer-modified-tick)))
|
||||||
|
(if (eq helm-cached-imenu-tick tick)
|
||||||
|
helm-cached-imenu-candidates
|
||||||
|
(setq imenu--index-alist nil)
|
||||||
|
(prog1 (setq helm-cached-imenu-candidates
|
||||||
|
(let ((index (imenu--make-index-alist t)))
|
||||||
|
(helm-imenu--candidates-1
|
||||||
|
(delete (assoc "*Rescan*" index) index))))
|
||||||
|
(setq helm-cached-imenu-tick tick))))))
|
||||||
|
|
||||||
|
(defun helm-imenu-candidates-in-all-buffers (&optional build-sources)
|
||||||
|
(let* ((lst (buffer-list))
|
||||||
|
(progress-reporter (make-progress-reporter
|
||||||
|
"Imenu indexing buffers..." 1 (length lst))))
|
||||||
|
(prog1
|
||||||
|
(cl-loop with cur-buf = (if build-sources
|
||||||
|
(current-buffer) helm-current-buffer)
|
||||||
|
for b in lst
|
||||||
|
for count from 1
|
||||||
|
when (with-current-buffer b
|
||||||
|
(and (or (member major-mode helm-imenu-extra-modes)
|
||||||
|
(derived-mode-p 'prog-mode))
|
||||||
|
(helm-same-major-mode-p
|
||||||
|
cur-buf helm-imenu-all-buffer-assoc)))
|
||||||
|
if build-sources
|
||||||
|
collect (helm-make-source
|
||||||
|
(format "Imenu in %s" (buffer-name b))
|
||||||
|
'helm-imenu-source
|
||||||
|
:candidates (with-current-buffer b
|
||||||
|
(helm-imenu-candidates b))
|
||||||
|
:fuzzy-match helm-imenu-fuzzy-match)
|
||||||
|
else
|
||||||
|
append (with-current-buffer b
|
||||||
|
(helm-imenu-candidates b))
|
||||||
|
do (progress-reporter-update progress-reporter count))
|
||||||
|
(progress-reporter-done progress-reporter))))
|
||||||
|
|
||||||
|
(defun helm-imenu--candidates-1 (alist)
|
||||||
|
(cl-loop for elm in alist
|
||||||
|
nconc (cond
|
||||||
|
((imenu--subalist-p elm)
|
||||||
|
(helm-imenu--candidates-1
|
||||||
|
(cl-loop for (e . v) in (cdr elm) collect
|
||||||
|
(cons (propertize
|
||||||
|
e 'helm-imenu-type (car elm))
|
||||||
|
;; If value is an integer, convert it
|
||||||
|
;; to a marker, otherwise it is a cons cell
|
||||||
|
;; and it will be converted on next recursions.
|
||||||
|
;; (Bug#1060) [1].
|
||||||
|
(if (integerp v) (copy-marker v) v)))))
|
||||||
|
((listp (cdr elm))
|
||||||
|
(and elm (list elm)))
|
||||||
|
(t
|
||||||
|
;; bug in imenu, should not be needed.
|
||||||
|
(and (cdr elm)
|
||||||
|
;; Semantic uses overlays whereas imenu uses
|
||||||
|
;; markers (Bug#1706).
|
||||||
|
(setcdr elm (helm-acase (cdr elm) ; Same as [1].
|
||||||
|
((guard (overlayp it))
|
||||||
|
(copy-overlay it))
|
||||||
|
((guard (or (markerp it) (integerp it)))
|
||||||
|
(copy-marker it))))
|
||||||
|
(list elm))))))
|
||||||
|
|
||||||
|
(defun helm-imenu--get-prop (item)
|
||||||
|
;; property value of ITEM can have itself
|
||||||
|
;; a property value which have itself a property value
|
||||||
|
;; ...and so on; Return a list of all these
|
||||||
|
;; properties values starting at ITEM.
|
||||||
|
(let* ((prop (get-text-property 0 'helm-imenu-type item))
|
||||||
|
(lst (list prop item)))
|
||||||
|
(when prop
|
||||||
|
(while prop
|
||||||
|
(setq prop (get-text-property 0 'helm-imenu-type prop))
|
||||||
|
(and prop (push prop lst)))
|
||||||
|
lst)))
|
||||||
|
|
||||||
|
(defun helm-imenu-icon-for-type (type)
|
||||||
|
"Return an icon for type TYPE.
|
||||||
|
The icon is found in `helm-imenu-icon-type-alist', if not
|
||||||
|
`helm-imenu-default-type-sexp' is evaled to provide a default icon."
|
||||||
|
(let ((all-the-icons-scale-factor 1.0)
|
||||||
|
(all-the-icons-default-adjust 0.0))
|
||||||
|
(or (helm-aand (assoc-default
|
||||||
|
type helm-imenu-icon-type-alist)
|
||||||
|
(apply (car it) (cdr it)))
|
||||||
|
(apply (car helm-imenu-default-type-sexp)
|
||||||
|
(cdr helm-imenu-default-type-sexp)))))
|
||||||
|
|
||||||
|
(defun helm-imenu-transformer (candidates)
|
||||||
|
(cl-loop for (k . v) in candidates
|
||||||
|
;; (k . v) == (symbol-name . marker)
|
||||||
|
for bufname = (buffer-name
|
||||||
|
(helm-acase v
|
||||||
|
((guard (overlayp it)) (overlay-buffer it))
|
||||||
|
((guard (markerp it)) (marker-buffer it))))
|
||||||
|
for types = (or (helm-imenu--get-prop k)
|
||||||
|
(list (if (with-current-buffer bufname
|
||||||
|
(derived-mode-p 'prog-mode))
|
||||||
|
"Function"
|
||||||
|
"Top level")
|
||||||
|
k))
|
||||||
|
for type-icon = (and helm-imenu-use-icon
|
||||||
|
(helm-imenu-icon-for-type (car types)))
|
||||||
|
for type-name = (propertize
|
||||||
|
(car types) 'face
|
||||||
|
(cl-loop for (p . f) in helm-imenu-type-faces
|
||||||
|
when (string-match p (car types))
|
||||||
|
return f
|
||||||
|
finally return 'default))
|
||||||
|
for disp1 = (mapconcat 'identity
|
||||||
|
(cdr types)
|
||||||
|
(propertize helm-imenu-delimiter
|
||||||
|
'face 'shadow))
|
||||||
|
for disp = (concat (if helm-imenu-use-icon
|
||||||
|
(concat (propertize " " 'display type-icon) " ")
|
||||||
|
"")
|
||||||
|
(if helm-imenu-hide-item-type-name
|
||||||
|
""
|
||||||
|
(concat type-name
|
||||||
|
(propertize helm-imenu-delimiter
|
||||||
|
'face 'shadow)))
|
||||||
|
(propertize disp1 'help-echo bufname 'types types))
|
||||||
|
collect
|
||||||
|
(cons (propertize disp 'type-name type-name) (cons k v))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-imenu ()
|
||||||
|
"Preconfigured `helm' for `imenu'."
|
||||||
|
(interactive)
|
||||||
|
(require 'which-func)
|
||||||
|
(unless helm-source-imenu
|
||||||
|
(setq helm-source-imenu
|
||||||
|
(helm-make-source "Imenu" 'helm-imenu-source
|
||||||
|
:fuzzy-match helm-imenu-fuzzy-match)))
|
||||||
|
(let* ((imenu-auto-rescan t)
|
||||||
|
(helm-highlight-matches-around-point-max-lines 'never)
|
||||||
|
(str (thing-at-point 'symbol))
|
||||||
|
(init-reg (and str (concat "\\_<" (regexp-quote str) "\\_>")))
|
||||||
|
(helm-execute-action-at-once-if-one
|
||||||
|
helm-imenu-execute-action-at-once-if-one))
|
||||||
|
(helm :sources 'helm-source-imenu
|
||||||
|
:default (and str (list init-reg str))
|
||||||
|
:preselect (helm-aif (which-function)
|
||||||
|
(concat "\\_<" (regexp-quote it) "\\_>")
|
||||||
|
init-reg)
|
||||||
|
:buffer "*helm imenu*")))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-imenu-in-all-buffers ()
|
||||||
|
"Fetch Imenu entries in all buffers with similar mode as current.
|
||||||
|
A mode is similar as current if it is the same, it is derived
|
||||||
|
i.e. `derived-mode-p' or it have an association in
|
||||||
|
`helm-imenu-all-buffer-assoc'."
|
||||||
|
(interactive)
|
||||||
|
(require 'which-func)
|
||||||
|
(unless helm-imenu-in-all-buffers-separate-sources
|
||||||
|
(unless helm-source-imenu-all
|
||||||
|
(setq helm-source-imenu-all
|
||||||
|
(helm-make-source "Imenu in all buffers" 'helm-imenu-source
|
||||||
|
:init (lambda ()
|
||||||
|
;; Use a cache to avoid repeatedly sending
|
||||||
|
;; progress-reporter message when updating
|
||||||
|
;; (Bug#1704).
|
||||||
|
(setq helm-imenu--in-all-buffers-cache
|
||||||
|
(helm-imenu-candidates-in-all-buffers)))
|
||||||
|
:candidates 'helm-imenu--in-all-buffers-cache
|
||||||
|
:fuzzy-match helm-imenu-fuzzy-match))))
|
||||||
|
(let* ((imenu-auto-rescan t)
|
||||||
|
(helm-highlight-matches-around-point-max-lines 'never)
|
||||||
|
(str (thing-at-point 'symbol))
|
||||||
|
(init-reg (and str (concat "\\_<" (regexp-quote str) "\\_>")))
|
||||||
|
(helm-execute-action-at-once-if-one
|
||||||
|
helm-imenu-execute-action-at-once-if-one)
|
||||||
|
(helm-maybe-use-default-as-input
|
||||||
|
(not (null (memq 'helm-source-imenu-all
|
||||||
|
helm-sources-using-default-as-input))))
|
||||||
|
(sources (if helm-imenu-in-all-buffers-separate-sources
|
||||||
|
(helm-imenu-candidates-in-all-buffers 'build-sources)
|
||||||
|
'(helm-source-imenu-all))))
|
||||||
|
(helm :sources sources
|
||||||
|
:default (and str (list init-reg str))
|
||||||
|
:preselect (helm-aif (which-function)
|
||||||
|
(concat "\\_<" (regexp-quote it) "\\_>")
|
||||||
|
init-reg)
|
||||||
|
:buffer "*helm imenu all*")))
|
||||||
|
|
||||||
|
(provide 'helm-imenu)
|
||||||
|
|
||||||
|
;;; helm-imenu.el ends here
|
315
code/elpa/helm-20240320.541/helm-info.el
Normal file
315
code/elpa/helm-20240320.541/helm-info.el
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
;;; helm-info.el --- Browse info index with helm -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'info)
|
||||||
|
;; helm-utils is requiring helm which is requiring helm-lib, but let's require
|
||||||
|
;; them explicitely anyway to make it clear what we need. helm-core is needed to
|
||||||
|
;; build all the helm-info-* commands and sources.
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-lib)
|
||||||
|
(require 'helm-utils) ; for `helm-goto-line'.
|
||||||
|
|
||||||
|
(declare-function Info-index-nodes "info" (&optional file))
|
||||||
|
(declare-function Info-goto-node "info" (&optional fork))
|
||||||
|
(declare-function Info-find-node "info" (filename nodename &optional no-going-back))
|
||||||
|
(declare-function ring-insert "ring")
|
||||||
|
(declare-function ring-empty-p "ring")
|
||||||
|
(declare-function ring-ref "ring")
|
||||||
|
(defvar Info-history)
|
||||||
|
(defvar Info-directory-list)
|
||||||
|
;; `Info-minibuf-history' is not declared in Emacs, see emacs bug/58786.
|
||||||
|
(when (and (> emacs-major-version 28)
|
||||||
|
(not (boundp 'Info-minibuf-history)))
|
||||||
|
(defvar Info-minibuf-history nil))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Customize
|
||||||
|
|
||||||
|
(defgroup helm-info nil
|
||||||
|
"Info-related applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-info-default-sources
|
||||||
|
'(helm-source-info-elisp
|
||||||
|
helm-source-info-cl
|
||||||
|
helm-source-info-eieio
|
||||||
|
helm-source-info-pages)
|
||||||
|
"Default sources to use for looking up symbols at point in Info
|
||||||
|
files with `helm-info-at-point'."
|
||||||
|
:group 'helm-info
|
||||||
|
:type '(repeat (choice symbol)))
|
||||||
|
|
||||||
|
;;; Build info-index sources with `helm-info-source' class.
|
||||||
|
|
||||||
|
(cl-defun helm-info-init (&optional (file (helm-get-attr 'info-file)))
|
||||||
|
"Initialize candidates for info FILE.
|
||||||
|
If FILE have nodes, loop through all nodes and accumulate candidates
|
||||||
|
found in each node, otherwise scan only the current info buffer."
|
||||||
|
;; Allow reinit candidate buffer when using edebug.
|
||||||
|
(helm-aif (and debug-on-error
|
||||||
|
(helm-candidate-buffer))
|
||||||
|
(kill-buffer it))
|
||||||
|
(unless (helm-candidate-buffer)
|
||||||
|
(save-window-excursion
|
||||||
|
(info file " *helm info temp buffer*")
|
||||||
|
(let ((tobuf (helm-candidate-buffer 'global))
|
||||||
|
Info-history)
|
||||||
|
(helm-aif (Info-index-nodes)
|
||||||
|
(dolist (node it)
|
||||||
|
(Info-goto-node node)
|
||||||
|
(helm-info-scan-current-buffer tobuf))
|
||||||
|
(helm-info-scan-current-buffer tobuf))
|
||||||
|
(bury-buffer)))))
|
||||||
|
|
||||||
|
(defun helm-info-scan-current-buffer (tobuf)
|
||||||
|
"Scan current info buffer and print lines to TOBUF.
|
||||||
|
Argument TOBUF is the `helm-candidate-buffer'."
|
||||||
|
(let (start end line)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (search-forward "\n* " nil t)
|
||||||
|
(unless (search-forward "Menu:\n" (1+ (pos-eol)) t)
|
||||||
|
(setq start (pos-bol)
|
||||||
|
;; Fix Bug#1503 by getting the invisible
|
||||||
|
;; info displayed on next line in long strings.
|
||||||
|
;; e.g "* Foo.\n (line 12)" instead of
|
||||||
|
;; "* Foo.(line 12)"
|
||||||
|
end (or (save-excursion
|
||||||
|
(goto-char (pos-bol))
|
||||||
|
(re-search-forward "(line +[0-9]+)" nil t))
|
||||||
|
(pos-eol))
|
||||||
|
;; Long string have a new line inserted before the
|
||||||
|
;; invisible spec, remove it.
|
||||||
|
line (replace-regexp-in-string
|
||||||
|
"\n" "" (buffer-substring start end)))
|
||||||
|
(with-current-buffer tobuf
|
||||||
|
(insert line)
|
||||||
|
(insert "\n"))))))
|
||||||
|
|
||||||
|
(defun helm-info-goto (node-line)
|
||||||
|
"The helm-info action to jump to NODE-LINE."
|
||||||
|
(require 'helm-utils)
|
||||||
|
(let ((alive (buffer-live-p (get-buffer "*info*"))))
|
||||||
|
(Info-goto-node (car node-line))
|
||||||
|
(when alive (revert-buffer nil t))
|
||||||
|
(helm-goto-line (cdr node-line))))
|
||||||
|
|
||||||
|
(defvar helm-info--node-regexp
|
||||||
|
"^\\* +\\(.+\\):[[:space:]]+\\(.*\\)\\(?:[[:space:]]*\\)(line +\\([0-9]+\\))"
|
||||||
|
"A regexp that should match file name, node name and line number in
|
||||||
|
a line like this:
|
||||||
|
|
||||||
|
\* bind: Bash Builtins. (line 21).")
|
||||||
|
|
||||||
|
(defun helm-info-display-to-real (line)
|
||||||
|
"Transform LINE to an acceptable argument for `info'.
|
||||||
|
If line have a node use the node, otherwise use directly first name found."
|
||||||
|
(let ((info-file (helm-get-attr 'info-file))
|
||||||
|
nodename linum)
|
||||||
|
(when (string-match helm-info--node-regexp line)
|
||||||
|
(setq nodename (match-string 2 line)
|
||||||
|
linum (match-string 3 line)))
|
||||||
|
(if nodename
|
||||||
|
(cons (format "(%s)%s"
|
||||||
|
info-file
|
||||||
|
(replace-regexp-in-string ":\\'" "" nodename))
|
||||||
|
(string-to-number (or linum "1")))
|
||||||
|
(cons (format "(%s)%s"
|
||||||
|
info-file
|
||||||
|
(helm-aand (replace-regexp-in-string "^* " "" line)
|
||||||
|
(replace-regexp-in-string "::?.*\\'" "" it)))
|
||||||
|
1))))
|
||||||
|
|
||||||
|
(defclass helm-info-source (helm-source-in-buffer)
|
||||||
|
((info-file :initarg :info-file
|
||||||
|
:initform nil
|
||||||
|
:custom 'string)
|
||||||
|
(init :initform #'helm-info-init)
|
||||||
|
(display-to-real :initform #'helm-info-display-to-real)
|
||||||
|
(get-line :initform #'buffer-substring)
|
||||||
|
(action :initform '(("Goto node" . helm-info-goto)))))
|
||||||
|
|
||||||
|
(defmacro helm-build-info-source (fname &rest args)
|
||||||
|
`(helm-make-source (concat "Info Index: " ,fname) 'helm-info-source
|
||||||
|
:info-file ,fname ,@args))
|
||||||
|
|
||||||
|
(defun helm-build-info-index-command (name doc source buffer)
|
||||||
|
"Define a Helm command NAME with documentation DOC.
|
||||||
|
Arg SOURCE will be an existing helm source named
|
||||||
|
`helm-source-info-<NAME>' and BUFFER a string buffer name."
|
||||||
|
(defalias (intern (concat "helm-info-" name))
|
||||||
|
(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(helm :sources source
|
||||||
|
:buffer buffer
|
||||||
|
:candidate-number-limit 1000))
|
||||||
|
doc))
|
||||||
|
|
||||||
|
(defun helm-define-info-index-sources (info-list &optional commands)
|
||||||
|
"Define Helm info sources for all entries in INFO-LIST.
|
||||||
|
|
||||||
|
Sources will be named named helm-source-info-<NAME> where NAME is an element of
|
||||||
|
INFO-LIST.
|
||||||
|
|
||||||
|
Sources are generated for all entries of `helm-default-info-index-list' which is
|
||||||
|
generated by `helm-get-info-files'.
|
||||||
|
|
||||||
|
If COMMANDS arg is non-nil, also build commands named `helm-info-<NAME>'."
|
||||||
|
(cl-loop for str in info-list
|
||||||
|
for sym = (intern (concat "helm-source-info-" str))
|
||||||
|
do (set sym (helm-build-info-source str))
|
||||||
|
when commands
|
||||||
|
do (helm-build-info-index-command
|
||||||
|
str (format "Predefined helm for %s info." str)
|
||||||
|
sym (format "*helm info %s*" str))))
|
||||||
|
|
||||||
|
(defun helm-info-index-set (var value)
|
||||||
|
(set var value)
|
||||||
|
(helm-define-info-index-sources value t))
|
||||||
|
|
||||||
|
;;; Search Info files
|
||||||
|
|
||||||
|
;; `helm-info' is the main entry point here. It prompts the user for an Info
|
||||||
|
;; file, then a term in the file's index to jump to.
|
||||||
|
|
||||||
|
(defvar helm-info-searched (make-ring 32)
|
||||||
|
"Ring of previously searched Info files.")
|
||||||
|
|
||||||
|
(defun helm-get-info-files ()
|
||||||
|
"Return list of Info files to use for `helm-info'.
|
||||||
|
|
||||||
|
Elements of the list are strings of Info file names without
|
||||||
|
extensions (e.g., \"emacs\" for file \"emacs.info.gz\"). Info
|
||||||
|
files are found by searching directories in
|
||||||
|
`Info-directory-list'."
|
||||||
|
(info-initialize) ; Build Info-directory-list from INFOPATH (Bug#2118)
|
||||||
|
(let ((files (cl-loop for d in (or Info-directory-list
|
||||||
|
Info-default-directory-list)
|
||||||
|
when (file-directory-p d)
|
||||||
|
append (directory-files d nil "\\.info"))))
|
||||||
|
(helm-fast-remove-dups
|
||||||
|
(cl-loop for f in files collect
|
||||||
|
(helm-file-name-sans-extension f))
|
||||||
|
:test 'equal)))
|
||||||
|
|
||||||
|
(defcustom helm-default-info-index-list
|
||||||
|
(helm-get-info-files)
|
||||||
|
"Info files to search in with `helm-info'."
|
||||||
|
:group 'helm-info
|
||||||
|
:type '(repeat (choice string))
|
||||||
|
:set 'helm-info-index-set)
|
||||||
|
|
||||||
|
(defun helm-info-search-index (candidate)
|
||||||
|
"Search the index of CANDIDATE's Info file using the function
|
||||||
|
helm-info-<CANDIDATE>."
|
||||||
|
(let ((helm-info-function
|
||||||
|
(intern-soft (concat "helm-info-" candidate))))
|
||||||
|
(when (fboundp helm-info-function)
|
||||||
|
(funcall helm-info-function)
|
||||||
|
(ring-insert helm-info-searched candidate))))
|
||||||
|
|
||||||
|
(defun helm-def-source--info-files ()
|
||||||
|
"Return a Helm source for Info files."
|
||||||
|
(helm-build-sync-source "Helm Info"
|
||||||
|
:candidates
|
||||||
|
(lambda () (copy-sequence helm-default-info-index-list))
|
||||||
|
:candidate-number-limit 999
|
||||||
|
:candidate-transformer
|
||||||
|
(lambda (candidates)
|
||||||
|
(sort candidates #'string-lessp))
|
||||||
|
:nomark t
|
||||||
|
:action '(("Search index" . helm-info-search-index))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-info (&optional refresh)
|
||||||
|
"Preconfigured `helm' for searching Info files' indices.
|
||||||
|
|
||||||
|
With a prefix argument \\[universal-argument], set REFRESH to
|
||||||
|
non-nil.
|
||||||
|
|
||||||
|
Optional parameter REFRESH, when non-nil, re-evaluates
|
||||||
|
`helm-default-info-index-list'. If the variable has been
|
||||||
|
customized, set it to its saved value. If not, set it to its
|
||||||
|
standard value. See `custom-reevaluate-setting' for more.
|
||||||
|
|
||||||
|
REFRESH is useful when new Info files are installed. If
|
||||||
|
`helm-default-info-index-list' has not been customized, the new
|
||||||
|
Info files are made available."
|
||||||
|
(interactive "P")
|
||||||
|
(let ((default (unless (ring-empty-p helm-info-searched)
|
||||||
|
(ring-ref helm-info-searched 0))))
|
||||||
|
(when refresh
|
||||||
|
(custom-reevaluate-setting 'helm-default-info-index-list))
|
||||||
|
(helm :sources (helm-def-source--info-files)
|
||||||
|
:buffer "*helm Info*"
|
||||||
|
:preselect (and default
|
||||||
|
(concat "\\_<" (regexp-quote default) "\\_>")))))
|
||||||
|
|
||||||
|
;;;; Info at point
|
||||||
|
|
||||||
|
;; `helm-info-at-point' is the main entry point here. It searches for the
|
||||||
|
;; symbol at point through the Info sources defined in
|
||||||
|
;; `helm-info-default-sources' and jumps to it.
|
||||||
|
|
||||||
|
(defvar helm-info--pages-cache nil
|
||||||
|
"Cache for all Info pages on the system.")
|
||||||
|
|
||||||
|
(defvar helm-source-info-pages
|
||||||
|
(helm-build-sync-source "Info Pages"
|
||||||
|
:init #'helm-info-pages-init
|
||||||
|
:candidates (lambda () helm-info--pages-cache)
|
||||||
|
:action '(("Show with Info" .
|
||||||
|
(lambda (node-str)
|
||||||
|
(info (replace-regexp-in-string
|
||||||
|
"^[^:]+: " "" node-str)))))
|
||||||
|
:requires-pattern 2)
|
||||||
|
"Helm source for Info pages.")
|
||||||
|
|
||||||
|
(defun helm-info-pages-init ()
|
||||||
|
"Collect candidates for initial Info node Top."
|
||||||
|
(or helm-info--pages-cache
|
||||||
|
(let ((info-topic-regexp "\\* +\\([^:]+: ([^)]+)[^.]*\\)\\."))
|
||||||
|
(save-selected-window
|
||||||
|
(info "dir" " *helm info temp buffer*")
|
||||||
|
(Info-find-node "dir" "top")
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (re-search-forward info-topic-regexp nil t)
|
||||||
|
(push (match-string-no-properties 1)
|
||||||
|
helm-info--pages-cache))
|
||||||
|
(kill-buffer)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-info-at-point ()
|
||||||
|
"Preconfigured `helm' for searching info at point."
|
||||||
|
(interactive)
|
||||||
|
;; Symbol at point is used as default as long as one of the sources
|
||||||
|
;; in `helm-info-default-sources' is member of
|
||||||
|
;; `helm-sources-using-default-as-input'.
|
||||||
|
(cl-loop for src in helm-info-default-sources
|
||||||
|
for name = (if (symbolp src)
|
||||||
|
(assoc 'name (symbol-value src))
|
||||||
|
(assoc 'name src))
|
||||||
|
unless name
|
||||||
|
do (warn "Couldn't build source `%S' without its info file" src))
|
||||||
|
(helm :sources helm-info-default-sources
|
||||||
|
:buffer "*helm info*"))
|
||||||
|
|
||||||
|
(provide 'helm-info)
|
||||||
|
|
||||||
|
;;; helm-info.el ends here
|
487
code/elpa/helm-20240320.541/helm-locate.el
Normal file
487
code/elpa/helm-20240320.541/helm-locate.el
Normal file
|
@ -0,0 +1,487 @@
|
||||||
|
;;; helm-locate.el --- helm interface for locate. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;; NOTE for WINDOZE users:
|
||||||
|
;; You have to install Everything with his command line interface here:
|
||||||
|
;; http://www.voidtools.com/download.php
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-types)
|
||||||
|
(require 'helm-help)
|
||||||
|
|
||||||
|
(defvar helm-ff-default-directory)
|
||||||
|
(declare-function helm-read-file-name "helm-mode")
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-locate nil
|
||||||
|
"Locate related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-locate-db-file-regexp "m?locate\\.db$"
|
||||||
|
"Default regexp to match locate database.
|
||||||
|
If nil Search in all files."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-ff-locate-db-filename "locate.db"
|
||||||
|
"The basename of the locatedb file you use locally in your directories.
|
||||||
|
When this is set and Helm finds such a file in the directory from
|
||||||
|
where you launch locate, it will use this file and will not
|
||||||
|
prompt you for a db file.
|
||||||
|
Note that this happen only when locate is launched with a prefix
|
||||||
|
arg."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-locate-command nil
|
||||||
|
"A list of arguments for locate program.
|
||||||
|
|
||||||
|
Helm will calculate a default value for your system on startup
|
||||||
|
unless `helm-locate-command' is non-nil.
|
||||||
|
|
||||||
|
Here are the default values it will use according to your system:
|
||||||
|
|
||||||
|
Gnu/linux: \"locate %s -e -A -N --regex %s\"
|
||||||
|
berkeley-unix: \"locate %s %s\"
|
||||||
|
windows-nt: \"es %s %s\"
|
||||||
|
Others: \"locate %s %s\"
|
||||||
|
|
||||||
|
This string will be passed to format so it should end with `%s'.
|
||||||
|
The first format spec is used for the \"-i\" value of locate/es,
|
||||||
|
so don't set it directly but use `helm-locate-case-fold-search'
|
||||||
|
for this.
|
||||||
|
|
||||||
|
The last option must be the one preceding pattern i.e \"-r\" or
|
||||||
|
\"--regex\".
|
||||||
|
|
||||||
|
The option \"-N\" may not be available on old locate versions, it is needed on
|
||||||
|
latest systems as locate send quoted filenames, it is BTW enabled by default, if
|
||||||
|
this option is not recognized on your system, remove it.
|
||||||
|
|
||||||
|
You will be able to pass other options such as \"-b\" or \"l\"
|
||||||
|
during Helm invocation after entering pattern only when multi
|
||||||
|
matching, not when fuzzy matching.
|
||||||
|
|
||||||
|
Note that the \"-b\" option is added automatically by Helm when
|
||||||
|
var `helm-locate-fuzzy-match' is non-nil and switching back from
|
||||||
|
multimatch to fuzzy matching (this is done automatically when a
|
||||||
|
space is detected in pattern)."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-locate-create-db-command
|
||||||
|
"updatedb -l 0 -o '%s' -U '%s'"
|
||||||
|
"Command used to create a locale locate db file."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-locate-case-fold-search helm-case-fold-search
|
||||||
|
"It have the same meaning as `helm-case-fold-search'.
|
||||||
|
The -i option of locate will be used depending of value of
|
||||||
|
`helm-pattern' when this is set to \\='smart.
|
||||||
|
When nil \"-i\" will not be used at all and when non-nil it will
|
||||||
|
always be used.
|
||||||
|
NOTE: the -i option of the \"es\" command used on windows does
|
||||||
|
the opposite of \"locate\" command."
|
||||||
|
:type 'symbol)
|
||||||
|
|
||||||
|
(defcustom helm-locate-fuzzy-match nil
|
||||||
|
"Enable fuzzy matching in `helm-locate'.
|
||||||
|
Note that when this is enabled searching is done on basename."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-locate-fuzzy-sort-fn
|
||||||
|
#'helm-locate-default-fuzzy-sort-fn
|
||||||
|
"Default fuzzy matching sort function for locate."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-locate-project-list nil
|
||||||
|
"A list of directories, your projects.
|
||||||
|
When set, allow browsing recursively files in all directories of
|
||||||
|
this list with `helm-projects-find-files'."
|
||||||
|
:type '(repeat string))
|
||||||
|
|
||||||
|
(defcustom helm-locate-recursive-dirs-command "locate -i -e -A --regex '^%s' '%s.*$'"
|
||||||
|
"Command used for recursive directories completion in `helm-find-files'.
|
||||||
|
|
||||||
|
For Windows and `es' use something like \"es -r ^%s.*%s.*$\"
|
||||||
|
|
||||||
|
The two format specs are mandatory.
|
||||||
|
|
||||||
|
If for some reasons you can't use locate because your filesystem
|
||||||
|
doesn't have a database, you can use find command from findutils
|
||||||
|
but be aware that it will be much slower. See `helm-find-files'
|
||||||
|
embedded help for more infos."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-files)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar helm-locate-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-generic-files-map)
|
||||||
|
(define-key map (kbd "DEL") 'helm-delete-backward-no-update)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defface helm-locate-finish
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "Green"))
|
||||||
|
"Face used in mode line when locate process is finish."
|
||||||
|
:group 'helm-locate)
|
||||||
|
|
||||||
|
|
||||||
|
(defun helm-ff-find-locatedb (&optional from-ff)
|
||||||
|
"Try to find if a local locatedb file is available.
|
||||||
|
The search is done in `helm-ff-default-directory' or falls back to
|
||||||
|
`default-directory' if FROM-FF is nil."
|
||||||
|
(helm-aif (and helm-ff-locate-db-filename
|
||||||
|
(locate-dominating-file
|
||||||
|
(or (and from-ff
|
||||||
|
helm-ff-default-directory)
|
||||||
|
default-directory)
|
||||||
|
helm-ff-locate-db-filename))
|
||||||
|
(expand-file-name helm-ff-locate-db-filename it)))
|
||||||
|
|
||||||
|
(defun helm-locate-create-db-default-function (db-name directory)
|
||||||
|
"Default function used to create a locale locate db file.
|
||||||
|
Argument DB-NAME name of the db file.
|
||||||
|
Argument DIRECTORY root of file system subtree to scan."
|
||||||
|
(format helm-locate-create-db-command
|
||||||
|
db-name (expand-file-name directory)))
|
||||||
|
|
||||||
|
(defvar helm-locate-create-db-function
|
||||||
|
#'helm-locate-create-db-default-function
|
||||||
|
"Function used to create a locale locate db file.
|
||||||
|
It should receive the same arguments as
|
||||||
|
`helm-locate-create-db-default-function'.")
|
||||||
|
|
||||||
|
(defun helm-locate-1 (&optional localdb init from-ff default)
|
||||||
|
"Generic function to run Locate.
|
||||||
|
Prefix arg LOCALDB when (4) search and use a local locate db file
|
||||||
|
when it exists or create it, when (16) force update of existing
|
||||||
|
db file even if exists.
|
||||||
|
It has no effect when locate command is \\='es'. INIT is a string
|
||||||
|
to use as initial input in prompt.
|
||||||
|
See `helm-locate-with-db' and `helm-locate'."
|
||||||
|
(require 'helm-mode)
|
||||||
|
(helm-locate-set-command)
|
||||||
|
(let ((pfn (lambda (candidate)
|
||||||
|
(if (file-directory-p candidate)
|
||||||
|
(message "Error: The locate Db should be a file")
|
||||||
|
(if (= (shell-command
|
||||||
|
(funcall helm-locate-create-db-function
|
||||||
|
candidate
|
||||||
|
helm-ff-default-directory))
|
||||||
|
0)
|
||||||
|
(message "New locatedb file `%s' created" candidate)
|
||||||
|
(error "Failed to create locatedb file `%s'" candidate)))))
|
||||||
|
(locdb (and localdb
|
||||||
|
(not (string-match "^es" helm-locate-command))
|
||||||
|
(or (and (equal '(4) localdb)
|
||||||
|
(helm-ff-find-locatedb from-ff))
|
||||||
|
(helm-read-file-name
|
||||||
|
"Create Locate Db file: "
|
||||||
|
:initial-input (expand-file-name "locate.db"
|
||||||
|
(or helm-ff-default-directory
|
||||||
|
default-directory))
|
||||||
|
:preselect helm-locate-db-file-regexp
|
||||||
|
:test (lambda (x)
|
||||||
|
(if helm-locate-db-file-regexp
|
||||||
|
;; Select only locate db files and directories
|
||||||
|
;; to allow navigation.
|
||||||
|
(or (string-match
|
||||||
|
helm-locate-db-file-regexp x)
|
||||||
|
(file-directory-p x))
|
||||||
|
x)))))))
|
||||||
|
(when (and locdb (or (equal localdb '(16))
|
||||||
|
(not (file-exists-p locdb))))
|
||||||
|
(funcall pfn locdb))
|
||||||
|
(helm-locate-with-db (and localdb locdb) init default)))
|
||||||
|
|
||||||
|
(defun helm-locate-set-command ()
|
||||||
|
"Setup `helm-locate-command' if not already defined."
|
||||||
|
(unless helm-locate-command
|
||||||
|
(setq helm-locate-command
|
||||||
|
(cl-case system-type
|
||||||
|
;; Use -N option by default (bug#2625)
|
||||||
|
(gnu/linux "locate %s -e -A -N --regex %s")
|
||||||
|
(berkeley-unix "locate %s %s")
|
||||||
|
(windows-nt "es %s %s")
|
||||||
|
(t "locate %s %s")))))
|
||||||
|
|
||||||
|
(defun helm-locate-initial-setup ()
|
||||||
|
(require 'helm-for-files)
|
||||||
|
(helm-locate-set-command))
|
||||||
|
|
||||||
|
(defvar helm-file-name-history nil)
|
||||||
|
(defun helm-locate-with-db (&optional db initial-input default)
|
||||||
|
"Run locate -d DB.
|
||||||
|
If DB is not given or nil use locate without -d option.
|
||||||
|
Argument DB can be given as a string or list of db files.
|
||||||
|
Argument INITIAL-INPUT is a string to use as initial-input.
|
||||||
|
See also `helm-locate'."
|
||||||
|
(require 'helm-files)
|
||||||
|
(when (and db (stringp db)) (setq db (list db)))
|
||||||
|
(helm-locate-set-command)
|
||||||
|
(let ((helm-locate-command
|
||||||
|
(if db
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"locate"
|
||||||
|
(format (if helm-locate-fuzzy-match
|
||||||
|
"locate -b -d '%s'" "locate -d '%s'")
|
||||||
|
(mapconcat 'identity
|
||||||
|
;; Remove eventually
|
||||||
|
;; marked directories by error.
|
||||||
|
(cl-loop for i in db
|
||||||
|
unless (file-directory-p i)
|
||||||
|
;; expand-file-name to resolve
|
||||||
|
;; abbreviated fnames not
|
||||||
|
;; expanding inside single
|
||||||
|
;; quotes i.e. '%s'.
|
||||||
|
collect (expand-file-name i))
|
||||||
|
":"))
|
||||||
|
helm-locate-command)
|
||||||
|
(if (and helm-locate-fuzzy-match
|
||||||
|
(not (string-match-p "\\`locate -b" helm-locate-command)))
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\\`locate" "locate -b" helm-locate-command)
|
||||||
|
helm-locate-command))))
|
||||||
|
(setq helm-file-name-history (mapcar 'helm-basename file-name-history))
|
||||||
|
(helm :sources 'helm-source-locate
|
||||||
|
:buffer "*helm locate*"
|
||||||
|
:ff-transformer-show-only-basename nil
|
||||||
|
:input initial-input
|
||||||
|
:default default
|
||||||
|
:history 'helm-file-name-history)))
|
||||||
|
|
||||||
|
(defun helm-locate-update-mode-line (process-name)
|
||||||
|
"Update mode-line with PROCESS-NAME status information."
|
||||||
|
(with-helm-window
|
||||||
|
(setq mode-line-format
|
||||||
|
`(" " mode-line-buffer-identification " "
|
||||||
|
(:eval (format "L%s" (helm-candidate-number-at-point))) " "
|
||||||
|
(:eval (propertize
|
||||||
|
(format "[%s process finished - (%s results)]"
|
||||||
|
(max (1- (count-lines
|
||||||
|
(point-min) (point-max)))
|
||||||
|
0)
|
||||||
|
,process-name)
|
||||||
|
'face 'helm-locate-finish))))
|
||||||
|
(force-mode-line-update)))
|
||||||
|
|
||||||
|
(defun helm-locate--default-process-coding-system ()
|
||||||
|
"Fix `default-process-coding-system' in locate for Windows systems."
|
||||||
|
;; This is an attempt to fix issue #1322.
|
||||||
|
(if (and (eq system-type 'windows-nt)
|
||||||
|
(boundp 'w32-ansi-code-page))
|
||||||
|
(let ((code-page-eol
|
||||||
|
(intern (format "cp%s-%s" w32-ansi-code-page "dos"))))
|
||||||
|
(if (ignore-errors (check-coding-system code-page-eol))
|
||||||
|
(cons code-page-eol code-page-eol)
|
||||||
|
default-process-coding-system))
|
||||||
|
default-process-coding-system))
|
||||||
|
|
||||||
|
(defun helm-locate-init ()
|
||||||
|
"Initialize async locate process for `helm-source-locate'."
|
||||||
|
(let* ((default-process-coding-system
|
||||||
|
(helm-locate--default-process-coding-system))
|
||||||
|
(locate-is-es (string-match "\\`es" helm-locate-command))
|
||||||
|
(real-locate (string-match "\\`locate" helm-locate-command))
|
||||||
|
(case-sensitive-flag (if locate-is-es "-i" ""))
|
||||||
|
(ignore-case-flag (if (or locate-is-es
|
||||||
|
(not real-locate)) "" "-i"))
|
||||||
|
(args (helm-mm-split-pattern helm-pattern))
|
||||||
|
(cmd (format helm-locate-command
|
||||||
|
(cl-case helm-locate-case-fold-search
|
||||||
|
(smart (let ((case-fold-search nil))
|
||||||
|
(if (string-match "[[:upper:]]" helm-pattern)
|
||||||
|
case-sensitive-flag
|
||||||
|
ignore-case-flag)))
|
||||||
|
(t (if helm-locate-case-fold-search
|
||||||
|
ignore-case-flag
|
||||||
|
case-sensitive-flag)))
|
||||||
|
(helm-aif (cdr args)
|
||||||
|
(concat
|
||||||
|
;; The pattern itself.
|
||||||
|
(shell-quote-argument (car args)) " "
|
||||||
|
;; Possible locate args added
|
||||||
|
;; after pattern, don't quote them.
|
||||||
|
(mapconcat 'identity it " "))
|
||||||
|
(shell-quote-argument (car args)))))
|
||||||
|
(default-directory (if (file-directory-p default-directory)
|
||||||
|
default-directory "/")))
|
||||||
|
(helm-log "helm-locat-init" "Starting helm-locate process")
|
||||||
|
(helm-log "helm-locat-init" "Command line used was:\n\n%s"
|
||||||
|
(concat ">>> " (propertize cmd 'face 'font-lock-comment-face) "\n\n"))
|
||||||
|
(prog1
|
||||||
|
(start-process-shell-command
|
||||||
|
"locate-process" helm-buffer
|
||||||
|
cmd)
|
||||||
|
(set-process-sentinel
|
||||||
|
(get-buffer-process helm-buffer)
|
||||||
|
(lambda (process event)
|
||||||
|
(let* ((err (process-exit-status process))
|
||||||
|
(noresult (= err 1)))
|
||||||
|
(cond (noresult
|
||||||
|
(with-helm-buffer
|
||||||
|
(unless (cdr helm-sources)
|
||||||
|
(insert (concat "* Exit with code 1, no result found,"
|
||||||
|
" command line was:\n\n "
|
||||||
|
cmd)))))
|
||||||
|
((string= event "finished\n")
|
||||||
|
(when (and helm-locate-fuzzy-match
|
||||||
|
(not (string-match-p "\\s-" helm-pattern)))
|
||||||
|
(helm-redisplay-buffer))
|
||||||
|
(helm-locate-update-mode-line "Locate"))
|
||||||
|
(t
|
||||||
|
(helm-log "helm-locat-init" "Error: Locate %s"
|
||||||
|
(replace-regexp-in-string "\n" "" event))))))))))
|
||||||
|
|
||||||
|
(defun helm-locate-default-fuzzy-sort-fn (candidates)
|
||||||
|
"Default sort function for files in fuzzy matching.
|
||||||
|
Sort is done on basename of CANDIDATES."
|
||||||
|
(helm-fuzzy-matching-default-sort-fn-1 candidates nil t))
|
||||||
|
|
||||||
|
(defclass helm-locate-override-inheritor (helm-type-file) ())
|
||||||
|
|
||||||
|
(defclass helm-locate-source (helm-source-async helm-locate-override-inheritor)
|
||||||
|
((init :initform 'helm-locate-initial-setup)
|
||||||
|
(candidates-process :initform 'helm-locate-init)
|
||||||
|
(requires-pattern :initform 3)
|
||||||
|
(history :initform 'helm-file-name-history)
|
||||||
|
(persistent-action :initform 'helm-ff-kill-or-find-buffer-fname)
|
||||||
|
(candidate-number-limit :initform 9999)
|
||||||
|
(redisplay :initform (progn helm-locate-fuzzy-sort-fn))))
|
||||||
|
|
||||||
|
;; Override helm-type-file class keymap.
|
||||||
|
(cl-defmethod helm--setup-source :after ((source helm-locate-override-inheritor))
|
||||||
|
(setf (slot-value source 'keymap) helm-locate-map)
|
||||||
|
(setf (slot-value source 'group) 'helm-locate))
|
||||||
|
|
||||||
|
(defvar helm-source-locate
|
||||||
|
(helm-make-source "Locate" 'helm-locate-source
|
||||||
|
:pattern-transformer 'helm-locate-pattern-transformer
|
||||||
|
;; :match-part is only used here to tell helm which part
|
||||||
|
;; of candidate to highlight.
|
||||||
|
:match-part (lambda (candidate)
|
||||||
|
(if (or (string-match-p " -b\\'" helm-pattern)
|
||||||
|
(and helm-locate-fuzzy-match
|
||||||
|
(not (string-match "\\s-" helm-pattern))))
|
||||||
|
(helm-basename candidate)
|
||||||
|
candidate))))
|
||||||
|
|
||||||
|
(defun helm-locate-pattern-transformer (pattern)
|
||||||
|
(if helm-locate-fuzzy-match
|
||||||
|
;; When fuzzy is enabled helm add "-b" option on startup.
|
||||||
|
(cond ((string-match-p " " pattern)
|
||||||
|
(when (string-match "\\`locate -b" helm-locate-command)
|
||||||
|
(setq helm-locate-command
|
||||||
|
(replace-match "locate" t t helm-locate-command)))
|
||||||
|
pattern)
|
||||||
|
(t
|
||||||
|
(unless (string-match-p "\\`locate -b" helm-locate-command)
|
||||||
|
(setq helm-locate-command
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\\`locate" "locate -b" helm-locate-command)))
|
||||||
|
(helm--mapconcat-pattern pattern)))
|
||||||
|
pattern))
|
||||||
|
|
||||||
|
(defun helm-locate-find-dbs-in-projects (&optional update)
|
||||||
|
(let* ((pfn (lambda (candidate directory)
|
||||||
|
(unless (= (shell-command
|
||||||
|
(funcall helm-locate-create-db-function
|
||||||
|
candidate
|
||||||
|
directory))
|
||||||
|
0)
|
||||||
|
(error "Failed to create locatedb file `%s'" candidate)))))
|
||||||
|
(cl-loop for p in helm-locate-project-list
|
||||||
|
for db = (expand-file-name
|
||||||
|
helm-ff-locate-db-filename
|
||||||
|
(file-name-as-directory p))
|
||||||
|
if (and (null update) (file-exists-p db))
|
||||||
|
collect db
|
||||||
|
else do (funcall pfn db p)
|
||||||
|
and collect db)))
|
||||||
|
|
||||||
|
;;; Directory completion for hff.
|
||||||
|
;;
|
||||||
|
(defclass helm-locate-subdirs-source (helm-source-in-buffer)
|
||||||
|
((basedir :initarg :basedir
|
||||||
|
:initform nil
|
||||||
|
:custom string)
|
||||||
|
(subdir :initarg :subdir
|
||||||
|
:initform nil
|
||||||
|
:custom 'string)
|
||||||
|
(data :initform #'helm-locate-init-subdirs)
|
||||||
|
(group :initform 'helm-locate)))
|
||||||
|
|
||||||
|
(defun helm-locate-init-subdirs ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(call-process-shell-command
|
||||||
|
(if (string-match-p "\\`fd" helm-locate-recursive-dirs-command)
|
||||||
|
(format helm-locate-recursive-dirs-command
|
||||||
|
;; fd pass path at end.
|
||||||
|
(helm-get-attr 'subdir) (helm-get-attr 'basedir))
|
||||||
|
(format helm-locate-recursive-dirs-command
|
||||||
|
(if (string-match-p "\\`es" helm-locate-recursive-dirs-command)
|
||||||
|
;; Fix W32 paths.
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"/" "\\\\\\\\" (helm-get-attr 'basedir))
|
||||||
|
(helm-get-attr 'basedir))
|
||||||
|
(helm-get-attr 'subdir)))
|
||||||
|
nil t nil)
|
||||||
|
(buffer-string)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-projects-find-files (update)
|
||||||
|
"Find files with locate in `helm-locate-project-list'.
|
||||||
|
With a prefix arg refresh the database in each project."
|
||||||
|
(interactive "P")
|
||||||
|
(helm-locate-set-command)
|
||||||
|
(cl-assert (and (string-match-p "\\`locate" helm-locate-command)
|
||||||
|
(executable-find "updatedb"))
|
||||||
|
nil "Unsupported locate version")
|
||||||
|
(let ((dbs (helm-locate-find-dbs-in-projects update)))
|
||||||
|
(if dbs
|
||||||
|
(helm-locate-with-db dbs)
|
||||||
|
(user-error "No projects found, please setup `helm-locate-project-list'"))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-locate (arg)
|
||||||
|
"Preconfigured `helm' for Locate.
|
||||||
|
Note: you can add locate options after entering pattern.
|
||||||
|
See \\='man locate' for valid options and also `helm-locate-command'.
|
||||||
|
|
||||||
|
You can specify a local database with prefix argument ARG.
|
||||||
|
With two prefix arg, refresh the current local db or create it if
|
||||||
|
it doesn't exists.
|
||||||
|
|
||||||
|
To create a user specific db, use
|
||||||
|
\"updatedb -l 0 -o db_path -U directory\".
|
||||||
|
Where db_path is a filename matched by
|
||||||
|
`helm-locate-db-file-regexp'."
|
||||||
|
(interactive "P")
|
||||||
|
(helm-set-local-variable 'helm-async-outer-limit-hook
|
||||||
|
(list (lambda ()
|
||||||
|
(when (and helm-locate-fuzzy-match
|
||||||
|
(not (string-match-p
|
||||||
|
"\\s-" helm-pattern)))
|
||||||
|
(helm-redisplay-buffer)))))
|
||||||
|
(setq helm-ff-default-directory default-directory)
|
||||||
|
(helm-locate-1 arg nil nil (thing-at-point 'filename)))
|
||||||
|
|
||||||
|
(provide 'helm-locate)
|
||||||
|
|
||||||
|
;;; helm-locate.el ends here
|
114
code/elpa/helm-20240320.541/helm-man.el
Normal file
114
code/elpa/helm-20240320.541/helm-man.el
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
;;; helm-man.el --- Man and woman UI -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
|
||||||
|
(defvar woman-topic-all-completions)
|
||||||
|
(defvar woman-manpath)
|
||||||
|
(defvar woman-path)
|
||||||
|
(defvar woman-expanded-directory-path)
|
||||||
|
(declare-function woman-file-name "woman.el" (topic &optional re-cache))
|
||||||
|
(declare-function woman-file-name-all-completions "woman.el" (topic))
|
||||||
|
(declare-function Man-getpage-in-background "man.el" (topic))
|
||||||
|
(declare-function woman-expand-directory-path "woman.el" (path-dirs path-regexps))
|
||||||
|
(declare-function woman-topic-all-completions "woman.el" (path))
|
||||||
|
(declare-function helm-generic-sort-fn "helm-utils.el" (S1 S2))
|
||||||
|
(declare-function helm-comp-read "helm-mode")
|
||||||
|
|
||||||
|
(defgroup helm-man nil
|
||||||
|
"Man and Woman applications for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-man-or-woman-function 'Man-getpage-in-background
|
||||||
|
"Default command to display a man page."
|
||||||
|
:group 'helm-man
|
||||||
|
:type '(radio :tag "Preferred command to display a man page"
|
||||||
|
(const :tag "Man" Man-getpage-in-background)
|
||||||
|
(const :tag "Woman" woman)))
|
||||||
|
|
||||||
|
(defcustom helm-man-format-switches (cl-case system-type
|
||||||
|
((darwin macos) "%s")
|
||||||
|
(t "-l %s"))
|
||||||
|
"Arguments to pass to the `manual-entry' function.
|
||||||
|
Arguments are passed to `manual-entry' with `format.'"
|
||||||
|
:group 'helm-man
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
;; Internal
|
||||||
|
(defvar helm-man--pages nil
|
||||||
|
"All man pages on system.
|
||||||
|
Will be calculated the first time you invoke Helm with this
|
||||||
|
source.")
|
||||||
|
|
||||||
|
(defun helm-man-default-action (candidate)
|
||||||
|
"Default action for jumping to a woman or man page from Helm."
|
||||||
|
(let ((wfiles (mapcar #'car (woman-file-name-all-completions candidate))))
|
||||||
|
(condition-case nil
|
||||||
|
(let ((file (if (cdr wfiles)
|
||||||
|
(helm-comp-read "ManFile: " wfiles :must-match t)
|
||||||
|
(car wfiles))))
|
||||||
|
(if (eq helm-man-or-woman-function 'Man-getpage-in-background)
|
||||||
|
(manual-entry (format helm-man-format-switches file))
|
||||||
|
(condition-case nil
|
||||||
|
(woman-find-file file)
|
||||||
|
;; If woman is unable to format correctly
|
||||||
|
;; try Man instead.
|
||||||
|
(error (kill-buffer)
|
||||||
|
(manual-entry (format helm-man-format-switches file))))))
|
||||||
|
;; If even Man failed with file as argument, try again with Man
|
||||||
|
;; but using Topic candidate instead of the file calculated by
|
||||||
|
;; woman.
|
||||||
|
(error (kill-buffer)
|
||||||
|
(Man-getpage-in-background candidate)))))
|
||||||
|
|
||||||
|
(defun helm-man--init ()
|
||||||
|
(require 'woman)
|
||||||
|
(require 'helm-utils)
|
||||||
|
(unless helm-man--pages
|
||||||
|
(setq woman-expanded-directory-path
|
||||||
|
(woman-expand-directory-path woman-manpath woman-path))
|
||||||
|
(setq woman-topic-all-completions
|
||||||
|
(woman-topic-all-completions woman-expanded-directory-path))
|
||||||
|
(setq helm-man--pages (mapcar 'car woman-topic-all-completions)))
|
||||||
|
(helm-init-candidates-in-buffer 'global helm-man--pages))
|
||||||
|
|
||||||
|
(defvar helm-source-man-pages
|
||||||
|
(helm-build-in-buffer-source "Manual Pages"
|
||||||
|
:init #'helm-man--init
|
||||||
|
:persistent-action #'ignore
|
||||||
|
:filtered-candidate-transformer
|
||||||
|
(lambda (candidates _source)
|
||||||
|
(sort candidates #'helm-generic-sort-fn))
|
||||||
|
:action '(("Display Man page" . helm-man-default-action))
|
||||||
|
:group 'helm-man))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-man-woman (arg)
|
||||||
|
"Preconfigured `helm' for Man and Woman pages.
|
||||||
|
With a prefix arg reinitialize the cache."
|
||||||
|
(interactive "P")
|
||||||
|
(when arg (setq helm-man--pages nil))
|
||||||
|
(helm :sources 'helm-source-man-pages
|
||||||
|
:buffer "*helm man woman*"))
|
||||||
|
|
||||||
|
(provide 'helm-man)
|
||||||
|
|
||||||
|
;;; helm-man.el ends here
|
393
code/elpa/helm-20240320.541/helm-misc.el
Normal file
393
code/elpa/helm-20240320.541/helm-misc.el
Normal file
|
@ -0,0 +1,393 @@
|
||||||
|
;;; helm-misc.el --- Various functions for helm -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-types)
|
||||||
|
|
||||||
|
(declare-function display-time-world-display "time.el")
|
||||||
|
(defvar display-time-world-list)
|
||||||
|
(declare-function LaTeX-math-mode "ext:latex.el")
|
||||||
|
(declare-function jabber-chat-with "ext:jabber.el")
|
||||||
|
(declare-function jabber-read-account "ext:jabber.el")
|
||||||
|
(declare-function helm-comp-read "helm-mode")
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-misc nil
|
||||||
|
"Various Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-time-zone-home-location "Paris"
|
||||||
|
"The time zone of your home."
|
||||||
|
:group 'helm-misc
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-timezone-actions
|
||||||
|
'(("Set timezone env (TZ)" . (lambda (candidate)
|
||||||
|
(setenv "TZ" candidate))))
|
||||||
|
"Actions for helm-timezone."
|
||||||
|
:group 'helm-misc
|
||||||
|
:type '(alist :key-type string :value-type function))
|
||||||
|
|
||||||
|
(defface helm-time-zone-current
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "green"))
|
||||||
|
"Face used to colorize current time in `helm-world-time'."
|
||||||
|
:group 'helm-misc)
|
||||||
|
|
||||||
|
(defface helm-time-zone-home
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "red"))
|
||||||
|
"Face used to colorize home time in `helm-world-time'."
|
||||||
|
:group 'helm-misc)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; Latex completion
|
||||||
|
;;
|
||||||
|
;; Test
|
||||||
|
;; (setq LaTeX-math-menu '("Math"
|
||||||
|
;; ["foo" val0 t]
|
||||||
|
;; ("bar"
|
||||||
|
;; ["baz" val1 t])
|
||||||
|
;; ("aze"
|
||||||
|
;; ["zer" val2 t])
|
||||||
|
;; ("AMS"
|
||||||
|
;; ("rec"
|
||||||
|
;; ["fer" val3 t])
|
||||||
|
;; ("rty"
|
||||||
|
;; ["der" val4 t]))
|
||||||
|
;; ("ABC"
|
||||||
|
;; ("xcv"
|
||||||
|
;; ["sdf" val5 t])
|
||||||
|
;; ("dfg"
|
||||||
|
;; ["fgh" val6 t]))))
|
||||||
|
;; (helm-latex-math-candidates)
|
||||||
|
;; =>
|
||||||
|
;; (("foo" . val0)
|
||||||
|
;; ("baz" . val1)
|
||||||
|
;; ("zer" . val2)
|
||||||
|
;; ("fer" . val3)
|
||||||
|
;; ("der" . val4)
|
||||||
|
;; ("sdf" . val5)
|
||||||
|
;; ("fgh" . val6))
|
||||||
|
|
||||||
|
(defvar LaTeX-math-menu)
|
||||||
|
(defun helm-latex-math-candidates ()
|
||||||
|
(cl-labels ((helm-latex--math-collect (L)
|
||||||
|
(cond ((vectorp L)
|
||||||
|
(list (cons (aref L 0) (aref L 1))))
|
||||||
|
((listp L)
|
||||||
|
(cl-loop for a in L nconc
|
||||||
|
(helm-latex--math-collect a))))))
|
||||||
|
(helm-latex--math-collect LaTeX-math-menu)))
|
||||||
|
|
||||||
|
(defvar helm-source-latex-math
|
||||||
|
(helm-build-sync-source "Latex Math Menu"
|
||||||
|
:init (lambda ()
|
||||||
|
(with-helm-current-buffer
|
||||||
|
(LaTeX-math-mode 1)))
|
||||||
|
:candidate-number-limit 9999
|
||||||
|
:candidates 'helm-latex-math-candidates
|
||||||
|
:action (lambda (candidate)
|
||||||
|
(call-interactively candidate))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Jabber Contacts (jabber.el)
|
||||||
|
(defun helm-jabber-online-contacts ()
|
||||||
|
"List online Jabber contacts."
|
||||||
|
(with-no-warnings
|
||||||
|
(cl-loop for item in (jabber-concat-rosters)
|
||||||
|
when (get item 'connected)
|
||||||
|
collect
|
||||||
|
(if (get item 'name)
|
||||||
|
(cons (get item 'name) item)
|
||||||
|
(cons (symbol-name item) item)))))
|
||||||
|
|
||||||
|
(defvar helm-source-jabber-contacts
|
||||||
|
(helm-build-sync-source "Jabber Contacts"
|
||||||
|
:init (lambda () (require 'jabber))
|
||||||
|
:candidates (lambda () (mapcar 'car (helm-jabber-online-contacts)))
|
||||||
|
:action (lambda (x)
|
||||||
|
(jabber-chat-with
|
||||||
|
(jabber-read-account)
|
||||||
|
(symbol-name
|
||||||
|
(cdr (assoc x (helm-jabber-online-contacts))))))))
|
||||||
|
|
||||||
|
;;; World time
|
||||||
|
;;
|
||||||
|
(defvar zoneinfo-style-world-list)
|
||||||
|
(defvar legacy-style-world-list)
|
||||||
|
|
||||||
|
(defun helm-time-zone-transformer (candidates _source)
|
||||||
|
(cl-loop for i in candidates
|
||||||
|
for (z . p) in display-time-world-list
|
||||||
|
collect
|
||||||
|
(cons
|
||||||
|
(cond ((string-match (format-time-string "%H:%M" (current-time)) i)
|
||||||
|
(propertize i 'face 'helm-time-zone-current))
|
||||||
|
((string-match helm-time-zone-home-location i)
|
||||||
|
(propertize i 'face 'helm-time-zone-home))
|
||||||
|
(t i))
|
||||||
|
z)))
|
||||||
|
|
||||||
|
(defvar helm-source-time-world
|
||||||
|
(helm-build-in-buffer-source "Time World List"
|
||||||
|
:init (lambda ()
|
||||||
|
(require 'time)
|
||||||
|
(unless (and display-time-world-list
|
||||||
|
(listp display-time-world-list))
|
||||||
|
;; adapted from `time--display-world-list' from
|
||||||
|
;; emacs-27 for compatibility as
|
||||||
|
;; `display-time-world-list' is set by default to t.
|
||||||
|
(setq display-time-world-list
|
||||||
|
;; Determine if zoneinfo style timezones are
|
||||||
|
;; supported by testing that America/New York and
|
||||||
|
;; Europe/London return different timezones.
|
||||||
|
(let ((nyt (format-time-string "%z" nil "America/New_York"))
|
||||||
|
(gmt (format-time-string "%z" nil "Europe/London")))
|
||||||
|
(if (string-equal nyt gmt)
|
||||||
|
legacy-style-world-list
|
||||||
|
zoneinfo-style-world-list)))))
|
||||||
|
:data (lambda ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(display-time-world-display display-time-world-list)
|
||||||
|
(buffer-string)))
|
||||||
|
:action 'helm-timezone-actions
|
||||||
|
:filtered-candidate-transformer 'helm-time-zone-transformer))
|
||||||
|
|
||||||
|
;;; Commands
|
||||||
|
;;
|
||||||
|
(defun helm-call-interactively (cmd-or-name)
|
||||||
|
"Execute CMD-OR-NAME as Emacs command.
|
||||||
|
It is added to `extended-command-history'.
|
||||||
|
`helm-current-prefix-arg' is used as the command's prefix argument."
|
||||||
|
(setq extended-command-history
|
||||||
|
(cons (helm-stringify cmd-or-name)
|
||||||
|
(delete (helm-stringify cmd-or-name) extended-command-history)))
|
||||||
|
(let ((current-prefix-arg helm-current-prefix-arg)
|
||||||
|
(cmd (helm-symbolify cmd-or-name)))
|
||||||
|
(if (stringp (symbol-function cmd))
|
||||||
|
(execute-kbd-macro (symbol-function cmd))
|
||||||
|
(setq this-command cmd)
|
||||||
|
(call-interactively cmd))))
|
||||||
|
|
||||||
|
;;; Minibuffer History
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-minibuffer-history-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map [remap helm-minibuffer-history] 'undefined)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defcustom helm-minibuffer-history-must-match t
|
||||||
|
"Allow inserting non matching elements when nil or \\='confirm."
|
||||||
|
:group 'helm-misc
|
||||||
|
:type '(choice
|
||||||
|
(const :tag "Must match" t)
|
||||||
|
(const :tag "Confirm" confirm)
|
||||||
|
(const :tag "Always allow" nil)))
|
||||||
|
|
||||||
|
(defcustom helm-minibuffer-history-key "C-r"
|
||||||
|
"The key `helm-minibuffer-history' is bound to in minibuffer local maps."
|
||||||
|
:type '(choice (string :tag "Key") (const :tag "no binding"))
|
||||||
|
:group 'helm-mode)
|
||||||
|
|
||||||
|
(defconst helm-minibuffer-history-old-key
|
||||||
|
(cl-loop for map in '(minibuffer-local-completion-map
|
||||||
|
minibuffer-local-filename-completion-map
|
||||||
|
minibuffer-local-filename-must-match-map ; Emacs 23.1.+
|
||||||
|
minibuffer-local-isearch-map
|
||||||
|
minibuffer-local-map
|
||||||
|
minibuffer-local-must-match-filename-map ; Older Emacsen
|
||||||
|
minibuffer-local-must-match-map
|
||||||
|
minibuffer-local-ns-map)
|
||||||
|
when (and (boundp map) (symbol-value map))
|
||||||
|
collect (cons map (lookup-key (symbol-value map) "\C-r"))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode helm-minibuffer-history-mode
|
||||||
|
"Bind `helm-minibuffer-history-key' in al minibuffer maps.
|
||||||
|
This mode is enabled by `helm-mode', so there is no need to enable it directly."
|
||||||
|
:group 'helm-misc
|
||||||
|
:global t
|
||||||
|
(if helm-minibuffer-history-mode
|
||||||
|
(let ((key helm-minibuffer-history-key))
|
||||||
|
(dolist (map '(minibuffer-local-completion-map
|
||||||
|
minibuffer-local-filename-completion-map
|
||||||
|
minibuffer-local-filename-must-match-map ; Emacs 23.1.+
|
||||||
|
minibuffer-local-isearch-map
|
||||||
|
minibuffer-local-map
|
||||||
|
minibuffer-local-must-match-filename-map ; Older Emacsen
|
||||||
|
minibuffer-local-must-match-map
|
||||||
|
minibuffer-local-ns-map))
|
||||||
|
(let ((vmap (and (boundp map) (symbol-value map))))
|
||||||
|
(when (keymapp vmap)
|
||||||
|
(let ((val (and (boundp 'helm-minibuffer-history-key)
|
||||||
|
(symbol-value 'helm-minibuffer-history-key))))
|
||||||
|
(when val
|
||||||
|
(define-key vmap
|
||||||
|
(if (stringp val) (read-kbd-macro val) val)
|
||||||
|
nil)))
|
||||||
|
(when key
|
||||||
|
(define-key (symbol-value map)
|
||||||
|
(if (stringp key) (read-kbd-macro key) key)
|
||||||
|
'helm-minibuffer-history))))))
|
||||||
|
(dolist (map '(minibuffer-local-completion-map
|
||||||
|
minibuffer-local-filename-completion-map
|
||||||
|
minibuffer-local-filename-must-match-map
|
||||||
|
minibuffer-local-isearch-map
|
||||||
|
minibuffer-local-map
|
||||||
|
minibuffer-local-must-match-filename-map
|
||||||
|
minibuffer-local-must-match-map
|
||||||
|
minibuffer-local-ns-map))
|
||||||
|
(let ((vmap (and (boundp map) (symbol-value map))))
|
||||||
|
(when (keymapp vmap)
|
||||||
|
(let ((val (and (boundp 'helm-minibuffer-history-key)
|
||||||
|
(symbol-value 'helm-minibuffer-history-key))))
|
||||||
|
(when val
|
||||||
|
(define-key vmap
|
||||||
|
(if (stringp val) (read-kbd-macro val) val)
|
||||||
|
(assoc-default map helm-minibuffer-history-old-key)))))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Helm ratpoison UI
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-source-ratpoison-commands
|
||||||
|
(helm-build-in-buffer-source "Ratpoison Commands"
|
||||||
|
:init 'helm-ratpoison-commands-init
|
||||||
|
:action (helm-make-actions
|
||||||
|
"Execute the command" 'helm-ratpoison-commands-execute)
|
||||||
|
:display-to-real 'helm-ratpoison-commands-display-to-real
|
||||||
|
:candidate-number-limit 999999))
|
||||||
|
|
||||||
|
(defun helm-ratpoison-commands-init ()
|
||||||
|
(unless (helm-candidate-buffer)
|
||||||
|
(with-current-buffer (helm-candidate-buffer 'global)
|
||||||
|
;; with ratpoison prefix key
|
||||||
|
(save-excursion
|
||||||
|
(call-process "ratpoison" nil (current-buffer) nil "-c" "help"))
|
||||||
|
(while (re-search-forward "^\\([^ ]+\\) \\(.+\\)$" nil t)
|
||||||
|
(replace-match "<ratpoison> \\1: \\2"))
|
||||||
|
(goto-char (point-max))
|
||||||
|
;; direct binding
|
||||||
|
(save-excursion
|
||||||
|
(call-process "ratpoison" nil (current-buffer) nil "-c" "help top"))
|
||||||
|
(while (re-search-forward "^\\([^ ]+\\) \\(.+\\)$" nil t)
|
||||||
|
(replace-match "\\1: \\2")))))
|
||||||
|
|
||||||
|
(defun helm-ratpoison-commands-display-to-real (display)
|
||||||
|
(and (string-match ": " display)
|
||||||
|
(substring display (match-end 0))))
|
||||||
|
|
||||||
|
(defun helm-ratpoison-commands-execute (candidate)
|
||||||
|
(call-process "ratpoison" nil nil nil "-ic" candidate))
|
||||||
|
|
||||||
|
;;; Helm stumpwm UI
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-source-stumpwm-commands
|
||||||
|
(helm-build-in-buffer-source "Stumpwm Commands"
|
||||||
|
:init 'helm-stumpwm-commands-init
|
||||||
|
:action (helm-make-actions
|
||||||
|
"Execute the command" 'helm-stumpwm-commands-execute)
|
||||||
|
:candidate-number-limit 999999))
|
||||||
|
|
||||||
|
(defun helm-stumpwm-commands-init ()
|
||||||
|
(with-current-buffer (helm-candidate-buffer 'global)
|
||||||
|
(save-excursion
|
||||||
|
(call-process "stumpish" nil (current-buffer) nil "commands"))
|
||||||
|
(while (re-search-forward "[ ]*\\([^ ]+\\)[ ]*\n?" nil t)
|
||||||
|
(replace-match "\n\\1\n"))
|
||||||
|
(delete-blank-lines)
|
||||||
|
(sort-lines nil (point-min) (point-max))
|
||||||
|
(goto-char (point-max))))
|
||||||
|
|
||||||
|
(defun helm-stumpwm-commands-execute (candidate)
|
||||||
|
(call-process "stumpish" nil nil nil candidate))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-world-time ()
|
||||||
|
"Preconfigured `helm' to show world time.
|
||||||
|
Default action change TZ environment variable locally to emacs."
|
||||||
|
(interactive)
|
||||||
|
(helm-other-buffer 'helm-source-time-world "*helm world time*"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-insert-latex-math ()
|
||||||
|
"Preconfigured helm for latex math symbols completion."
|
||||||
|
(interactive)
|
||||||
|
(helm-other-buffer 'helm-source-latex-math "*helm latex*"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-ratpoison-commands ()
|
||||||
|
"Preconfigured `helm' to execute ratpoison commands."
|
||||||
|
(interactive)
|
||||||
|
(helm-other-buffer 'helm-source-ratpoison-commands
|
||||||
|
"*helm ratpoison commands*"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-stumpwm-commands()
|
||||||
|
"Preconfigured helm for stumpwm commands."
|
||||||
|
(interactive)
|
||||||
|
(helm-other-buffer 'helm-source-stumpwm-commands
|
||||||
|
"*helm stumpwm commands*"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-minibuffer-history ()
|
||||||
|
"Preconfigured `helm' for `minibuffer-history'."
|
||||||
|
(interactive)
|
||||||
|
(cl-assert (minibuffer-window-active-p (selected-window)) nil
|
||||||
|
"Error: Attempt to use minibuffer history outside a minibuffer")
|
||||||
|
(let* ((enable-recursive-minibuffers t)
|
||||||
|
(query-replace-p (or (eq last-command 'query-replace)
|
||||||
|
(eq last-command 'query-replace-regexp)))
|
||||||
|
(elm (helm-comp-read "Next element matching (regexp): "
|
||||||
|
(cl-loop for i in
|
||||||
|
(symbol-value minibuffer-history-variable)
|
||||||
|
unless (equal "" i) collect i into history
|
||||||
|
finally return
|
||||||
|
(if (consp (car history))
|
||||||
|
(mapcar 'prin1-to-string history)
|
||||||
|
history))
|
||||||
|
:header-name
|
||||||
|
(lambda (name)
|
||||||
|
(format "%s (%s)" name minibuffer-history-variable))
|
||||||
|
:buffer "*helm minibuffer-history*"
|
||||||
|
:must-match helm-minibuffer-history-must-match
|
||||||
|
:multiline t
|
||||||
|
:keymap helm-minibuffer-history-map
|
||||||
|
:allow-nest t)))
|
||||||
|
;; Fix Bug#1667 with emacs-25+ `query-replace-from-to-separator'.
|
||||||
|
(when (and (boundp 'query-replace-from-to-separator) query-replace-p)
|
||||||
|
(let ((pos (string-match "\0" elm)))
|
||||||
|
(and pos
|
||||||
|
(add-text-properties
|
||||||
|
pos (1+ pos)
|
||||||
|
`(display ,query-replace-from-to-separator separator t)
|
||||||
|
elm))))
|
||||||
|
(delete-minibuffer-contents)
|
||||||
|
(insert elm)))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'helm-misc)
|
||||||
|
|
||||||
|
;;; helm-misc.el ends here
|
2804
code/elpa/helm-20240320.541/helm-mode.el
Normal file
2804
code/elpa/helm-20240320.541/helm-mode.el
Normal file
File diff suppressed because it is too large
Load diff
436
code/elpa/helm-20240320.541/helm-net.el
Normal file
436
code/elpa/helm-20240320.541/helm-net.el
Normal file
|
@ -0,0 +1,436 @@
|
||||||
|
;;; helm-net.el --- helm browse url and search web. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'url)
|
||||||
|
(require 'xml)
|
||||||
|
(require 'browse-url)
|
||||||
|
|
||||||
|
(declare-function helm-comp-read "helm-mode")
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup helm-net nil
|
||||||
|
"Net related applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-google-suggest-default-browser-function nil
|
||||||
|
"The browse url function you prefer to use with Google suggest.
|
||||||
|
When nil, use the first browser function available
|
||||||
|
See `helm-browse-url-default-browser-alist'."
|
||||||
|
:group 'helm-net
|
||||||
|
:type 'symbol)
|
||||||
|
|
||||||
|
(defcustom helm-home-url "https://www.google.com"
|
||||||
|
"Default url to use as home url."
|
||||||
|
:group 'helm-net
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom helm-surfraw-default-browser-function nil
|
||||||
|
"The browse url function you prefer to use with surfraw.
|
||||||
|
When nil, fallback to `browse-url-browser-function'."
|
||||||
|
:group 'helm-net
|
||||||
|
:type 'symbol)
|
||||||
|
|
||||||
|
(defcustom helm-google-suggest-url
|
||||||
|
"https://encrypted.google.com/complete/search?output=toolbar&q=%s"
|
||||||
|
"URL used for looking up Google suggestions.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-google-suggest-search-url
|
||||||
|
"https://encrypted.google.com/search?ie=utf-8&oe=utf-8&q=%s"
|
||||||
|
"URL used for Google searching.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defvaralias 'helm-google-suggest-use-curl-p 'helm-net-prefer-curl)
|
||||||
|
(make-obsolete-variable 'helm-google-suggest-use-curl-p 'helm-net-prefer-curl "1.7.7")
|
||||||
|
|
||||||
|
(defcustom helm-net-prefer-curl nil
|
||||||
|
"When non--nil use CURL external program to fetch data.
|
||||||
|
Otherwise `url-retrieve-synchronously' is used."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-surfraw-duckduckgo-url
|
||||||
|
"https://duckduckgo.com/lite/?q=%s&kp=1"
|
||||||
|
"The Duckduckgo url.
|
||||||
|
This is a format string, don't forget the `%s'.
|
||||||
|
If you have personal settings saved on duckduckgo you should have
|
||||||
|
a personal url, see your settings on duckduckgo."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-search-suggest-action-wikipedia-url
|
||||||
|
"https://en.wikipedia.org/wiki/Special:Search?search=%s"
|
||||||
|
"The Wikipedia search url.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-search-suggest-action-youtube-url
|
||||||
|
"https://www.youtube.com/results?aq=f&search_query=%s"
|
||||||
|
"The Youtube search url.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-search-suggest-action-imdb-url
|
||||||
|
"http://www.imdb.com/find?s=all&q=%s"
|
||||||
|
"The IMDb search url.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-search-suggest-action-google-maps-url
|
||||||
|
"https://maps.google.com/maps?f=q&source=s_q&q=%s"
|
||||||
|
"The Google Maps search url.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-search-suggest-action-google-news-url
|
||||||
|
"https://www.google.com/search?safe=off&prmd=nvlifd&source=lnms&tbs=nws:1&q=%s"
|
||||||
|
"The Google News search url.
|
||||||
|
This is a format string, don't forget the `%s'."
|
||||||
|
:type 'string
|
||||||
|
:group 'helm-net)
|
||||||
|
|
||||||
|
(defcustom helm-google-suggest-actions
|
||||||
|
'(("Google Search" . helm-google-suggest-action)
|
||||||
|
("Wikipedia" . (lambda (candidate)
|
||||||
|
(helm-search-suggest-perform-additional-action
|
||||||
|
helm-search-suggest-action-wikipedia-url
|
||||||
|
candidate)))
|
||||||
|
("Youtube" . (lambda (candidate)
|
||||||
|
(helm-search-suggest-perform-additional-action
|
||||||
|
helm-search-suggest-action-youtube-url
|
||||||
|
candidate)))
|
||||||
|
("IMDb" . (lambda (candidate)
|
||||||
|
(helm-search-suggest-perform-additional-action
|
||||||
|
helm-search-suggest-action-imdb-url
|
||||||
|
candidate)))
|
||||||
|
("Google Maps" . (lambda (candidate)
|
||||||
|
(helm-search-suggest-perform-additional-action
|
||||||
|
helm-search-suggest-action-google-maps-url
|
||||||
|
candidate)))
|
||||||
|
("Google News" . (lambda (candidate)
|
||||||
|
(helm-search-suggest-perform-additional-action
|
||||||
|
helm-search-suggest-action-google-news-url
|
||||||
|
candidate))))
|
||||||
|
"List of actions for google suggest sources."
|
||||||
|
:group 'helm-net
|
||||||
|
:type '(alist :key-type string :value-type function))
|
||||||
|
|
||||||
|
(defcustom helm-browse-url-firefox-new-window "--new-tab"
|
||||||
|
"Allow choosing to browse url in new window or new tab.
|
||||||
|
Can be \"--new-tab\" (default), \"--new-window\" or \"--private-window\"."
|
||||||
|
:group 'helm-net
|
||||||
|
:type '(radio
|
||||||
|
(const :tag "New tab" "--new-tab")
|
||||||
|
(const :tag "New window" "--new-window")
|
||||||
|
(const :tag "New private window" "--private-window")))
|
||||||
|
|
||||||
|
(defcustom helm-net-curl-switches '("-s" "-L")
|
||||||
|
"Arguments list passed to curl when using `helm-net-prefer-curl'."
|
||||||
|
:group 'helm-net
|
||||||
|
:type '(repeat string))
|
||||||
|
|
||||||
|
;;; Additional actions for search suggestions
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;; Internal
|
||||||
|
(defvar helm-net-curl-log-file (expand-file-name "helm-curl.log" user-emacs-directory))
|
||||||
|
(defun helm-search-suggest-perform-additional-action (url query)
|
||||||
|
"Perform the search via URL using QUERY as input."
|
||||||
|
(browse-url (format url (url-hexify-string query))))
|
||||||
|
|
||||||
|
(defun helm-net--url-retrieve-sync (request parser)
|
||||||
|
(if helm-net-prefer-curl
|
||||||
|
(with-temp-buffer
|
||||||
|
(apply #'call-process "curl"
|
||||||
|
nil `(t ,helm-net-curl-log-file) nil request helm-net-curl-switches)
|
||||||
|
(funcall parser))
|
||||||
|
(with-current-buffer (url-retrieve-synchronously request)
|
||||||
|
(funcall parser))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Google Suggestions
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-google-suggest-parser ()
|
||||||
|
(cl-loop
|
||||||
|
with result-alist = (xml-get-children
|
||||||
|
(car (xml-parse-region
|
||||||
|
(point-min) (point-max)))
|
||||||
|
'CompleteSuggestion)
|
||||||
|
for i in result-alist collect
|
||||||
|
(cdr (cl-caadr (assq 'suggestion i)))))
|
||||||
|
|
||||||
|
(defun helm-google-suggest-fetch (input)
|
||||||
|
"Fetch suggestions for INPUT from XML buffer."
|
||||||
|
(let ((request (format helm-google-suggest-url
|
||||||
|
(url-hexify-string input))))
|
||||||
|
(helm-net--url-retrieve-sync
|
||||||
|
request #'helm-google-suggest-parser)))
|
||||||
|
|
||||||
|
(defun helm-google-suggest-set-candidates (&optional request-prefix)
|
||||||
|
"Set candidates with result and number of Google results found."
|
||||||
|
(let ((suggestions (helm-google-suggest-fetch
|
||||||
|
(or (and request-prefix
|
||||||
|
(concat request-prefix
|
||||||
|
" " helm-pattern))
|
||||||
|
helm-pattern))))
|
||||||
|
(if (member helm-pattern suggestions)
|
||||||
|
suggestions
|
||||||
|
;; if there is no suggestion exactly matching the input then
|
||||||
|
;; prepend a Search on Google item to the list
|
||||||
|
(append
|
||||||
|
suggestions
|
||||||
|
(list (cons (format "Search for '%s' on Google" helm-input)
|
||||||
|
helm-input))))))
|
||||||
|
|
||||||
|
(defun helm-ggs-set-number-result (num)
|
||||||
|
(if num
|
||||||
|
(progn
|
||||||
|
(and (numberp num) (setq num (number-to-string num)))
|
||||||
|
(cl-loop for i in (reverse (split-string num "" t))
|
||||||
|
for count from 1
|
||||||
|
append (list i) into C
|
||||||
|
when (= count 3)
|
||||||
|
append (list ",") into C
|
||||||
|
and do (setq count 0)
|
||||||
|
finally return
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"^," "" (mapconcat 'identity (reverse C) ""))))
|
||||||
|
"?"))
|
||||||
|
|
||||||
|
(defun helm-google-suggest-action (candidate)
|
||||||
|
"Default action to jump to a Google suggested candidate."
|
||||||
|
(let ((arg (format helm-google-suggest-search-url
|
||||||
|
(url-hexify-string candidate))))
|
||||||
|
(helm-aif helm-google-suggest-default-browser-function
|
||||||
|
(funcall it arg)
|
||||||
|
(helm-browse-url arg))))
|
||||||
|
|
||||||
|
(defvar helm-google-suggest-default-function
|
||||||
|
'helm-google-suggest-set-candidates
|
||||||
|
"Default function to use in `helm-google-suggest'.")
|
||||||
|
|
||||||
|
(defvar helm-source-google-suggest
|
||||||
|
(helm-build-sync-source "Google Suggest"
|
||||||
|
:candidates (lambda ()
|
||||||
|
(funcall helm-google-suggest-default-function))
|
||||||
|
:action 'helm-google-suggest-actions
|
||||||
|
:match-dynamic t
|
||||||
|
:keymap helm-map
|
||||||
|
:requires-pattern 3))
|
||||||
|
|
||||||
|
(defun helm-google-suggest-emacs-lisp ()
|
||||||
|
"Try to emacs lisp complete with Google suggestions."
|
||||||
|
(helm-google-suggest-set-candidates "emacs lisp"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Web browser functions.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;; If default setting of `w3m-command' is not
|
||||||
|
;; what you want and you modify it, you will have to reeval
|
||||||
|
;; also `helm-browse-url-default-browser-alist'.
|
||||||
|
|
||||||
|
(defvar helm-browse-url-chromium-program "chromium-browser")
|
||||||
|
(defvar helm-browse-url-uzbl-program "uzbl-browser")
|
||||||
|
(defvar helm-browse-url-nyxt-program "nyxt")
|
||||||
|
(defvar helm-browse-url-conkeror-program "conkeror")
|
||||||
|
(defvar helm-browse-url-opera-program "opera")
|
||||||
|
(defvar helm-browse-url-w3m-program (or (and (boundp 'w3m-command) w3m-command)
|
||||||
|
(executable-find "w3m")))
|
||||||
|
(defvar helm-browse-url-default-browser-alist
|
||||||
|
'((helm-browse-url-w3m-program . w3m-browse-url)
|
||||||
|
(browse-url-firefox-program . browse-url-firefox)
|
||||||
|
(helm-browse-url-chromium-program . helm-browse-url-chromium)
|
||||||
|
(helm-browse-url-conkeror-program . helm-browse-url-conkeror)
|
||||||
|
(helm-browse-url-opera-program . helm-browse-url-opera)
|
||||||
|
(helm-browse-url-uzbl-program . helm-browse-url-uzbl)
|
||||||
|
(helm-browse-url-nyxt-program . helm-browse-url-nyxt)
|
||||||
|
(browse-url-kde-program . browse-url-kde)
|
||||||
|
(browse-url-gnome-moz-program . browse-url-gnome-moz)
|
||||||
|
(browse-url-mozilla-program . browse-url-mozilla)
|
||||||
|
(browse-url-galeon-program . browse-url-galeon)
|
||||||
|
(browse-url-netscape-program . browse-url-netscape)
|
||||||
|
(browse-url-xterm-program . browse-url-text-xterm)
|
||||||
|
("emacs" . eww-browse-url))
|
||||||
|
"Alist of (browse_url_variable . function) to try to find a suitable url browser.")
|
||||||
|
|
||||||
|
(cl-defun helm-generic-browser (url cmd-name &rest args)
|
||||||
|
"Browse URL with NAME browser."
|
||||||
|
(let ((proc (concat cmd-name " " url)))
|
||||||
|
(message "Starting %s..." cmd-name)
|
||||||
|
(apply 'start-process proc nil cmd-name
|
||||||
|
(append args (list url)))
|
||||||
|
(set-process-sentinel
|
||||||
|
(get-process proc)
|
||||||
|
(lambda (process event)
|
||||||
|
(when (string= event "finished\n")
|
||||||
|
(message "%s process %s" process event))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-browse-url-firefox (url &optional _ignore)
|
||||||
|
"Same as `browse-url-firefox' but detach from Emacs.
|
||||||
|
|
||||||
|
So when you quit Emacs you can keep your Firefox session open and
|
||||||
|
not be prompted to kill the Firefox process.
|
||||||
|
|
||||||
|
NOTE: Probably not supported on some systems (e.g., Windows)."
|
||||||
|
(interactive (list (read-string "URL: " (browse-url-url-at-point))
|
||||||
|
nil))
|
||||||
|
(setq url (browse-url-encode-url url))
|
||||||
|
(let ((process-environment (browse-url-process-environment)))
|
||||||
|
(call-process-shell-command
|
||||||
|
(format "(%s %s %s &)"
|
||||||
|
browse-url-firefox-program
|
||||||
|
helm-browse-url-firefox-new-window
|
||||||
|
(shell-quote-argument url)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-browse-url-opera (url &optional _ignore)
|
||||||
|
"Browse URL with Opera browser and detach from Emacs.
|
||||||
|
|
||||||
|
So when you quit Emacs you can keep your Opera session open and
|
||||||
|
not be prompted to kill the Opera process.
|
||||||
|
|
||||||
|
NOTE: Probably not supported on some systems (e.g., Windows)."
|
||||||
|
(interactive (list (read-string "URL: " (browse-url-url-at-point))
|
||||||
|
nil))
|
||||||
|
(setq url (browse-url-encode-url url))
|
||||||
|
(let ((process-environment (browse-url-process-environment)))
|
||||||
|
(call-process-shell-command
|
||||||
|
(format "(%s %s &)"
|
||||||
|
helm-browse-url-opera-program (shell-quote-argument url)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-browse-url-chromium (url &optional _ignore)
|
||||||
|
"Browse URL with Google Chrome browser."
|
||||||
|
(interactive "sURL: ")
|
||||||
|
(helm-generic-browser
|
||||||
|
url helm-browse-url-chromium-program))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-browse-url-uzbl (url &optional _ignore)
|
||||||
|
"Browse URL with uzbl browser."
|
||||||
|
(interactive "sURL: ")
|
||||||
|
(helm-generic-browser url helm-browse-url-uzbl-program "-u"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-browse-url-conkeror (url &optional _ignore)
|
||||||
|
"Browse URL with conkeror browser."
|
||||||
|
(interactive "sURL: ")
|
||||||
|
(helm-generic-browser url helm-browse-url-conkeror-program))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-browse-url-nyxt (url &optional _ignore)
|
||||||
|
"Browse URL with nyxt browser."
|
||||||
|
(interactive "sURL: ")
|
||||||
|
(helm-generic-browser url helm-browse-url-nyxt-program))
|
||||||
|
|
||||||
|
(defun helm-browse-url-default-browser (url &rest args)
|
||||||
|
"Find the first available browser and ask it to load URL."
|
||||||
|
(let ((default-browser-fn
|
||||||
|
(cl-loop for (var . fn) in helm-browse-url-default-browser-alist
|
||||||
|
for exe = (if (stringp var)
|
||||||
|
var
|
||||||
|
(and (boundp var) (symbol-value var)))
|
||||||
|
thereis (and exe (executable-find exe) (fboundp fn) fn))))
|
||||||
|
(if default-browser-fn
|
||||||
|
(apply default-browser-fn url args)
|
||||||
|
(error "No usable browser found"))))
|
||||||
|
|
||||||
|
(defun helm-browse-url (url &rest args)
|
||||||
|
"Default command to browse URL."
|
||||||
|
(if browse-url-browser-function
|
||||||
|
(browse-url url args)
|
||||||
|
(helm-browse-url-default-browser url args)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Surfraw
|
||||||
|
;;
|
||||||
|
;; Need external program surfraw.
|
||||||
|
;; <http://surfraw.alioth.debian.org/>
|
||||||
|
|
||||||
|
;; Internal
|
||||||
|
(defvar helm-surfraw-engines-history nil)
|
||||||
|
(defvar helm-surfraw-input-history nil)
|
||||||
|
(defvar helm-surfraw--elvi-cache nil)
|
||||||
|
|
||||||
|
(defun helm-build-elvi-list ()
|
||||||
|
"Return list of all engines and descriptions handled by surfraw."
|
||||||
|
(or helm-surfraw--elvi-cache
|
||||||
|
(setq helm-surfraw--elvi-cache
|
||||||
|
(cdr (with-temp-buffer
|
||||||
|
(call-process "surfraw" nil t nil "-elvi")
|
||||||
|
(split-string (buffer-string) "\n"))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-surfraw (pattern engine)
|
||||||
|
"Preconfigured `helm' to search PATTERN with search ENGINE."
|
||||||
|
(interactive
|
||||||
|
(list
|
||||||
|
(let* ((default (if (use-region-p)
|
||||||
|
(buffer-substring-no-properties
|
||||||
|
(region-beginning) (region-end))
|
||||||
|
(thing-at-point 'symbol)))
|
||||||
|
(prompt (if default
|
||||||
|
(format "SearchFor (default %s): " default)
|
||||||
|
"SearchFor: ")))
|
||||||
|
(read-string prompt nil 'helm-surfraw-input-history default))
|
||||||
|
(helm-comp-read
|
||||||
|
"Engine: "
|
||||||
|
(helm-build-elvi-list)
|
||||||
|
:must-match t
|
||||||
|
:name "Surfraw Search Engines"
|
||||||
|
:history 'helm-surfraw-engines-history)))
|
||||||
|
(let* ((engine-nodesc (car (split-string engine)))
|
||||||
|
(url (if (string= engine-nodesc "duckduckgo")
|
||||||
|
;; "sr duckduckgo -p foo" is broken, workaround.
|
||||||
|
(format helm-surfraw-duckduckgo-url
|
||||||
|
(url-hexify-string pattern))
|
||||||
|
(with-temp-buffer
|
||||||
|
(apply 'call-process "surfraw" nil t nil
|
||||||
|
(append (list engine-nodesc "-p") (split-string pattern)))
|
||||||
|
(replace-regexp-in-string
|
||||||
|
"\n" "" (buffer-string)))))
|
||||||
|
(browse-url-browser-function (or helm-surfraw-default-browser-function
|
||||||
|
browse-url-browser-function)))
|
||||||
|
(if (string= engine-nodesc "W")
|
||||||
|
(helm-browse-url helm-home-url)
|
||||||
|
(helm-browse-url url))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-google-suggest ()
|
||||||
|
"Preconfigured `helm' for Google search with Google suggest."
|
||||||
|
(interactive)
|
||||||
|
(helm-other-buffer 'helm-source-google-suggest "*helm google*"))
|
||||||
|
|
||||||
|
(provide 'helm-net)
|
||||||
|
|
||||||
|
;;; helm-net.el ends here
|
894
code/elpa/helm-20240320.541/helm-occur.el
Normal file
894
code/elpa/helm-20240320.541/helm-occur.el
Normal file
|
@ -0,0 +1,894 @@
|
||||||
|
;;; helm-occur.el --- Incremental Occur for Helm. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'helm-help)
|
||||||
|
(require 'helm-utils)
|
||||||
|
|
||||||
|
(declare-function helm-buffers-get-visible-buffers "helm-buffers")
|
||||||
|
(declare-function helm-buffer-list "helm-buffers")
|
||||||
|
(declare-function helm-grep-split-line "helm-grep")
|
||||||
|
(declare-function helm-grep-highlight-match "helm-grep")
|
||||||
|
(declare-function helm-comp-read "helm-mode")
|
||||||
|
|
||||||
|
(defvar helm-current-error)
|
||||||
|
|
||||||
|
;;; Internals
|
||||||
|
;;
|
||||||
|
(defvar helm-source-occur nil
|
||||||
|
"This will be the name of the source related to `current-buffer'.
|
||||||
|
Don't use it as it value changes always.")
|
||||||
|
(defvar helm-source-moccur nil
|
||||||
|
"This is just a flag to add to `helm-sources-using-default-as-input'.
|
||||||
|
Don't set it to any value, it will have no effect.")
|
||||||
|
(defvar helm-occur--buffer-list nil)
|
||||||
|
(defvar helm-occur--buffer-tick nil)
|
||||||
|
(defvar helm-occur-history nil)
|
||||||
|
(defvar helm-occur--search-buffer-regexp "\\`\\([0-9]*\\)\\s-\\(.*\\)\\'"
|
||||||
|
"The regexp matching candidates in helm-occur candidate buffer.")
|
||||||
|
(defvar helm-occur-mode--last-pattern nil)
|
||||||
|
(defvar helm-occur--initial-pos 0)
|
||||||
|
|
||||||
|
(defvar helm-occur-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map helm-map)
|
||||||
|
(define-key map (kbd "C-c o") 'helm-occur-run-goto-line-ow)
|
||||||
|
(define-key map (kbd "C-c C-o") 'helm-occur-run-goto-line-of)
|
||||||
|
(define-key map (kbd "C-x C-s") 'helm-occur-run-save-buffer)
|
||||||
|
map)
|
||||||
|
"Keymap used in occur source.")
|
||||||
|
|
||||||
|
(defgroup helm-occur nil
|
||||||
|
"Regexp related Applications and libraries for Helm."
|
||||||
|
:group 'helm)
|
||||||
|
|
||||||
|
(defcustom helm-occur-actions
|
||||||
|
'(("Go to Line" . helm-occur-goto-line)
|
||||||
|
("Goto line other window (C-u vertically)" . helm-occur-goto-line-ow)
|
||||||
|
("Goto line new frame" . helm-occur-goto-line-of)
|
||||||
|
("Save buffer" . helm-occur-save-results)
|
||||||
|
)
|
||||||
|
"Actions for helm-occur."
|
||||||
|
:type '(alist :key-type string :value-type function))
|
||||||
|
|
||||||
|
(defcustom helm-occur-use-ioccur-style-keys nil
|
||||||
|
"Similar to `helm-grep-use-ioccur-style-keys' but for multi occur.
|
||||||
|
|
||||||
|
Note that if you define this variable with `setq' your change will
|
||||||
|
have no effect, use customize instead."
|
||||||
|
:type 'boolean
|
||||||
|
:set (lambda (var val)
|
||||||
|
(set var val)
|
||||||
|
(if val
|
||||||
|
(progn
|
||||||
|
(define-key helm-occur-map (kbd "<right>") 'helm-occur-right)
|
||||||
|
(define-key helm-occur-map (kbd "<left>") 'helm-occur-run-default-action))
|
||||||
|
(define-key helm-occur-map (kbd "<right>") nil)
|
||||||
|
(define-key helm-occur-map (kbd "<left>") nil))))
|
||||||
|
|
||||||
|
(defcustom helm-occur-always-search-in-current nil
|
||||||
|
"Helm multi occur always search in current buffer when non--nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-occur-truncate-lines t
|
||||||
|
"Truncate lines in occur buffer when non nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-occur-auto-update-on-resume nil
|
||||||
|
"Allow auto updating helm-occur buffer when outdated.
|
||||||
|
noask => Always update without asking
|
||||||
|
nil => Don't update but signal buffer needs update
|
||||||
|
never => Never update and do not signal buffer needs update
|
||||||
|
Any other non--nil value update after confirmation."
|
||||||
|
:type '(radio :tag "Allow auto updating helm-occur buffer when outdated."
|
||||||
|
(const :tag "Always update without asking" noask)
|
||||||
|
(const :tag "Never update and do not signal buffer needs update" never)
|
||||||
|
(const :tag "Don't update but signal buffer needs update" nil)
|
||||||
|
(const :tag "Update after confirmation" t)))
|
||||||
|
|
||||||
|
(defcustom helm-occur-candidate-number-limit 99999
|
||||||
|
"Value of `helm-candidate-number-limit' for helm-occur."
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
|
(defcustom helm-occur-buffer-substring-fn-for-modes
|
||||||
|
'((mu4e-headers-mode . buffer-substring))
|
||||||
|
"Function used to display buffer contents per major-mode.
|
||||||
|
|
||||||
|
Use this to display lines with their text properties in helm-occur
|
||||||
|
buffer. Can be one of `buffer-substring' or `buffer-substring-no-properties'.
|
||||||
|
See `helm-occur-buffer-substring-default-mode' to setup this globally.
|
||||||
|
|
||||||
|
Note that when using `buffer-substring' initialization will be slower."
|
||||||
|
:type '(alist :key-type (symbol :tag "Mode")
|
||||||
|
:value-type (radio (const :tag "With text properties"
|
||||||
|
buffer-substring)
|
||||||
|
(const :tag "Without text properties"
|
||||||
|
buffer-substring-no-properties))))
|
||||||
|
|
||||||
|
(defcustom helm-occur-buffer-substring-default-mode
|
||||||
|
'buffer-substring-no-properties
|
||||||
|
"Function used to display buffer contents in helm-occur buffer.
|
||||||
|
|
||||||
|
Default mode for major modes not defined in
|
||||||
|
`helm-occur-buffer-substring-fn-for-modes'.
|
||||||
|
Can be one of `buffer-substring' or `buffer-substring-no-properties'.
|
||||||
|
|
||||||
|
Note that when using `buffer-substring' initialization will be
|
||||||
|
slower. If buffer-substring, all buffers with the modes not
|
||||||
|
defined in helm-occur-buffer-substring-fn-for-modes will be
|
||||||
|
displayed with colors and properties in the helm-occur buffer"
|
||||||
|
:type '(radio
|
||||||
|
(const :tag "With text properties" buffer-substring)
|
||||||
|
(const :tag "Without text properties" buffer-substring-no-properties)))
|
||||||
|
|
||||||
|
(defcustom helm-occur-keep-closest-position t
|
||||||
|
"When non nil select closest candidate from point after update.
|
||||||
|
This happen only in `helm-source-occur' which is always related to
|
||||||
|
`current-buffer'."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-occur-ignore-diacritics nil
|
||||||
|
"When non nil helm-occur will ignore diacritics in patterns."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom helm-occur-match-shorthands nil
|
||||||
|
"Transform pattern according to `read-symbol-shorthands' when non nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defface helm-moccur-buffer
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:foreground "DarkTurquoise" :underline t))
|
||||||
|
"Face used to highlight occur buffer names.")
|
||||||
|
|
||||||
|
(defface helm-resume-need-update
|
||||||
|
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
:background "red"))
|
||||||
|
"Face used to flash occur buffer when it needs update.")
|
||||||
|
|
||||||
|
|
||||||
|
(defun helm-occur--select-closest-candidate ()
|
||||||
|
;; Prevent error with `with-helm-window' when switching to help.
|
||||||
|
(unless (or (not (get-buffer-window helm-buffer 'visible))
|
||||||
|
(string-equal helm-pattern ""))
|
||||||
|
(with-helm-window
|
||||||
|
(let ((lst '())
|
||||||
|
(name (helm-get-attr 'name helm-source-occur))
|
||||||
|
closest beg end)
|
||||||
|
(while-no-input
|
||||||
|
(goto-char (point-min))
|
||||||
|
(if (string= name "Helm occur")
|
||||||
|
(setq beg (point)
|
||||||
|
end (point-max))
|
||||||
|
(helm-awhile (helm-get-next-header-pos)
|
||||||
|
(when (string= name (buffer-substring-no-properties
|
||||||
|
(pos-bol) (pos-eol)))
|
||||||
|
(forward-line 1)
|
||||||
|
(setq beg (point)
|
||||||
|
end (or (helm-get-next-header-pos) (point-max)))
|
||||||
|
(cl-return))))
|
||||||
|
(save-excursion
|
||||||
|
(when (and beg end)
|
||||||
|
(goto-char beg)
|
||||||
|
(while (re-search-forward "^[0-9]+" end t)
|
||||||
|
(push (string-to-number (match-string 0)) lst))
|
||||||
|
(setq closest (helm-closest-number-in-list
|
||||||
|
helm-occur--initial-pos lst))))
|
||||||
|
(when (and closest (re-search-forward (format "^%s" closest) end t))
|
||||||
|
(helm-mark-current-line)
|
||||||
|
(goto-char (overlay-start
|
||||||
|
helm-selection-overlay))))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-occur ()
|
||||||
|
"Preconfigured helm for searching lines matching pattern in `current-buffer'.
|
||||||
|
|
||||||
|
When `helm-source-occur' is member of
|
||||||
|
`helm-sources-using-default-as-input' which is the default,
|
||||||
|
symbol at point is searched at startup.
|
||||||
|
|
||||||
|
When a region is marked search only in this region by narrowing.
|
||||||
|
|
||||||
|
To search in multiples buffers start from one of the commands listing
|
||||||
|
buffers (i.e. a helm command using `helm-source-buffers-list' like
|
||||||
|
`helm-mini') and use the multi occur buffers action.
|
||||||
|
|
||||||
|
This is the helm implementation that collect lines matching pattern
|
||||||
|
like vanilla Emacs `occur' but have nothing to do with it, the search
|
||||||
|
engine beeing completely different and also much faster."
|
||||||
|
(interactive)
|
||||||
|
(setq helm-source-occur
|
||||||
|
(car (helm-occur-build-sources (list (current-buffer)) "Helm occur")))
|
||||||
|
(helm-set-local-variable 'helm-occur--buffer-list (list (current-buffer))
|
||||||
|
'helm-occur--buffer-tick
|
||||||
|
(list (buffer-chars-modified-tick (current-buffer))))
|
||||||
|
(helm-set-attr 'header-name (lambda (_name)
|
||||||
|
(format "HO [%s]"
|
||||||
|
(buffer-name helm-current-buffer)))
|
||||||
|
helm-source-occur)
|
||||||
|
(when helm-occur-keep-closest-position
|
||||||
|
(setq helm-occur--initial-pos (line-number-at-pos))
|
||||||
|
(add-hook 'helm-after-update-hook 'helm-occur--select-closest-candidate))
|
||||||
|
(save-restriction
|
||||||
|
(let ((helm-sources-using-default-as-input
|
||||||
|
(unless (> (buffer-size) 2000000)
|
||||||
|
helm-sources-using-default-as-input))
|
||||||
|
def pos)
|
||||||
|
(when (use-region-p)
|
||||||
|
;; When user mark defun with `mark-defun' with intention of
|
||||||
|
;; using helm-occur on this region, it is relevant to use the
|
||||||
|
;; thing-at-point located at previous position which have been
|
||||||
|
;; pushed to `mark-ring', if it's within the active region.
|
||||||
|
(let ((beg (region-beginning))
|
||||||
|
(end (region-end))
|
||||||
|
(prev-pos (car mark-ring)))
|
||||||
|
(when (and prev-pos (>= prev-pos beg) (< prev-pos end))
|
||||||
|
(setq def (save-excursion
|
||||||
|
(goto-char (setq pos prev-pos))
|
||||||
|
(helm-aif (thing-at-point 'symbol) (regexp-quote it)))))
|
||||||
|
(narrow-to-region beg end)))
|
||||||
|
(unwind-protect
|
||||||
|
(helm :sources 'helm-source-occur
|
||||||
|
:buffer "*helm occur*"
|
||||||
|
:history 'helm-occur-history
|
||||||
|
:default (or def (helm-aif (thing-at-point 'symbol)
|
||||||
|
(regexp-quote it)))
|
||||||
|
:preselect (and (memq 'helm-source-occur
|
||||||
|
helm-sources-using-default-as-input)
|
||||||
|
(format "^%d:" (line-number-at-pos
|
||||||
|
(or pos (point)))))
|
||||||
|
:truncate-lines helm-occur-truncate-lines)
|
||||||
|
(deactivate-mark t)
|
||||||
|
(remove-hook 'helm-after-update-hook 'helm-occur--select-closest-candidate)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-occur-visible-buffers ()
|
||||||
|
"Run helm-occur on all visible buffers in frame."
|
||||||
|
(interactive)
|
||||||
|
(require 'helm-buffers)
|
||||||
|
(if (or (one-window-p) (region-active-p))
|
||||||
|
(call-interactively #'helm-occur)
|
||||||
|
(let ((buffers (helm-buffers-get-visible-buffers)))
|
||||||
|
(helm-multi-occur-1 (mapcar 'get-buffer buffers)))))
|
||||||
|
|
||||||
|
(defun helm-occur-transformer (candidates source)
|
||||||
|
"Return CANDIDATES prefixed with line number."
|
||||||
|
(cl-loop with buf = (helm-get-attr 'buffer-name source)
|
||||||
|
for c in candidates
|
||||||
|
for disp-linum = (when (string-match helm-occur--search-buffer-regexp c)
|
||||||
|
(let ((linum (match-string 1 c))
|
||||||
|
(disp (match-string 2 c)))
|
||||||
|
(list
|
||||||
|
linum
|
||||||
|
(format "%s:%s"
|
||||||
|
(propertize
|
||||||
|
linum 'face 'helm-grep-lineno
|
||||||
|
'help-echo (buffer-file-name
|
||||||
|
(get-buffer buf)))
|
||||||
|
disp))))
|
||||||
|
for linum = (car disp-linum)
|
||||||
|
for disp = (cadr disp-linum)
|
||||||
|
when (and disp (not (string= disp "")))
|
||||||
|
collect (cons disp (string-to-number linum))))
|
||||||
|
|
||||||
|
(defvar helm-occur--gshorthands nil)
|
||||||
|
(defun helm-occur-symbol-shorthands-pattern-transformer (pattern buffer gshorthands)
|
||||||
|
"Maybe transform PATTERN to its `read-symbol-shorthands' counterpart in BUFFER.
|
||||||
|
|
||||||
|
GSHORTHANDS is the concatenation of all `read-symbol-shorthands' value found in
|
||||||
|
all buffers i.e. `buffer-list'.
|
||||||
|
When GSHORTHANDS is nil use PATTERN unmodified."
|
||||||
|
(if gshorthands
|
||||||
|
(let* ((lshorthands (buffer-local-value 'read-symbol-shorthands buffer))
|
||||||
|
(prefix (cl-loop for (k . v) in gshorthands
|
||||||
|
if (string-match (concat "\\`" k) pattern)
|
||||||
|
return k
|
||||||
|
else
|
||||||
|
if (string-match (concat "\\`" v) pattern)
|
||||||
|
return v))
|
||||||
|
(lgstr (cdr (or (assoc prefix gshorthands)
|
||||||
|
(rassoc prefix gshorthands)))))
|
||||||
|
(if (and lgstr lshorthands)
|
||||||
|
(concat (car (rassoc lgstr lshorthands))
|
||||||
|
(replace-regexp-in-string prefix "" pattern))
|
||||||
|
pattern))
|
||||||
|
pattern))
|
||||||
|
|
||||||
|
(defclass helm-moccur-class (helm-source-in-buffer)
|
||||||
|
((buffer-name :initarg :buffer-name
|
||||||
|
:initform nil)
|
||||||
|
(moccur-buffers :initarg :moccur-buffers
|
||||||
|
:initform nil)
|
||||||
|
(find-file-target :initform #'helm-occur-quit-an-find-file-fn)))
|
||||||
|
|
||||||
|
(defun helm-occur-build-sources (buffers &optional source-name)
|
||||||
|
"Build sources for `helm-occur' for each buffer in BUFFERS list."
|
||||||
|
(setq helm-occur--gshorthands nil)
|
||||||
|
(and helm-occur-match-shorthands
|
||||||
|
(setq helm-occur--gshorthands
|
||||||
|
(cl-loop for b in (buffer-list)
|
||||||
|
for rss = (buffer-local-value
|
||||||
|
'read-symbol-shorthands
|
||||||
|
b)
|
||||||
|
when rss append rss)))
|
||||||
|
(let (sources)
|
||||||
|
(dolist (buf buffers)
|
||||||
|
(let ((bname (buffer-name buf)))
|
||||||
|
(push (helm-make-source (or source-name bname)
|
||||||
|
'helm-moccur-class
|
||||||
|
:header-name (lambda (name)
|
||||||
|
(format "HO [%s]" (if (string= name "Helm occur")
|
||||||
|
bname name)))
|
||||||
|
:buffer-name bname
|
||||||
|
:match-part
|
||||||
|
(lambda (candidate)
|
||||||
|
;; The regexp should match what is in candidate buffer,
|
||||||
|
;; not what is displayed in helm-buffer e.g. "12 foo"
|
||||||
|
;; and not "12:foo".
|
||||||
|
(when (string-match helm-occur--search-buffer-regexp
|
||||||
|
candidate)
|
||||||
|
(match-string 2 candidate)))
|
||||||
|
:diacritics helm-occur-ignore-diacritics
|
||||||
|
:search (lambda (pattern)
|
||||||
|
(when (string-match "\\`\\^\\([^ ]*\\)" pattern)
|
||||||
|
(setq pattern (concat "^[0-9]*\\s-" (match-string 1 pattern))))
|
||||||
|
(condition-case _err
|
||||||
|
(re-search-forward pattern nil t)
|
||||||
|
(invalid-regexp nil)))
|
||||||
|
:pattern-transformer (lambda (pattern)
|
||||||
|
(helm-occur-symbol-shorthands-pattern-transformer
|
||||||
|
pattern buf helm-occur--gshorthands))
|
||||||
|
:init (lambda ()
|
||||||
|
(with-current-buffer buf
|
||||||
|
(let* ((bsfn (or (cdr (assq
|
||||||
|
major-mode
|
||||||
|
helm-occur-buffer-substring-fn-for-modes))
|
||||||
|
helm-occur-buffer-substring-default-mode))
|
||||||
|
(contents (funcall bsfn (point-min) (point-max))))
|
||||||
|
(helm-set-attr 'get-line bsfn)
|
||||||
|
(with-current-buffer (helm-candidate-buffer 'global)
|
||||||
|
(insert contents)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(let ((linum 1))
|
||||||
|
(insert (format "%s " linum))
|
||||||
|
(while (re-search-forward "\n" nil t)
|
||||||
|
(cl-incf linum)
|
||||||
|
(insert (format "%s " linum))))))))
|
||||||
|
:filtered-candidate-transformer 'helm-occur-transformer
|
||||||
|
:help-message 'helm-moccur-help-message
|
||||||
|
:nomark t
|
||||||
|
:migemo t
|
||||||
|
;; Needed for resume.
|
||||||
|
:history 'helm-occur-history
|
||||||
|
:candidate-number-limit helm-occur-candidate-number-limit
|
||||||
|
:action 'helm-occur-actions
|
||||||
|
:requires-pattern 2
|
||||||
|
:follow 1
|
||||||
|
:group 'helm-occur
|
||||||
|
:keymap helm-occur-map
|
||||||
|
:resume 'helm-occur-resume-fn
|
||||||
|
:moccur-buffers buffers)
|
||||||
|
sources)))
|
||||||
|
(nreverse sources)))
|
||||||
|
|
||||||
|
(defun helm-multi-occur-1 (buffers &optional input default)
|
||||||
|
"Run `helm-occur' on a list of buffers.
|
||||||
|
Each buffer's result is displayed in a separated source.
|
||||||
|
Arg INPUT if specified will be inserted as initial input in minibuffer.
|
||||||
|
Arg DEFAULT if specified will be inserted in minibuffer with M-n.
|
||||||
|
Arg INPUT takes precedence on DEFAULT if both are specified.
|
||||||
|
If `helm-source-moccur' is member of `helm-sources-using-default-as-input'
|
||||||
|
helm-occur will start immediately with DEFAULT as INPUT.
|
||||||
|
Always prefer using DEFAULT instead of INPUT, they have the same effect but
|
||||||
|
DEFAULT keep the minibuffer empty, allowing the user to write immediately
|
||||||
|
without having to delete its contents before."
|
||||||
|
(let* ((curbuf (current-buffer))
|
||||||
|
(bufs (if helm-occur-always-search-in-current
|
||||||
|
(cons curbuf (remove curbuf buffers))
|
||||||
|
buffers))
|
||||||
|
(helm-sources-using-default-as-input
|
||||||
|
(unless (cl-loop with total_size = 0
|
||||||
|
for b in bufs
|
||||||
|
do (setq total_size (buffer-size b))
|
||||||
|
finally return (> total_size 2000000))
|
||||||
|
helm-sources-using-default-as-input))
|
||||||
|
(sources (helm-occur-build-sources bufs (and (eql curbuf (car bufs))
|
||||||
|
(not (cdr bufs))
|
||||||
|
"Helm occur")))
|
||||||
|
(helm-maybe-use-default-as-input
|
||||||
|
(not (null (memq 'helm-source-moccur
|
||||||
|
helm-sources-using-default-as-input)))))
|
||||||
|
(helm-set-local-variable 'helm-occur--buffer-list bufs
|
||||||
|
'helm-occur--buffer-tick
|
||||||
|
(cl-loop for b in bufs collect
|
||||||
|
(buffer-chars-modified-tick
|
||||||
|
(get-buffer b))))
|
||||||
|
(when (and helm-occur-always-search-in-current
|
||||||
|
helm-occur-keep-closest-position)
|
||||||
|
(setq helm-source-occur
|
||||||
|
(cl-loop for s in sources
|
||||||
|
when (eql helm-current-buffer
|
||||||
|
(get-buffer (helm-get-attr 'buffer-name s)))
|
||||||
|
return s))
|
||||||
|
(setq helm-occur--initial-pos (line-number-at-pos))
|
||||||
|
(add-hook 'helm-after-update-hook 'helm-occur--select-closest-candidate))
|
||||||
|
(unwind-protect
|
||||||
|
(helm :sources sources
|
||||||
|
:buffer "*helm moccur*"
|
||||||
|
:history 'helm-occur-history
|
||||||
|
:default (or default
|
||||||
|
(helm-aif (thing-at-point 'symbol)
|
||||||
|
(regexp-quote it)))
|
||||||
|
:input input
|
||||||
|
:truncate-lines helm-occur-truncate-lines)
|
||||||
|
(remove-hook 'helm-after-update-hook 'helm-occur--select-closest-candidate))))
|
||||||
|
|
||||||
|
;;; Actions
|
||||||
|
;;
|
||||||
|
(cl-defun helm-occur-action (lineno
|
||||||
|
&optional (method (quote buffer)))
|
||||||
|
"Jump to line number LINENO with METHOD.
|
||||||
|
METHOD can be one of buffer, buffer-other-window, buffer-other-frame."
|
||||||
|
(require 'helm-grep)
|
||||||
|
(let ((buf (if (eq major-mode 'helm-occur-mode)
|
||||||
|
(get-text-property (point) 'buffer-name)
|
||||||
|
(helm-get-attr 'buffer-name)))
|
||||||
|
(split-pat (helm-mm-split-pattern helm-input)))
|
||||||
|
(cl-case method
|
||||||
|
(buffer (switch-to-buffer buf))
|
||||||
|
(buffer-other-window (helm-window-show-buffers (list buf) t))
|
||||||
|
(buffer-other-frame (switch-to-buffer-other-frame buf)))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(helm-goto-line lineno)
|
||||||
|
;; Move point to the nearest matching regexp from bol.
|
||||||
|
(cl-loop for str in split-pat
|
||||||
|
for reg = (helm-occur-symbol-shorthands-pattern-transformer
|
||||||
|
str (get-buffer buf) helm-occur--gshorthands)
|
||||||
|
when (save-excursion
|
||||||
|
(condition-case _err
|
||||||
|
(if helm-migemo-mode
|
||||||
|
(helm-mm-migemo-forward reg (pos-eol) t)
|
||||||
|
(re-search-forward reg (pos-eol) t))
|
||||||
|
(invalid-regexp nil)))
|
||||||
|
collect (match-beginning 0) into pos-ls
|
||||||
|
finally (when pos-ls (goto-char (apply #'min pos-ls)))))))
|
||||||
|
|
||||||
|
(defun helm-occur-goto-line (candidate)
|
||||||
|
"From multi occur, switch to buffer and CANDIDATE line."
|
||||||
|
(helm-occur-action
|
||||||
|
candidate 'buffer))
|
||||||
|
|
||||||
|
(defun helm-occur-goto-line-ow (candidate)
|
||||||
|
"Go to CANDIDATE line in other window.
|
||||||
|
Same as `helm-occur-goto-line' but go in other window."
|
||||||
|
(helm-occur-action
|
||||||
|
candidate 'buffer-other-window))
|
||||||
|
|
||||||
|
(defun helm-occur-goto-line-of (candidate)
|
||||||
|
"Go to CANDIDATE line in new frame.
|
||||||
|
Same as `helm-occur-goto-line' but go in new frame."
|
||||||
|
(helm-occur-action
|
||||||
|
candidate 'buffer-other-frame))
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-occur-run-goto-line-ow
|
||||||
|
"Run goto line other window action from `helm-occur'."
|
||||||
|
'helm-occur-goto-line-ow)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-occur-run-goto-line-of
|
||||||
|
"Run goto line new frame action from `helm-occur'."
|
||||||
|
'helm-occur-goto-line-of)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-occur-run-default-action
|
||||||
|
"Goto matching line from helm-occur buffer."
|
||||||
|
'helm-occur-goto-line)
|
||||||
|
|
||||||
|
(helm-make-command-from-action helm-occur-run-save-buffer
|
||||||
|
"Run moccur save results action from `helm-moccur'."
|
||||||
|
'helm-occur-save-results)
|
||||||
|
|
||||||
|
(defun helm-occur-right ()
|
||||||
|
"`helm-occur' action for right arrow.
|
||||||
|
This is used when `helm-occur-use-ioccur-style-keys' is enabled.
|
||||||
|
If follow is enabled (default) go to next source, otherwise execute
|
||||||
|
persistent action."
|
||||||
|
(interactive)
|
||||||
|
(if (helm-aand (helm-get-attr 'follow) (> it 0))
|
||||||
|
(helm-next-source)
|
||||||
|
(helm-execute-persistent-action)))
|
||||||
|
(put 'helm-occur-right 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-occur-quit-an-find-file-fn (source)
|
||||||
|
(let* ((sel (helm-get-selection nil nil source))
|
||||||
|
(occur-fname (helm-aand (numberp sel)
|
||||||
|
(helm-get-attr 'buffer-name)
|
||||||
|
(buffer-file-name (get-buffer it)))))
|
||||||
|
(when (and occur-fname (file-exists-p occur-fname))
|
||||||
|
(expand-file-name occur-fname))))
|
||||||
|
|
||||||
|
;;; helm-occur-mode
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defvar helm-occur-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map (kbd "RET") 'helm-occur-mode-goto-line)
|
||||||
|
(define-key map (kbd "C-o") 'helm-occur-mode-goto-line-ow)
|
||||||
|
(define-key map (kbd "<C-down>") 'helm-occur-mode-goto-line-ow-forward)
|
||||||
|
(define-key map (kbd "<C-up>") 'helm-occur-mode-goto-line-ow-backward)
|
||||||
|
(define-key map (kbd "<M-down>") 'helm-gm-next-file)
|
||||||
|
(define-key map (kbd "<M-up>") 'helm-gm-precedent-file)
|
||||||
|
(define-key map (kbd "M-n") 'helm-occur-mode-goto-line-ow-forward)
|
||||||
|
(define-key map (kbd "M-p") 'helm-occur-mode-goto-line-ow-backward)
|
||||||
|
(define-key map (kbd "M-N") 'helm-gm-next-file)
|
||||||
|
(define-key map (kbd "M-P") 'helm-gm-precedent-file)
|
||||||
|
(define-key map (kbd "C-c b") 'helm-occur-mode-resume-session)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defun helm-occur-mode-goto-line ()
|
||||||
|
(interactive)
|
||||||
|
(setq next-error-last-buffer (current-buffer))
|
||||||
|
(setq-local helm-current-error (point-marker))
|
||||||
|
(helm-aif (get-text-property (point) 'helm-realvalue)
|
||||||
|
(progn (helm-occur-goto-line it) (helm-match-line-cleanup-pulse))))
|
||||||
|
|
||||||
|
(defun helm-occur-mode-goto-line-ow ()
|
||||||
|
(interactive)
|
||||||
|
(setq next-error-last-buffer (current-buffer))
|
||||||
|
(setq-local helm-current-error (point-marker))
|
||||||
|
(helm-aif (get-text-property (point) 'helm-realvalue)
|
||||||
|
(progn (helm-occur-goto-line-ow it) (helm-match-line-cleanup-pulse))))
|
||||||
|
|
||||||
|
(defun helm-occur-mode-goto-line-ow-forward-1 (arg)
|
||||||
|
(condition-case nil
|
||||||
|
(progn
|
||||||
|
(when (or (eq last-command 'helm-occur-mode-goto-line-ow-forward)
|
||||||
|
(eq last-command 'helm-occur-mode-goto-line-ow-backward))
|
||||||
|
(forward-line arg))
|
||||||
|
(save-selected-window
|
||||||
|
(helm-occur-mode-goto-line-ow)
|
||||||
|
(recenter)))
|
||||||
|
(error nil)))
|
||||||
|
|
||||||
|
(defun helm-occur-mode-goto-line-ow-forward (arg)
|
||||||
|
(interactive "p")
|
||||||
|
(helm-occur-mode-goto-line-ow-forward-1 arg))
|
||||||
|
|
||||||
|
(defun helm-occur-mode-goto-line-ow-backward (arg)
|
||||||
|
(interactive "p")
|
||||||
|
(helm-occur-mode-goto-line-ow-forward-1 (- arg)))
|
||||||
|
|
||||||
|
(defun helm-occur-save-results (_candidate)
|
||||||
|
"Save helm moccur results in a `helm-moccur-mode' buffer."
|
||||||
|
(let ((buf "*hmoccur*")
|
||||||
|
new-buf)
|
||||||
|
(when (get-buffer buf)
|
||||||
|
(setq new-buf (helm-read-string "OccurBufferName: " buf))
|
||||||
|
(cl-loop for b in (helm-buffer-list)
|
||||||
|
when (and (string= new-buf b)
|
||||||
|
(not (y-or-n-p
|
||||||
|
(format "Buffer `%s' already exists overwrite? "
|
||||||
|
new-buf))))
|
||||||
|
do (setq new-buf (helm-read-string
|
||||||
|
"OccurBufferName: " "*hmoccur ")))
|
||||||
|
(setq buf new-buf))
|
||||||
|
(with-current-buffer (get-buffer-create buf)
|
||||||
|
(kill-all-local-variables)
|
||||||
|
(setq buffer-read-only t)
|
||||||
|
(buffer-disable-undo)
|
||||||
|
(let ((inhibit-read-only t)
|
||||||
|
(map (make-sparse-keymap))
|
||||||
|
buf-name)
|
||||||
|
(erase-buffer)
|
||||||
|
(insert "-*- mode: helm-occur -*-\n\n"
|
||||||
|
(format "Occur Results for `%s':\n\n" helm-input))
|
||||||
|
(save-excursion
|
||||||
|
(insert (with-current-buffer helm-buffer
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line 1)
|
||||||
|
(buffer-substring (point) (point-max)))))
|
||||||
|
(save-excursion
|
||||||
|
(forward-line -2)
|
||||||
|
(while (not (eobp))
|
||||||
|
(if (helm-pos-header-line-p)
|
||||||
|
(let ((beg (pos-bol))
|
||||||
|
(end (pos-eol)))
|
||||||
|
(set-text-properties beg (1+ end) nil)
|
||||||
|
(delete-region (1- beg) end))
|
||||||
|
(helm-aif (setq buf-name (assoc-default
|
||||||
|
'buffer-name
|
||||||
|
(get-text-property (point) 'helm-cur-source)))
|
||||||
|
(progn
|
||||||
|
(insert (propertize (concat it ":")
|
||||||
|
'face 'helm-moccur-buffer
|
||||||
|
'helm-realvalue (get-text-property (point) 'helm-realvalue)))
|
||||||
|
(add-text-properties
|
||||||
|
(pos-bol) (pos-eol)
|
||||||
|
`(buffer-name ,buf-name))
|
||||||
|
(add-text-properties
|
||||||
|
(pos-bol) (pos-eol)
|
||||||
|
`(keymap ,map
|
||||||
|
help-echo ,(concat
|
||||||
|
(buffer-file-name
|
||||||
|
(get-buffer buf-name))
|
||||||
|
"\nmouse-1: set point\nmouse-2: jump to selection")
|
||||||
|
mouse-face highlight
|
||||||
|
invisible nil))
|
||||||
|
(define-key map [mouse-1] 'mouse-set-point)
|
||||||
|
(define-key map [mouse-2] 'helm-occur-mode-mouse-goto-line)
|
||||||
|
(define-key map [mouse-3] 'ignore))))
|
||||||
|
(forward-line 1))))
|
||||||
|
(buffer-enable-undo)
|
||||||
|
(helm-occur-mode))
|
||||||
|
(pop-to-buffer buf)
|
||||||
|
(setq next-error-last-buffer (get-buffer buf))
|
||||||
|
(message "Helm occur Results saved in `%s' buffer" buf)))
|
||||||
|
|
||||||
|
(defun helm-occur-mode-mouse-goto-line (event)
|
||||||
|
(interactive "e")
|
||||||
|
(let* ((window (posn-window (event-end event)))
|
||||||
|
(pos (posn-point (event-end event))))
|
||||||
|
(with-selected-window window
|
||||||
|
(when (eq major-mode 'helm-occur-mode)
|
||||||
|
(goto-char pos)
|
||||||
|
(helm-occur-mode-goto-line)))))
|
||||||
|
(put 'helm-moccur-mode-mouse-goto-line 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-occur-mode-resume-session ()
|
||||||
|
(interactive)
|
||||||
|
(cl-assert (eq major-mode 'helm-occur-mode) nil "Helm command called in wrong context")
|
||||||
|
(helm-multi-occur-1 helm-occur--buffer-list helm-occur-mode--last-pattern))
|
||||||
|
|
||||||
|
(defun helm-occur-buffer-substring-with-linums ()
|
||||||
|
"Return current-buffer contents as a string with all lines
|
||||||
|
numbered. The property \\='buffer-name is added to the whole string."
|
||||||
|
(let ((bufstr (buffer-substring-no-properties (point-min) (point-max)))
|
||||||
|
(bufname (buffer-name)))
|
||||||
|
(with-temp-buffer
|
||||||
|
(save-excursion
|
||||||
|
(insert bufstr))
|
||||||
|
(let ((linum 1))
|
||||||
|
(insert (format "%s " linum))
|
||||||
|
(while (re-search-forward "\n" nil t)
|
||||||
|
(cl-incf linum)
|
||||||
|
(insert (format "%s " linum)))
|
||||||
|
(add-text-properties (point-min) (point-max) `(buffer-name ,bufname)))
|
||||||
|
(buffer-string))))
|
||||||
|
|
||||||
|
(defun helm-occur-mode--revert-buffer-function (&optional _ignore-auto _noconfirm)
|
||||||
|
"The `revert-buffer-function' for `helm-occur-mode'."
|
||||||
|
(goto-char (point-min))
|
||||||
|
(let (pattern)
|
||||||
|
(when (re-search-forward "^Occur Results for `\\(.*\\)'" nil t)
|
||||||
|
(setq pattern (match-string 1))
|
||||||
|
(forward-line 0)
|
||||||
|
(when (re-search-forward "^$" nil t)
|
||||||
|
(forward-line 1))
|
||||||
|
(let ((inhibit-read-only t)
|
||||||
|
(buffer (current-buffer))
|
||||||
|
(buflst helm-occur--buffer-list))
|
||||||
|
(delete-region (point) (point-max))
|
||||||
|
(message "Reverting buffer...")
|
||||||
|
(save-excursion
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert
|
||||||
|
"\n"
|
||||||
|
(cl-loop for buf in buflst
|
||||||
|
for bufstr = (or (and (buffer-live-p (get-buffer buf))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(helm-occur-buffer-substring-with-linums)))
|
||||||
|
"")
|
||||||
|
concat bufstr)
|
||||||
|
"\n")
|
||||||
|
(goto-char (point-min))
|
||||||
|
(cl-loop with linum
|
||||||
|
with mpart
|
||||||
|
;; Bind helm-pattern used by `helm-grep-split-line'.
|
||||||
|
with helm-pattern = pattern
|
||||||
|
while (helm-mm-search pattern) ; point is at eol.
|
||||||
|
;; Calculate line number (linum) and extract real
|
||||||
|
;; part of line (mpart).
|
||||||
|
do (when (save-excursion
|
||||||
|
;; `helm-mm-search' puts point at eol.
|
||||||
|
(forward-line 0)
|
||||||
|
(re-search-forward "^\\([0-9]*\\)\\s-\\{1\\}\\(.*\\)$"
|
||||||
|
(pos-eol) t))
|
||||||
|
(setq linum (string-to-number (match-string 1))
|
||||||
|
mpart (match-string 2)))
|
||||||
|
;; Match part after line number.
|
||||||
|
when (and mpart (helm-mm-match mpart pattern))
|
||||||
|
for line = (format "%s:%d:%s"
|
||||||
|
(get-text-property (point) 'buffer-name)
|
||||||
|
linum
|
||||||
|
mpart)
|
||||||
|
when line
|
||||||
|
do (with-current-buffer buffer
|
||||||
|
(insert
|
||||||
|
(propertize
|
||||||
|
(car (helm-occur-filter-one-by-one line))
|
||||||
|
'helm-realvalue linum)
|
||||||
|
"\n"))))
|
||||||
|
(when (fboundp 'wgrep-cleanup-overlays)
|
||||||
|
(wgrep-cleanup-overlays (point-min) (point-max)))
|
||||||
|
(message "Reverting buffer done")
|
||||||
|
(when executing-kbd-macro (sit-for 1)))))))
|
||||||
|
|
||||||
|
(defun helm-occur-filter-one-by-one (candidate)
|
||||||
|
"`filter-one-by-one' function for `helm-source-moccur'."
|
||||||
|
(require 'helm-grep)
|
||||||
|
(let* ((split (helm-grep-split-line candidate))
|
||||||
|
(buf (car split))
|
||||||
|
(lineno (nth 1 split))
|
||||||
|
(str (nth 2 split)))
|
||||||
|
(cons (concat (propertize
|
||||||
|
buf
|
||||||
|
'face 'helm-moccur-buffer
|
||||||
|
'help-echo (buffer-file-name
|
||||||
|
(get-buffer buf))
|
||||||
|
'buffer-name buf)
|
||||||
|
":"
|
||||||
|
(propertize lineno 'face 'helm-grep-lineno)
|
||||||
|
":"
|
||||||
|
(helm-grep-highlight-match str))
|
||||||
|
candidate)))
|
||||||
|
|
||||||
|
(define-derived-mode helm-occur-mode
|
||||||
|
special-mode "helm-moccur"
|
||||||
|
"Major mode to provide actions in helm moccur saved buffer.
|
||||||
|
|
||||||
|
Special commands:
|
||||||
|
\\{helm-occur-mode-map}"
|
||||||
|
(set (make-local-variable 'helm-occur--buffer-list)
|
||||||
|
(with-helm-buffer helm-occur--buffer-list))
|
||||||
|
(set (make-local-variable 'revert-buffer-function)
|
||||||
|
#'helm-occur-mode--revert-buffer-function)
|
||||||
|
(set (make-local-variable 'helm-occur-mode--last-pattern)
|
||||||
|
helm-input)
|
||||||
|
(set (make-local-variable 'next-error-function)
|
||||||
|
#'helm-occur-next-error)
|
||||||
|
(set (make-local-variable 'helm-current-error) nil))
|
||||||
|
(put 'helm-moccur-mode 'helm-only t)
|
||||||
|
|
||||||
|
(defun helm-occur-next-error (&optional argp reset)
|
||||||
|
"Goto ARGP position from a `helm-occur-mode' buffer.
|
||||||
|
RESET non-nil means rewind to the first match.
|
||||||
|
This is the `next-error-function' for `helm-occur-mode'."
|
||||||
|
(interactive "p")
|
||||||
|
(goto-char (cond (reset (point-min))
|
||||||
|
((and (< argp 0) helm-current-error)
|
||||||
|
(line-beginning-position))
|
||||||
|
((and (> argp 0) helm-current-error)
|
||||||
|
(line-end-position))
|
||||||
|
((point))))
|
||||||
|
(let ((fun (if (> argp 0)
|
||||||
|
#'next-single-property-change
|
||||||
|
#'previous-single-property-change)))
|
||||||
|
(helm-aif (funcall fun (point) 'buffer-name)
|
||||||
|
(progn
|
||||||
|
(goto-char it)
|
||||||
|
(forward-line 0)
|
||||||
|
;; `helm-current-error' is set in
|
||||||
|
;; `helm-occur-mode-goto-line'.
|
||||||
|
(helm-occur-mode-goto-line))
|
||||||
|
(user-error "No more matches"))))
|
||||||
|
|
||||||
|
;;; Resume
|
||||||
|
;;
|
||||||
|
(defun helm-occur-resume-fn ()
|
||||||
|
(with-helm-buffer
|
||||||
|
(let (new-tick-ls buffer-is-modified)
|
||||||
|
(set (make-local-variable 'helm-occur--buffer-list)
|
||||||
|
(cl-loop for b in helm-occur--buffer-list
|
||||||
|
when (buffer-live-p (get-buffer b))
|
||||||
|
collect b))
|
||||||
|
(setq buffer-is-modified (/= (length helm-occur--buffer-list)
|
||||||
|
(length (helm-get-attr 'moccur-buffers))))
|
||||||
|
(helm-set-attr 'moccur-buffers helm-occur--buffer-list)
|
||||||
|
(setq new-tick-ls (cl-loop for b in helm-occur--buffer-list
|
||||||
|
collect (buffer-chars-modified-tick
|
||||||
|
(get-buffer b))))
|
||||||
|
(when buffer-is-modified
|
||||||
|
(setq helm-occur--buffer-tick new-tick-ls))
|
||||||
|
(cl-assert (> (length helm-occur--buffer-list) 0) nil
|
||||||
|
"helm-resume error: helm-(m)occur buffer list is empty")
|
||||||
|
(unless (eq helm-occur-auto-update-on-resume 'never)
|
||||||
|
(when (or buffer-is-modified
|
||||||
|
(cl-loop for b in helm-occur--buffer-list
|
||||||
|
for new-tick = (buffer-chars-modified-tick
|
||||||
|
(get-buffer b))
|
||||||
|
for tick in helm-occur--buffer-tick
|
||||||
|
thereis (/= tick new-tick)))
|
||||||
|
(helm-aif helm-occur-auto-update-on-resume
|
||||||
|
(when (or (eq it 'noask)
|
||||||
|
(y-or-n-p "Helm (m)occur Buffer outdated, update? "))
|
||||||
|
(run-with-idle-timer
|
||||||
|
0.1 nil (lambda ()
|
||||||
|
(with-helm-buffer
|
||||||
|
(helm-force-update)
|
||||||
|
(message "Helm (m)occur Buffer have been udated")
|
||||||
|
(sit-for 1) (message nil))))
|
||||||
|
(unless buffer-is-modified (setq helm-occur--buffer-tick
|
||||||
|
new-tick-ls)))
|
||||||
|
(run-with-idle-timer
|
||||||
|
0.1 nil
|
||||||
|
(lambda ()
|
||||||
|
(with-helm-buffer
|
||||||
|
(let ((ov (make-overlay (save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line 1)
|
||||||
|
(point))
|
||||||
|
(point-max))))
|
||||||
|
(overlay-put ov 'face 'helm-resume-need-update)
|
||||||
|
(sit-for 0)
|
||||||
|
(delete-overlay ov)
|
||||||
|
(message "[Helm occur Buffer outdated (C-c C-u to update)]")))))
|
||||||
|
(unless buffer-is-modified
|
||||||
|
(with-helm-after-update-hook
|
||||||
|
(setq helm-occur--buffer-tick new-tick-ls)
|
||||||
|
(message "Helm (m)occur Buffer have been udated")))))))))
|
||||||
|
|
||||||
|
;;; Helm occur from isearch
|
||||||
|
;;
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-occur-from-isearch ()
|
||||||
|
"Invoke `helm-occur' from isearch.
|
||||||
|
|
||||||
|
To use this bind it to a key in `isearch-mode-map'."
|
||||||
|
(interactive)
|
||||||
|
(let ((input (if isearch-regexp
|
||||||
|
isearch-string
|
||||||
|
(regexp-quote isearch-string)))
|
||||||
|
(bufs (list (current-buffer)))
|
||||||
|
;; Use `helm-occur-always-search-in-current' as a flag for
|
||||||
|
;; `helm-occur--select-closest-candidate'.
|
||||||
|
(helm-occur-always-search-in-current t))
|
||||||
|
(isearch-exit)
|
||||||
|
(helm-multi-occur-1 bufs input)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-multi-occur-from-isearch ()
|
||||||
|
"Invoke `helm-multi-occur' from isearch.
|
||||||
|
|
||||||
|
With a prefix arg, reverse the behavior of
|
||||||
|
`helm-moccur-always-search-in-current'.
|
||||||
|
The prefix arg can be set before calling
|
||||||
|
`helm-multi-occur-from-isearch' or during the buffer selection.
|
||||||
|
|
||||||
|
To use this bind it to a key in `isearch-mode-map'."
|
||||||
|
(interactive)
|
||||||
|
(let (buf-list
|
||||||
|
helm-moccur-always-search-in-current
|
||||||
|
(input (if isearch-regexp
|
||||||
|
isearch-string
|
||||||
|
(regexp-quote isearch-string))))
|
||||||
|
(isearch-exit)
|
||||||
|
(setq buf-list (mapcar 'get-buffer
|
||||||
|
(helm-comp-read "Buffers: "
|
||||||
|
(helm-buffer-list)
|
||||||
|
:name "Occur in buffer(s)"
|
||||||
|
:marked-candidates t)))
|
||||||
|
(setq helm-moccur-always-search-in-current
|
||||||
|
(if (or current-prefix-arg
|
||||||
|
helm-current-prefix-arg)
|
||||||
|
(not helm-moccur-always-search-in-current)
|
||||||
|
helm-moccur-always-search-in-current))
|
||||||
|
(helm-multi-occur-1 buf-list input)))
|
||||||
|
|
||||||
|
(provide 'helm-occur)
|
||||||
|
|
||||||
|
;;; helm-occur.el ends here
|
288
code/elpa/helm-20240320.541/helm-packages.el
Normal file
288
code/elpa/helm-20240320.541/helm-packages.el
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
;;; helm-packages.el --- helm interface to manage packages -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012 ~ 2023 Thierry Volpiatto
|
||||||
|
|
||||||
|
;; This program 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.
|
||||||
|
|
||||||
|
;; This program 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/>.
|
||||||
|
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'helm)
|
||||||
|
(require 'package)
|
||||||
|
(require 'helm-utils) ; For with-helm-display-marked-candidates.
|
||||||
|
|
||||||
|
|
||||||
|
(defclass helm-packages-class (helm-source-in-buffer)
|
||||||
|
((coerce :initform #'helm-symbolify)
|
||||||
|
(find-file-target :initform #'helm-packages-quit-an-find-file)
|
||||||
|
(filtered-candidate-transformer
|
||||||
|
:initform
|
||||||
|
'(helm-packages-transformer
|
||||||
|
(lambda (candidates _source)
|
||||||
|
(sort candidates #'helm-generic-sort-fn))))
|
||||||
|
(update :initform #'helm-packages--refresh-contents))
|
||||||
|
"A class to define `helm-packages' sources.")
|
||||||
|
|
||||||
|
;;; Actions
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-packages-upgrade (_candidate)
|
||||||
|
"Helm action for upgrading marked packages."
|
||||||
|
(let ((mkd (helm-marked-candidates)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
(mapcar #'symbol-name mkd)
|
||||||
|
(when (y-or-n-p (format "Upgrade %s packages? " (length mkd)))
|
||||||
|
(mapc #'package-upgrade mkd)))))
|
||||||
|
|
||||||
|
(defun helm-packages-describe (candidate)
|
||||||
|
"Helm action for describing package CANDIDATE."
|
||||||
|
(describe-package candidate))
|
||||||
|
|
||||||
|
(defun helm-packages-visit-homepage (candidate)
|
||||||
|
"Helm action for visiting package CANDIDATE home page."
|
||||||
|
(let* ((id (package-get-descriptor candidate))
|
||||||
|
(name (package-desc-name id))
|
||||||
|
(extras (package-desc-extras id))
|
||||||
|
(url (and (listp extras) (cdr-safe (assoc :url extras)))))
|
||||||
|
(if (stringp url)
|
||||||
|
(browse-url url)
|
||||||
|
(message "Package %s has no homepage"
|
||||||
|
(propertize (symbol-name name)
|
||||||
|
'face 'font-lock-keyword-face)))))
|
||||||
|
|
||||||
|
(defun helm-packages-package-reinstall (_candidate)
|
||||||
|
"Helm action for reinstalling marked packages."
|
||||||
|
(let ((mkd (helm-marked-candidates)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
(mapcar #'symbol-name mkd)
|
||||||
|
(when (y-or-n-p (format "Reinstall %s packages? " (length mkd)))
|
||||||
|
(mapc #'package-reinstall mkd)))))
|
||||||
|
|
||||||
|
(defun helm-packages-delete-1 (packages &optional force)
|
||||||
|
"Run `package-delete' on PACKAGES.
|
||||||
|
If FORCE is non nil force deleting packages."
|
||||||
|
(mapc (lambda (x)
|
||||||
|
(package-delete (package-get-descriptor x) force))
|
||||||
|
packages))
|
||||||
|
|
||||||
|
(defun helm-packages-uninstall (_candidate)
|
||||||
|
"Helm action for uninstalling marked packages.
|
||||||
|
Unlike `helm-packages-delete' this will refuse to delete packages when they are
|
||||||
|
needed by others packages as dependencies."
|
||||||
|
(let ((mkd (helm-marked-candidates)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
(mapcar #'symbol-name mkd)
|
||||||
|
(when (y-or-n-p (format "Uninstall %s packages? " (length mkd)))
|
||||||
|
(helm-packages-delete-1 mkd)))))
|
||||||
|
|
||||||
|
(defun helm-packages-delete (_candidate)
|
||||||
|
"Helm action for deleting marked packages.
|
||||||
|
Unlike `helm-packages-uninstall' this delete packages even when they are needed
|
||||||
|
as dependencies."
|
||||||
|
(let ((mkd (helm-marked-candidates)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
(mapcar #'symbol-name mkd)
|
||||||
|
(when (y-or-n-p (format "Delete %s packages? " (length mkd)))
|
||||||
|
(helm-packages-delete-1 mkd 'force)))))
|
||||||
|
|
||||||
|
(defun helm-packages-recompile (_candidate)
|
||||||
|
"Helm action for recompiling marked packages."
|
||||||
|
(let ((mkd (helm-marked-candidates)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
(mapcar #'symbol-name mkd)
|
||||||
|
(when (y-or-n-p (format "Recompile %s packages? " (length mkd)))
|
||||||
|
(mapc #'package-recompile mkd)))))
|
||||||
|
|
||||||
|
(defun helm-packages-install (_candidate)
|
||||||
|
"Helm action for installing marked packages."
|
||||||
|
(let ((mkd (helm-marked-candidates)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
(mapcar #'symbol-name mkd)
|
||||||
|
(when (y-or-n-p (format "Install %s packages? " (length mkd)))
|
||||||
|
(condition-case err
|
||||||
|
(mapc #'package-install mkd)
|
||||||
|
(error "%S:\n Please refresh package list before installing" err))))))
|
||||||
|
|
||||||
|
(defun helm-packages-isolate-1 (packages)
|
||||||
|
"Start an Emacs with only PACKAGES loaded.
|
||||||
|
Arg PACKAGES is a list of strings."
|
||||||
|
(let* ((name (concat "package-isolate-" (mapconcat #'identity packages "_")))
|
||||||
|
(deps (cl-loop for p in packages
|
||||||
|
for sym = (intern p)
|
||||||
|
nconc (package--dependencies sym))))
|
||||||
|
(apply #'start-process name nil
|
||||||
|
(list (expand-file-name invocation-name invocation-directory)
|
||||||
|
"-Q" "--debug-init"
|
||||||
|
(format "--eval=%S"
|
||||||
|
`(progn
|
||||||
|
(require 'package)
|
||||||
|
(setq package-load-list
|
||||||
|
',(append (mapcar (lambda (p) (list (intern p) t))
|
||||||
|
packages)
|
||||||
|
(mapcar (lambda (p) (list p t)) deps)))
|
||||||
|
(package-initialize)))))))
|
||||||
|
|
||||||
|
(defun helm-packages-isolate (_candidate)
|
||||||
|
"Start a new Emacs with only marked packages loaded."
|
||||||
|
(let* ((mkd (helm-marked-candidates))
|
||||||
|
(pkg-names (mapcar #'symbol-name mkd))
|
||||||
|
(isolate (if (fboundp 'package-isolate)
|
||||||
|
#'package-isolate
|
||||||
|
#'helm-packages-isolate-1)))
|
||||||
|
(with-helm-display-marked-candidates
|
||||||
|
helm-marked-buffer-name
|
||||||
|
pkg-names
|
||||||
|
(when (y-or-n-p "Start a new Emacs with only package(s)? ")
|
||||||
|
(funcall isolate pkg-names)))))
|
||||||
|
|
||||||
|
(defun helm-packages-quit-an-find-file (source)
|
||||||
|
"`find-file-target' function for `helm-packages'."
|
||||||
|
(let* ((sel (helm-get-selection nil nil source))
|
||||||
|
(pkg (package-get-descriptor (intern sel))))
|
||||||
|
(if (and pkg (package-installed-p pkg))
|
||||||
|
(expand-file-name (package-desc-dir pkg))
|
||||||
|
package-user-dir)))
|
||||||
|
|
||||||
|
;;; Transformers
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
(defun helm-packages-transformer (candidates _source)
|
||||||
|
"Transformer function for `helm-packages'."
|
||||||
|
(cl-loop for c in candidates
|
||||||
|
for sym = (intern-soft c)
|
||||||
|
for archive = (assq sym package-archive-contents)
|
||||||
|
for id = (package-get-descriptor sym)
|
||||||
|
for provider = (and archive (package-desc-archive (cadr archive)))
|
||||||
|
for status = (and id (package-desc-status id))
|
||||||
|
for version = (and id (mapconcat #'number-to-string (package-desc-version id) "."))
|
||||||
|
for description = (and id (package-desc-summary id))
|
||||||
|
for disp = (format "%s%s%s%s%s%s%s%s%s"
|
||||||
|
;; Package name.
|
||||||
|
(propertize
|
||||||
|
c
|
||||||
|
'face (if (equal status "dependency")
|
||||||
|
font-lock-type-face
|
||||||
|
'font-lock-keyword-face)
|
||||||
|
'match-part c)
|
||||||
|
;; Separator.
|
||||||
|
(make-string (1+ (- (helm-in-buffer-get-longest-candidate)
|
||||||
|
(length c)))
|
||||||
|
? )
|
||||||
|
;; Package status.
|
||||||
|
(propertize
|
||||||
|
(or status "")
|
||||||
|
'face (if (equal status "dependency")
|
||||||
|
'bold-italic
|
||||||
|
'default))
|
||||||
|
;; Separator.
|
||||||
|
(make-string (1+ (- 10 (length status))) ? )
|
||||||
|
;; Package provider.
|
||||||
|
(or provider "")
|
||||||
|
;; Separator.
|
||||||
|
(make-string (1+ (- 10 (length provider))) ? )
|
||||||
|
;; Package version.
|
||||||
|
(or version "")
|
||||||
|
;; Separator.
|
||||||
|
(make-string (1+ (- 20 (length version))) ? )
|
||||||
|
;; Package description.
|
||||||
|
(if description
|
||||||
|
(propertize description 'face 'font-lock-warning-face)
|
||||||
|
""))
|
||||||
|
collect (cons disp c)))
|
||||||
|
|
||||||
|
(defun helm-packages-transformer-1 (candidates _source)
|
||||||
|
"Transformer function for `helm-packages' upgrade and delete sources."
|
||||||
|
(cl-loop for c in candidates
|
||||||
|
collect (cons (propertize c 'face 'font-lock-keyword-face) c)))
|
||||||
|
|
||||||
|
(defvar helm-packages--updated nil)
|
||||||
|
(defun helm-packages--refresh-contents ()
|
||||||
|
(unless helm-packages--updated (package-refresh-contents))
|
||||||
|
(helm-set-local-variable 'helm-packages--updated t))
|
||||||
|
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun helm-packages (&optional arg)
|
||||||
|
"Helm interface to manage packages.
|
||||||
|
|
||||||
|
With a prefix arg ARG refresh package list.
|
||||||
|
|
||||||
|
When installing or upgrading ensure to refresh the package list
|
||||||
|
to avoid errors with outdated packages no more availables."
|
||||||
|
(interactive "P")
|
||||||
|
(package-initialize)
|
||||||
|
(when arg (helm-packages--refresh-contents))
|
||||||
|
(let ((upgrades (package--upgradeable-packages))
|
||||||
|
(removables (package--removable-packages)))
|
||||||
|
(helm :sources (list
|
||||||
|
(helm-make-source "Availables for upgrade" 'helm-packages-class
|
||||||
|
:init (lambda ()
|
||||||
|
(helm-init-candidates-in-buffer 'global upgrades))
|
||||||
|
:filtered-candidate-transformer #'helm-packages-transformer-1
|
||||||
|
:action '(("Upgrade package(s)"
|
||||||
|
. helm-packages-upgrade)))
|
||||||
|
(helm-make-source "Packages to delete" 'helm-packages-class
|
||||||
|
:init (lambda ()
|
||||||
|
(helm-init-candidates-in-buffer 'global removables))
|
||||||
|
:filtered-candidate-transformer #'helm-packages-transformer-1
|
||||||
|
:action '(("Delete package(s)" . helm-packages-delete)))
|
||||||
|
(helm-make-source "Installed packages" 'helm-packages-class
|
||||||
|
:init (lambda ()
|
||||||
|
(helm-init-candidates-in-buffer 'global
|
||||||
|
(mapcar #'car package-alist)))
|
||||||
|
:action '(("Describe package" . helm-packages-describe)
|
||||||
|
("Visit homepage" . helm-packages-visit-homepage)
|
||||||
|
("Reinstall package(s)"
|
||||||
|
. helm-packages-package-reinstall)
|
||||||
|
("Recompile package(s)" . helm-packages-recompile)
|
||||||
|
("Uninstall package(s)" . helm-packages-uninstall)
|
||||||
|
("Isolate package(s)" . helm-packages-isolate)))
|
||||||
|
(helm-make-source "Available external packages" 'helm-packages-class
|
||||||
|
:data (cl-loop for p in package-archive-contents
|
||||||
|
for sym = (car p)
|
||||||
|
for id = (package-get-descriptor sym)
|
||||||
|
for status = (package-desc-status id)
|
||||||
|
unless (or (and id (member
|
||||||
|
status
|
||||||
|
'("installed" "dependency" "source")))
|
||||||
|
(and id (assoc sym package--builtins)))
|
||||||
|
nconc (list (car p)))
|
||||||
|
:action '(("Describe package" . helm-packages-describe)
|
||||||
|
("Visit homepage" . helm-packages-visit-homepage)
|
||||||
|
("Install packages(s)"
|
||||||
|
. helm-packages-install)))
|
||||||
|
(helm-make-source "Available built-in packages" 'helm-packages-class
|
||||||
|
:data (cl-loop for p in package--builtins
|
||||||
|
;; Show only builtins that are available as
|
||||||
|
;; well on (m)elpa. Other builtins don't
|
||||||
|
;; have a package-descriptor, the format is
|
||||||
|
;; (sym . [version reqs summary]).
|
||||||
|
when (package-desc-p (package-get-descriptor (car p)))
|
||||||
|
collect (car p))
|
||||||
|
:action '(("Describe package" . helm-packages-describe)
|
||||||
|
("Visit homepage" . helm-packages-visit-homepage)
|
||||||
|
("Install packages(s)"
|
||||||
|
. helm-packages-install))))
|
||||||
|
:buffer "*helm packages*")))
|
||||||
|
|
||||||
|
(provide 'helm-packages)
|
||||||
|
|
||||||
|
;;; helm-packages ends here
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue