Archived
1
0
Fork 0

add helm packages

This commit is contained in:
KemoNine 2022-04-25 15:22:36 -04:00
parent dd329205e3
commit f56827fd01
73 changed files with 45439 additions and 86 deletions

View file

@ -3236,7 +3236,7 @@
(:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com")
(:keywords "large files" "utilities"))])
(vundo .
[(1 0 0)
[(2 0 0)
((emacs
(28 1)))
"Visual undo tree" tar
@ -3245,7 +3245,7 @@
(:maintainer "Yuan Fu" . "casouri@gmail.com")
(:authors
("Yuan Fu" . "casouri@gmail.com"))
(:commit . "0e3af84944c2c69ddaf5364868fe77c31f62527e"))])
(:commit . "10d5debe317b2244d19085151040f955dda4a9ab"))])
(wcheck-mode .
[(2021)
nil "General interface for text checkers" tar

View file

@ -1 +1 @@
Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-04-22T17:05:03-0400 using RSA
Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-04-25T05:10:02-0400 using RSA

View file

@ -68,7 +68,7 @@
(add-hooks . [(20171217 123) nil "Functions for setting multiple hooks" single ((:commit . "1845137703461fc44bd77cf24014ba58f19c369d") (:authors ("Nick McCurdy" . "nick@nickmccurdy.com")) (:maintainer "Nick McCurdy" . "nick@nickmccurdy.com") (:keywords "lisp") (:url . "https://github.com/nickmccurdy/add-hooks"))])
(add-node-modules-path . [(20220315 340) ((s (1 12 0))) "Add node_modules to your exec-path" single ((:commit . "63f047fd84b825876152743f66de7ee6f9ed203b") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:keywords "javascript" "node" "node_modules" "eslint") (:url . "https://github.com/codesuki/add-node-modules-path"))])
(addressbook-bookmark . [(20190612 1638) ((emacs (24))) "An address book based on Standard Emacs bookmarks." single ((:commit . "d8e502fc2f3d3ab1508ce9e50ebf8a9addc6e5b3") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/addressbook-bookmark"))])
(ado-mode . [(20210510 1902) ((emacs (25 1))) "Major mode for editing Stata-related files" tar ((:commit . "4832a51c2e94e969a99817ccdd13d656344d0afc") (:authors ("Bill Rising" . "brising@alum.mit.edu")) (:maintainer "Bill Rising" . "brising@alum.mit.edu") (:keywords "tools" "languages" "files" "convenience" "stata" "mata" "ado") (:url . "https://github.com/louabill/ado-mode"))])
(ado-mode . [(20220415 1647) ((emacs (25 1))) "Major mode for editing Stata-related files" tar ((:commit . "07ab2979692d70ca21ac64313903d5347ab748a9") (:authors ("Bill Rising" . "brising@alum.mit.edu")) (:maintainer "Bill Rising" . "brising@alum.mit.edu") (:keywords "tools" "languages" "files" "convenience" "stata" "mata" "ado") (:url . "https://github.com/louabill/ado-mode"))])
(adoc-mode . [(20160314 2130) ((markup-faces (1 0 0))) "a major-mode for editing AsciiDoc files in Emacs" single ((:commit . "745884359a1b8826ede2c4cfd2f0b5478953ac40") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:keywords "wp" "asciidoc") (:url . "https://github.com/sensorflo/adoc-mode/wiki"))])
(aes . [(20211204 2348) ((emacs (26 1))) "Implementation of AES" single ((:commit . "c9cd12d6c1dbc18603eb4703276132cea59d5c78") (:authors ("Markus Sauermann" . "emacs-aes@sauermann-consulting.de")) (:maintainer "Markus Sauermann" . "emacs-aes@sauermann-consulting.de") (:keywords "data" "tools") (:url . "https://github.com/Sauermann/emacs-aes"))])
(affe . [(20220407 2313) ((emacs (27 1)) (consult (0 16))) "Asynchronous Fuzzy Finder for Emacs" tar ((:commit . "a61d593d0cbff65a93111be96b9f53d3e640cf8d") (:authors ("Daniel Mendler")) (:maintainer "Daniel Mendler") (:url . "https://github.com/minad/affe"))])
@ -100,9 +100,9 @@
(all-the-icons-completion . [(20220409 1204) ((emacs (26 1)) (all-the-icons (5 0))) "Add icons to completion candidates" single ((:commit . "286e2c064a1298be0d8d4100dc91d7a7a554d04a") (:authors ("Itai Y. Efrat <https://github.com/iyefrat>")) (:maintainer "Itai Y. Efrat" . "itai3397@gmail.com") (:keywords "convenient" "lisp") (:url . "https://github.com/iyefrat/all-the-icons-completion"))])
(all-the-icons-dired . [(20220304 1638) ((emacs (24 4)) (all-the-icons (2 2 0))) "Shows icons for each file in dired mode" single ((:commit . "147ed0dfd1034a686795a08dc63e2c293128597e") (:authors ("jtbm37")) (:maintainer "Jimmy Yuen Ho Wong" . "wyuenho@gmail.com") (:keywords "files" "icons" "dired") (:url . "https://github.com/wyuenho/all-the-icons-dired"))])
(all-the-icons-gnus . [(20180511 654) ((emacs (24 4)) (dash (2 12 0)) (all-the-icons (3 1 0))) "Shows icons for in Gnus" single ((:commit . "27f78996da0725943bcfb2d18038e6f7bddfa9c7") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "mail" "tools"))])
(all-the-icons-ibuffer . [(20220422 1034) ((emacs (24 4)) (all-the-icons (2 2 0))) "Display icons for all buffers in ibuffer" single ((:commit . "feebb1c2fe6564cc46489e37b7423afec670f3a6") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "icons" "ibuffer") (:url . "https://github.com/seagle0128/all-the-icons-ibuffer"))])
(all-the-icons-ibuffer . [(20220424 1027) ((emacs (24 4)) (all-the-icons (2 2 0))) "Display icons for all buffers in ibuffer" single ((:commit . "0fcb43eb440e18078c8faf67c27a2189bbb45dfb") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "icons" "ibuffer") (:url . "https://github.com/seagle0128/all-the-icons-ibuffer"))])
(all-the-icons-ivy . [(20190508 1803) ((emacs (24 4)) (all-the-icons (2 4 0)) (ivy (0 8 0))) "Shows icons while using ivy and counsel" single ((:commit . "a70cbfa1effe36efc946a823a580cec686d5e88d") (:authors ("asok")) (:maintainer "asok") (:keywords "faces"))])
(all-the-icons-ivy-rich . [(20220411 222) ((emacs (25 1)) (ivy-rich (0 1 0)) (all-the-icons (2 2 0))) "Better experience with icons for ivy" single ((:commit . "b2fc7db5432431e56babb3440c7a4aab8ff0744d") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "icons" "ivy") (:url . "https://github.com/seagle0128/all-the-icons-ivy-rich"))])
(all-the-icons-ivy-rich . [(20220411 222) ((emacs (25 1)) (ivy-rich (0 1 0)) (all-the-icons (2 2 0))) "Better experience with icons for ivy" single ((:commit . "4b6123ac7850ca083ec791f50857341635a813aa") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "icons" "ivy") (:url . "https://github.com/seagle0128/all-the-icons-ivy-rich"))])
(almost-mono-themes . [(20220422 1714) ((emacs (24))) "Almost monochromatic color themes" tar ((:commit . "0641bf565c113caef8d5c2a93f38cff32ebb62b7") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:keywords "faces") (:url . "https://github.com/cryon/almost-mono-themes"))])
(alsamixer . [(20191002 1133) nil "Functions to call out to amixer." single ((:commit . "1bdb99e433acd38685f05408562746cfbf2bc820") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:keywords "convenience") (:url . "https://github.com/remvee/alsamixer-el"))])
(alt-codes . [(20220212 1526) ((emacs (26 1))) "Insert alt codes using meta key" single ((:commit . "dc0eb3f7b1bec182df6e831f5d09e519e8bb5fd6") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/alt-codes"))])
@ -130,7 +130,7 @@
(annalist . [(20190929 207) ((emacs (24 4)) (cl-lib (0 5))) "Record and display information such as keybindings" tar ((:commit . "134fa3f0fb91a636a1c005c483516d4b64905a6d") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:keywords "convenience" "tools" "keybindings" "org") (:url . "https://github.com/noctuid/annalist.el"))])
(annotate . [(20220408 921) nil "annotate files without changing them" single ((:commit . "a3d42262f518a52e221c038cca3c1630ea90db25") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold <bastibe.dev@mailbox.org>, cage" . "cage-dev@twistfold.it") (:url . "https://github.com/bastibe/annotate.el"))])
(annotate-depth . [(20160520 2040) nil "Annotate buffer if indentation depth is beyond threshold." single ((:commit . "fcb24fa36287250e40d195590c4ca4a8a696277b") (:authors ("Morten Slot Kristensen <msk AT nullpointer DOT dk>")) (:maintainer "Morten Slot Kristensen <msk AT nullpointer DOT dk>") (:keywords "convenience") (:url . "https://github.com/netromdk/annotate-depth"))])
(annotation . [(20200914 644) nil "Functions for annotating text with faces and help bubbles" single ((:commit . "505464961f07f0991263708fd8cbf5f7ad12f53f") (:url . "https://github.com/agda/agda"))])
(annotation . [(20200914 644) nil "Functions for annotating text with faces and help bubbles" single ((:commit . "7ca527c6f1712cff2975508e140103b49f03d526") (:url . "https://github.com/agda/agda"))])
(annoying-arrows-mode . [(20161024 646) ((cl-lib (0 5))) "Ring the bell if using arrows too much" single ((:commit . "3c42e9807d7696da2da2a21b63beebf9cdb3f5dc") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))])
(ansi . [(20211104 1420) ((emacs (24 1)) (cl-lib (0 6))) "Turn string into ansi strings" single ((:commit . "2367fba7b3b2340364a30cd6de7f3eb6bb9898a3") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "terminals" "color" "ansi") (:url . "http://github.com/rejeep/ansi"))])
(ansible . [(20220114 45) ((s (1 9 0)) (f (0 16 2))) "Ansible minor mode" tar ((:commit . "d89ac0ee57742cca0f0e0a3453d9dcc521575690") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "https://github.com/k1LoW/emacs-ansible"))])
@ -198,7 +198,7 @@
(auto-async-byte-compile . [(20160916 454) nil "Automatically byte-compile when saved" single ((:commit . "8681e74ddb8481789c5dbb3cafabb327db4c4484") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "lisp" "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/auto-async-byte-compile.el"))])
(auto-auto-indent . [(20131106 1903) ((es-lib (0 1)) (cl-lib (1 0))) "Indents code as you type" single ((:commit . "0139378577f936d34b20276af6f022fb457af490") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/auto-auto-indent"))])
(auto-compile . [(20220422 1600) ((emacs (25 1)) (compat (28 1 1 0)) (packed (3 0 3))) "Automatically compile Emacs Lisp libraries" single ((:commit . "f19e9fbb8d72a47f0cef049b784e1a492bef9287") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "compile" "convenience" "lisp") (:url . "https://github.com/emacscollective/auto-compile"))])
(auto-complete . [(20220105 439) ((popup (0 5 0)) (cl-lib (0 5))) "Auto Completion for GNU Emacs" tar ((:commit . "8edf20ae3e794cd3ab016a4cabcf6ee3763eecf6") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Jen-Chieh Shen" . "jcs090218@gmail.com") (:keywords "completion" "convenience") (:url . "https://github.com/auto-complete/auto-complete"))])
(auto-complete . [(20220105 439) ((popup (0 5 0)) (cl-lib (0 5))) "Auto Completion for GNU Emacs" tar ((:commit . "d546b18c3e83e38686d9b7316c6c705597e1a8b3") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Jen-Chieh Shen" . "jcs090218@gmail.com") (:keywords "completion" "convenience") (:url . "https://github.com/auto-complete/auto-complete"))])
(auto-complete-auctex . [(20140223 1758) ((yasnippet (0 6 1)) (auto-complete (1 4))) "auto-completion for auctex" single ((:commit . "855633f668bcc4b9408396742a7cb84e0c4a2f77") (:authors ("Christopher Monsanto" . "chris@monsan.to")) (:maintainer "Christopher Monsanto" . "chris@monsan.to"))])
(auto-complete-c-headers . [(20150912 323) ((auto-complete (1 4))) "An auto-complete source for C/C++ header files" single ((:commit . "52fef720c6f274ad8de52bef39a343421006c511") (:authors ("Masafumi Oyamada" . "stillpedant@gmail.com")) (:maintainer "Masafumi Oyamada" . "stillpedant@gmail.com") (:keywords "c"))])
(auto-complete-chunk . [(20140225 946) ((auto-complete (1 4))) "Auto-completion for dot.separated.words." single ((:commit . "a9aa77ffb84a1037984a7ce4dda25074272f13fe") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-chunk"))])
@ -239,7 +239,7 @@
(avandu . [(20170101 1903) nil "Gateway to Tiny Tiny RSS" tar ((:commit . "f44588d8e747fa880411cb4542cc39962252b90a") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "net"))])
(avk-emacs-themes . [(20210521 1051) nil "Collection of avk themes" tar ((:commit . "7b9b6517873c4d4d73e6e34ca56c54062db60759") (:authors ("Alex V. Koval" . "alex@koval.kharkov.ua")) (:maintainer "Alex V. Koval" . "alex@koval.kharkov.ua") (:keywords "theme") (:url . "https://github.com/avkoval/avk-emacs-themes"))])
(avy . [(20220102 805) ((emacs (24 1)) (cl-lib (0 5))) "Jump to arbitrary positions in visible text and select text quickly." single ((:commit . "ba5f035be33693d1a136a5cbeedb24327f551a92") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "point" "location") (:url . "https://github.com/abo-abo/avy"))])
(avy-embark-collect . [(20220221 1638) ((emacs (25 1)) (embark (0 9)) (avy (0 5))) "Use avy to jump to Embark Collect entries" single ((:commit . "29e227f7ec4cdf9fdab8b5723f4db236c81c2eb7") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
(avy-embark-collect . [(20220221 1638) ((emacs (25 1)) (embark (0 9)) (avy (0 5))) "Use avy to jump to Embark Collect entries" single ((:commit . "df43af2faad986c81ba6df3a4bd19010ed664f80") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
(avy-flycheck . [(20160720 1500) ((emacs (24 1)) (flycheck (0 14)) (seq (1 11)) (avy (0 4 0))) "Jump to and fix syntax errors using `flycheck' with `avy' interface" single ((:commit . "5522f3bbbed1801d9278ed696ec0cbba38352985") (:authors ("Xu Ma" . "magicdirac@gmail.com")) (:maintainer "Xu Ma" . "magicdirac@gmail.com") (:keywords "tools" "convenience" "avy" "flycheck") (:url . "https://github.com/magicdirac/avy-flycheck"))])
(avy-menu . [(20210321 1732) ((emacs (24 3)) (avy (0 4 0))) "Library providing avy-powered popup menu" single ((:commit . "18bb320f395b7e412f7e377cf4c46d205d4b4e1a") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "popup" "menu") (:url . "https://github.com/mrkkrp/avy-menu"))])
(avy-migemo . [(20180716 1455) ((emacs (24 4)) (avy (0 4 0)) (migemo (1 9))) "avy with migemo" tar ((:commit . "922a6dd82c0bfa316b0fbb56a9d4dd4ffa5707e7") (:authors ("momomo5717")) (:maintainer "momomo5717") (:keywords "avy" "migemo") (:url . "https://github.com/momomo5717/avy-migemo"))])
@ -254,7 +254,7 @@
(babel-repl . [(20160504 2201) ((emacs (24))) "Run babel REPL" single ((:commit . "e619c16e349a1ee7bd0ee0d7f3650d33bff73fc3") (:authors ("Hung Phan")) (:maintainer "Hung Phan") (:keywords "babel" "javascript" "es6") (:url . "https://github.com/hung-phan/babel-repl/"))])
(back-button . [(20150804 2004) ((nav-flash (1 0 0)) (smartrep (0 0 3)) (ucs-utils (0 7 2)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Visual navigation through mark rings" single ((:commit . "98d92984a740acd1547bd7ed05cca0affdb21c3e") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:keywords "convenience" "navigation" "interface") (:url . "http://github.com/rolandwalker/back-button"))])
(backlight . [(20210513 129) ((emacs (24 3))) "backlight brightness adjustment on GNU/Linux" single ((:commit . "b6826a60440d8bf440618e3cdafb40158de920e6") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:keywords "hardware") (:url . "https://github.com/mschuldt/backlight.el"))])
(backline . [(20220422 1600) ((emacs (25 1)) (compat (28 1 1 0)) (outline-minor-faces (0 1 2))) "Preserve appearance of outline headings" single ((:commit . "5d9d4b784468af620e4892ba14895ae6c28237a0") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "outlines") (:url . "https://github.com/tarsius/backline"))])
(backline . [(20220424 2212) ((emacs (25 1)) (compat (28 1 1 0)) (outline-minor-faces (0 1 2))) "Preserve appearance of outline headings" single ((:commit . "0d44408262080cdf998de5a52516f220e7e7c99a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "outlines") (:url . "https://github.com/tarsius/backline"))])
(backup-each-save . [(20180227 557) nil "backup each savepoint of a file" single ((:commit . "3c414b9d6b278911c95c5b8b71819e6af6f8a02a") (:authors ("Benjamin Rutt" . "brutt@bloomington.in.us")) (:maintainer "Conor Nash" . "conor@nashcobusinessservicesllc.com"))])
(backup-walker . [(20130720 1516) nil "quickly traverse all backups of a file" single ((:commit . "934a4128c122972ac32bb9952addf279a60a94da") (:authors ("Le Wang")) (:maintainer "Le Wang") (:keywords "backup") (:url . "https://github.com/lewang/backup-walker"))])
(backward-forward . [(20161229 550) ((emacs (24 5))) "navigation backwards and forwards across marks" single ((:commit . "58489957a62a0da25dfb5df902624d2548d800b4") (:authors ("Currell Berry" . "currellberry@gmail.com")) (:maintainer "Currell Berry" . "currellberry@gmail.com") (:keywords "navigation" "convenience" "backward" "forward") (:url . "https://gitlab.com/vancan1ty/emacs-backward-forward/tree/master"))])
@ -422,7 +422,7 @@
(calfw-howm . [(20170704 4) nil "calendar view for howm" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar"))])
(calfw-ical . [(20150703 819) nil "calendar view for ical format" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar"))])
(calfw-org . [(20160303 258) nil "calendar view for org-agenda" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:keywords "calendar" "org"))])
(calibredb . [(20220423 754) ((emacs (25 1)) (org (9 3)) (transient (0 1 0)) (s (1 12 0)) (dash (2 17 0)) (request (0 3 3)) (esxml (0 3 7))) "Yet another calibre client" tar ((:commit . "8432243b402bab499ca730be270944b4e1196dcd") (:authors ("Damon Chan" . "elecming@gmail.com")) (:maintainer "Damon Chan" . "elecming@gmail.com") (:keywords "tools") (:url . "https://github.com/chenyanming/calibredb.el"))])
(calibredb . [(20220424 1610) ((emacs (25 1)) (org (9 3)) (transient (0 1 0)) (s (1 12 0)) (dash (2 17 0)) (request (0 3 3)) (esxml (0 3 7))) "Yet another calibre client" tar ((:commit . "8a6148a264e5e57e11824a238ae7b92bb3b6c9ab") (:authors ("Damon Chan" . "elecming@gmail.com")) (:maintainer "Damon Chan" . "elecming@gmail.com") (:keywords "tools") (:url . "https://github.com/chenyanming/calibredb.el"))])
(call-graph . [(20220422 1432) ((emacs (25 1)) (hierarchy (0 7 0)) (tree-mode (1 0 0)) (ivy (0 10 0))) "Generate call graph for c/c++ functions" tar ((:commit . "89a130f04bf04b0b1e5dac41fc640023db2ddc21") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "programming" "convenience") (:url . "https://github.com/beacoder/call-graph"))])
(calmer-forest-theme . [(20130926 510) nil "Darkish theme with green/orange tint" single ((:commit . "87ba7bae389084d13fe3bc34e0c923017eda6ba0") (:authors ("Artur Hefczyc, created 2003-04-18") ("David Caldwell" . "david@porkrind.org")) (:maintainer "Artur Hefczyc, created 2003-04-18") (:url . "https://github.com/caldwell/calmer-forest-theme"))])
(camcorder . [(20190317 2138) ((emacs (24)) (names (20150000)) (cl-lib (0 5))) "Record screencasts in gif or other formats." single ((:commit . "b11ca61491a27681bb3131b72b51c105fd996bed") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:keywords "multimedia" "screencast") (:url . "http://github.com/Bruce-Connor/camcorder.el"))])
@ -460,7 +460,7 @@
(centimacro . [(20201225 1132) nil "Assign multiple macros as global key bindings" single ((:commit . "0149877584b333c4f1953f0767f0cae23881b0df") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "macros") (:url . "https://github.com/abo-abo/centimacro"))])
(cerbere . [(20181113 1641) ((pkg-info (0 5))) "Unit testing in Emacs for several programming languages" tar ((:commit . "c667c165d9c1657f13d2d46f09ba21b61f9402cc") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:keywords "python" "go" "php" "phpunit" "elisp" "ert" "tests" "tdd") (:url . "https://github.com/nlamirault/cerbere"))])
(ceylon-mode . [(20180606 1324) ((emacs (25))) "Major mode for editing Ceylon source code" single ((:commit . "948515672bc596dc118e8e3ede3ede5ec6a3c95a") (:authors ("Lucas Werkmeister" . "mail@lucaswerkmeister.de")) (:maintainer "Lucas Werkmeister" . "mail@lucaswerkmeister.de") (:keywords "languages" "ceylon") (:url . "https://github.com/lucaswerkmeister/ceylon-mode"))])
(cfengine-code-style . [(20171115 2108) nil "C code style for CFEngine project." single ((:commit . "8a11a6ae40396bac028437b5bb472ac722c54dda") (:authors ("Mikhail Gusarov" . "mikhail.gusarov@cfengine.com")) (:maintainer "Mikhail Gusarov" . "mikhail.gusarov@cfengine.com") (:url . "https://github.com/cfengine/core"))])
(cfengine-code-style . [(20171115 2108) nil "C code style for CFEngine project." single ((:commit . "77ae2447fb421f2c4e62f612f59e7c4073307492") (:authors ("Mikhail Gusarov" . "mikhail.gusarov@cfengine.com")) (:maintainer "Mikhail Gusarov" . "mikhail.gusarov@cfengine.com") (:url . "https://github.com/cfengine/core"))])
(cff . [(20160118 2018) ((cl-lib (0 5)) (emacs (24))) "Search of the C/C++ file header by the source and vice versa" single ((:commit . "b6ab2a28e64ef06f281ec74cfe3114e450644dfa") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:keywords "find-file") (:url . "https://github.com/fourier/cff"))])
(cfml-mode . [(20190617 1130) ((emacs (25))) "Emacs mode for editing CFML files" single ((:commit . "2de315abddb6af088a2346e142cc305889dcd775") (:authors ("Andrew Myers" . "am2605@gmail.com")) (:maintainer "Andrew Myers" . "am2605@gmail.com") (:url . "https://github.com/am2605/cfml-mode"))])
(cfn-mode . [(20220221 1029) ((emacs (26 0)) (f (0 20 0)) (s (1 12 0)) (yaml-mode (0 0 13))) "AWS cloudformation mode" tar ((:commit . "4cf56affe3035fda364109836e26499431095185") (:authors ("William Orr" . "will@worrbase.com")) (:maintainer "William Orr" . "will@worrbase.com") (:keywords "convenience" "languages" "tools") (:url . "https://gitlab.com/worr/cfn-mode"))])
@ -491,10 +491,10 @@
(chocolate-theme . [(20210128 1647) ((emacs (24 1)) (autothemer (0 2))) "A dark chocolaty theme" single ((:commit . "ccc05f7ad96d3d1332727689bf6250443adc7ec0") (:url . "http://github.com/SavchenkoValeriy/emacs-chocolate-theme"))])
(choice-program . [(20201217 1751) ((emacs (26)) (dash (2 17 0))) "Parameter based program" tar ((:commit . "b8b1b6c5568f8778783454d5747912487c8e69b8") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:keywords "execution" "processes" "unix" "lisp") (:url . "https://github.com/plandes/choice-program"))])
(chronometer . [(20190304 1528) ((emacs (24))) "a [not so] simple chronometer" single ((:commit . "8457b296ef87be339cbe47730b922757d60bdcd5") (:authors ("Marcelo Toledo" . "marcelo@marcelotoledo.com")) (:maintainer "Marcelo Toledo" . "marcelo@marcelotoledo.com") (:keywords "tools" "convenience") (:url . "https://github.com/marcelotoledo/chronometer"))])
(chronometrist . [(20220415 1213) ((emacs (27 1)) (dash (2 16 0)) (seq (2 20)) (ts (0 2))) "Friendly and powerful personal time tracker and analyzer" tar ((:commit . "c5d5ba419e7024f4152e141232e948267337d6ca") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
(chronometrist . [(20220415 1213) ((emacs (27 1)) (dash (2 16 0)) (seq (2 20)) (ts (0 2))) "Friendly and powerful personal time tracker and analyzer" tar ((:commit . "e64113949733d10cc2a264add173ea78b20cca61") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
(chronometrist-goal . [(20210510 1831) ((emacs (25 1)) (alert (1 2)) (chronometrist (0 7 0))) "Adds support for time goals to Chronometrist" single ((:commit . "6cb939d160f5d5966d7853aa23f3ed7c7ef9df44") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabber.fr")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabber.fr") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist-goal"))])
(chronometrist-key-values . [(20220414 726) ((chronometrist (0 7 0))) "add key-values to Chronometrist data" tar ((:commit . "c5d5ba419e7024f4152e141232e948267337d6ca") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
(chronometrist-spark . [(20220321 349) ((emacs (25 1)) (chronometrist (0 7 0)) (spark (0 1))) "Show sparklines in Chronometrist buffers" tar ((:commit . "c5d5ba419e7024f4152e141232e948267337d6ca") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
(chronometrist-key-values . [(20220414 726) ((chronometrist (0 7 0))) "add key-values to Chronometrist data" tar ((:commit . "e64113949733d10cc2a264add173ea78b20cca61") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
(chronometrist-spark . [(20220321 349) ((emacs (25 1)) (chronometrist (0 7 0)) (spark (0 1))) "Show sparklines in Chronometrist buffers" tar ((:commit . "e64113949733d10cc2a264add173ea78b20cca61") (:authors ("contrapunctus" . "xmpp:contrapunctus@jabjab.de")) (:maintainer "contrapunctus" . "xmpp:contrapunctus@jabjab.de") (:keywords "calendar") (:url . "https://tildegit.org/contrapunctus/chronometrist"))])
(chronos . [(20150602 1529) nil "multiple simultaneous countdown / countup timers" tar ((:commit . "b360d9dae57aa553cf2a14ffa0756a51ad71de09") (:authors ("David Knight" . "dxknight@opmbx.org")) (:maintainer "David Knight" . "dxknight@opmbx.org") (:keywords "calendar") (:url . "http://github.com/dxknight/chronos"))])
(chruby . [(20180114 1652) ((cl-lib (0 5))) "Emacs integration for chruby" single ((:commit . "42bc6d521f832eca8e2ba210f30d03ad5529788f") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:keywords "languages") (:url . "https://github.com/plexus/chruby.el"))])
(chyla-theme . [(20180302 1658) nil "chyla.org - green color theme." single ((:commit . "ae5e7ecace2ab474151eb0ac5ef07fba2dc32f8a") (:authors ("Adam Chyła" . "adam@chyla.org")) (:maintainer "Adam Chyła" . "adam@chyla.org") (:url . "https://github.com/chyla/ChylaThemeForEmacs"))])
@ -510,7 +510,7 @@
(circe . [(20220421 1956) ((emacs (24 5)) (cl-lib (0 5))) "Client for IRC in Emacs" tar ((:commit . "710f057fedae6e9b820cce9336fef24b7d057e4c") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:keywords "irc" "chat" "comm") (:url . "https://github.com/emacs-circe/circe"))])
(circe-notifications . [(20180102 2318) ((emacs (24 4)) (circe (2 3)) (alert (1 2))) "Add desktop notifications to Circe." single ((:commit . "291149ac12877bbd062da993479d3533a26862b0") (:authors ("Ruben Maher" . "r@rkm.id.au")) (:maintainer "Ruben Maher" . "r@rkm.id.au") (:url . "https://github.com/eqyiel/circe-notifications"))])
(circleci-api . [(20210227 1607) ((emacs (27)) (request (0 3 2))) "Bindings for the CircleCI API" single ((:commit . "2e39c5896819bb2063f9d7795c4299f419cf5542") (:authors ("Robin Schroer")) (:maintainer "Robin Schroer") (:url . "https://github.com/sulami/circleci-api"))])
(citar . [(20220420 1123) ((emacs (27 1)) (parsebib (3 0)) (org (9 5)) (citeproc (0 9))) "Citation-related commands for org, latex, markdown" tar ((:commit . "8bc284ce6d9d13a0432f89d64580bfae85eb1c2e") (:authors ("Bruce D'Arcus <https://github.com/bdarcus>")) (:maintainer "Bruce D'Arcus <https://github.com/bdarcus>") (:url . "https://github.com/bdarcus/citar"))])
(citar . [(20220423 1738) ((emacs (27 1)) (parsebib (3 0)) (org (9 5)) (citeproc (0 9))) "Citation-related commands for org, latex, markdown" tar ((:commit . "4fbdbdddb7f564b19d2507cafbbe29e18938ee51") (:authors ("Bruce D'Arcus <https://github.com/bdarcus>")) (:maintainer "Bruce D'Arcus <https://github.com/bdarcus>") (:url . "https://github.com/bdarcus/citar"))])
(citeproc . [(20220124 721) ((emacs (25)) (dash (2 13 0)) (s (1 12 0)) (f (0 18 0)) (queue (0 2)) (string-inflection (1 0)) (org (9)) (parsebib (2 4))) "A CSL 1.0.2 Citation Processor" tar ((:commit . "ba49516265fa24b138346c4918d39d19b4de8a62") (:authors ("András Simonyi" . "andras.simonyi@gmail.com")) (:maintainer "András Simonyi" . "andras.simonyi@gmail.com") (:keywords "bib") (:url . "https://github.com/andras-simonyi/citeproc-el"))])
(citeproc-org . [(20200915 2009) ((emacs (25 1)) (dash (2 12 0)) (org (9)) (f (0 18 0)) (citeproc (0 1)) (org-ref (1 1 1))) "Render org-mode references in CSL styles" tar ((:commit . "20cd7e817420a3f6e7b82faea901a3c67c6d4d9f") (:authors ("András Simonyi" . "andras.simonyi@gmail.com")) (:maintainer "András Simonyi" . "andras.simonyi@gmail.com") (:keywords "org-ref" "org-mode" "cite" "bib") (:url . "https://github.com/andras-simonyi/citeproc-org"))])
(citre . [(20220406 315) ((emacs (26 1))) "Ctags IDE on the True Editor" tar ((:commit . "0ae60846b0b58f09ea463f603bcc3f414a8fb35d") (:authors ("Hao Wang" . "amaikinono@gmail.com")) (:maintainer "Hao Wang" . "amaikinono@gmail.com") (:keywords "convenience" "tools") (:url . "https://github.com/universal-ctags/citre"))])
@ -556,7 +556,7 @@
(cm-mode . [(20170203 2107) ((cl-lib (0 5))) "Minor mode for CriticMarkup" single ((:commit . "276d49c859822265070ae5dfbb403fd7d8d06436") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm") (:keywords "text" "markdown"))])
(cmake-font-lock . [(20211224 2006) ((cmake-mode (0 0))) "Advanced, type aware, highlight support for CMake" single ((:commit . "0d6111b36a66013aa9b452e664c93308df3b07e1") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "faces" "languages") (:url . "https://github.com/Lindydancer/cmake-font-lock"))])
(cmake-ide . [(20210610 1525) ((emacs (24 4)) (cl-lib (0 5)) (seq (1 11)) (levenshtein (0)) (s (1 11 0))) "Calls CMake to find out include paths and other compiler flags" single ((:commit . "28dc4ab5bd01d99553901b4efeb7234280928b18") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:keywords "languages") (:url . "http://github.com/atilaneves/cmake-ide"))])
(cmake-mode . [(20220322 1258) ((emacs (24 1))) "major-mode for editing CMake sources" single ((:commit . "5b21ca73027630e70b944c852da9ede04b010be5"))])
(cmake-mode . [(20220322 1258) ((emacs (24 1))) "major-mode for editing CMake sources" single ((:commit . "c6ead9be834f779ae5d45841043431944d00e379"))])
(cmake-project . [(20171121 1115) nil "Integrates CMake build process with Emacs" single ((:commit . "a7cf9e4c01c4683e14b6942cc5cc5e8cddc98721") (:authors ("Alexander Lamaison" . "alexander.lamaison@gmail")) (:maintainer "Alexander Lamaison" . "alexander.lamaison@gmail") (:keywords "c" "cmake" "languages" "tools") (:url . "http://github.com/alamaison/emacs-cmake-project"))])
(cmd-to-echo . [(20161203 2133) ((emacs (24 4)) (s (1 11 0)) (shell-split-string (20151224 208))) "Show the output of long-running commands in the echo area" single ((:commit . "e0e874fc0e1ad6d291e39ed76023445297ad438a") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))])
(cmm-mode . [(20150225 746) nil "Major mode for C-- source code" single ((:commit . "c3ad514dff3eb30434f6b20d953276d4c00de1ee"))])
@ -603,7 +603,7 @@
(commenter . [(20160219 1627) ((emacs (24 4)) (let-alist (1 0 4))) "multiline-comment support package" single ((:commit . "6d1885419434ba779270c6fda0e30d390bb074bd") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:keywords "comment") (:url . "https://github.com/yuutayamada/commenter"))])
(commify . [(20210904 1106) ((s (1 9 0))) "Toggle grouping commas in numbers" single ((:commit . "d6656bd3a909917a51ba033a11d4ab5f5fe55f83") (:authors ("Daniel E. Doherty" . "ded-commify@ddoherty.net")) (:maintainer "Daniel E. Doherty" . "ded-commify@ddoherty.net") (:keywords "convenience" "editing" "numbers" "grouping" "commas") (:url . "https://github.com/ddoherty03/commify"))])
(common-lisp-snippets . [(20180226 1523) ((yasnippet (0 8 0))) "Yasnippets for Common Lisp" tar ((:commit . "c82ebf18f4ad49f390dd96ffcc59f8683c1a868b") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:keywords "snippets") (:url . "https://github.com/mrkkrp/common-lisp-snippets"))])
(company . [(20220406 2323) ((emacs (25 1))) "Modular text completion framework" tar ((:commit . "1005540b1cdf176cbcf893b2fa83d2075cbbe3ca") (:authors ("Nikolaj Schumacher")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:keywords "abbrev" "convenience" "matching") (:url . "http://company-mode.github.io/"))])
(company . [(20220425 1145) ((emacs (25 1))) "Modular text completion framework" tar ((:commit . "d5145006b948f93e673f439a766da01f636d39fc") (:authors ("Nikolaj Schumacher")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:keywords "abbrev" "convenience" "matching") (:url . "http://company-mode.github.io/"))])
(company-anaconda . [(20200404 1859) ((company (0 8 0)) (anaconda-mode (0 1 1)) (cl-lib (0 5 0)) (dash (2 6 0)) (s (1 9))) "Anaconda backend for company-mode" single ((:commit . "da1566db41a68809ef7f91ebf2de28118067c89b") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))])
(company-ansible . [(20200306 1441) ((emacs (24 4)) (company (0 8 12))) "A company back-end for ansible" tar ((:commit . "79dd421b161efa49fbdffad57fa40edb41f484a3") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:keywords "ansible") (:url . "https://github.com/krzysztof-magosa/company-ansible"))])
(company-arduino . [(20160306 1739) ((emacs (24 1)) (company (0 8 0)) (irony (0 1 0)) (cl-lib (0 5)) (company-irony (0 1 0)) (company-c-headers (20140930)) (arduino-mode (1 0))) "company-mode for Arduino" single ((:commit . "d7e369702b8eee63e6dfdeba645ce28b6dc66fb1") (:authors ("Yuta Yamada" . "sleepboy.zzz@gmail.com")) (:maintainer "Yuta Yamada" . "sleepboy.zzz@gmail.com") (:keywords "convenience" "development" "company") (:url . "https://github.com/yuutayamada/company-arduino"))])
@ -687,7 +687,8 @@
(conllu-mode . [(20200501 2328) ((emacs (25)) (cl-lib (0 5)) (flycheck (30)) (hydra (0 13 0)) (s (1 0))) "editing mode for CoNLL-U files" tar ((:commit . "0db3063572b0de08874822e20570bb153747e6ed") (:authors ("bruno cuconato" . "bcclaro+emacs@gmail.com")) (:maintainer "bruno cuconato" . "bcclaro+emacs@gmail.com") (:keywords "extensions") (:url . "https://github.com/odanoburu/conllu-mode"))])
(connection . [(20191111 446) nil "TCP-based client connection" single ((:commit . "bdf0aa7761d1c1a3bc0652b2fdc4a54b3acdb06a") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net") (:keywords "network"))])
(constant-theme . [(20180921 1012) ((emacs (24 1))) "A calm, dark, almost monochrome color theme." tar ((:commit . "23543a09729569b566175abe1efbe774048d3fa8") (:authors ("Jannis Pohlmann" . "contact@jannispohlmann.de")) (:maintainer "Jannis Pohlmann" . "contact@jannispohlmann.de") (:keywords "themes") (:url . "https://github.com/jannis/emacs-constant-theme"))])
(consult . [(20220423 417) ((emacs (27 1))) "Consulting completing-read" tar ((:commit . "8fab8a0061e030bf1d0d583f5b4da687df564d14") (:authors ("Daniel Mendler and Consult contributors")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/consult"))])
(consult . [(20220423 417) ((emacs (27 1))) "Consulting completing-read" tar ((:commit . "ed44a20c23b7ee1b78a8cd0f56b005c880fc4c29") (:authors ("Daniel Mendler and Consult contributors")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/consult"))])
(consult-ag . [(20220419 1721) ((emacs (27 1)) (consult (0 16))) "The silver searcher integration using Consult" single ((:commit . "2460ae6829e86c9f1186a852304d919526838cb8") (:authors ("Kanon Kakuno" . "yadex205@outlook.jp")) (:maintainer "Kanon Kakuno" . "yadex205@outlook.jp") (:url . "https://github.com/yadex205/consult-ag"))])
(consult-company . [(20211021 1152) ((emacs (27 1)) (company (0 9)) (consult (0 9))) "Consult frontend for company" single ((:commit . "ef1c553b4a72b23297b55708bf6f6dd1b27cc68e") (:authors ("mohsin kaleem" . "mohkale@kisara.moe")) (:maintainer "mohsin kaleem" . "mohkale@kisara.moe") (:url . "https://github.com/mohkale/consult-company"))])
(consult-dir . [(20211007 2352) ((emacs (26 1)) (consult (0 9)) (project (0 6 0))) "Insert paths into the minibuffer prompt" single ((:commit . "08f543ae6acbfc1ffe579ba1d00a5414012d5c0b") (:authors ("Karthik Chikmagalur")) (:maintainer "Karthik Chikmagalur" . "karthik.chikmagalur@gmail.com") (:keywords "convenience") (:url . "https://github.com/karthink/consult-dir"))])
(consult-eglot . [(20220409 1238) ((emacs (27 1)) (eglot (1 7)) (consult (0 16)) (project (0 3 0))) "A consulting-read interface for eglot" single ((:commit . "0da8801dd8435160ce1f62ad8066bd52e38f5cbd") (:authors ("mohsin kaleem" . "mohkale@kisara.moe")) (:maintainer "Mohsin Kaleem") (:keywords "tools" "completion" "lsp") (:url . "https://github.com/mohkale/consult-eglot"))])
@ -697,7 +698,7 @@
(consult-lsp . [(20220409 1107) ((emacs (27 1)) (lsp-mode (5 0)) (consult (0 16)) (f (0 20 0))) "LSP-mode Consult integration" single ((:commit . "a8eb3a062feb2715f174500d0624d3a85e000cf7") (:authors ("Gerry Agbobada")) (:maintainer "Gerry Agbobada") (:keywords "tools" "completion" "lsp") (:url . "https://github.com/gagbo/consult-lsp"))])
(consult-notmuch . [(20220421 717) ((emacs (26 1)) (consult (0 9)) (notmuch (0 31))) "Notmuch search using consult" single ((:commit . "16eb2c100ca144140f07014c32e99487c6a73e18") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "mail") (:url . "https://codeberg.org/jao/consult-notmuch"))])
(consult-org-roam . [(20220420 528) ((emacs (27 1)) (org-roam (2 2 0)) (consult (0 16))) "Consult integration for org-roam" single ((:commit . "41f5d43c50e283a7d509675cd448e69f0f94ef6b") (:authors ("jgru <https://github.com/jgru>")) (:maintainer "jgru <https://github.com/jgru>") (:url . "https://github.com/jgru/consult-org-roam"))])
(consult-project-extra . [(20220228 843) ((emacs (27 1)) (consult (0 15)) (project (0 8 1))) "Consult integration for project.el" single ((:commit . "897f2f71a94ce1b72c3bf823e14791a332befbb7") (:authors ("Enrique Kessler Martínez")) (:maintainer "Enrique Kessler Martínez") (:keywords "convenience" "project" "management") (:url . "https://github.com/Qkessler/consult-project-extra"))])
(consult-project-extra . [(20220424 1815) ((emacs (27 1)) (consult (0 17)) (project (0 8 1))) "Consult integration for project.el" single ((:commit . "fa882a0bf9b697ebb59d0dfa2ffd81ea6daabf41") (:authors ("Enrique Kessler Martínez")) (:maintainer "Enrique Kessler Martínez") (:keywords "convenience" "project" "management") (:url . "https://github.com/Qkessler/consult-project-extra"))])
(consult-projectile . [(20220414 738) ((emacs (25 1)) (consult (0 12)) (projectile (2 5 0))) "Consult integration for projectile" single ((:commit . "f510a5ca83cc8a42a2038ae15e998ca1c4f2f575") (:authors ("Marco Pawłowski")) (:maintainer "Marco Pawłowski") (:keywords "convenience") (:url . "https://gitlab.com/OlMon/consult-projectile"))])
(consult-recoll . [(20220227 2050) ((emacs (26 1)) (consult (0 9))) "Recoll queries using consult" single ((:commit . "228306eeda8c57db45609ca068f60ee433367c17") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "docs" "convenience") (:url . "https://codeberg.org/jao/consult-recoll"))])
(consult-spotify . [(20211114 2258) ((emacs (26 1)) (consult (0 8)) (espotify (0 1))) "Spotify queries using consult" single ((:commit . "ea6d6021e5acc550560325db2f09198839ee702f") (:authors ("Jose A Ortega Ruiz" . "jao@gnu.org")) (:maintainer "Jose A Ortega Ruiz") (:keywords "multimedia") (:url . "https://codeberg.org/jao/espotify"))])
@ -813,7 +814,7 @@
(dakrone-light-theme . [(20170808 2140) nil "dakrone's custom light theme" single ((:commit . "06f198dc8b4ca7421990b30a23d89c8e0b8c5de4") (:authors ("Lee Hinman <lee _AT_ writequit.org>")) (:maintainer "Lee Hinman <lee _AT_ writequit.org>") (:keywords "color" "themes" "faces") (:url . "https://github.com/dakrone/dakrone-light-theme"))])
(dakrone-theme . [(20170801 1933) nil "dakrone's custom dark theme" single ((:commit . "232ad1be5f3572dcbdf528f1655109aa355a6937") (:authors ("Lee Hinman <lee _AT_ writequit.org>")) (:maintainer "Lee Hinman <lee _AT_ writequit.org>") (:keywords "color" "themes") (:url . "https://github.com/dakrone/dakrone-theme"))])
(danneskjold-theme . [(20220316 1101) nil "Beautiful high-contrast Emacs theme." tar ((:commit . "054c0b9bc9cefb53a4065096e66707d20885c461") (:authors ("Dmitry Akatov" . "akatovda@yandex.com")) (:maintainer "Dmitry Akatov" . "akatovda@yandex.com") (:url . "https://github.com/rails-to-cosmos/"))])
(dante . [(20210301 1738) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (company (0 9)) (haskell-mode (13 14)) (s (1 11 0)) (lcr (1 0))) "Development mode for Haskell" single ((:commit . "8741419333fb85ed2c1d71f5902688f5201b0a40") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:keywords "haskell" "tools") (:url . "https://github.com/jyp/dante"))])
(dante . [(20220423 1731) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (company (0 9)) (haskell-mode (13 14)) (s (1 11 0)) (lcr (1 0))) "Development mode for Haskell" single ((:commit . "81c67457ca72c9be7d90d037fcd306c1ca7c1f05") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:keywords "haskell" "tools") (:url . "https://github.com/jyp/dante"))])
(dap-mode . [(20220422 1951) ((emacs (26 1)) (dash (2 18 0)) (lsp-mode (6 0)) (bui (1 1 0)) (f (0 20 0)) (s (1 12 0)) (lsp-treemacs (0 1)) (posframe (0 7 0)) (ht (2 3))) "Debug Adapter Protocol mode" tar ((:commit . "944fb95542fc57d9a533c4de442817e11cea8a11") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "languages" "debug") (:url . "https://github.com/emacs-lsp/dap-mode"))])
(darcsum . [(20190316 2215) nil "a pcl-cvs like interface for managing darcs patches" single ((:commit . "6a8b690539d133c5e3d17cb23fe4365fbb6fb493") (:authors ("John Wiegley" . "johnw@gnu.org")) (:maintainer "John Wiegley" . "johnw@gnu.org") (:keywords "completion" "convenience" "tools" "vc"))])
(darcula-theme . [(20171227 1845) nil "Inspired by IntelliJ's Darcula theme" single ((:commit . "d9b82b58ded9014985be6658f4ab17e26ed9e93e") (:authors ("Sam Halliday" . "Sam.Halliday@gmail.com")) (:maintainer "Sam Halliday" . "Sam.Halliday@gmail.com") (:keywords "faces") (:url . "https://gitlab.com/fommil/emacs-darcula-theme"))])
@ -872,7 +873,7 @@
(describe-hash . [(20200718 1556) nil "Help function for examining a hash map" single ((:commit . "18e69a932d5495c8439571ba8f2d2ee123d434b1") (:url . "https://github.com/Junker/describe-hash"))])
(describe-number . [(20151101 55) ((yabin (1 1))) "Describe arbitrarily large number at point." single ((:commit . "40618345a37831804b29589849a785ef5aa5ac24") (:authors ("Morten Slot Kristensen <msk AT nullpointer DOT dk>")) (:maintainer "Morten Slot Kristensen <msk AT nullpointer DOT dk>") (:keywords "describe" "value" "help") (:url . "https://github.com/netromdk/describe-number"))])
(desktop+ . [(20170107 2132) ((emacs (24 4)) (dash (2 11 0)) (f (0 17 2))) "Handle special buffers when saving & restoring sessions" single ((:commit . "88055cee526a000056201898499cebbd35e3ea76") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:url . "https://github.com/ffevotte/desktop-plus"))])
(desktop-environment . [(20220422 1837) ((emacs (25 1))) "Helps you control your GNU/Linux computer" single ((:commit . "08404b6e6ab1ffec3130cf9ef6277e7fe46c8727") (:authors ("Damien Cassou <damien@cassou.me>, Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Damien Cassou <damien@cassou.me>, Nicolas Petton" . "nicolas@petton.fr") (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))])
(desktop-environment . [(20220424 805) ((emacs (25 1))) "Helps you control your GNU/Linux computer" single ((:commit . "c4b7680861cb47c4f9d020b13c82dc57c9304893") (:authors ("Damien Cassou <damien@cassou.me>, Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Damien Cassou <damien@cassou.me>, Nicolas Petton" . "nicolas@petton.fr") (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))])
(desktop-mail-user-agent . [(20210519 1008) ((emacs (24 3))) "Call OS default mail program to compose mail" single ((:commit . "caac672ef7e4ddced960fa31cef3a6ba5d7ab451") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "mail") (:url . "https://github.com/lassik/emacs-desktop-mail-user-agent"))])
(desktop-registry . [(20140119 2143) nil "Keep a central registry of desktop files" single ((:commit . "244c2e7f9f0a1050aa8a47ad0b38f4e4584682dd") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:keywords "convenience") (:url . "http://projects.ryuslash.org/desktop-registry/"))])
(detour . [(20181122 2138) ((emacs (24 4))) "Take a quick detour and return" single ((:commit . "1ff23c236e18971ed1077840daf047cde79a45ee") (:authors ("Stefan Kamphausen <www.skamphausen.de>")) (:maintainer "Stefan Kamphausen <www.skamphausen.de>") (:keywords "convenience" "abbrev") (:url . "https://github.com/ska2342/detour/"))])
@ -949,7 +950,7 @@
(direx-grep . [(20140515 1506) ((direx (0 1 -3))) "Grep node of direx.el using incremental search like anything.el/helm.el" single ((:commit . "1109a512a80b2673a70b18b8568514049017faad") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:keywords "convenience") (:url . "https://github.com/aki2o/direx-grep"))])
(dirtree . [(20140129 832) ((tree-mode (1 1 1 1)) (windata (0))) "Directory tree views" single ((:commit . "ba55f1e716e386fdd37cb8e7f48616e405dc7251") (:authors ("Ye Wenbin" . "wenbinye@gmail.com")) (:maintainer "Ye Wenbin" . "wenbinye@gmail.com"))])
(dirtree-prosjekt . [(20140129 904) ((prosjekt (0 3)) (dirtree (0 1))) "dirtree integration for prosjekt." single ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/prosjekt"))])
(dirvish . [(20220423 1140) ((emacs (27 1))) "A modern file manager based on dired mode" tar ((:commit . "523ad7e1be4188521cf543176c61750665159695") (:authors ("Alex Lu <https://github.com/alexluigit>")) (:maintainer "Alex Lu <https://github.com/alexluigit>") (:keywords "files" "convenience") (:url . "https://github.com/alexluigit/dirvish"))])
(dirvish . [(20220425 1522) ((emacs (27 1))) "A modern file manager based on dired mode" tar ((:commit . "3e0a414df35742799759f71915443226574fc961") (:authors ("Alex Lu <https://github.com/alexluigit>")) (:maintainer "Alex Lu <https://github.com/alexluigit>") (:keywords "files" "convenience") (:url . "https://github.com/alexluigit/dirvish"))])
(disable-mouse . [(20210512 2114) ((emacs (24 1))) "Disable mouse commands globally" single ((:commit . "cae3be9dd012727b40ad3b511731191f79cebe42") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "mouse") (:url . "https://github.com/purcell/disable-mouse"))])
(disaster . [(20171016 2152) nil "Disassemble C/C++ code under cursor in Emacs" single ((:commit . "10a785facc60d89d78e0d5177985ab1af1741bb4") (:authors ("Justine Tunney" . "jtunney@gmail.com")) (:maintainer "Justine Tunney" . "jtunney@gmail.com") (:keywords "tools") (:url . "https://github.com/jart/disaster"))])
(discourse . [(20160911 819) ((cl-lib (0 5)) (request (0 2)) (s (1 11 0))) "discourse api" single ((:commit . "a86c7e608851e186fe12e892a573994f08c8e65e") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:keywords "lisp" "discourse") (:url . "https://github.com/lujun9972/discourse-api"))])
@ -1036,7 +1037,7 @@
(dumb-diff . [(20171211 2122) ((emacs (24 3))) "fast arbitrary diffs" single ((:commit . "1a2331d283049b71a07c1b06b1e0627a950d55f4") (:authors ("jack angers")) (:maintainer "jack angers") (:keywords "programming" "diff"))])
(dumb-jump . [(20211018 1545) ((emacs (24 3)) (s (1 11 0)) (dash (2 9 0)) (popup (0 5 3))) "Jump to definition for 50+ languages without configuration" single ((:commit . "dbb915441a2b66f2fbb954ff5de2723c5a4771d4") (:authors ("jack angers and contributors")) (:maintainer "jack angers and contributors") (:keywords "programming") (:url . "https://github.com/jacktasia/dumb-jump"))])
(dummyparens . [(20141009 1024) nil "parenthesis auto-pairing and wrapping" single ((:commit . "9798ef1d0eaa24e4fe66f8aa6022a8c62714cc89") (:authors ("Sergei Nosov <sergei.nosov [at] gmail.com>")) (:maintainer "Sergei Nosov <sergei.nosov [at] gmail.com>") (:keywords "dummyparens" "auto-pair" "wrapping") (:url . "https://github.com/snosov1/dummyparens"))])
(dune . [(20210909 1010) nil "Integration with the dune build system" tar ((:commit . "b6299ec743c71c762a25caa4e66f72e590267a42") (:url . "https://github.com/ocaml/dune"))])
(dune . [(20210909 1010) nil "Integration with the dune build system" tar ((:commit . "37d0cb628482fb17ec8adc6265251d13db7deb6e") (:url . "https://github.com/ocaml/dune"))])
(dune-format . [(20210505 108) ((reformatter (0 6)) (emacs (24 1))) "Reformat OCaml's dune files automatically" single ((:commit . "196f16a01f4c855de7becddbc4cfed2f6788693a") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:keywords "languages") (:url . "https://github.com/purcell/emacs-dune-format"))])
(duplicate-thing . [(20181031 1500) nil "Duplicate current line & selection" single ((:commit . "9d8fd05e3e5caa35d3f2a0c0032c92f0c0908e21") (:authors ("ongaeshi")) (:maintainer "ongaeshi") (:keywords "convenience" "command" "duplicate" "line" "selection") (:url . "https://github.com/ongaeshi/duplicate-thing"))])
(dut-mode . [(20170729 2111) ((emacs (24))) "Major mode for the Dut programming language" single ((:commit . "9235c7acaa6690942e9de8b7acd1e4be0c859dc1") (:authors ("The dut-mode Authors")) (:maintainer "The dut-mode Authors") (:keywords "languages" "gut") (:url . "https://github.com/dut-lang/dut-mode"))])
@ -1225,8 +1226,8 @@
(emamux . [(20200315 1220) ((emacs (24 3))) "Interact with tmux" single ((:commit . "6172131d78038f0b1490e24bac60534bf4ad3b30") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-emamux"))])
(emamux-ruby-test . [(20130812 1639) ((emamux (0 1)) (projectile (0 9 1))) "Ruby test with emamux" single ((:commit . "23b73c650573b340351a919da3da416acfc2ac84") (:url . "https://github.com/syohex/emamux-ruby-test"))])
(emaps . [(20200508 1759) ((dash (2 17 0)) (emacs (24))) "Utilities for working with keymaps" single ((:commit . "7c561f3ded2015ed3774e5784059d6601082743e") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:keywords "convenience" "keyboard" "keymap" "utility") (:url . "https://github.com/GuiltyDolphin/emaps"))])
(embark . [(20220423 250) ((emacs (26 1))) "Conveniently act on minibuffer completions" tar ((:commit . "29e227f7ec4cdf9fdab8b5723f4db236c81c2eb7") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
(embark-consult . [(20220423 354) ((emacs (26 1)) (embark (0 12)) (consult (0 10))) "Consult integration for Embark" single ((:commit . "29e227f7ec4cdf9fdab8b5723f4db236c81c2eb7") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
(embark . [(20220425 1718) ((emacs (26 1))) "Conveniently act on minibuffer completions" tar ((:commit . "19e0de0786f7d5db196ff1d5a459d39e265b2960") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
(embark-consult . [(20220423 1631) ((emacs (26 1)) (embark (0 12)) (consult (0 10))) "Consult integration for Embark" single ((:commit . "19e0de0786f7d5db196ff1d5a459d39e265b2960") (:authors ("Omar Antolín Camarena" . "omar@matem.unam.mx")) (:maintainer "Omar Antolín Camarena" . "omar@matem.unam.mx") (:keywords "convenience") (:url . "https://github.com/oantolin/embark"))])
(ember-mode . [(20200208 1423) ((cl-lib (0 5))) "Ember navigation mode for emacs" single ((:commit . "a587c423041b2fcb065fd5b6a03b2899b764e462") (:authors ("Aad Versteden" . "madnificent@gmail.com")) (:maintainer "Aad Versteden" . "madnificent@gmail.com") (:keywords "ember" "ember.js" "emberjs"))])
(ember-yasnippets . [(20160526 1658) ((yasnippet (0 8 0))) "Snippets for Ember.js development" tar ((:commit . "3b5bd01569646237bf1b540d097e12f9118b67f4") (:authors ("Ron White" . "ronco@costite.com")) (:maintainer "Ron White" . "ronco@costite.com") (:keywords "tools" "abbrev" "languages"))])
(embrace . [(20171031 1833) ((cl-lib (0 5)) (expand-region (0 10 0))) "Add/Change/Delete pairs based on `expand-region'" single ((:commit . "dd5da196e5bcc5e6d87e1937eca0c21da4334ef2") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:keywords "extensions"))])
@ -1264,12 +1265,12 @@
(epic . [(20170210 23) ((htmlize (1 47))) "Evernote Picker for Cocoa Emacs" single ((:commit . "a41826c330eb0ea061d58a08cc861b0c4ac8ec4e") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "evernote" "applescript") (:url . "https://github.com/yoshinari-nomura/epic"))])
(eping . [(20201027 2149) ((emacs (25 1))) "Ping websites to check internet connectivity" tar ((:commit . "99d3a4b6973d5b09864e0af7425a61f99c19b90a") (:authors ("Sean Hutchings" . "seanhut@yandex.com")) (:maintainer "Sean Hutchings" . "seanhut@yandex.com") (:keywords "comm" "processes" "terminals" "unix") (:url . "https://github.com/sean-hut/eping"))])
(epkg . [(20220423 1552) ((emacs (25 1)) (compat (28 1 1 0)) (closql (20210927))) "Browse the Emacsmirror package database" tar ((:commit . "5dd40e242f305859a26ebbd6249e7cbf7361e005") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/emacscollective/epkg"))])
(epkg-marginalia . [(20220422 1607) ((emacs (26)) (compat (28 1 1 0)) (epkg (3 3 1)) (marginalia (0 12))) "Show Epkg information in completion annotations" single ((:commit . "c04a92b29c653020016c7928f3b89a5f804b9fd7") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/emacscollective/epkg-marginalia"))])
(epkg-marginalia . [(20220424 2211) ((emacs (26)) (compat (28 1 1 0)) (epkg (3 3 1)) (marginalia (0 12))) "Show Epkg information in completion annotations" single ((:commit . "73519c62db12c17804bfbcdfb0a6028389374bec") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/emacscollective/epkg-marginalia"))])
(epl . [(20180205 2049) ((cl-lib (0 3))) "Emacs Package Library" single ((:commit . "78ab7a85c08222cd15582a298a364774e3282ce6") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "convenience") (:url . "http://github.com/cask/epl"))])
(epm . [(20190509 443) ((emacs (24 3)) (epl (0 8))) "Emacs Package Manager" tar ((:commit . "6375ddbf93c5f25647f6ebb25b54045b3c93a5be") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/epm"))])
(epresent . [(20160411 201) ((org (8)) (cl-lib (0 5))) "Simple presentation mode for Emacs Org-mode" single ((:commit . "6c8abedcf46ff08091fa2bba52eb905c6290057d") (:keywords "gui") (:url . "https://github.com/dakrone/epresent"))])
(eproject . [(20180312 1642) ((helm (1 6 4))) "assign files to projects, programatically" tar ((:commit . "068218d2cf2138cb2e8fc29b57e773a0097a7e8b") (:authors ("Jonathan Rockway" . "jon@jrock.us")) (:maintainer "Jonathan Rockway" . "jon@jrock.us") (:keywords "programming" "projects"))])
(equake . [(20210913 145) ((emacs (26 1)) (dash (2 14 1))) "Drop-down console for (e)shell & terminal emulation" single ((:commit . "4d6ef75a4d91ded22caad220909518ccb67b7b87") (:authors ("Benjamin Slade" . "slade@lambda-y.net")) (:maintainer "Benjamin Slade" . "slade@lambda-y.net") (:keywords "convenience" "frames" "terminals" "tools" "window-system") (:url . "https://gitlab.com/emacsomancer/equake"))])
(equake . [(20220424 350) ((emacs (26 1)) (dash (2 14 1))) "Drop-down console for (e)shell & terminal emulation" single ((:commit . "ea5c0570f58b8e62249e001ed434a1056a50abe7") (:authors ("Benjamin Slade" . "slade@lambda-y.net")) (:maintainer "Benjamin Slade" . "slade@lambda-y.net") (:keywords "convenience" "frames" "terminals" "tools" "window-system") (:url . "https://gitlab.com/emacsomancer/equake"))])
(eradio . [(20210327 1000) ((emacs (24 1))) "A simple Internet radio player" single ((:commit . "47769986c79def84307921f0277e9bb2714756c2") (:authors ("Olav Fosse" . "mail@olavfosse.no")) (:maintainer "Olav Fosse" . "mail@olavfosse.no") (:url . "https://github.com/fossegrim/eradio"))])
(erblint . [(20200622 5) ((emacs (24))) "An interface for checking HTML ERB files using Erblint" single ((:commit . "89af42f776d8dc656104322edaace2ede7499932") (:authors ("Leonardo Santos")) (:maintainer "Leonardo Santos") (:keywords "project" "convenience") (:url . "https://github.com/leodcs/erblint-emacs"))])
(erc-colorize . [(20170107 1339) nil "Per user colorization of whole message" single ((:commit . "d026a016dcb9d63d9ac66d30627a92a8f1681bbd") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:keywords "erc" "convenience") (:url . "https://github.com/thisirs/erc-colorize.git"))])
@ -1293,8 +1294,8 @@
(erefactor . [(20200513 1252) ((cl-lib (0 3))) "Emacs-Lisp refactoring utilities" single ((:commit . "bfe27a1b8c7cac0fe054e76113e941efa3775fe8") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:keywords "extensions" "tools" "maint") (:url . "https://github.com/mhayashi1120/Emacs-erefactor"))])
(ergoemacs-mode . [(20220411 338) ((emacs (24 1)) (cl-lib (0 5))) "Emacs mode based on common modern interface and ergonomics." tar ((:commit . "9cd89eef490f6c9f4af273bb3dd2c68d5ed2de61") (:authors ("Xah Lee" . "xah@xahlee.org") ("David Capello" . "davidcapello@gmail.com") ("Matthew L. Fidler" . "matthew.fidler@gmail.com") ("Kim F. Storm" . "storm@cua.dk")) (:maintainer "Matthew L. Fidler" . "matthew.fidler@gmail.com") (:keywords "convenience") (:url . "https://github.com/ergoemacs/ergoemacs-mode"))])
(ergoemacs-status . [(20160318 538) ((powerline (2 3)) (mode-icons (0 1 0))) "Adaptive Status Bar / Mode Line" single ((:commit . "d952cc2361adf6eb4d6af60950ad4ab699c81320") (:authors ("Matthew Fidler")) (:maintainer "Matthew Fidler"))])
(eri . [(20200914 644) nil "Enhanced relative indentation (eri)" single ((:commit . "505464961f07f0991263708fd8cbf5f7ad12f53f") (:url . "https://github.com/agda/agda"))])
(erlang . [(20220215 1844) ((emacs (24 1))) "Erlang major mode" tar ((:commit . "277c1d5bd088d8114395d1cf1b666539d42b86c7") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "erlang" "languages" "processes"))])
(eri . [(20200914 644) nil "Enhanced relative indentation (eri)" single ((:commit . "7ca527c6f1712cff2975508e140103b49f03d526") (:url . "https://github.com/agda/agda"))])
(erlang . [(20220215 1844) ((emacs (24 1))) "Erlang major mode" tar ((:commit . "990db3c92a55265673be883554ada262b16616fa") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:keywords "erlang" "languages" "processes"))])
(erlstack-mode . [(20210419 1917) ((emacs (25 1)) (dash (2 12 0))) "Minor mode for analysing Erlang stacktraces" single ((:commit . "ca264bca24cdaa8b2bac57882716f03f633e42b0") (:authors ("k32")) (:maintainer "k32") (:keywords "tools" "erlang") (:url . "https://github.com/k32/erlstack-mode"))])
(eros . [(20180415 618) ((emacs (24 4))) "Evaluation Result OverlayS for Emacs Lisp" single ((:commit . "dd8910279226259e100dab798b073a52f9b4233a") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:keywords "convenience" "lisp") (:url . "https://github.com/xiongtx/eros"))])
(ert-async . [(20200105 1031) ((emacs (24 1))) "Async support for ERT" single ((:commit . "948cf2faa10e085bda3739034ca5ea1912893433") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:keywords "lisp" "test") (:url . "http://github.com/rejeep/ert-async.el"))])
@ -1358,7 +1359,7 @@
(evalator-clojure . [(20160208 2148) ((cider (0 10 0)) (evalator (1 0 0))) "Clojure evaluation context for evalator via CIDER." tar ((:commit . "caa4e0a137bdfada86593128a654e16aa617ad50") (:authors ("Sean Irby")) (:maintainer "Sean Irby" . "sean.t.irby@gmail.com") (:keywords "languages" "clojure" "cider" "helm") (:url . "http://www.github.com/seanirby/evalator-clojure"))])
(eve-mode . [(20170822 2231) ((emacs (25)) (polymode (1 0)) (markdown-mode (2 0))) "Major mode for editing Eve documents." single ((:commit . "a4661114d9c18725691b76321d72167ca5a9070a") (:authors ("Joshua Cole" . "joshuafcole@gmail.com")) (:maintainer "Joshua Cole" . "joshuafcole@gmail.com") (:keywords "languages" "wp" "tools") (:url . "https://github.com/witheve/emacs-eve-mode"))])
(everlasting-scratch . [(20220412 921) ((emacs (25 1))) "The *scratch* that lasts forever" single ((:commit . "8706c55f3b7c267c15b8f10170ecec9998b3cc3d") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "convenience" "tool") (:url . "https://github.com/beacoder/everlasting-scratch"))])
(evil . [(20220423 811) ((emacs (24 1)) (goto-chg (1 6)) (cl-lib (0 5))) "Extensible Vi layer for Emacs." tar ((:commit . "48404a336850a20ed093fcf78539037c17386235") (:maintainer "Tom Dalziel" . "tom.dalziel@gmail.com") (:keywords "emulation" "vim") (:url . "https://github.com/emacs-evil/evil"))])
(evil . [(20220424 2228) ((emacs (24 1)) (goto-chg (1 6)) (cl-lib (0 5))) "Extensible Vi layer for Emacs." tar ((:commit . "f75732de0ca5cae70f17dbc4bf7df03cb4ec491f") (:maintainer "Tom Dalziel" . "tom.dalziel@gmail.com") (:keywords "emulation" "vim") (:url . "https://github.com/emacs-evil/evil"))])
(evil-anzu . [(20200514 1902) ((evil (1 0 0)) (anzu (0 46))) "anzu for evil-mode" single ((:commit . "d3f6ed4773b48767bd5f4708c7f083336a8a8a86") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com") ("Fredrik Bergroth" . "fbergroth@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-evil-anzu"))])
(evil-args . [(20220125 1626) ((evil (1 0 8))) "Motions and text objects for delimited arguments in Evil." single ((:commit . "2671071a4a57eaee7cc8c27b9e4b6fc60fd2ccd3") (:authors ("Connor Smith" . "wconnorsmith@gmail.com")) (:maintainer "Connor Smith" . "wconnorsmith@gmail.com") (:keywords "evil" "vim-emulation") (:url . "http://github.com/wcsmith/evil-args"))])
(evil-avy . [(20150908 748) ((emacs (24 1)) (cl-lib (0 5)) (avy (0 3 0)) (evil (1 2 3))) "set-based completion" single ((:commit . "2dd955cc3ecaa7ddeb67b295298abdc6d16dd3a5") (:authors ("Yufan Lou" . "loganlyf@gmail.com")) (:maintainer "Yufan Lou" . "loganlyf@gmail.com") (:keywords "point" "location" "evil" "vim") (:url . "https://github.com/louy2/evil-avy"))])
@ -1366,7 +1367,7 @@
(evil-cleverparens . [(20170718 413) ((evil (1 0)) (paredit (1)) (smartparens (1 6 1)) (emacs (24 4)) (dash (2 12 0))) "Evil friendly minor-mode for editing lisp." tar ((:commit . "8c45879d49bfa6d4e414b6c1df700a4a51cbb869") (:authors ("Olli Piepponen" . "opieppo@gmail.com")) (:maintainer "Olli Piepponen" . "opieppo@gmail.com") (:keywords "cleverparens" "parentheses" "evil" "paredit" "smartparens") (:url . "https://github.com/luxbock/evil-cleverparens"))])
(evil-colemak-basics . [(20220222 1856) ((emacs (24 3)) (evil (1 2 12)) (evil-snipe (2 0 3))) "Basic Colemak key bindings for evil-mode" single ((:commit . "66648de206a7368013f28c0d053b1b32c3efe6c6") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience" "emulations" "colemak" "evil") (:url . "https://github.com/wbolster/evil-colemak-basics"))])
(evil-colemak-minimal . [(20171006 1317) ((emacs (24)) (evil (1 2 12))) "Minimal Colemak key bindings for evil-mode" single ((:commit . "6d98b6da60f414524a0d718f76024c26dce742b3") (:authors ("Bryan Allred" . "bryan@revolvingcow.com")) (:maintainer "Bryan Allred" . "bryan@revolvingcow.com") (:keywords "colemak" "evil") (:url . "https://github.com/bmallred/evil-colemak-minimal"))])
(evil-collection . [(20220417 1119) ((emacs (25 1)) (evil (1 2 13)) (annalist (1 0))) "A set of keybindings for Evil mode" tar ((:commit . "a075a4e439ac7fe2cc57e5bba910291820fd31f1") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "evil" "tools") (:url . "https://github.com/emacs-evil/evil-collection"))])
(evil-collection . [(20220425 851) ((emacs (25 1)) (evil (1 2 13)) (annalist (1 0))) "A set of keybindings for Evil mode" tar ((:commit . "694c1b4201dce70e7a98bdf6d95cd1a08107fc97") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "evil" "tools") (:url . "https://github.com/emacs-evil/evil-collection"))])
(evil-commentary . [(20210210 1702) ((evil (1 0 0))) "Comment stuff out. A port of vim-commentary." tar ((:commit . "2dab6ac34d1617971768ad219d73af48f7473fec") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:keywords "evil" "comment" "commentary" "evil-commentary") (:url . "http://github.com/linktohack/evil-commentary"))])
(evil-dvorak . [(20160416 1841) ((evil (1 0 8))) "evil keybindings for that work with dvorak mode" tar ((:commit . "824f7c56980d72a0ff04c662223540cd66f13754") (:authors ("Joshua Branson")) (:maintainer "Joshua Branson") (:keywords "dvorak" "evil" "vim"))])
(evil-easymotion . [(20200424 135) ((emacs (24)) (avy (0 3 0)) (cl-lib (0 5))) "A port of vim's easymotion to emacs" single ((:commit . "f96c2ed38ddc07908db7c3c11bcd6285a3e8c2e9") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:keywords "convenience" "evil") (:url . "https://github.com/pythonnut/evil-easymotion"))])
@ -1420,7 +1421,7 @@
(evil-swap-keys . [(20191105 1426) ((emacs (24 4))) "Intelligently swap keys on text input with evil" single ((:commit . "b5ef105499f998b5667da40da30c073229a213ea") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience" "data" "languages" "tools") (:url . "https://github.com/wbolster/evil-swap-keys"))])
(evil-tabs . [(20160217 1520) ((evil (0 0 0)) (elscreen (0 0 0))) "Integrating Vim-style tabs for Evil mode users." single ((:commit . "53d3314a810017b6056ab6796aef671f5ea1c063") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:keywords "evil" "tab" "tabs" "vim") (:url . "https://github.com/krisajenkins/evil-tabs"))])
(evil-terminal-cursor-changer . [(20220422 255) ((evil (1 0 8))) "Change cursor shape and color by evil state in terminal" single ((:commit . "69d562932f9ab9869ab1ed923e9789cbfa0ff14c") (:authors ("7696122")) (:maintainer "7696122") (:keywords "evil" "terminal" "cursor") (:url . "https://github.com/7696122/evil-terminal-cursor-changer"))])
(evil-test-helpers . [(20201008 1515) ((evil (1 14 0))) "unit test helpers for Evil" single ((:commit . "48404a336850a20ed093fcf78539037c17386235") (:authors ("Vegard Øye <vegard_oye at hotmail.com>")) (:maintainer "Vegard Øye <vegard_oye at hotmail.com>"))])
(evil-test-helpers . [(20201008 1515) ((evil (1 14 0))) "unit test helpers for Evil" single ((:commit . "f75732de0ca5cae70f17dbc4bf7df03cb4ec491f") (:authors ("Vegard Øye <vegard_oye at hotmail.com>")) (:maintainer "Vegard Øye <vegard_oye at hotmail.com>"))])
(evil-tex . [(20220415 842) ((emacs (26 1)) (evil (1 0)) (auctex (11 88))) "Useful features for editing LaTeX in evil-mode" single ((:commit . "26035ec9a09f8b38ce0d495ff788e83ec8b195d5") (:keywords "tex" "emulation" "vi" "evil" "wp") (:url . "https://github.com/iyefrat/evil-tex"))])
(evil-text-object-python . [(20191010 1328) ((emacs (25)) (evil (1 2 14)) (dash (2 16 0))) "Python specific evil text objects" single ((:commit . "39d22fc524f0413763f291267eaab7f4e7984318") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/wbolster/evil-text-object-python"))])
(evil-textobj-anyblock . [(20170905 1907) ((cl-lib (0 5)) (evil (1 1 0))) "Textobject for the closest user-defined blocks." single ((:commit . "ff00980f0634f95bf2ad9956b615a155ea8743be") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:keywords "evil") (:url . "https://github.com/noctuid/evil-textobj-anyblock"))])
@ -1512,7 +1513,7 @@
(fill-function-arguments . [(20201223 819) ((emacs (24 4))) "Convert function arguments to/from single line" single ((:commit . "a0a2f8538c80ac08e497dea784fcb90c93ab465b") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:keywords "convenience") (:url . "https://github.com/davidshepherd7/fill-function-arguments"))])
(fill-page . [(20210707 354) ((emacs (24 4))) "Fill buffer so you don't see empty lines at the end" single ((:commit . "cc15eb323685bf09ed4a7828fd40c5da1aeb8795") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/fill-page"))])
(fillcode . [(20200524 2226) nil "Fill (wrap) function calls and expressions in source code" single ((:commit . "501468082e46bd0975ef4d8765363fd564338099") (:authors ("Ryan Barrett" . "fillcode@ryanb.org")) (:maintainer "Ryan Barrett" . "fillcode@ryanb.org") (:url . "https://snarfed.org/fillcode"))])
(filldent . [(20220419 1628) ((emacs (24 1))) "Fill or indent" single ((:commit . "b55fd3aae9f389b76fe695b300984188f24f9366") (:authors ("Case Duckworth" . "acdw@acdw.net")) (:maintainer "Case Duckworth" . "acdw@acdw.net") (:url . "https://github.com/duckwork/filldent.el"))])
(filldent . [(20220423 2216) ((emacs (24 1))) "Fill or indent" single ((:commit . "2f32e0cf5e27c613f962fa41bf3427bbdc04e6c0") (:authors ("Case Duckworth" . "acdw@acdw.net")) (:maintainer "Case Duckworth" . "acdw@acdw.net") (:url . "https://github.com/duckwork/filldent.el"))])
(finalize . [(20170418 1945) ((emacs (24 1)) (cl-generic (0 3)) (cl-lib (0 3)) (eieio (1 4))) "finalizers for Emacs Lisp" tar ((:commit . "846731531e7d1d80451787992e07bfe7dedbe9ff") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elisp-finalize"))])
(find-by-pinyin-dired . [(20180210 218) ((pinyinlib (0 1 0))) "Find file by first PinYin character of Chinese Hanzi" single ((:commit . "3b4781148dddc84a701ad76c0934ed991ecd59d5") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:keywords "hanzi" "chinese" "dired" "find" "file" "pinyin") (:url . "http://github.com/redguardtoo/find-by-pinyin-dired"))])
(find-dupes-dired . [(20210426 835) ((emacs (26 1))) "Find dupes and handle in dired" single ((:commit . "904225a3f89bbd3b44ea097a282ec6ca7945f7f1") (:authors ("Shuguang Sun" . "shuguang79@qq.com")) (:maintainer "Shuguang Sun" . "shuguang79@qq.com") (:keywords "tools") (:url . "https://github.com/ShuguangSun/find-dupes-dired"))])
@ -1671,7 +1672,7 @@
(flycheck-ycmd . [(20181016 618) ((emacs (24)) (dash (2 13 0)) (flycheck (0 22)) (ycmd (1 2)) (let-alist (1 0 5))) "flycheck integration for ycmd" single ((:commit . "c17ff9e0250a9b39d23af37015a2b300e2f36fed") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-ycmd"))])
(flymake-aspell . [(20220411 826) ((emacs (26 1))) "Aspell checker for flymake" single ((:commit . "dcf7e6543e4d94d58375e00e4a10db615ef06941") (:authors ("Leo Gaskin" . "leo.gaskin@le0.gs")) (:maintainer "Leo Gaskin" . "leo.gaskin@le0.gs") (:keywords "wp" "flymake" "spell" "aspell") (:url . "https://github.com/leotaku/flycheck-aspell"))])
(flymake-coffee . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for coffee script" single ((:commit . "dee295acf30820ed15fe0de17137d50bc27fc80c") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-coffee"))])
(flymake-collection . [(20220410 1343) ((emacs (28 1)) (let-alist (1 0)) (flymake (1 2 1))) "Collection of checkers for flymake, bringing flymake to the level of flycheck" tar ((:commit . "297406f601daffbec2b3305013442b2829451416") (:authors ("Mohsin Kaleem" . "mohkale@kisara.moe")) (:maintainer "Mohsin Kaleem" . "mohkale@kisara.moe") (:keywords "language" "tools") (:url . "https://github.com/mohkale/flymake-collection"))])
(flymake-collection . [(20220410 1343) ((emacs (28 1)) (let-alist (1 0)) (flymake (1 2 1))) "Collection of checkers for flymake, bringing flymake to the level of flycheck" tar ((:commit . "8f36fed9eef834cf94931fc8b813f9ac8db6d2a4") (:authors ("Mohsin Kaleem" . "mohkale@kisara.moe")) (:maintainer "Mohsin Kaleem" . "mohkale@kisara.moe") (:keywords "language" "tools") (:url . "https://github.com/mohkale/flymake-collection"))])
(flymake-css . [(20170723 146) ((flymake-easy (0 1))) "Flymake support for css using csslint" single ((:commit . "de090163ba289910ceeb61b13368ce42d0f2dfd8") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-css"))])
(flymake-cursor . [(20210126 1733) ((flymake (0 3))) "Show flymake messages in the minibuffer after delay" single ((:commit . "9feffdd1fa286070a54842ebbd31e7d1e4204f1c") (:authors ("Unknown Original Author") ("Dino Chiesa" . "dpchiesa@hotmail.com") ("Sam Graham <libflymake-emacs BLAHBLAH illusori.co.uk>")) (:maintainer "Sam Graham <libflymake-emacs BLAHBLAH illusori.co.uk>") (:keywords "languages" "mode" "flymake") (:url . "https://github.com/flymake/emacs-flymake-cursor"))])
(flymake-diagnostic-at-point . [(20180815 1004) ((emacs (26 1)) (popup (0 5 3))) "Display flymake diagnostics at point" single ((:commit . "379616b1c6f5ebeaf08fbe54ae765008a78b3be7") (:authors ("Ricardo Martins" . "ricardo@scarybox.net")) (:maintainer "Ricardo Martins" . "ricardo@scarybox.net") (:keywords "convenience" "languages" "tools") (:url . "https://github.com/meqif/flymake-diagnostic-at-point"))])
@ -1709,6 +1710,7 @@
(flymake-python-pyflakes . [(20170723 146) ((flymake-easy (0 8))) "A flymake handler for python-mode files using pyflakes (or flake8)" single ((:commit . "1d65c26bf65a5dcbd29fcd967e2feb90e1e7a33d") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-python-pyflakes"))])
(flymake-quickdef . [(20200308 2342) ((emacs (26 1))) "Quickly define a new Flymake backend" single ((:commit . "150c5839768a3d32f988f9dc08052978a68f2ad7") (:authors ("Karl Otness")) (:maintainer "Karl Otness") (:keywords "languages" "tools" "convenience" "lisp") (:url . "https://github.com/karlotness/flymake-quickdef"))])
(flymake-racket . [(20210105 606) ((emacs (26 1))) "Flymake extension for Racket." single ((:commit . "3d3e5f2a9ab696670f9e52baa4dde7b84b7542df") (:maintainer "James Nguyen" . "james@jojojames.com") (:keywords "languages" "racket" "scheme") (:url . "https://github.com/jojojames/flymake-racket"))])
(flymake-rakudo . [(20220424 637) ((emacs (28 1)) (flymake-collection (2 0 0)) (let-alist (1 0))) "Flymake syntax checker for Rakudo" single ((:commit . "f8e3d03a7207876cd891174702efd572d74f2e49") (:authors ("Siavash Askari Nasr" . "ciavash@proton.me")) (:maintainer "Siavash Askari Nasr" . "ciavash@proton.me") (:keywords "language" "tools" "convenience") (:url . "https://github.com/Raku/flymake-rakudo"))])
(flymake-ruby . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for ruby-mode files" single ((:commit . "6c320c6fb686c5223bf975cc35178ad6b195e073") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-ruby"))])
(flymake-sass . [(20170723 146) ((flymake-easy (0 1))) "Flymake handler for sass and scss files" single ((:commit . "2de28148e92deb93bff3d55fe14e7c67ac476056") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-sass"))])
(flymake-shell . [(20170723 146) ((flymake-easy (0 1))) "A flymake syntax-checker for shell scripts" single ((:commit . "a16cf453056b9849cc7c912bb127fb0b08fc6dab") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-shell"))])
@ -1747,7 +1749,7 @@
(foreign-regexp . [(20200325 50) nil "search and replace by foreign regexp." tar ((:commit . "e2dd47f2160cadc194eb156e7c76c3c869e6706e") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>") (:keywords "convenience" "emulations" "matching" "tools" "unix" "wp"))])
(foreman-mode . [(20170725 1422) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "View and manage Procfile-based applications" single ((:commit . "22b3bb13134b617870ed1e888af739f4818be929") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "foreman") (:url . "http://github.com/zweifisch/foreman-mode"))])
(forest-blue-theme . [(20160627 842) ((emacs (24))) "Emacs theme with a dark background." single ((:commit . "58096ce1a25615d2bae806c3775bae3e2775019d") (:authors ("olkinn")) (:maintainer "olkinn"))])
(forge . [(20220423 1139) ((emacs (25 1)) (compat (28 1 1 0)) (closql (1 2 0)) (dash (2 19 1)) (emacsql-sqlite (3 0 0)) (ghub (3 5 4)) (let-alist (1 0 6)) (magit (3 3 0)) (markdown-mode (2 4)) (transient (0 3 6)) (yaml (0 3 4))) "Access Git forges from Magit." tar ((:commit . "0ebd444a1125161b1933143059d01525f1dd22fe") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/forge"))])
(forge . [(20220424 1416) ((emacs (25 1)) (compat (28 1 1 0)) (closql (1 2 0)) (dash (2 19 1)) (emacsql-sqlite (3 0 0)) (ghub (3 5 4)) (let-alist (1 0 6)) (magit (3 3 0)) (markdown-mode (2 4)) (transient (0 3 6)) (yaml (0 3 4))) "Access Git forges from Magit." tar ((:commit . "627972bbc83b2355047e075ce938f79136b1f74a") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/forge"))])
(form-feed . [(20210508 1627) ((emacs (24 1))) "Display ^L glyphs as horizontal lines" single ((:commit . "ac1f0ef30a11979f5dfe12d8c05a666739e486ff") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:keywords "faces") (:url . "https://depp.brause.cc/form-feed"))])
(format-all . [(20220412 1141) ((emacs (24 4)) (inheritenv (0 1)) (language-id (0 19))) "Auto-format C, C++, JS, Python, Ruby and 50 other languages" single ((:commit . "a07bf109ce8e27458a40420508943f53856549fc") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-format-all-the-code"))])
(format-sql . [(20150422 1333) nil "Use format-sql to make your SQL readable in directly Emacs." single ((:commit . "97f475c245cd6c81a72a265678e2087cee66ac7b") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "https://github.com/paetzke/format-sql.el"))])
@ -1787,7 +1789,7 @@
(function-args . [(20211231 1150) ((ivy (0 9 1))) "C++ completion for GNU Emacs" tar ((:commit . "503e78fad9e7741ef4b8f5c24ff70c8909240db2") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/function-args"))])
(fuo . [(20190812 927) ((emacs (24 4))) "feeluown client." single ((:commit . "0e4122f94a336a50c02bc96652d25ac3d74bedeb") (:authors ("cosven" . "yinshaowen241@gmail.com")) (:maintainer "cosven" . "yinshaowen241@gmail.com") (:keywords "feeluown" "multimedia" "unix") (:url . "http://github.com/cosven/emacs-fuo"))])
(furl . [(20150509 316) nil "Friendly URL retrieval" single ((:commit . "014438271e0ef27333dfcd599cb247f12a20d870") (:authors ("Natalie Weizenbaum" . "nweiz@google.com")) (:maintainer "Natalie Weizenbaum" . "nweiz@google.com"))])
(futhark-mode . [(20220415 1524) ((emacs (24 3)) (cl-lib (0 5))) "major mode for editing Futhark source files" tar ((:commit . "a4a8d5151273aba04f622cf0df0ba806a6e95c25") (:keywords "languages") (:url . "https://github.com/diku-dk/futhark-mode"))])
(futhark-mode . [(20220425 1144) ((emacs (24 3)) (cl-lib (0 5))) "major mode for editing Futhark source files" tar ((:commit . "7fd0a3c6c96ed8afd0249ab0734d9b63d4fd1cb1") (:keywords "languages") (:url . "https://github.com/diku-dk/futhark-mode"))])
(fuz . [(20200104 524) ((emacs (25 1))) "Fast and precise fuzzy scoring/matching utils" tar ((:commit . "fee874aa35d2ee6b12b836290b5c8eaa44175a28") (:authors ("Zhu Zihao" . "all_but_last@163.com")) (:maintainer "Zhu Zihao" . "all_but_last@163.com") (:keywords "lisp") (:url . "https://github.com/cireu/fuz.el"))])
(fuzzy . [(20211231 1837) ((emacs (24 3))) "Fuzzy Matching" single ((:commit . "ea361ce0f702c5f92ad4a89017def9c1619a3191") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com") (:keywords "convenience") (:url . "https://github.com/auto-complete/fuzzy-el"))])
(fuzzy-finder . [(20210906 217) ((emacs (24 4))) "Fuzzy Finder App Integration" single ((:commit . "915a281fc8e50df84dcc205f9357e8314d60fa54") (:authors ("10sr" . "8.slashes@gmail.com")) (:maintainer "10sr" . "8.slashes@gmail.com") (:keywords "matching") (:url . "https://github.com/10sr/fuzzy-finder-el"))])
@ -1840,7 +1842,7 @@
(gherkin-mode . [(20171224 1353) nil "An emacs major mode for editing gherkin files." single ((:commit . "0313492e7da152f0aa73ddf96c0287ded8f51253") (:authors ("Craig Andera")) (:maintainer "Craig Andera") (:keywords "languages"))])
(ghost-blog . [(20171023 742) ((markdown-mode (1 0))) "A package to manage Ghost blog" single ((:commit . "71b358643cc9a2db1bf752281ff94aba9b59e4cc") (:authors ("Javier Aguirre" . "hello@javaguirre.net")) (:maintainer "Javier Aguirre" . "hello@javaguirre.net") (:keywords "ghost" "blog") (:url . "https://github.com/javaguirre/ghost-blog"))])
(ghq . [(20210504 902) nil "Ghq interface for emacs" single ((:commit . "582bd6daa505d04c7cc06d6c82ed8aee0624bfbe") (:authors ("Roman Coedo" . "romancoedo@gmail.com")) (:maintainer "Roman Coedo" . "romancoedo@gmail.com") (:keywords "ghq"))])
(ghub . [(20220423 1203) ((emacs (25 1)) (compat (28 1 1 0)) (let-alist (1 0 6)) (treepy (0 1 1))) "Client libraries for Git forge APIs." tar ((:commit . "0946102838df9e79abc309c45aeff1e4fafa61a5") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/magit/ghub"))])
(ghub . [(20220424 947) ((emacs (25 1)) (compat (28 1 1 0)) (let-alist (1 0 6)) (treepy (0 1 1))) "Client libraries for Git forge APIs." tar ((:commit . "5135058a78a2bea112f9e591500790c1e3b731fd") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/magit/ghub"))])
(ghub+ . [(20191229 1748) ((emacs (25)) (ghub (2 0)) (apiwrap (0 5))) "a thick GitHub API client built on ghub" single ((:commit . "b1adef2402d7599911d4dd447a987a0cea04e6fe") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:keywords "extensions" "multimedia" "tools") (:url . "https://github.com/vermiculus/ghub-plus"))])
(gif-screencast . [(20210401 656) ((emacs (25 1))) "One-frame-per-action GIF recording" single ((:commit . "5517a557a17d8016c9e26b0acb74197550f829b9") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:keywords "multimedia" "screencast") (:url . "https://gitlab.com/ambrevar/emacs-gif-screencast"))])
(gift-mode . [(20210528 1459) nil "major mode for editing GIFT format quizzes" single ((:commit . "c93354e8fe1173b22f398f17b127875807f15b87") (:authors ("Christophe Rhodes" . "christophe@rhodes.io")) (:maintainer "Christophe Rhodes" . "christophe@rhodes.io") (:url . "https://github.com/csrhodes/gift-mode"))])
@ -1855,11 +1857,11 @@
(git-backup-ivy . [(20220412 1914) ((ivy (0 12 0)) (git-backup (0 0 1)) (emacs (25 1))) "An ivy interface to git-backup" single ((:commit . "c53e1bc800963c0d826226c37c22e36f2353c70d") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:keywords "backup" "convenience" "files" "tools" "vc") (:url . "https://github.com/walseb/git-backup-ivy"))])
(git-blamed . [(20161028 1926) nil "Minor mode for incremental blame for Git" single ((:commit . "cef196abf398e2dd11f775d1e6cd8690567408aa") (:keywords "git" "version control" "release management"))])
(git-command . [(20191028 333) ((term-run (0 1 4)) (with-editor (2 3 1))) "A Git Command-Line interface" single ((:commit . "a773d40da39dfb1c6ecf2b0758aa370ddea8f06d") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:keywords "utility" "git") (:url . "https://github.com/10sr/git-command-el"))])
(git-commit . [(20220422 1903) ((emacs (25 1)) (compat (28 1 0 4)) (transient (20210920)) (with-editor (20211001))) "Edit Git commit messages." tar ((:commit . "b4d54d3f8ee047479980b6d8079f3ce1a93bb6a4") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li") ("Sebastian Wiesner" . "lunaryorn@gmail.com") ("Florian Ragwitz" . "rafl@debian.org") ("Marius Vollmer" . "marius.vollmer@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
(git-commit . [(20220422 1903) ((emacs (25 1)) (compat (28 1 0 4)) (transient (20210920)) (with-editor (20211001))) "Edit Git commit messages." tar ((:commit . "3cb7f5ba430906bded9e5d9951f5260ab25644d0") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li") ("Sebastian Wiesner" . "lunaryorn@gmail.com") ("Florian Ragwitz" . "rafl@debian.org") ("Marius Vollmer" . "marius.vollmer@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
(git-commit-insert-issue . [(20210107 2018) ((emacs (25)) (projectile (0)) (s (0)) (ghub (0)) (bitbucket (0))) "Get issues list when typing \"Fixes #\"" single ((:commit . "6cfb8b4b5b23ae881cf3d005da4d7f60d91cd2cd") (:authors ("Vindarel")) (:maintainer "Vindarel") (:keywords "tools" "vc" "github" "gitlab" "bitbucket" "commit" "issues") (:url . "https://gitlab.com/emacs-stuff/git-commit-insert-issue/"))])
(git-dwim . [(20170126 1214) nil "Context-aware git commands such as branch handling" single ((:commit . "485c732130686c2f28a026e385366006435394b9") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "git" "tools" "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/git-dwim.el"))])
(git-grep . [(20200920 1751) ((projectile (0 10 0))) "Search tools using git grep" single ((:commit . "12ff6045e9b6aa42f98abd4ddc44d670268a0849") (:authors ("Sam Kleinman")) (:maintainer "tychoish" . "garen@tychoish.com") (:keywords "matching" "files" "grep" "search" "using" "git-grep") (:url . "https://github.com/tychoish/git-grep.el"))])
(git-gutter . [(20220421 2107) ((emacs (24 4))) "Port of Sublime Text plugin GitGutter" single ((:commit . "66dc2a284d7e5b554d28ef94b998255079709c01") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/git-gutter"))])
(git-gutter . [(20220423 1704) ((emacs (25 1))) "Port of Sublime Text plugin GitGutter" single ((:commit . "a50672b62a678922b8c0cab95225d520f493439b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/git-gutter"))])
(git-gutter+ . [(20151204 1723) ((git-commit (0)) (dash (0))) "Manage Git hunks straight from the buffer" single ((:commit . "b7726997806d9a2da9fe84ff00ecf21d62b6f975") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:keywords "git" "vc") (:url . "https://github.com/nonsequitur/git-gutter-plus"))])
(git-gutter-fringe . [(20211003 2228) ((git-gutter (0 88)) (fringe-helper (0 1 1)) (cl-lib (0 5)) (emacs (24))) "Fringe version of git-gutter.el" single ((:commit . "648cb5b57faec55711803cdc9434e55a733c3eba") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/emacsorphanage/git-gutter-fringe"))])
(git-gutter-fringe+ . [(20140729 1103) ((git-gutter+ (0 1)) (fringe-helper (1 0 1))) "Fringe version of git-gutter+.el" single ((:commit . "7a2f49d2455a3a872e90e5f7dd4e6b27f1d96cfc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-fringe-plus"))])
@ -2006,7 +2008,7 @@
(gregorio-mode . [(20170705 1451) nil "Gregorio Mode for .gabc files" single ((:commit . "736fd3d05fb67f707cca1a7ce24e3ee7ca5e9567") (:authors ("Fr. John Jenkins" . "jenkins@sspx.ng")) (:maintainer "Fr. John Jenkins" . "jenkins@sspx.ng") (:keywords "gregorio" "chant") (:url . "https://jsrjenkins.github.io/gregorio-mode/"))])
(grep-a-lot . [(20210618 1420) nil "manages multiple search results buffers for grep.el" single ((:commit . "223819dbea049bdeb5f97f9849fce139a5f16a75") (:authors ("Avi Rozen" . "avi.rozen@gmail.com")) (:maintainer "Avi Rozen" . "avi.rozen@gmail.com") (:keywords "tools" "convenience" "search") (:url . "https://github.com/ZungBang/emacs-grep-a-lot"))])
(greymatters-theme . [(20150621 1123) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "a7220a8c6cf18ccae2b76946b6f01188a7c9d5d1") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))])
(grip-mode . [(20220323 1519) ((emacs (24 4))) "Instant GitHub-flavored Markdown/Org preview using grip." single ((:commit . "6b427143a8f61bb0b5dd070d554e5058130d15ff") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "markdown" "preview") (:url . "https://github.com/seagle0128/grip-mode"))])
(grip-mode . [(20220323 1519) ((emacs (24 4))) "Instant GitHub-flavored Markdown/Org preview using grip." single ((:commit . "53df3f961b65b60ed888cebc6ccc57fab3a3ecb7") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:keywords "convenience" "markdown" "preview") (:url . "https://github.com/seagle0128/grip-mode"))])
(grizzl . [(20160818 737) ((cl-lib (0 5)) (emacs (24 3))) "Fast fuzzy search index for Emacs." single ((:commit . "1e917253ce2b846f0272b8356fad3dbff9cd513a") (:authors ("Chris Corbyn" . "chris@w3style.co.uk")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:keywords "convenience" "usability") (:url . "https://github.com/grizzl/grizzl"))])
(groovy-imports . [(20210505 1807) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Groovy imports" single ((:commit . "a60c3202973e3185091db623d960f71840a22205") (:authors ("Miro Bezjak")) (:maintainer "Miro Bezjak") (:keywords "groovy") (:url . "http://www.github.com/mbezjak/emacs-groovy-imports"))])
(groovy-mode . [(20220212 646) ((s (1 12 0)) (emacs (24 3)) (dash (2 13 0))) "Major mode for Groovy source files" tar ((:commit . "29210e5a969c02169b68e04f2e28e3bf2fc13363") (:authors ("Russel Winder" . "russel@winder.org.uk") ("Jim Morris" . "morris@wolfman.com") ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Russel Winder" . "russel@winder.org.uk") (:keywords "languages"))])
@ -2066,7 +2068,7 @@
(hcl-mode . [(20200315 2129) ((emacs (24 3))) "Major mode for Hashicorp" single ((:commit . "e4d9eef631e8a386341ae8f94f7c2579586e65b5") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/emacs-hcl-mode"))])
(headlong . [(20150417 1526) nil "reckless completion" single ((:commit . "f6830f87f236eee88263cb6976125f72422abe72") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "completion") (:url . "https://github.com/abo-abo/headlong"))])
(heaven-and-hell . [(20190713 1830) ((emacs (24 4))) "easy toggle light/dark themes" single ((:commit . "e1febfd60d060c110a1e43c5f093cd8537251308") (:authors ("Valentin Ignatev" . "valentignatev@gmail.com")) (:maintainer "Valentin Ignatev" . "valentignatev@gmail.com") (:keywords "faces") (:url . "https://github.com/valignatev/heaven-and-hell"))])
(helm . [(20220421 806) ((helm-core (3 8 4)) (popup (0 5 3))) "Helm is an Emacs incremental and narrowing framework" tar ((:commit . "7ff0b93b79117babeb5262b2f0754005b6d050ad") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://emacs-helm.github.io/helm/"))])
(helm . [(20220423 1712) ((helm-core (3 8 4)) (popup (0 5 3))) "Helm is an Emacs incremental and narrowing framework" tar ((:commit . "dc0c082a451cfe25d35ba3b9b0c0fc2766cc8319") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://emacs-helm.github.io/helm/"))])
(helm-R . [(20120820 14) ((helm (20120517)) (ess (20120509))) "helm-sources and some utilities for GNU R." single ((:commit . "b0eb9d5f6a483a9dbe6eb6cf1f2024d4f5938bc2") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:keywords "convenience") (:url . "https://github.com/myuhe/helm-R.el"))])
(helm-ack . [(20141030 1226) ((helm (1 0)) (cl-lib (0 5))) "Ack command with helm interface" single ((:commit . "889bc225318d14c6e3be80e73b1d9d6fb30e48c3") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ack"))])
(helm-ad . [(20151209 1015) ((dash (2 8 0)) (helm (1 6 2))) "helm source for Active Directory" single ((:commit . "8ac044705d8620ee354a9cfa8cc1b865e83c0d55") (:authors ("Takahiro Noda" . "takahiro.noda+github@gmail.com")) (:maintainer "Takahiro Noda" . "takahiro.noda+github@gmail.com") (:keywords "comm"))])
@ -2101,7 +2103,7 @@
(helm-codesearch . [(20190412 1153) ((emacs (25 1)) (s (1 11 0)) (dash (2 12 0)) (helm (1 7 7)) (cl-lib (0 5))) "helm interface for codesearch" single ((:commit . "72f1d1de746115ab7e861178b49fa3c0b6b58d90") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com") (:keywords "tools"))])
(helm-commandlinefu . [(20150611 545) ((emacs (24 1)) (helm (1 7 0)) (json (1 3)) (let-alist (1 0 3))) "Search and browse commandlinefu.com from helm" single ((:commit . "9ee7e018c5db23ae9c8d1c8fa969876f15b7280d") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:keywords "commandlinefu.com") (:url . "https://github.com/xuchunyang/helm-commandlinefu"))])
(helm-company . [(20190812 1429) ((helm (1 5 9)) (company (0 6 13))) "Helm interface for company-mode" single ((:commit . "6eb5c2d730a60e394e005b47c1db018697094dde") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Daniel Ralston" . "Sodel-the-Vociferous@users.noreply.github.com") (:url . "https://github.com/Sodel-the-Vociferous/helm-company"))])
(helm-core . [(20220422 706) ((emacs (25 1)) (async (1 9 4))) "Development files for Helm" tar ((:commit . "7ff0b93b79117babeb5262b2f0754005b6d050ad") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://emacs-helm.github.io/helm/"))])
(helm-core . [(20220423 1804) ((emacs (25 1)) (async (1 9 4))) "Development files for Helm" tar ((:commit . "dc0c082a451cfe25d35ba3b9b0c0fc2766cc8319") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://emacs-helm.github.io/helm/"))])
(helm-cscope . [(20190615 41) ((xcscope (1 0)) (helm (1 6 7)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface for xcscope.el." single ((:commit . "af1d9e7f4460a88d7400b5a74d5da68084089ac1") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:keywords "cscope" "helm") (:url . "https://github.com/alpha22jp/helm-cscope.el"))])
(helm-css-scss . [(20191230 1549) ((emacs (24 3)) (helm (1 0))) "CSS/SCSS/LESS Selectors with helm interface" single ((:commit . "48b996f73af1fef8d6e88a1c545d98f8c50b0cf3") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:keywords "convenience" "scss" "css" "less" "selector" "helm") (:url . "https://github.com/ShingoFukuyama/helm-css-scss"))])
(helm-ctest . [(20191031 1435) ((s (1 9 0)) (dash (2 11 0)) (helm-core (1 7 4))) "Run ctest from within emacs" single ((:commit . "2a29cfb4ec583da247fa2ae7bac88790b1223e40") (:authors ("Dan LaManna" . "me@danlamanna.com")) (:maintainer "Dan LaManna" . "me@danlamanna.com") (:keywords "helm" "ctest"))])
@ -2768,7 +2770,7 @@
(license-snippets . [(20201117 1619) ((emacs (26)) (yasnippet (0 8 0))) "LICENSE templates for yasnippet" tar ((:commit . "a729748b7d7f38a916fe61f23db6e7446c0a5e8f") (:authors ("Seong Yong-ju" . "sei40kr@gmail.com")) (:maintainer "Seong Yong-ju" . "sei40kr@gmail.com") (:keywords "tools") (:url . "https://github.com/sei40kr/license-snippets"))])
(license-templates . [(20200906 2047) ((emacs (24 3)) (request (0 3 0))) "Create LICENSE using GitHub API" single ((:commit . "3a714dd7b658d86879da42d10c4fd64bf5c427be") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/license-templates"))])
(light-soap-theme . [(20150607 1445) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "76a787bd40c6b567ae68ced7f5d9f9f10725e00d"))])
(ligo-mode . [(20220209 755) ((emacs (27 1))) "A major mode for editing LIGO source code" single ((:commit . "77a759c93039a51e01ac46509792c029337ed990") (:authors ("LigoLang SASU")) (:maintainer "LigoLang SASU") (:keywords "languages") (:url . "https://gitlab.com/ligolang/ligo/-/tree/dev/tools/emacs"))])
(ligo-mode . [(20220209 755) ((emacs (27 1))) "A major mode for editing LIGO source code" single ((:commit . "d95e515dd210302627b8da86df747ccef9056db7") (:authors ("LigoLang SASU")) (:maintainer "LigoLang SASU") (:keywords "languages") (:url . "https://gitlab.com/ligolang/ligo/-/tree/dev/tools/emacs"))])
(line-reminder . [(20220405 1658) ((emacs (25 1)) (indicators (0 0 4)) (fringe-helper (1 0 1)) (ov (1 0 6)) (ht (2 0))) "Line annotation for changed and saved lines" single ((:commit . "af939295a503974a021d24b6d972cbb915204b10") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-vs/line-reminder"))])
(line-up-words . [(20180219 1024) nil "Align words in an intelligent way" single ((:commit . "254ee815eb3fe77edea7c9da6f6f3839163735f3") (:url . "https://github.com/janestreet/line-up-words"))])
(lines-at-once . [(20180422 247) ((emacs (25))) "Insert and edit multiple lines at once" single ((:commit . "31bce4b79fe16251b7cf118f0d343b0b46f72360") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:keywords "abbrev" "tools") (:url . "https://github.com/jiahaowork/lines-at-once.el"))])
@ -2806,7 +2808,7 @@
(litex-mode . [(20220415 1704) ((cl-lib (0 5)) (emacs (24 1))) "Minor mode for converting lisp to LaTeX" tar ((:commit . "5d5750af2990c050c8d36baa4b8e7a45850d5a6a") (:authors ("Gaurav Atreya" . "allmanpride@gmail.com")) (:maintainer "Gaurav Atreya" . "allmanpride@gmail.com") (:keywords "calculator" "lisp" "latex") (:url . "https://github.com/Atreyagaurav/litex-mode"))])
(live-code-talks . [(20180907 1647) ((emacs (24)) (cl-lib (0 5)) (narrowed-page-navigation (0 1))) "Support for slides with live code in them" single ((:commit . "97f16a9ee4e6ff3e0f9291eaead772c66e3e12ae") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk") (:keywords "docs" "multimedia"))])
(live-preview . [(20201010 1948) ((emacs (24 4))) "Live preview by any shell command while editing" single ((:commit . "603a4a1759fbec92e7a1cabc249517c78e59ce7e") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "languages" "util") (:url . "https://github.com/lassik/emacs-live-preview"))])
(live-py-mode . [(20220404 0) ((emacs (24 3))) "Live Coding in Python" tar ((:commit . "733b755912ce705b0afca51585448dd0a659a377") (:authors ("Don Kirkby http://donkirkby.github.io")) (:maintainer "Don Kirkby http://donkirkby.github.io") (:keywords "live" "coding") (:url . "http://donkirkby.github.io/live-py-plugin/"))])
(live-py-mode . [(20220404 0) ((emacs (24 3))) "Live Coding in Python" tar ((:commit . "b6583c0c845e3ef607d57e35a009255d630df2c1") (:authors ("Don Kirkby http://donkirkby.github.io")) (:maintainer "Don Kirkby http://donkirkby.github.io") (:keywords "live" "coding") (:url . "http://donkirkby.github.io/live-py-plugin/"))])
(lively . [(20171005 754) nil "interactively updating text" single ((:commit . "348675828c6a81bfa1ac311ca465aad813542c1b") (:authors ("Luke Gorrie" . "luke@bup.co.nz")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))])
(livereload . [(20170629 650) ((emacs (25)) (websocket (1 8))) "Livereload server" tar ((:commit . "1e501d7e46dbd476c2c7cc9d20b5ac9d41fb1955") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:keywords "convenience"))])
(livescript-mode . [(20140613 421) nil "Major mode for editing LiveScript files" single ((:commit . "90a918d9686e256e6d4d439cc20f24dad8d3b804") (:authors ("Hisamatsu Yasuyuki" . "yas@null.net")) (:maintainer "Hisamatsu Yasuyuki" . "yas@null.net") (:keywords "languages" "livescript") (:url . "https://github.com/yhisamatsu/livescript-mode"))])
@ -2843,7 +2845,7 @@
(lorem-ipsum . [(20190819 2042) nil "Insert dummy pseudo Latin text." single ((:commit . "da75c155da327c7a7aedb80f5cfe409984787049") (:authors ("Jean-Philippe Theberge" . "jphil21@sourceforge.net")) (:maintainer "Joe Schafer" . "joe@jschaf.com") (:keywords "tools" "language" "convenience"))])
(lox-mode . [(20200619 1700) ((emacs (24 3))) "Major mode for the Lox programming language" single ((:commit . "b6935b3f5b131d2c1c7685cf6464274f7cd64943") (:authors ("Timmy Jose" . "zoltan.jose@gmail.com")) (:maintainer "Timmy Jose" . "zoltan.jose@gmail.com") (:keywords "languages" "lox") (:url . "https://github.com/timmyjose-projects/lox-mode"))])
(lpy . [(20201027 1425) ((emacs (25 1)) (lispy (0 27 0))) "A lispy interface to Python" tar ((:commit . "076ce9acb68f6ac1b39127b634a91ffd865d13d8") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "python" "lisp") (:url . "https://github.com/abo-abo/lpy"))])
(lsp-dart . [(20220313 1835) ((emacs (26 3)) (lsp-treemacs (0 3)) (lsp-mode (7 0 1)) (dap-mode (0 6)) (f (0 20 0)) (dash (2 14 1)) (dart-mode (1 0 5))) "Dart support lsp-mode" tar ((:commit . "fda433671f38874f0ebe66c43c64fec14af3f492") (:keywords "languages" "extensions") (:url . "https://emacs-lsp.github.io/lsp-dart"))])
(lsp-dart . [(20220425 1211) ((emacs (26 3)) (lsp-treemacs (0 3)) (lsp-mode (7 0 1)) (dap-mode (0 6)) (f (0 20 0)) (dash (2 14 1)) (dart-mode (1 0 5))) "Dart support lsp-mode" tar ((:commit . "a1336f196daf6048c48681f5fe3e77bf46fd5a1d") (:keywords "languages" "extensions") (:url . "https://emacs-lsp.github.io/lsp-dart"))])
(lsp-docker . [(20211203 1659) ((emacs (25 1)) (dash (2 14 1)) (lsp-mode (6 2 1)) (f (0 20 0)) (yaml (0 2 0)) (ht (2 0))) "LSP Docker integration" single ((:commit . "c2da2a65cb11e92d23c480dcc12387aa53997181") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "languages" "langserver") (:url . "https://github.com/emacs-lsp/lsp-docker"))])
(lsp-focus . [(20200906 1917) ((emacs (26 1)) (focus (0 1 1)) (lsp-mode (6 1))) "focus.el support for lsp-mode" single ((:commit . "d01f0af156e4e78dcb9fa8e080a652cf8f221d30") (:authors ("Vibhav Pant")) (:maintainer "Vibhav Pant") (:keywords "languages" "lsp-mode") (:url . "https://github.com/emacs-lsp/lsp-focus"))])
(lsp-grammarly . [(20220222 638) ((emacs (27 1)) (lsp-mode (6 1)) (grammarly (0 3 0)) (request (0 3 0)) (s (1 12 0)) (ht (2 3))) "LSP Clients for Grammarly" single ((:commit . "1e2aff23dfaf419bfae66718761a0eddbd6f613e") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-grammarly/lsp-grammarly"))])
@ -2857,20 +2859,20 @@
(lsp-latex . [(20210815 1426) ((emacs (25 1)) (lsp-mode (6 0))) "LSP-mode client for LaTeX, on texlab" single ((:commit . "3f6b2ac9585682828eef81f895757f74cfba7309") (:authors ("ROCKTAKEY" . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY" . "rocktakey@gmail.com") (:keywords "languages" "tex") (:url . "https://github.com/ROCKTAKEY/lsp-latex"))])
(lsp-ltex . [(20220222 656) ((emacs (26 1)) (lsp-mode (6 1))) "LSP Clients for LTEX" single ((:commit . "e13bedf0032d376e1e28026abda5970bbbdb636d") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/emacs-languagetool/lsp-ltex"))])
(lsp-metals . [(20220330 1958) ((emacs (26 1)) (scala-mode (1 1)) (lsp-mode (7 0)) (lsp-treemacs (0 2)) (dap-mode (0 3)) (dash (2 18 0)) (f (0 20 0)) (ht (2 0)) (treemacs (2 5))) "Scala Client settings" tar ((:commit . "b7f77de69431786c54e9a57845e4f2d75fbee053") (:authors ("Ross A. Baker" . "ross@rossabaker.com") ("Evgeny Kurnevsky" . "kurnevsky@gmail.com")) (:maintainer "Ross A. Baker" . "ross@rossabaker.com") (:keywords "languages" "extensions") (:url . "https://github.com/emacs-lsp/lsp-metals"))])
(lsp-mode . [(20220422 2059) ((emacs (26 1)) (dash (2 18 0)) (f (0 20 0)) (ht (2 3)) (spinner (1 7 3)) (markdown-mode (2 3)) (lv (0))) "LSP mode" tar ((:commit . "4f6dfc761249e9d3ee9b773ee6eb682cd58de60e") (:authors ("Vibhav Pant, Fangrui Song, Ivan Yonchovski")) (:maintainer "Vibhav Pant, Fangrui Song, Ivan Yonchovski") (:keywords "languages") (:url . "https://github.com/emacs-lsp/lsp-mode"))])
(lsp-mode . [(20220424 1824) ((emacs (26 1)) (dash (2 18 0)) (f (0 20 0)) (ht (2 3)) (spinner (1 7 3)) (markdown-mode (2 3)) (lv (0))) "LSP mode" tar ((:commit . "fd1a431b3d50ab1426681bce2d5c4ff8c9c6301e") (:authors ("Vibhav Pant, Fangrui Song, Ivan Yonchovski")) (:maintainer "Vibhav Pant, Fangrui Song, Ivan Yonchovski") (:keywords "languages") (:url . "https://github.com/emacs-lsp/lsp-mode"))])
(lsp-mssql . [(20191204 1150) ((emacs (25 1)) (lsp-mode (6 2)) (dash (2 14 1)) (f (0 20 0)) (ht (2 0)) (lsp-treemacs (0 1))) "MSSQL LSP bindings" tar ((:commit . "88319a61a06e27fc1d3ea2e7b853ec1692b4c166") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:keywords "data" "languages") (:url . "https://github.com/emacs-lsp/lsp-mssql"))])
(lsp-origami . [(20211016 1045) ((origami (1 0)) (lsp-mode (6 1))) "origami.el support for lsp-mode" single ((:commit . "5b88ab77dc2696c93fa5dd9debe183821c533b71") (:authors ("Vibhav Pant")) (:maintainer "Vibhav Pant") (:keywords "languages" "lsp-mode") (:url . "https://github.com/emacs-lsp/lsp-origami"))])
(lsp-p4 . [(20190127 1049) ((lsp-mode (3 0))) "P4 support for lsp-mode" tar ((:commit . "669460d93b87fb876df11b2b68229677e7ad1a26") (:authors ("Dmitri Makarov")) (:maintainer "Dmitri Makarov") (:keywords "lsp" "p4") (:url . "https://github.com/dmakarov/p4ls"))])
(lsp-pascal . [(20200422 1610) ((emacs (24 4)) (lsp-mode (6 3))) "LSP client for Pascal" single ((:commit . "b132bdf66748e4abe0d4140f6d061b1ccd56082a") (:authors ("Arjan Adriaanse" . "arjan@adriaan.se")) (:maintainer "Arjan Adriaanse" . "arjan@adriaan.se") (:keywords "languages" "tools") (:url . "https://github.com/arjanadriaanse/lsp-pascal"))])
(lsp-pyre . [(20190406 335) ((lsp-mode (6 0))) "lsp-mode client for python using pyre" single ((:commit . "e177b8f5efd1a955b5753aeb5d1894e6d21be35a") (:authors ("John Allen" . "oss@porcnick.com")) (:maintainer "John Allen" . "oss@porcnick.com") (:url . "https://github.com/jra3/lsp-pyre"))])
(lsp-pyright . [(20220411 1753) ((emacs (26 1)) (lsp-mode (7 0)) (dash (2 18 0)) (ht (2 0))) "Python LSP client using Pyright" single ((:commit . "308ba57a272c5b17705e534584bd52933e2ace6b") (:authors ("Arif Rezai, Vincent Zhang, Andrew Christianson")) (:maintainer "Arif Rezai, Vincent Zhang, Andrew Christianson") (:keywords "languages" "tools" "lsp") (:url . "https://github.com/emacs-lsp/lsp-pyright"))])
(lsp-pyright . [(20220411 1753) ((emacs (26 1)) (lsp-mode (7 0)) (dash (2 18 0)) (ht (2 0))) "Python LSP client using Pyright" single ((:commit . "34cb61b1fee1d87890f3ea9f63b1934ae7c917d6") (:authors ("Arif Rezai, Vincent Zhang, Andrew Christianson")) (:maintainer "Arif Rezai, Vincent Zhang, Andrew Christianson") (:keywords "languages" "tools" "lsp") (:url . "https://github.com/emacs-lsp/lsp-pyright"))])
(lsp-python-ms . [(20211204 1209) ((emacs (25 1)) (lsp-mode (6 1))) "The lsp-mode client for Microsoft python-language-server" single ((:commit . "f8e7c4bcaefbc3fd96e1ca53d17589be0403b828") (:authors ("Charl Botha")) (:maintainer "Andrew Christianson, Vincent Zhang") (:keywords "languages" "tools") (:url . "https://github.com/emacs-lsp/lsp-python-ms"))])
(lsp-rescript . [(20220314 1957) ((lsp-mode (7 0 1)) (emacs (25 1)) (rescript-mode (0 1))) "LSP client configuration for lsp-mode and rescript-vscode" single ((:commit . "7baf9adf10234cf964feefae99050268e9bc5681") (:authors ("John Lee")) (:maintainer "John Lee") (:keywords "languages") (:url . "https://github.com/jjlee/lsp-rescript"))])
(lsp-sonarlint . [(20210820 2044) ((emacs (25)) (dash (2 12 0)) (lsp-mode (6 3)) (ht (2 3))) "Emacs Sonarlint lsp client" tar ((:commit . "3af97828f9c08d782fb2086e3a73bda5759e6788") (:authors ("Fermin MF" . "fmfs@posteo.net")) (:maintainer "Fermin MF" . "fmfs@posteo.net") (:keywords "languages" "tools" "php" "javascript" "xml" "ruby" "html" "scala" "java" "python") (:url . "https://github.com/emacs-lsp/lsp-sonarlint"))])
(lsp-sourcekit . [(20210905 2017) ((emacs (25 1)) (lsp-mode (5))) "sourcekit-lsp client for lsp-mode" single ((:commit . "97ff36b228a61e69734c7180f33cc6951b1a600f") (:authors ("Daniel Martín")) (:maintainer "Daniel Martín") (:keywords "languages" "lsp" "swift" "objective-c" "c++") (:url . "https://github.com/emacs-lsp/lsp-sourcekit"))])
(lsp-tailwindcss . [(20211211 248) ((lsp-mode (7 1)) (emacs (26 1))) "A lsp-mode client for tailwindcss" single ((:commit . "010318052021ec041727e58e41752af094c8827a") (:authors ("A.I." . "merrick@luois.me")) (:maintainer "A.I." . "merrick@luois.me") (:keywords "language" "tools") (:url . "https://github.com/merrickluo/lsp-tailwindcss"))])
(lsp-treemacs . [(20220328 625) ((emacs (26 1)) (dash (2 18 0)) (f (0 20 0)) (ht (2 0)) (treemacs (2 5)) (lsp-mode (6 0))) "LSP treemacs" tar ((:commit . "355e468b7fa9887c616a8bfe873d8e456303b67b") (:authors ("Ivan Yonchovski")) (:maintainer "Ivan Yonchovski") (:keywords "languages") (:url . "https://github.com/emacs-lsp/lsp-treemacs"))])
(lsp-ui . [(20220411 1413) ((emacs (26 1)) (dash (2 18 0)) (lsp-mode (6 0)) (markdown-mode (2 3))) "UI modules for lsp-mode" tar ((:commit . "b988e5ead62f7bea24aba09bf3a21e1f2ca787eb") (:authors ("Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me")) (:maintainer "Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me") (:keywords "languages" "tools") (:url . "https://github.com/emacs-lsp/lsp-ui"))])
(lsp-ui . [(20220425 1046) ((emacs (26 1)) (dash (2 18 0)) (lsp-mode (6 0)) (markdown-mode (2 3))) "UI modules for lsp-mode" tar ((:commit . "6cd0409de6ca59c02d752b8e543bb5eaa61357e4") (:authors ("Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me")) (:maintainer "Sebastien Chapuis <sebastien@chapu.is>, Fangrui Song" . "i@maskray.me") (:keywords "languages" "tools") (:url . "https://github.com/emacs-lsp/lsp-ui"))])
(lua-mode . [(20210809 1320) ((emacs (24 3))) "a major-mode for editing Lua scripts" single ((:commit . "5a9bee8d5fc978dc64fcb677167417010321ba65") (:authors ("2011-2013 immerrr" . "immerrr+lua@gmail.com") ("2010-2011 Reuben Thomas" . "rrt@sc3d.org") ("2006 Juergen Hoetzel" . "juergen@hoetzel.info") ("2004 various (support for Lua 5 and byte compilation)") ("2001 Christian Vogler" . "cvogler@gradient.cis.upenn.edu") ("1997 Bret Mogilefsky" . "mogul-lua@gelatinous.com") ("tcl-mode by Gregor Schmid" . "schmid@fb3-s7.math.tu-berlin.de") ("with tons of assistance from") ("Paul Du Bois" . "pld-lua@gelatinous.com") ("Aaron Smith" . "aaron-lua@gelatinous.com")) (:maintainer "2011-2013 immerrr" . "immerrr+lua@gmail.com") (:keywords "languages" "processes" "tools") (:url . "https://immerrr.github.io/lua-mode"))])
(luarocks . [(20170430 2305) ((emacs (24)) (cl-lib (0 5))) "luarocks tools" single ((:commit . "cee27ba0716edf338077387969883226dd2b7484") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/luarocks.el"))])
(lush-theme . [(20180816 2200) ((emacs (24))) "A dark theme with lush colors" single ((:commit . "645e1959143532df8f7ef90e1184e9556df18af7") (:authors ("Andre Richter" . "andre.o.richter@gmail.com")) (:maintainer "Andre Richter" . "andre.o.richter@gmail.com") (:keywords "theme" "dark" "strong colors") (:url . "https://github.com/andre-richter/emacs-lush-theme"))])
@ -2893,7 +2895,7 @@
(magic-filetype . [(20180219 1552) ((emacs (24)) (s (1 9 0))) "Enhance filetype major mode" single ((:commit . "019494add5ff02dd36cb3f500142fc51125522cc") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:keywords "emulations" "vim" "ft" "file" "magic-mode") (:url . "https://github.com/zonuexe/magic-filetype.el"))])
(magic-latex-buffer . [(20210306 422) ((cl-lib (0 5)) (emacs (25 1))) "Magically enhance LaTeX-mode font-locking for semi-WYSIWYG editing" single ((:commit . "903ec91872760e47c0e5715795f8465173615098") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://zk-phi.github.io/"))])
(magik-mode . [(20220422 837) nil "mode for editing Magik + some utils." tar ((:commit . "af1b83786c95d448dcb4df5406eb1cdba975abf5") (:keywords "languages") (:url . "http://github.com/roadrunner1776/magik"))])
(magit . [(20220423 1215) ((emacs (25 1)) (compat (28 1 0 4)) (dash (20210826)) (git-commit (20220222)) (magit-section (20220325)) (transient (20220325)) (with-editor (20220318))) "A Git porcelain inside Emacs." tar ((:commit . "b4d54d3f8ee047479980b6d8079f3ce1a93bb6a4") (:authors ("Marius Vollmer" . "marius.vollmer@gmail.com") ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
(magit . [(20220425 1153) ((emacs (25 1)) (compat (28 1 0 4)) (dash (20210826)) (git-commit (20220222)) (magit-section (20220325)) (transient (20220325)) (with-editor (20220318))) "A Git porcelain inside Emacs." tar ((:commit . "3cb7f5ba430906bded9e5d9951f5260ab25644d0") (:authors ("Marius Vollmer" . "marius.vollmer@gmail.com") ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
(magit-annex . [(20220302 1725) ((cl-lib (0 3)) (magit (3 0 0))) "Control git-annex from Magit" single ((:commit . "efe484644666c6b7c544b0fb7b87e30703fa9425") (:authors ("Kyle Meyer" . "kyle@kyleam.com") ("Rémi Vanicat" . "vanicat@debian.org")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "vc" "tools") (:url . "https://github.com/magit/magit-annex"))])
(magit-circleci . [(20191209 2113) ((dash (2 16 0)) (transient (0 1 0)) (magit (2 90 0)) (emacs (25 3))) "CircleCI integration for Magit" single ((:commit . "2d4bdacf498ed3ff7d2c3574d346b2d24cbb12da") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:keywords "circleci" "continuous" "integration" "magit" "vc" "tools") (:url . "https://github.com/abrochard/magit-circleci"))])
(magit-commit-mark . [(20220422 705) ((emacs (28 1)) (magit (3 3 0))) "Support marking commits as read" single ((:commit . "2a4d08ac816734fc8195f86f685443e58e63da06") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://gitlab.com/ideasman42/emacs-magit-commit-mark"))])
@ -2906,13 +2908,13 @@
(magit-gitflow . [(20170929 824) ((magit (2 1 0)) (magit-popup (2 2 0))) "gitflow extension for magit" single ((:commit . "cc41b561ec6eea947fe9a176349fb4f771ed865b") (:authors ("Jan Tatarik" . "Jan.Tatarik@gmail.com")) (:maintainer "Jan Tatarik" . "Jan.Tatarik@gmail.com") (:keywords "vc" "tools") (:url . "https://github.com/jtatarik/magit-gitflow"))])
(magit-imerge . [(20220306 2311) ((emacs (25 1)) (magit (3 0 0))) "Magit extension for git-imerge" single ((:commit . "37bca48218dc32cad964e01e0f9936a90f634fba") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "vc" "tools") (:url . "https://github.com/magit/magit-imerge"))])
(magit-lfs . [(20220314 1957) ((emacs (24 4)) (magit (2 10 3)) (dash (2 13 0))) "Magit plugin for Git LFS" single ((:commit . "8ebe246f20f4ab5c9f191c38137833c7f01a0432") (:authors ("Junyoung/Clare Jang" . "jjc9310@gmail.com")) (:maintainer "Junyoung/Clare Jang" . "jjc9310@gmail.com") (:keywords "magit" "git" "lfs" "tools" "vc") (:url . "https://github.com/ailrun/magit-lfs"))])
(magit-libgit . [(20220422 1903) ((emacs (25 1)) (compat (28 1 0 4)) (libgit (0)) (magit (20211004))) "." tar ((:commit . "b4d54d3f8ee047479980b6d8079f3ce1a93bb6a4") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
(magit-libgit . [(20220422 1903) ((emacs (25 1)) (compat (28 1 0 4)) (libgit (0)) (magit (20211004))) "." tar ((:commit . "3cb7f5ba430906bded9e5d9951f5260ab25644d0") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "git" "tools" "vc") (:url . "https://github.com/magit/magit"))])
(magit-org-todos . [(20180709 1950) ((magit (2 0 0)) (emacs (24))) "Add local todo items to the magit status buffer" single ((:commit . "9ffa3efb098434d837cab4bacd1601fdfc6fe999") (:authors ("Daniel Ma")) (:maintainer "Daniel Ma") (:keywords "org-mode" "magit" "tools") (:url . "http://github.com/danielma/magit-org-todos"))])
(magit-patch-changelog . [(20220313 1229) ((emacs (25 1)) (magit (3 3 0))) "Generate a patch according to emacs-mirror/CONTRIBUTE" single ((:commit . "96936d2bd92c8bbf87f65bc293f3246014bc2764") (:keywords "git" "tools" "vc") (:url . "https://github.com/dickmao/magit-patch-changelog"))])
(magit-popup . [(20200719 1015) ((emacs (24 4)) (dash (2 13 0))) "Define prefix-infix-suffix command combos" tar ((:commit . "d8585fa39f88956963d877b921322530257ba9f5") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "bindings") (:url . "https://github.com/magit/magit-popup"))])
(magit-rbr . [(20181009 2016) ((magit (2 13 0)) (emacs (24 3))) "Support for git rbr in Magit" single ((:commit . "029203b3e48537205052a058e964f058cd802c3c") (:authors ("Anatoly Fayngelerin" . "fanatoly+magitrbr@gmail.com")) (:maintainer "Anatoly Fayngelerin" . "fanatoly+magitrbr@gmail.com") (:keywords "git" "magit" "rbr" "tools") (:url . "https://github.com/fanatoly/magit-rbr"))])
(magit-reviewboard . [(20200727 1748) ((emacs (25 2)) (magit (2 13 0)) (s (1 12 0)) (request (0 3 0))) "Show open Reviewboard reviews in Magit" single ((:commit . "aceedff88921f1dfef8a6b2fb18fe316fb7223a8") (:authors ("Jules Tamagnan" . "jtamagnan@gmail.com")) (:maintainer "Jules Tamagnan" . "jtamagnan@gmail.com") (:keywords "magit" "vc") (:url . "http://github.com/jtamagnan/magit-reviewboard"))])
(magit-section . [(20220422 1903) ((emacs (25 1)) (compat (28 1 0 4)) (dash (20210826))) "Sections for read-only buffers" tar ((:commit . "b4d54d3f8ee047479980b6d8079f3ce1a93bb6a4") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/magit/magit"))])
(magit-section . [(20220425 1002) ((emacs (25 1)) (compat (28 1 0 4)) (dash (20210826))) "Sections for read-only buffers" tar ((:commit . "3cb7f5ba430906bded9e5d9951f5260ab25644d0") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "tools") (:url . "https://github.com/magit/magit"))])
(magit-svn . [(20210426 2114) ((emacs (25 1)) (magit (2 90 1)) (transient (0 3 2))) "Git-Svn extension for Magit" single ((:commit . "350493217afdb7637564e089f475909adecd9208") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk") (:keywords "vc" "tools"))])
(magit-tbdiff . [(20220306 2311) ((emacs (25 1)) (magit (3 0 0))) "Magit extension for range diffs" single ((:commit . "ae9345d867539a4c5c635be04df2e26468444da8") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:keywords "vc" "tools") (:url . "https://github.com/magit/magit-tbdiff"))])
(magit-todos . [(20220326 519) ((emacs (25 2)) (async (1 9 2)) (dash (2 13 0)) (f (0 17 2)) (hl-todo (1 9 0)) (magit (2 13 0)) (pcre2el (1 8)) (s (1 12 0)) (transient (0 2 0))) "Show source file TODOs in Magit" single ((:commit . "67fd80c2f10aec4d5b2a24b5d3d53c08cc1f05dc") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "magit" "vc") (:url . "http://github.com/alphapapa/magit-todos"))])
@ -2986,7 +2988,7 @@
(memoize . [(20200103 2036) nil "Memoization functions" single ((:commit . "51b075935ca7070f62fae1d69fe0ff7d8fa56fdd") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/emacs-memoize"))])
(memolist . [(20150804 1721) ((markdown-mode (22 0)) (ag (0 45))) "memolist.el is Emacs port of memolist.vim." single ((:commit . "c437a32d3955f859d9bbcbadf0911bbe27d877ff") (:authors ("mikanfactory <k952i4j14x17_at_gmail.com>")) (:maintainer "mikanfactory") (:keywords "markdown" "memo") (:url . "http://github.com/mikanfactory/emacs-memolist"))])
(mentor . [(20220113 2136) ((emacs (25 1)) (xml-rpc (1 6 15)) (seq (1 11)) (async (1 9 3))) "Frontend for the rTorrent bittorrent client" tar ((:commit . "afab3a14a4bfb5117f8e25417fdf151611b3df0b") (:authors ("Stefan Kangas" . "stefankangas@gmail.com")) (:maintainer "Stefan Kangas" . "stefankangas@gmail.com") (:keywords "comm" "processes" "bittorrent") (:url . "https://github.com/skangas/mentor"))])
(meow . [(20220423 341) ((emacs (27 1))) "Yet Another modal editing" tar ((:commit . "c4b7df0305530da4a51561556794abaf831a228e") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:keywords "convenience" "modal-editing") (:url . "https://www.github.com/DogLooksGood/meow"))])
(meow . [(20220425 1626) ((emacs (27 1))) "Yet Another modal editing" tar ((:commit . "2144ef179bce8338b45f91a1d538c33e2f53771e") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:keywords "convenience" "modal-editing") (:url . "https://www.github.com/DogLooksGood/meow"))])
(merlin . [(20220404 2046) ((emacs (25 1))) "Mode for Merlin, an assistant for OCaml" tar ((:commit . "0fb973c5490216b1cfa364bbbe9da60f572d43c2") (:authors ("Frédéric Bour <frederic.bour(_)lakaban.net>")) (:maintainer "Frédéric Bour <frederic.bour(_)lakaban.net>") (:keywords "ocaml" "languages") (:url . "https://github.com/ocaml/merlin"))])
(merlin-ac . [(20210615 1208) ((emacs (25 1)) (merlin (3)) (auto-complete (1 5))) "Merlin and auto-complete integration." single ((:commit . "0fb973c5490216b1cfa364bbbe9da60f572d43c2") (:authors ("Simon Castellan <simon.castellan(_)iuwt.fr>") ("Frédéric Bour <frederic.bour(_)lakaban.net>") ("Thomas Refis <thomas.refis(_)gmail.com>")) (:maintainer "Simon Castellan <simon.castellan(_)iuwt.fr>") (:keywords "ocaml" "languages") (:url . "http://github.com/ocaml/merlin"))])
(merlin-company . [(20210615 1208) ((emacs (25 1)) (merlin (3)) (company (0 9))) "Merlin and company mode integration." single ((:commit . "0fb973c5490216b1cfa364bbbe9da60f572d43c2") (:authors ("Simon Castellan <simon.castellan(_)iuwt.fr>") ("Frédéric Bour <frederic.bour(_)lakaban.net>") ("Thomas Refis <thomas.refis(_)gmail.com>")) (:maintainer "Simon Castellan <simon.castellan(_)iuwt.fr>") (:keywords "ocaml" "languages") (:url . "http://github.com/ocaml/merlin"))])
@ -3059,7 +3061,7 @@
(modern-sh . [(20211101 1001) ((emacs (25 1)) (hydra (0 15 0)) (eval-in-repl (0 9 7))) "Minor mode for editing shell script" single ((:commit . "8ebebe77304aa8170f7af809e7564c79d3bd45da") (:keywords "languages" "programming") (:url . "https://github.com/damon-kwok/modern-sh"))])
(modtime-skip-mode . [(20140128 2201) nil "Minor mode for disabling modtime and supersession checks on files." single ((:commit . "c0e49523aa26b2263a8693691ac775988015f592") (:authors ("Jordon Biondo" . "biondoj@mail.gvsu.edu")) (:maintainer "Jordon Biondo" . "biondoj@mail.gvsu.edu") (:url . "http://www.github.com/jordonbiondo/modtime-skip-mode"))])
(modular-config . [(20210726 1614) ((emacs (25 1))) "Organize your config into small and loadable modules" single ((:commit . "2bd77193fa3a7ec0541db284b4034821a8f59fea") (:authors ("Sidharth Arya" . "sidhartharya10@gmail.com")) (:maintainer "Sidharth Arya" . "sidhartharya10@gmail.com") (:keywords "startup" "lisp" "tools") (:url . "https://github.com/SidharthArya/modular-config.el"))])
(modus-themes . [(20220423 340) ((emacs (27 1))) "Elegant, highly legible and customizable themes" tar ((:commit . "f2445a43d845adfb65485a02e653cb4844574983") (:authors ("Protesilaos Stavrou" . "info@protesilaos.com")) (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com") (:keywords "faces" "theme" "accessibility") (:url . "https://git.sr.ht/~protesilaos/modus-themes"))])
(modus-themes . [(20220425 333) ((emacs (27 1))) "Elegant, highly legible and customizable themes" tar ((:commit . "29b8a115046f864e454ded9e2ff864d9cf9d6d6e") (:authors ("Protesilaos Stavrou" . "info@protesilaos.com")) (:maintainer "Protesilaos Stavrou" . "info@protesilaos.com") (:keywords "faces" "theme" "accessibility") (:url . "https://git.sr.ht/~protesilaos/modus-themes"))])
(moe-theme . [(20220111 1220) nil "A colorful eye-candy theme. Moe, moe, kyun!" tar ((:commit . "edf3fe47fb986e283e3b04cba443dcb39fe8720e") (:authors ("kuanyui" . "azazabc123@gmail.com")) (:maintainer "kuanyui" . "azazabc123@gmail.com") (:keywords "themes") (:url . "https://github.com/kuanyui/moe-theme.el"))])
(molar-mass . [(20210519 1342) ((emacs (24 3))) "Calculates molar mass of a molecule" single ((:commit . "838db1486a2dc5a3774eb195d62fbcdef71a63f7") (:authors ("Sergi Ruiz Trepat")) (:maintainer "Sergi Ruiz Trepat") (:keywords "convenience" "chemistry") (:url . "https://github.com/sergiruiztrepat/molar-mass.el"))])
(molecule . [(20180527 743) ((emacs (25 1))) "Simple wrapper for molecule" single ((:commit . "2ef72b81d9aa24ea782b71a061a3abdad6cae162") (:authors (": drymer <drymer [ AT ] autistici.org>")) (:maintainer ": drymer <drymer [ AT ] autistici.org>") (:keywords ":" "languages" "terminals") (:url . "https://git.daemons.it/drymer/molecule.el"))])
@ -3215,7 +3217,7 @@
(nndiscourse . [(20220210 1529) ((emacs (25 1)) (dash (2 18 1)) (anaphora (1 0 4)) (rbenv (0 0 3)) (json-rpc (0 0 1))) "Gnus backend for Discourse" tar ((:commit . "1b7d7bfc99b104b7c4948af9f3394b416105e9d9") (:keywords "news") (:url . "https://github.com/dickmao/nndiscourse"))])
(nnhackernews . [(20220107 1537) ((emacs (25 2)) (request (0 3 3)) (dash (2 18 1)) (anaphora (1 0 4))) "Gnus backend for Hacker News" single ((:commit . "6748065db2f12ae6ea07058e7d643f586fb4b3bc") (:keywords "news") (:url . "https://github.com/dickmao/nnhackernews"))])
(nnir-est . [(20180710 2103) nil "Gnus nnir interface for HyperEstraier" single ((:commit . "6d0d5c8e33f4e4ccbc22350324c0990d2676fb5a") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "mail") (:url . "https://github.com/kawabata/nnir-est"))])
(nnreddit . [(20220124 351) ((emacs (25 1)) (request (0 3 3)) (anaphora (1 0 4)) (dash (2 18 1)) (json-rpc (0 0 1)) (virtualenvwrapper (20151123)) (s (1 6 1))) "Gnus Backend For Reddit" tar ((:commit . "ddb59e309018416d1f867b6dddca44f17a1b6bb9") (:keywords "news") (:url . "https://github.com/dickmao/nnreddit"))])
(nnreddit . [(20220423 2302) ((emacs (25 1)) (request (0 3 3)) (anaphora (1 0 4)) (dash (2 18 1)) (json-rpc (0 0 1)) (virtualenvwrapper (20151123)) (s (1 6 1))) "Gnus Backend For Reddit" tar ((:commit . "8f247dce12bd10de37f0903f3027a1ddbc318eff") (:keywords "news") (:url . "https://github.com/dickmao/nnreddit"))])
(nntwitter . [(20220213 1654) ((emacs (25 1)) (dash (20190401)) (anaphora (20180618)) (request (20190819))) "Gnus Backend For Twitter" tar ((:commit . "354781f9d2da04649823a6923ad372d801f10ca7") (:keywords "news") (:url . "https://github.com/dickmao/nntwitter"))])
(no-emoji . [(20180515 1837) ((emacs (24))) "Show :emoji-name: instead of emoji characters" single ((:commit . "ebceeab50dbfe4d60235180a57633745dbc18c77") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:keywords "extensions") (:url . "https://github.com/ecraven/no-emoji"))])
(no-littering . [(20220422 1616) ((emacs (25 1)) (compat (28 1 1 0))) "Help keeping ~/.emacs.d clean" single ((:commit . "405dc3f842fe74a3ea58fe798007f94d3ee60b68") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "convenience") (:url . "https://github.com/emacscollective/no-littering"))])
@ -3235,7 +3237,7 @@
(northcode-theme . [(20180423 1649) ((emacs (24))) "A dark theme focused on blue and orange colors." single ((:commit . "4d3750461ba25ec45321318b5f1af4e8fdf16147") (:authors ("Andreas Larsen" . "andreas@northcode.no")) (:maintainer "Andreas Larsen" . "andreas@northcode.no") (:url . "https://github.com/Northcode/northcode-theme.el"))])
(nothing-theme . [(20200504 402) ((emacs (24 1))) "Monochrome theme" single ((:commit . "d2514bb9707f66dda0d60f40f465e79914c50946") (:authors ("Jared Gorski," . "jaredgorski6@gmail.com")) (:maintainer "Jared Gorski," . "jaredgorski6@gmail.com") (:url . "https://github.com/jaredgorski/nothing.el"))])
(notink-theme . [(20220114 1955) ((emacs (26 1))) "A custom theme inspired by e-ink displays" single ((:commit . "6115857fe75c1adbbce4165a2b77a11a271aaf31") (:authors ("MetroWind" . "chris.corsair@gmail.com")) (:maintainer "MetroWind" . "chris.corsair@gmail.com") (:keywords "faces") (:url . "https://github.com/MetroWind/notink-theme"))])
(notmuch . [(20220226 1200) nil "run notmuch within emacs" tar ((:commit . "2c61fff4ec8fea9a0bdefd13a7a14a34c5e27ada") (:url . "https://notmuchmail.org"))])
(notmuch . [(20220226 1200) nil "run notmuch within emacs" tar ((:commit . "e3ad0087f3453c89871acac8b11da8bab1ac54df") (:url . "https://notmuchmail.org"))])
(notmuch-addr . [(20220422 1618) ((emacs (27 1)) (compat (28 1 1 0)) (notmuch (0 32))) "An alternative to notmuch-address.el" single ((:commit . "2e479851b5cb2d25c31f21b400cfd34777348874") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "mail") (:url . "https://git.sr.ht/~tarsius/notmuch-addr"))])
(notmuch-bookmarks . [(20200322 1925) ((seq (2 20)) (emacs (26 1)) (notmuch (0 29 3))) "Add bookmark handling for notmuch buffers" single ((:commit . "ec8edfdbd1ac475530591d73a570ded5c18ed86a") (:authors ("Jörg Volbers" . "joerg@joergvolbers.de")) (:maintainer "Jörg Volbers" . "joerg@joergvolbers.de") (:keywords "mail") (:url . "https://github.com/publicimageltd/notmuch-bookmarks"))])
(notmuch-labeler . [(20131230 1719) ((notmuch (0))) "Improve notmuch way of displaying labels" tar ((:commit . "d65d1129555d368243df4770ecc1e7ccb88efc58") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:keywords "emacs" "package" "elisp" "notmuch" "emails") (:url . "https://github.com/DamienCassou/notmuch-labeler"))])
@ -3256,7 +3258,7 @@
(number . [(20170901 1312) nil "Working with numbers at point." single ((:commit . "bbc278d34dbcca83e70e3be855ec98b23debfb99"))])
(number-lock . [(20160830 200) nil "Enter symbols on your number keys without pressing shift" single ((:commit . "74417b1238953bf485961a0dd7d20f5c36ae25ea") (:authors ("Liu233w" . "wwwlsmcom@outlook.com")) (:maintainer "Liu233w" . "wwwlsmcom@outlook.com") (:keywords "convenience") (:url . "https://github.com/Liu233w/number-lock.el"))])
(numbers . [(20170802 1134) ((emacs (24))) "Display information and trivia about numbers" single ((:commit . "dd02508b788a13b7d4dbcc4923fa23134b783ab3") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "games" "trivia" "maths" "numbers") (:url . "https://github.com/davep/numbers.el"))])
(numbex . [(20220327 2049) ((emacs (26 1))) "Manage numbered examples" single ((:commit . "78a4f72e666a67486dd616b89f7318a8ae3c125b") (:authors ("Enrico Flor" . "enrico@eflor.net")) (:maintainer "Enrico Flor" . "enrico@eflor.net") (:url . "https://github.com/enricoflor/numbex"))])
(numbex . [(20220425 1619) ((emacs (26 1))) "Manage numbered examples" single ((:commit . "af069f1df3cd0f7612083e4e6a5ddfb0dde07a5d") (:authors ("Enrico Flor" . "enrico@eflor.net")) (:maintainer "Enrico Flor" . "enrico@eflor.net") (:url . "https://github.com/enricoflor/numbex"))])
(nummm-mode . [(20131117 1014) nil "Display the number of minor modes instead of their names" single ((:commit . "81951e12032274543c5f7a585b29bd93961e94e4") (:authors ("Andreu Gil" . "agpchil@gmail.com")) (:maintainer "Andreu Gil" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/nummm-mode"))])
(numpydoc . [(20220304 1546) ((emacs (25 1)) (s (1 12 0)) (dash (2 18 0))) "NumPy style docstring insertion" single ((:commit . "1b8c5ef3301fed5e5c1941817dbb7435188ff417") (:authors ("Doug Davis" . "ddavis@ddavis.io")) (:maintainer "Doug Davis" . "ddavis@ddavis.io") (:keywords "convenience") (:url . "https://github.com/douglasdavis/numpydoc.el"))])
(nv-delete-back . [(20170224 1249) ((emacs (24))) "backward delete like modern text editors" single ((:commit . "b17cb826f14c18c2875d112574edb5e4f46f5296") (:authors ("Nicolas Vaughan <n.vaughan [at] oxon.org>")) (:maintainer "Nicolas Vaughan <n.vaughan [at] oxon.org>") (:keywords "lisp"))])
@ -3285,7 +3287,7 @@
(ob-dart . [(20170106 1624) nil "org-babel functions for Dart evaluation" single ((:commit . "04d63b922a5469506560ca0c00678e57131e0269") (:authors ("Milan Zimmermann")) (:maintainer "Milan Zimmermann") (:keywords "literate programming" "reproducible research" "emacs" "org" "babel" "dart") (:url . "http://github.org/mzimmerm/ob-dart"))])
(ob-deno . [(20201019 101) ((emacs (26 1))) "Babel Functions for Javascript/TypeScript with Deno" single ((:commit . "f1129d20fe9931f1c0b62c4af781f5489abd957f") (:authors ("HIGASHI Taiju")) (:maintainer "HIGASHI Taiju") (:keywords "literate programming" "reproducible research" "javascript" "typescript" "tools") (:url . "https://github.com/taiju/ob-deno"))])
(ob-diagrams . [(20160407 1237) nil "org-babel functions for diagrams evaluation" single ((:commit . "ed6649616325ca5b2d2109f74aded8bcb8aa5186") (:authors ("Daniel Bergey")) (:maintainer "Daniel Bergey") (:keywords "literate programming" "reproducible research") (:url . "http://orgmode.org"))])
(ob-dsq . [(20220422 2201) ((emacs (27 1))) "Babel functions for the `dsq` CLI tool by Multiprocess Labs" single ((:commit . "550d28da274932d9744045b74dde75b276883f76") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "data" "tools") (:url . "https://github.com/fritzgrabo/ob-dsq"))])
(ob-dsq . [(20220425 716) ((emacs (27 1))) "Babel functions for the `dsq` CLI tool by Multiprocess Labs" single ((:commit . "b8dbf53e5d9ed359fbf69e9d14adf68a7c08af10") (:authors ("Fritz Grabo" . "hello@fritzgrabo.com")) (:maintainer "Fritz Grabo" . "hello@fritzgrabo.com") (:keywords "data" "tools") (:url . "https://github.com/fritzgrabo/ob-dsq"))])
(ob-elixir . [(20170725 1419) ((org (8))) "org-babel functions for elixir evaluation" single ((:commit . "8990a8178b2f7bd93504a9ab136622aab6e82e32") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:keywords "org" "babel" "elixir") (:url . "http://github.com/zweifisch/ob-elixir"))])
(ob-elm . [(20200528 1857) ((emacs (26 1)) (org (9 3))) "Org-babel functions for elm evaluation" single ((:commit . "d3a9fbc2f56416894c9aed65ea9a20cc1d98f15d") (:authors ("Bonface M. K.")) (:maintainer "Bonface M. K.") (:keywords "languages" "tools") (:url . "https://www.bonfacemunyoki.com"))])
(ob-elvish . [(20180427 1900) nil "org-babel functions for Elvish shell" single ((:commit . "369181ceae1190bf971c71aebf9fc6133bd98c39") (:authors ("Diego Zamboni" . "diego@zzamboni.org")) (:maintainer "Diego Zamboni" . "diego@zzamboni.org") (:keywords "literate programming" "elvish" "shell" "languages" "processes" "tools") (:url . "https://github.com/zzamboni/ob-elvish"))])
@ -3496,7 +3498,7 @@
(org-reverse-datetree . [(20220310 1646) ((emacs (26 1)) (dash (2 12)) (org (9 3))) "Create reverse date trees in org-mode" single ((:commit . "9ebd42b521e7adf26a35cbb17144113a83f73264") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:keywords "outlines") (:url . "https://github.com/akirak/org-reverse-datetree"))])
(org-review . [(20220411 1205) nil "schedule reviews for Org entries" single ((:commit . "466f7d8f183f226f1e665cf806cb094471903d9c") (:authors ("Alan Schmitt" . "alan.schmitt@polytechnique.org")) (:maintainer "Alan Schmitt" . "alan.schmitt@polytechnique.org") (:keywords "org" "review") (:url . "https://github.com/brabalan/org-review"))])
(org-rich-yank . [(20220227 2154) ((emacs (24 4))) "Paste with org-mode markup and link to source" single ((:commit . "4bcd030f0d736d77c647955739b61fae541417e9") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:keywords "convenience" "hypermedia" "org") (:url . "https://github.com/unhammer/org-rich-yank"))])
(org-roam . [(20220417 332) ((emacs (26 1)) (dash (2 13)) (org (9 4)) (emacsql (3 0 0)) (emacsql-sqlite (1 0 0)) (magit-section (3 0 0))) "A database abstraction layer for Org-mode" tar ((:commit . "b948cfbe3763f49346f89523845d65ef4baf3aed") (:authors ("Jethro Kuan" . "jethrokuan95@gmail.com")) (:maintainer "Jethro Kuan" . "jethrokuan95@gmail.com") (:keywords "org-mode" "roam" "convenience") (:url . "https://github.com/org-roam/org-roam"))])
(org-roam . [(20220425 12) ((emacs (26 1)) (dash (2 13)) (org (9 4)) (emacsql (3 0 0)) (emacsql-sqlite (1 0 0)) (magit-section (3 0 0))) "A database abstraction layer for Org-mode" tar ((:commit . "b63ff2a7bbd888128939b8ae88c3f62c0d529945") (:authors ("Jethro Kuan" . "jethrokuan95@gmail.com")) (:maintainer "Jethro Kuan" . "jethrokuan95@gmail.com") (:keywords "org-mode" "roam" "convenience") (:url . "https://github.com/org-roam/org-roam"))])
(org-roam-bibtex . [(20220213 1609) ((emacs (27 1)) (org-roam (2 2 0)) (bibtex-completion (2 0 0))) "Org Roam meets BibTeX" tar ((:commit . "efdac6fe4134c33f50b06a0a6d192003d0e5094c") (:authors ("Mykhailo Shevchuk" . "mail@mshevchuk.com") ("Leo Vivier" . "leo.vivier+dev@gmail.com")) (:maintainer "Mykhailo Shevchuk" . "mail@mshevchuk.com") (:keywords "bib" "hypermedia" "outlines" "wp") (:url . "https://github.com/org-roam/org-roam-bibtex"))])
(org-roam-timestamps . [(20220111 1755) ((emacs (26 1)) (org-roam (2 0 0))) "Keep track of modification times for org-roam" single ((:commit . "604fdad0feb61419751d3d6b828cc443a99f418f") (:authors ("Thomas F. K. Jorna <https://github.com/thomas>")) (:maintainer "Thomas F. K. Jorna" . "jorna@jtrialerror.com") (:keywords "calendar" "outlines" "files") (:url . "https://github.com/ThomasFKJorna/org-roam-timestamps/"))])
(org-roam-ui . [(20220225 2151) ((emacs (27 1)) (org-roam (2 0 0)) (simple-httpd (20191103 1446)) (websocket (1 13))) "User Interface for Org-roam" tar ((:commit . "9474a254390b1e42488a1801fed5826b32a8030b") (:authors ("Kirill Rogovoy, Thomas Jorna")) (:maintainer "Kirill Rogovoy, Thomas Jorna") (:keywords "files" "outlines") (:url . "https://github.com/org-roam/org-roam-ui"))])
@ -3554,7 +3556,7 @@
(organic-green-theme . [(20201216 2240) nil "Low-contrast green color theme." single ((:commit . "0ed99a9c0cf14be0a1f491518821f0e9b7e88b88"))])
(organize-imports-java . [(20210715 1155) ((emacs (25 1)) (f (0 20 0)) (s (1 12 0)) (dash (2 14 1)) (ht (2 2))) "Automatically organize imports in Java code" tar ((:commit . "fae07966e9d29f287784c778959a87a26d7caa28") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs-elpa/organize-imports-java"))])
(orgbox . [(20180827 218) ((org (8 0)) (cl-lib (0 5))) "Mailbox-like task scheduling Org." single ((:commit . "3982f56efd67ec016389cad82ce5a44f619b36a9") (:authors ("Yasuhito Takamiya" . "yasuhito@gmail.com")) (:maintainer "Yasuhito Takamiya" . "yasuhito@gmail.com") (:keywords "org") (:url . "https://github.com/yasuhito/orgbox"))])
(orgit . [(20220422 1624) ((emacs (25 1)) (compat (28 1 1 0)) (magit (3 0)) (org (9 4))) "Support for Org links to Magit buffers" single ((:commit . "79ed3337ab0ca3d5018732dcdabfbf700c4822d9") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia" "vc") (:url . "https://github.com/magit/orgit"))])
(orgit . [(20220425 1157) ((emacs (25 1)) (compat (28 1 1 0)) (magit (3 0)) (org (9 4))) "Support for Org links to Magit buffers" single ((:commit . "6dc4d4bfffd6c11550952203a51346b13e120165") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia" "vc") (:url . "https://github.com/magit/orgit"))])
(orgit-forge . [(20220422 1625) ((emacs (25 1)) (compat (28 1 1 0)) (forge (0 3)) (magit (3 3)) (org (9 5)) (orgit (1 8))) "Org links to Forge issue buffers" single ((:commit . "72285807707a802ebe7f3c6149de9a78a022b17e") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia" "vc") (:url . "https://github.com/magit/orgit-forge"))])
(orglink . [(20220422 1626) ((emacs (25 1)) (compat (28 1 1 0)) (org (9 5)) (seq (2 23))) "Use Org Mode links in other modes" single ((:commit . "36129691e60e992f31065be4c26d58645b83b033") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "hypermedia") (:url . "https://github.com/tarsius/orglink"))])
(orglue . [(20200411 311) ((org (9 3)) (epic (0 2))) "more functionality to org-mode." tar ((:commit . "9d5a8e24be9acb8c55bb4d6aa8b98e30e2677401") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "org"))])
@ -3583,7 +3585,7 @@
(otama . [(20160404 1032) nil "Org-table Manipulator" single ((:commit . "c114fd8006762f891bc120a7c0ea213872e7ab31") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:keywords "database" "org-mode"))])
(other-emacs-eval . [(20180408 1348) ((emacs (25 1)) (async (1 9 2))) "Evaluate the Emacs Lisp expression in other Emacs" single ((:commit . "8ace5acafef65daabf0c6619eff60733d7f5d792") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:keywords "tools") (:url . "https://github.com/xuchunyang/other-emacs-eval"))])
(outline-magic . [(20180619 1819) nil "outline mode extensions for Emacs" single ((:commit . "2a5f07417b696cf7541d435c43bafcc64817636b") (:authors ("Carsten Dominik" . "dominik@science.uva.nl")) (:maintainer "Thorsten Jolitz <tjolitz AT gmail DOT com>") (:keywords "outlines"))])
(outline-minor-faces . [(20220422 1824) ((emacs (25 1)) (compat (28 1 1 0))) "Headings faces for outline-minor-mode" single ((:commit . "cd2313cda6cddab77f0de89bc6f4e5399077bc34") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "faces" "outlines") (:url . "https://github.com/tarsius/outline-minor-faces"))])
(outline-minor-faces . [(20220424 1803) ((emacs (25 1)) (compat (28 1 1 0))) "Headings faces for outline-minor-mode" single ((:commit . "e92af60c68c4cb05db84c13bb71becaca90763d7") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "faces" "outlines") (:url . "https://github.com/tarsius/outline-minor-faces"))])
(outline-toc . [(20200401 1208) nil "Sidebar showing a \"table of contents\"." single ((:commit . "81d373633b40628cc3a6b6fb534fd7730076bcdb") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:keywords "convenience" "outlines") (:url . "https://github.com/abingham/outline-toc.el"))])
(outlook . [(20180428 1430) ((emacs (24 4))) "send emails in MS Outlook style" tar ((:commit . "359683aff91b38bd1398a6ed4058a06f09a02d65") (:authors ("Andrew Savonichev")) (:maintainer "Andrew Savonichev") (:keywords "mail") (:url . "https://github.com/asavonic/outlook.el"))])
(outorg . [(20190720 2002) ((emacs (24 4))) "Org-style comment editing" single ((:commit . "ef0f86f4b893b30be8bcf8b43a5ec357a6c70f07") (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "https://github.com/alphapapa/outorg"))])
@ -3606,7 +3608,7 @@
(ox-gist . [(20220410 2034) ((emacs (26 1)) (gist (1 4 0)) (s (1 12 0))) "Export Org mode buffers and subtrees to GitHub gists" single ((:commit . "e9f1f11af0e97fee30c2b15b56c236b1f4e1f400") (:authors ("Puneeth Chaganti" . "punchagan+emacs@muse-amuse.in")) (:maintainer "Puneeth Chaganti" . "punchagan+emacs@muse-amuse.in") (:keywords "org" "lisp" "gist" "github") (:url . "https://github.com/punchagan/org2gist/"))])
(ox-haunt . [(20200202 229) ((emacs (24 3)) (org (9 0))) "Haunt-flavored HTML backend for the Org export engine" single ((:commit . "f3c8fda6fee78f45a259e5d218a519dfd11c00c7") (:authors ("Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org")) (:maintainer "Jakob L. Kreuze" . "zerodaysfordays@sdf.lonestar.org") (:keywords "convenience" "hypermedia" "wp") (:url . "https://git.sr.ht/~jakob/ox-haunt"))])
(ox-html5slide . [(20131228 606) ((org (8 0))) "Export org-mode to HTML5 slide." single ((:commit . "4703dfbd9d79161509def673d2c1e118d722a58f") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:keywords "html" "presentation") (:url . "http://github.com/coldnew/org-html5slide"))])
(ox-hugo . [(20220421 1318) ((emacs (24 4)) (org (9 0))) "Hugo Markdown Back-End for Org Export Engine" tar ((:commit . "2b762139bc8e68b97ef17420cec2df1fcec1ef13") (:keywords "org" "markdown" "docs") (:url . "https://ox-hugo.scripter.co"))])
(ox-hugo . [(20220425 301) ((emacs (24 4)) (org (9 0))) "Hugo Markdown Back-End for Org Export Engine" tar ((:commit . "262b7b432a7f81124fe181c07b57a4f42b6eedc9") (:keywords "org" "markdown" "docs") (:url . "https://ox-hugo.scripter.co"))])
(ox-impress-js . [(20150412 1716) ((org (8))) "impress.js Back-End for Org Export Engine" tar ((:commit . "91c6d2af6af308ade352a03355c4fb551b238c6b") (:authors ("Takumi Kinjo <takumi dot kinjo at gmail dot org>")) (:maintainer "Takumi Kinjo <takumi dot kinjo at gmail dot org>") (:keywords "outlines" "hypermedia" "calendar" "wp") (:url . "https://github.com/kinjo/org-impress-js.el"))])
(ox-ioslide . [(20161015 1338) ((emacs (24 1)) (org (8 0)) (cl-lib (0 5)) (f (0 17 2)) (makey (0 3))) "Export org-mode to Google I/O HTML5 slide." tar ((:commit . "6555680be5364c8ddd2bf446865cb1a82adb6b9e") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:keywords "html" "presentation") (:url . "http://github.com/coldnew/org-ioslide"))])
(ox-jekyll-md . [(20211222 1718) nil "Export Jekyll on Markdown articles using org-mode." single ((:commit . "26edb3f4575bcb0f1a2aed56237cd89694284449") (:authors ("Elsa Gonsiorowski" . "gonsie@me.com")) (:maintainer "Elsa Gonsiorowski" . "gonsie@me.com") (:keywords "org" "jekyll"))])
@ -3738,7 +3740,7 @@
(perspective-exwm . [(20220125 1939) ((emacs (27 1)) (burly (0 2 -1)) (exwm (0 26)) (perspective (2 17))) "Better integration for perspective.el and EXWM" single ((:commit . "8afdbf894a888854ce9dfbe0ad2a5dc41f75ecb8") (:authors ("Korytov Pavel" . "thexcloud@gmail.com")) (:maintainer "Korytov Pavel" . "thexcloud@gmail.com") (:url . "https://github.com/SqrtMinusOne/perspective-exwm.el"))])
(perspeen . [(20171203 1021) ((emacs (25 0)) (powerline (2 4))) "An package for multi-workspace" tar ((:commit . "edb70c530bda50ff3d1756e32a703d5fef5e5480") (:authors ("Peng Li" . "seudut@gmail.com")) (:maintainer "Peng Li" . "seudut@gmail.com") (:keywords "lisp") (:url . "https://github.com/seudut/perspeen"))])
(pest-mode . [(20200321 504) ((emacs (26 3))) "Major mode for editing Pest files" single ((:commit . "43447a2c70f98edd1139005e32f437d3f142442b") (:authors ("ksqsf" . "i@ksqsf.moe")) (:maintainer "ksqsf" . "i@ksqsf.moe") (:keywords "languages") (:url . "https://github.com/ksqsf/pest-mode"))])
(pfuture . [(20211229 1513) ((emacs (25 2))) "a simple wrapper around asynchronous processes" single ((:commit . "bde5b06795e3e35bfb2bba4c34b538d506a0856e") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/pfuture"))])
(pfuture . [(20220425 1242) ((emacs (25 2))) "a simple wrapper around asynchronous processes" single ((:commit . "f9e67bd7edbd5b4e033efd82c0acc4a85ff860a8") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/pfuture"))])
(pg . [(20130731 2142) nil "Emacs Lisp interface to the PostgreSQL RDBMS" single ((:commit . "4f6516ec3946d95dcef49abb6703cc89ecb5183d") (:authors ("Eric Marsden" . "emarsden@laas.fr")) (:maintainer "Helmut Eller" . "heller@common-lisp.net") (:keywords "data" "comm" "database" "postgresql"))])
(pgdevenv . [(20150105 2236) nil "Manage your PostgreSQL development envs" tar ((:commit . "7f1d5bc734750aca98cf67a9491cdbd5615fd132") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:keywords "emacs" "postgresql" "development" "environment" "shell" "debug" "gdb"))])
(ph . [(20161029 1522) ((emacs (24 3))) "A global minor mode for managing multiple projects." tar ((:commit . "ed80dad9211583ed0db633448b3624c99b7fac23") (:authors ("Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com")) (:maintainer "Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com"))])
@ -3973,7 +3975,7 @@
(pyimport . [(20180308 1752) ((dash (2 8 0)) (s (1 9 0)) (shut-up (0 3 2))) "Manage Python imports!" single ((:commit . "a6f63cf7ed93f0c0f7c207e6595813966f8852b9") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))])
(pyimpsort . [(20160130 453) ((emacs (24 3))) "Sort python imports." tar ((:commit . "d5c61d70896b642646dfd3c809c06174ae086c1a") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/pyimpsort.el"))])
(pyinspect . [(20211102 1415) ((emacs (27 1))) "Python object inspector" tar ((:commit . "36cf624236c8b4cce852dd52b64d058d4d4a32fd") (:authors ("Maor Kadosh" . "git@avocadosh.xyz")) (:maintainer "Maor Kadosh" . "git@avocadosh.xyz") (:keywords "tools") (:url . "https://github.com/it-is-wednesday/pyinspect.el"))])
(pylint . [(20210411 1931) nil "minor mode for running `pylint'" single ((:commit . "abfc2a4f4fe33c7499b008632b098399e3cf4320") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com") (:keywords "languages" "python"))])
(pylint . [(20210411 1931) nil "minor mode for running `pylint'" single ((:commit . "aca9c1739c15ba5ea74a7d814f1b6cc23e79267b") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com") (:keywords "languages" "python"))])
(pynt . [(20180710 726) ((emacs (24 4)) (ein (0 13 1)) (epc (0 1 1)) (deferred (0 5 1))) "Generate and scroll EIN buffers from python code" single ((:commit . "86cf9ce78d34f92bfd0764c9cbb75427ebd429e6") (:authors ("Edward Banner" . "edward.banner@gmail.com")) (:maintainer "Edward Banner" . "edward.banner@gmail.com") (:keywords "convenience") (:url . "https://github.com/ebanner/pynt"))])
(pyramid . [(20210427 1032) ((emacs (25 2)) (pythonic (0 1 1)) (tablist (0 70))) "Minor mode for working with pyramid projects" tar ((:commit . "66f54f4a9cc9fa81edf768ab433d5b3c5517363c") (:authors ("Daniel Kraus" . "daniel@kraus.my")) (:maintainer "Daniel Kraus" . "daniel@kraus.my") (:keywords "python" "pyramid" "pylons" "convenience" "tools" "processes") (:url . "https://github.com/dakra/pyramid.el"))])
(pytest . [(20200330 41) ((s (1 9 0))) "Easy Python test running in Emacs" single ((:commit . "6934047242db79b1c53e9fe3e0734cc9719ed1c4") (:keywords "pytest" "python" "testing") (:url . "https://github.com/ionrock/pytest-el"))])
@ -4215,13 +4217,13 @@
(say-what-im-doing . [(20160706 1931) nil "dictate what you're doing with text to speech" single ((:commit . "5b2ce6783b02805bcac1107a149bfba3852cd9d5") (:authors ("Benaiah Mischenko")) (:maintainer "Benaiah Mischenko") (:keywords "text to speech" "dumb" "funny") (:url . "http://github.com/benaiah/say-what-im-doing"))])
(sayid . [(20220101 1357) ((cider (0 21 0))) "sayid nREPL middleware client" single ((:commit . "879aff586336a0ec4d46c0ed4720fb1de22082bd") (:authors ("Bill Piel" . "bill@billpiel.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.dev") (:keywords "clojure" "cider" "debugger") (:url . "https://github.com/clojure-emacs/sayid"))])
(sbt-mode . [(20211203 1148) ((emacs (24 4))) "Interactive support for sbt projects" tar ((:commit . "9fe1e8807c22cc1dc56a6233e000969518907f4d") (:keywords "languages") (:url . "https://github.com/hvesalai/emacs-sbt-mode"))])
(scad-mode . [(20200830 301) nil "A major mode for editing OpenSCAD code" single ((:commit . "c3dde29652b2433a0e68628e4b07fcfa9adbff7b") (:authors ("Len Trigg, Łukasz Stelmach")) (:maintainer "Len Trigg" . "lenbok@gmail.com") (:keywords "languages") (:url . "https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el"))])
(scad-mode . [(20200830 301) nil "A major mode for editing OpenSCAD code" single ((:commit . "eb2849ea946e823bd37f3444ec0bf6bb80c57c67") (:authors ("Len Trigg, Łukasz Stelmach")) (:maintainer "Len Trigg" . "lenbok@gmail.com") (:keywords "languages") (:url . "https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el"))])
(scad-preview . [(20211212 1128) ((scad-mode (91 0)) (emacs (24 4))) "Preview SCAD models in real-time within Emacs" single ((:commit . "c5449b26c63f3e0a695905a7e4e84f8d844f761b") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "https://zk-phi.github.io/"))])
(scala-mode . [(20210414 1126) nil "Major mode for editing Scala" tar ((:commit . "598cb680f321d9609295aa9b4679040cc703b602") (:keywords "languages") (:url . "https://github.com/hvesalai/emacs-scala-mode"))])
(scf-mode . [(20151122 248) nil "shorten file-names in compilation type buffers" single ((:commit . "dbfcdcd89034f208d65e181af58e0d73ad09f8b2") (:authors ("Le Wang")) (:maintainer "Le Wang") (:keywords "compilation") (:url . "https://github.com/lewang/scf-mode"))])
(scheme-complete . [(20201112 442) nil "Smart auto completion for Scheme in Emacs" single ((:commit . "b9a1448c4696f117d9ea4e59b6162dc31112e71a") (:authors ("Alex Shinn")) (:maintainer "Alex Shinn"))])
(schrute . [(20170521 1840) ((emacs (24 3))) "Help you remember there is a better way to do something." single ((:commit . "59faa6c4232ae183cea93237301acad8c0763997") (:authors ("Jorge Araya Navarro" . "elcorreo@deshackra.com")) (:maintainer "Jorge Araya Navarro" . "elcorreo@deshackra.com") (:keywords "convenience") (:url . "https://bitbucket.org/shackra/dwight-k.-schrute"))])
(scihub . [(20211020 420) ((emacs (27 1))) "Sci-Hub integration" single ((:commit . "aac29628d4eea2d6ec0bfda39503c1f71a379bc9") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/scihub.el"))])
(scihub . [(20220423 421) ((emacs (27 1))) "Sci-Hub integration" single ((:commit . "57333c849bcd4953663cbf7c271e9f3a62179765") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:keywords "convenience") (:url . "https://github.com/emacs-pe/scihub.el"))])
(scion . [(20130315 1255) nil "Haskell Minor Mode for Interacting with the Scion Library" single ((:commit . "99b4589175665687181a932cd836850205625f71") (:url . "https://code.google.com/p/scion-lib/"))])
(sclang-extensions . [(20160509 338) ((auto-complete (1 4 0)) (s (1 3 1)) (dash (1 2 0)) (emacs (24 1))) "Extensions for the SuperCollider Emacs mode." tar ((:commit . "e9cc79732f16fdb582129303110c163dcc0d6da0") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com") (:keywords "sclang" "supercollider" "languages" "tools"))])
(sclang-snippets . [(20130513 751) ((yasnippet (0 8 0))) "Snippets for the SuperCollider Emacs mode" tar ((:commit . "c840a416b96f83bdd70491e3d1fbe2f1ae8b3f58") (:authors ("ptrv" . "mail@petervasil.net")) (:maintainer "ptrv" . "mail@petervasil.net") (:keywords "snippets"))])
@ -4515,12 +4517,13 @@
(steam . [(20220218 1707) ((cl-lib (0 5))) "Organize and launch Steam games" single ((:commit . "20aa58c5ccd85f6c4f288a14e79adc66e691cd23") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:keywords "games") (:url . "http://github.com/Kungsgeten/steam.el"))])
(stem . [(20131102 1109) nil "Routines for stemming" single ((:commit . "d74e6611d6ba5025e0276a2cc7c8a90f46bfa9ac") (:authors ("Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp")) (:maintainer "Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp") (:keywords "stemming") (:url . "https://github.com/yuutayamada/stem"))])
(stem-english . [(20180109 358) ((emacs (24 3))) "- routines for stemming English word" single ((:commit . "c9fc4c6ed6bf82382e479dae80912f4ae17d31f4") (:authors ("Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:keywords "text") (:url . "http://github.com/kawabata/stem-english"))])
(stem-reading-mode . [(20220418 1136) ((emacs (25 1))) "Highlight word stems for speed-reading" single ((:commit . "a8bacd80fab6013c09e4e8d337fd88267cbe2ff8") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:keywords "convenience" "wp") (:url . "https://gitlab.com/wavexx/stem-reading-mode.el"))])
(stgit . [(20200606 1308) nil "major mode for StGit interaction" single ((:commit . "03fc757c4255bfd445cdbc2a62ca3b02a65beba5") (:authors ("David Kågedal" . "davidk@lysator.liu.se")) (:maintainer "David Kågedal" . "davidk@lysator.liu.se") (:url . "http://stacked-git.github.io"))])
(sticky . [(20170926 36) nil "Sticky key for capital letters" single ((:commit . "fec4e1af38f17f5cd80eca361d8e8ef8772db366") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:keywords "convenience") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sticky.el"))])
(stickyfunc-enhance . [(20150429 1814) ((emacs (24 3))) "An enhancement to stock `semantic-stickyfunc-mode'" single ((:commit . "13bdba51fcd83ccbc3267959d23afc94d458dcb0") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:keywords "c" "languages" "tools") (:url . "https://github.com/tuhdo/semantic-stickyfunc-enhance"))])
(stimmung-themes . [(20220412 1434) ((emacs (25))) "Themes tuned to inner harmonies" tar ((:commit . "77146bd3ad4f275847c965148572bb0ff0b54c1e") (:authors ("Love Lagerkvist")) (:maintainer "Love Lagerkvist") (:keywords "faces") (:url . "https://github.com/motform/stimmung-themes"))])
(stock-ticker . [(20150204 1052) ((s (1 9 0)) (request (0 2 0))) "Show stock prices in mode line" single ((:commit . "f2e564142c9de84232839a5b01979cf95b04d6a9") (:authors ("Gunther Hagleitner")) (:maintainer "Gunther Hagleitner") (:keywords "comms") (:url . "https://github.com/hagleitn/stock-ticker"))])
(stock-tracker . [(20220423 512) ((emacs (27 1)) (dash (2 16 0)) (async (1 9 5))) "Track stock price" single ((:commit . "1d1f247af491686fbe13dc8eae68190ee100e706") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "convenience" "stock" "finance") (:url . "https://github.com/beacoder/stock-tracker"))])
(stock-tracker . [(20220425 1537) ((emacs (27 1)) (dash (2 16 0)) (async (1 9 5))) "Track stock price" single ((:commit . "1ed9c7464cb0b1f570d60ce22bac876e32bfbd1f") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:keywords "convenience" "stock" "finance") (:url . "https://github.com/beacoder/stock-tracker"))])
(strace-mode . [(20171116 2039) nil "strace output syntax highlighting" single ((:commit . "2901baa968d5180ab985ac40ca22cc20914d01f5") (:authors ("Preston Moore" . "prestonkmoore@gmail.com")) (:maintainer "Preston Moore" . "prestonkmoore@gmail.com") (:keywords "languages"))])
(streak . [(20220311 1929) ((emacs (27 1))) "Track a daily streak in your Mode Line" single ((:commit . "b2206de2fe43f97e754bbcb0abe9b078a419e787") (:authors ("Colin Woodbury <https://www.fosskers.ca>")) (:maintainer "Colin Woodbury" . "colin@fosskers.ca") (:keywords "calendar") (:url . "https://github.com/fosskers/streak"))])
(streamlink . [(20210811 1429) ((s (1 12 0))) "A major mode for streamlink output" single ((:commit . "c265dc61c02ad29ec01dfd8b5cbe3bac60fbf097") (:keywords "multimedia" "streamlink") (:url . "https://github.com/BenediktBroich/streamlink"))])
@ -4608,10 +4611,11 @@
(tabbar . [(20180726 1735) nil "Display a tab bar in the header line" tar ((:commit . "82bbda31cbe8ef367dd6501c3aa14b7f2c835910") (:authors ("David Ponce" . "david@dponce.com")) (:maintainer "David Ponce" . "david@dponce.com") (:keywords "convenience"))])
(tabbar-ruler . [(20160802 307) ((tabbar (2 0 1)) (powerline (2 3)) (mode-icons (0 4 0)) (cl-lib (0 5))) "Pretty tabbar, autohide, use both tabbar/ruler" tar ((:commit . "535568189aa12a3eff7f977d2783e57b6a65ab6a") (:authors ("Matthew Fidler, Ta Quang Trung, Nathaniel Cunningham")) (:maintainer "Matthew L. Fidler") (:keywords "tabbar" "ruler mode" "menu" "tool bar.") (:url . "http://github.com/mlf176f2/tabbar-ruler.el"))])
(tablist . [(20200427 2205) ((emacs (24 3))) "Extended tabulated-list-mode" tar ((:commit . "faab7a035ef2258cc4ea2182f67e3aedab7e2af9") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de") (:keywords "extensions" "lisp"))])
(tabspaces . [(20220422 1957) ((emacs (27 1)) (project (0 8 1))) "Leverage tab-bar and project for buffer-isolated workspaces" single ((:commit . "72ab1f43f1385a3ca65ffaaf78222fb3c18a940d") (:authors ("Colin McLear" . "mclear@fastmail.com")) (:maintainer "Colin McLear") (:keywords "convenience" "frames") (:url . "https://github.com/mclear-tools/tabspaces"))])
(tabspaces . [(20220425 252) ((emacs (27 1)) (project (0 8 1))) "Leverage tab-bar and project for buffer-isolated workspaces" single ((:commit . "810ab43c5aad09d808ad643d90f4f53427966c57") (:authors ("Colin McLear" . "mclear@fastmail.com")) (:maintainer "Colin McLear") (:keywords "convenience" "frames") (:url . "https://github.com/mclear-tools/tabspaces"))])
(tabula-rasa . [(20141216 547) ((emacs (24 4))) "Distraction free writing mode" single ((:commit . "e85fff9de18dc31bc6a7aca726e34a95cc5459f5") (:authors ("Ido Magal" . "misc@satans.church")) (:maintainer "Ido Magal" . "misc@satans.church") (:keywords "distraction free" "writing") (:url . "https://github.com/idomagal/Tabula-Rasa/blob/master/tabula-rasa.el"))])
(tagedit . [(20161121 855) ((s (1 3 1)) (dash (1 0 3))) "Some paredit-like features for html-mode" single ((:commit . "b3a70101a0dcf85498c92b7fcfa7fdbac869746c") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com") (:keywords "convenience"))])
(take-off . [(20140531 917) ((emacs (24 3)) (web-server (0 1 0))) "Emacs remote web access" tar ((:commit . "aa9ea45566fc74febbb6ee9c409ecc4b59246215") (:authors ("Thomas Burette" . "burettethomas@gmail.com")) (:maintainer "Thomas Burette" . "burettethomas@gmail.com") (:url . "https://github.com/tburette/take-off"))])
(talonscript-mode . [(20220204 1441) ((emacs (24 3))) "Major mode for Talon Voice's .talon files" single ((:commit . "b6eb61f56349e0d47276270163ec611c2d5b188e") (:authors ("Jcaw" . "toastedjcaw@gmail.com")) (:maintainer "Jcaw" . "toastedjcaw@gmail.com") (:keywords "languages") (:url . "https://github.com/jcaw/talonscript-mode"))])
(tango-2-theme . [(20120312 2025) nil "Tango 2 color theme for GNU Emacs 24" single ((:commit . "64e44c98e41ebbe3b827d54280e3b9615787daaa") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))])
(tango-plus-theme . [(20211222 1100) nil "A color theme based on the tango palette" single ((:commit . "774b03f932bbc336ce5f943af175d5faa651f2e0") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/tango-plus-theme"))])
(tangotango-theme . [(20220106 1039) nil "Tango Palette color theme for Emacs 24." single ((:commit . "9509035842c5ea44f594879199a74c9fc6d2a368") (:authors ("Julien Barnier")) (:maintainer "Julien Barnier") (:keywords "tango" "palette" "color" "theme" "emacs") (:url . "https://github.com/juba/color-theme-tangotango"))])
@ -4628,7 +4632,7 @@
(teco . [(20200707 2309) nil "Teco interpreter" single ((:commit . "61caf8f419659a0567a269f290c90427a215d77b") (:authors ("Dale R. Worley" . "worley@alum.mit.edu")) (:maintainer "Mark T. Kennedy" . "mtk@acm.org") (:keywords "convenience" "emulations" "files") (:url . "https://github.com/mtk/teco.git"))])
(telega . [(20220418 1131) ((emacs (26 1)) (visual-fill-column (1 9)) (rainbow-identifiers (0 2 2))) "Telegram client (unofficial)" tar ((:commit . "d0dff3c63dcd9b9e38b225677c3d911c6091cf61") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru") (:keywords "comm") (:url . "https://github.com/zevlg/telega.el"))])
(telepathy . [(20131209 1258) nil "Access Telepathy from Emacs" single ((:commit . "211d785b02a29ddc254422fdcc3db45262582f8c") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com") (:keywords "telepathy" "tools"))])
(telephone-line . [(20220313 2218) ((emacs (24 4)) (cl-lib (0 5)) (cl-generic (0 2)) (seq (1 8))) "Rewrite of Powerline" tar ((:commit . "7a0ba06db860dfe9a9ca012c2750b13deec385c6") (:authors ("Daniel Bordak" . "dbordak@fastmail.fm")) (:maintainer "Daniel Bordak" . "dbordak@fastmail.fm") (:keywords "mode-line") (:url . "https://github.com/dbordak/telephone-line"))])
(telephone-line . [(20220424 400) ((emacs (24 4)) (cl-lib (0 5)) (cl-generic (0 2)) (seq (1 8))) "Rewrite of Powerline" tar ((:commit . "6f3455a365912e8f0c45a2240ea79507dee45ade") (:authors ("Daniel Bordak" . "dbordak@fastmail.fm")) (:maintainer "Daniel Bordak" . "dbordak@fastmail.fm") (:keywords "mode-line") (:url . "https://github.com/dbordak/telephone-line"))])
(teletext . [(20211203 1111) ((emacs (24 3))) "Teletext broadcast viewer" single ((:commit . "6b003e9dab9bd0c27d188a81f5fff740d66a2282") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "comm" "help" "hypermedia") (:url . "https://github.com/lassik/emacs-teletext"))])
(teletext-yle . [(20210927 825) ((emacs (24 3)) (teletext (0 1))) "Teletext provider for Finnish national network YLE" single ((:commit . "9c8f4b503923c4ec688e2dcc9dff62d71bc55933") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:keywords "comm" "help" "hypermedia") (:url . "https://github.com/lassik/emacs-teletext-yle"))])
(tempel . [(20220415 2157) ((emacs (27 1))) "Tempo templates/snippets with in-buffer field editing" single ((:commit . "f9e048e05c2c17a59d359a7724be6b5a2f394a0e") (:authors ("Daniel Mendler" . "mail@daniel-mendler.de")) (:maintainer "Daniel Mendler" . "mail@daniel-mendler.de") (:url . "https://github.com/minad/tempel"))])
@ -4677,7 +4681,7 @@
(thinks . [(20170802 1128) ((cl-lib (0 5))) "Insert text in a think bubble." single ((:commit . "c02f236abc8c2025d9f01460b09b89ebdc96e28d") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:keywords "convenience" "quoting") (:url . "https://github.com/davep/thinks.el"))])
(thread-dump . [(20170816 1850) nil "Java thread dump viewer" single ((:commit . "204c9600242756d4b514bb5ff6293e052bf4b49d") (:authors ("Dmitry Neverov")) (:maintainer "Dmitry Neverov") (:url . "http://github.com/nd/thread-dump.el"))])
(threes . [(20160820 1242) ((emacs (24)) (seq (1 11))) "A clone of Threes (a tiny puzzle game)" single ((:commit . "6981acb30b856c77cba6aba63fefbf102cbdfbb2") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:keywords "games") (:url . "https://github.com/xuchunyang/threes.el"))])
(thrift . [(20200212 1903) ((emacs (24))) "major mode for fbthrift and Apache Thrift files" single ((:commit . "17f3954dde5c659fca72378d8687cc93fe2df5d0") (:keywords "languages"))])
(thrift . [(20200212 1903) ((emacs (24))) "major mode for fbthrift and Apache Thrift files" single ((:commit . "38e709c569bb571806563d411459795fbd523e81") (:keywords "languages"))])
(thumb-through . [(20120119 534) nil "Plain text reader of HTML documents" single ((:commit . "08d8fb720f93c6172653e035191a8fa9c3305e63") (:keywords "html"))])
(tickscript-mode . [(20171219 203) ((emacs (24 1))) "A major mode for Tickscript files" single ((:commit . "f0579f38ff14954df5002ce30ae6d4a2c978d461") (:authors ("Marc Sherry" . "msherry@gmail.com")) (:maintainer "Marc Sherry" . "msherry@gmail.com") (:keywords "languages") (:url . "https://github.com/msherry/tickscript-mode"))])
(tidal . [(20210211 1531) ((haskell-mode (16)) (emacs (24))) "Interact with TidalCycles for live coding patterns" single ((:commit . "9dbd4c9b4dd4adb550323376a25a50917c971b00") (:authors (nil . "alex@slab.org")) (:maintainer nil . "alex@slab.org") (:keywords "tools") (:url . "https://github.com/tidalcycles/Tidal"))])
@ -4711,14 +4715,14 @@
(toggle-quotes . [(20140710 926) nil "Toggle between single and double quoted string" single ((:commit . "33abc221d6887f0518337851318065cd86c34b03") (:authors ("Jim Tian" . "tianjin.sc@gmail.com")) (:maintainer "Jim Tian" . "tianjin.sc@gmail.com") (:keywords "convenience" "quotes") (:url . "https://github.com/toctan/toggle-quotes.el"))])
(toggle-test . [(20140723 537) nil "Toggle between source and test files in various programming languages" single ((:commit . "e969321f274903d705995a7d0345a257576ec5ff") (:authors ("Raghunandan Rao" . "r.raghunandan@gmail.com")) (:maintainer "Raghunandan Rao" . "r.raghunandan@gmail.com") (:keywords "tdd" "test" "toggle" "productivity") (:url . "https://github.com/rags/toggle-test"))])
(toggle-window . [(20141207 1548) nil "toggle current window size between half and full" single ((:commit . "e82c60e543933880402ede11e9423e48a17dde53") (:authors ("Kenny Liu")) (:maintainer "Kenny Liu") (:keywords "hide" "window") (:url . "https://github.com/deadghost/toggle-window"))])
(tok-theme . [(20220423 1413) ((emacs (26 1))) "Minimal theme with light and yellow color scheme" single ((:commit . "505363f07d00b671e1d886c808574e42a25b8de8") (:authors ("Topi Kettunen" . "topi@topikettunen.com")) (:maintainer "Topi Kettunen" . "topi@topikettunen.com") (:url . "https://github.com/topikettunen/tok-theme"))])
(tok-theme . [(20220424 1852) ((emacs (26 1))) "Minimal theme with light and yellow color scheme" single ((:commit . "f0bdc2aa4c6f1e463a3027a5e194f6dab3d0fda6") (:authors ("Topi Kettunen" . "topi@topikettunen.com")) (:maintainer "Topi Kettunen" . "topi@topikettunen.com") (:url . "https://github.com/topikettunen/tok-theme"))])
(tokei . [(20220422 2234) ((emacs (27 1)) (magit-section (3 3 0))) "Display codebase statistics" single ((:commit . "181021cd881eecd604a546d4a717866a81c7a511") (:authors ("Daniel Nagy <https://github.com/nagy>")) (:maintainer "Daniel Nagy" . "danielnagy@posteo.de") (:url . "https://github.com/nagy/tokei.el"))])
(tomatinho . [(20180621 1748) nil "Simple and beautiful pomodoro timer" tar ((:commit . "b53354b9b9f496c0388d6a573b06b7d6fc53d0bd") (:authors ("Konrad Scorciapino" . "scorciapino@gmail.com")) (:maintainer "Konrad Scorciapino" . "scorciapino@gmail.com") (:keywords "time" "productivity" "pomodoro technique"))])
(toml . [(20130903 1255) nil "TOML (Tom's Obvious, Minimal Language) parser" single ((:commit . "994644f9e68c383071eeee23389a7989b228c2d2") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:keywords "toml" "parser") (:url . "https://github.com/gongo/emacs-toml"))])
(toml-mode . [(20161107 1800) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing TOML files" single ((:commit . "f6c61817b00f9c4a3cab1bae9c309e0fc45cdd06") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:keywords "data" "toml") (:url . "https://github.com/dryman/toml-mode.el"))])
(tommyh-theme . [(20131004 2330) nil "A bright, bold-colored theme for emacs" single ((:commit . "46d1c69ee0a1ca7c67b569b891a2f28fed89e7d5") (:authors ("William Glass" . "william.glass@gmail.com")) (:maintainer "William Glass" . "william.glass@gmail.com"))])
(tongbu . [(20200414 507) ((emacs (25 1)) (web-server (0 1 2))) "A web server to share text or files between two devices" single ((:commit . "6f6e5c5446f0c5735357ab520b249ab97295653e") (:authors ("Xu Chunyang")) (:maintainer "Xu Chunyang") (:keywords "tools") (:url . "https://github.com/xuchunyang/tongbu.el"))])
(topspace . [(20220419 2323) ((emacs (25 1))) "Scroll down & recenter top lines / get upper margins/padding" single ((:commit . "d376bca4c8cd8e787f54e46d73389cf0a7cfafbd") (:authors ("Trevor Edwin Pogue" . "trevor.pogue@gmail.com")) (:maintainer "Trevor Edwin Pogue" . "trevor.pogue@gmail.com") (:keywords "convenience" "scrolling" "center" "cursor" "margin" "padding") (:url . "https://github.com/trevorpogue/topspace"))])
(topspace . [(20220419 2323) ((emacs (25 1))) "Scroll down & recenter top lines / get upper margins/padding" single ((:commit . "d346f7b5e0d19fe6b945bbfe64a18543f70b31e1") (:authors ("Trevor Edwin Pogue" . "trevor.pogue@gmail.com")) (:maintainer "Trevor Edwin Pogue" . "trevor.pogue@gmail.com") (:keywords "convenience" "scrolling" "center" "cursor" "margin" "padding") (:url . "https://github.com/trevorpogue/topspace"))])
(topsy . [(20210831 133) ((emacs (26 3))) "Simple sticky header" single ((:commit . "8ae0976dfdbe4461c33ed44cf1dedc2c903b0bb0") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:keywords "convenience") (:url . "https://github.com/alphapapa/topsy.el"))])
(tornado-template-mode . [(20141128 1008) nil "A major mode for editing tornado templates" single ((:commit . "667c0663dbbd279b6c345446b9f2bc50eb52b747") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))])
(torus . [(20190325 753) ((emacs (26))) "A buffer groups manager" single ((:commit . "b309da8c2eaee573a2e2572f25a08ce5da9e9990") (:authors ("Chimay")) (:maintainer "Chimay") (:keywords "files" "buffers" "groups" "persistent" "history" "layout" "tabs") (:url . "https://github.com/chimay/torus"))])
@ -4736,8 +4740,8 @@
(tramp-hdfs . [(20210526 339) ((emacs (24 4))) "Tramp extension to access hadoop/hdfs file system in Emacs" single ((:commit . "aa93bdbb3d5619c262ce53af1981edcd2a0705e5") (:authors ("Raghav Kumar Gautam" . "raghav@apache.org")) (:maintainer "Raghav Kumar Gautam" . "raghav@apache.org") (:keywords "tramp" "emacs" "hdfs" "hadoop" "webhdfs" "rest"))])
(tramp-term . [(20220412 1546) nil "Automatic setup of directory tracking in ssh sessions" single ((:commit . "e2e5375a444d4eb5d144bef12e066c02befd1352") (:authors ("Randy Morris" . "randy.morris@archlinux.us")) (:maintainer "Randy Morris" . "randy.morris@archlinux.us") (:keywords "comm" "terminals") (:url . "https://github.com/randymorris/tramp-term.el"))])
(transfer-sh . [(20200601 1708) ((emacs (24 3)) (async (1 0))) "Simple interface for sending buffer contents to transfer.sh" single ((:commit . "0621a66d00ec91a209a542c10b158095088bd44d") (:keywords "comm" "convenience" "files") (:url . "https://gitlab.com/tuedachu/transfer-sh.el"))])
(transient . [(20220423 827) ((emacs (25 1)) (compat (28 1 1 0))) "Transient commands" tar ((:commit . "d4fb853d49196081269d9cdd267a53c1c0757f23") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "extensions") (:url . "https://github.com/magit/transient"))])
(transient-dwim . [(20200812 1033) ((emacs (26 1)) (transient (0 1))) "Useful preset transient commands" single ((:commit . "de03d875dd89b1d838be67b0c44d9786adf96717") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/transient-dwim.el"))])
(transient . [(20220425 1314) ((emacs (25 1)) (compat (28 1 1 0))) "Transient commands" tar ((:commit . "84f2d12ef31ec74c85e616283926780532fed13f") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:keywords "extensions") (:url . "https://github.com/magit/transient"))])
(transient-dwim . [(20220425 1331) ((emacs (26 1)) (transient (0 1))) "Useful preset transient commands" single ((:commit . "7b6e70fb49b9d18106748202011863ebc39b864a") (:authors ("Naoya Yamashita" . "conao3@gmail.com")) (:maintainer "Naoya Yamashita" . "conao3@gmail.com") (:keywords "tools") (:url . "https://github.com/conao3/transient-dwim.el"))])
(transient-posframe . [(20210102 130) ((emacs (26 0)) (posframe (0 4 3)) (transient (0 2 0))) "Using posframe to show transient" single ((:commit . "dcd898d1d35183a7d4f2c8f0ebcb43b4f8e70ebe") (:authors ("Yanghao Xie")) (:maintainer "Yanghao Xie" . "yhaoxie@gmail.com") (:keywords "convenience" "bindings" "tooltip") (:url . "https://github.com/yanghaoxie/transient-posframe"))])
(translate-mode . [(20220402 853) ((emacs (24 3))) "Paragraph-oriented side-by-side doc translation workflow" single ((:commit . "fb73b3d928a8011a21402e2c14aa4aab56bd05ae") (:authors ("Ray Wang" . "rayw.public@gmail.com")) (:maintainer "Ray Wang" . "rayw.public@gmail.com") (:keywords "translate" "convenience" "editing") (:url . "https://github.com/rayw000/translate-mode"))])
(transmission . [(20210705 2152) ((emacs (24 4)) (let-alist (1 0 5))) "Interface to a Transmission session" single ((:commit . "a03a6f5c7b133e0a37896b6d993dd6d6d4532cc2") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu") (:keywords "comm" "tools"))])
@ -4753,15 +4757,15 @@
(tree-sitter-indent . [(20220411 1439) ((emacs (26 1)) (tree-sitter (0 12 1)) (seq (2 20))) "Provide indentation with a Tree-sitter backend" single ((:commit . "4ef246db3e4ff99f672fe5e4b416c890f885c09e") (:authors ("Felipe Lema" . "felipelema@mortemale.org")) (:maintainer "Felipe Lema" . "felipelema@mortemale.org") (:keywords "convenience" "internal") (:url . "https://codeberg.org/FelipeLema/tree-sitter-indent.el"))])
(tree-sitter-langs . [(20220328 1344) ((emacs (25 1)) (tree-sitter (0 15 0))) "Grammar bundle for tree-sitter" tar ((:commit . "0dd5e56e2f5646aa51ed0fc9eb869a8f7090228a") (:authors ("Tuấn-Anh Nguyễn" . "ubolonton@gmail.com")) (:maintainer "Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") (:keywords "languages" "tools" "parsers" "tree-sitter") (:url . "https://github.com/emacs-tree-sitter/tree-sitter-langs"))])
(treefactor . [(20200516 1631) ((emacs (26 1)) (dash (2 16 0)) (f (0 20 0)) (org (9 2 6)) (avy (0 5 0))) "Restructure your messy Org documents" single ((:commit . "75357757022a4399ab772ff0d92065bd114dabe9") (:authors ("Leo Littlebook" . "Leo.Littlebook@gmail.com")) (:maintainer "Leo Littlebook" . "Leo.Littlebook@gmail.com") (:keywords "outlines" "files" "convenience") (:url . "https://github.com/cyberthal/treefactor"))])
(treemacs . [(20220411 1944) ((emacs (26 1)) (cl-lib (0 5)) (dash (2 11 0)) (s (1 12 0)) (ace-window (0 9 0)) (pfuture (1 7)) (hydra (0 13 2)) (ht (2 2)) (cfrs (1 3 2))) "A tree style file explorer package" tar ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-all-the-icons . [(20220124 1914) ((emacs (26 1)) (all-the-icons (4 0 1)) (treemacs (0 0))) "all-the-icons integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Eric Dallo" . "ercdll1337@gmail.com")) (:maintainer "Eric Dallo" . "ercdll1337@gmail.com") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-evil . [(20211019 1654) ((emacs (26 1)) (evil (1 2 12)) (treemacs (0 0))) "Evil mode integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-icons-dired . [(20211229 1448) ((treemacs (0 0)) (emacs (26 1))) "Treemacs icons for dired" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-magit . [(20211010 1005) ((emacs (26 1)) (treemacs (0 0)) (pfuture (1 3)) (magit (2 90 0))) "Magit integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-persp . [(20220209 2117) ((emacs (26 1)) (treemacs (0 0)) (persp-mode (2 9 7)) (dash (2 11 0))) "Persp-mode integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-perspective . [(20220209 2117) ((emacs (26 1)) (treemacs (0 0)) (perspective (2 8)) (dash (2 11 0))) "Perspective integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de") ("Jason Dufair" . "jase@dufair.org")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-projectile . [(20211223 1454) ((emacs (26 1)) (projectile (0 14 0)) (treemacs (0 0))) "Projectile integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-tab-bar . [(20220221 2038) ((emacs (27 1)) (treemacs (0 0)) (dash (2 11 0))) "Tab bar integration for treemacs" single ((:commit . "6e206216cec383d47acec872a0c8ef6e70b7746b") (:authors ("Alexander Miller" . "alexanderm@web.de") ("Jason Dufair" . "jase@dufair.org") ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs . [(20220425 1217) ((emacs (26 1)) (cl-lib (0 5)) (dash (2 11 0)) (s (1 12 0)) (ace-window (0 9 0)) (pfuture (1 7)) (hydra (0 13 2)) (ht (2 2)) (cfrs (1 3 2))) "A tree style file explorer package" tar ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-all-the-icons . [(20220425 1124) ((emacs (26 1)) (all-the-icons (4 0 1)) (treemacs (0 0))) "all-the-icons integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Eric Dallo" . "ercdll1337@gmail.com")) (:maintainer "Eric Dallo" . "ercdll1337@gmail.com") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-evil . [(20211019 1654) ((emacs (26 1)) (evil (1 2 12)) (treemacs (0 0))) "Evil mode integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-icons-dired . [(20211229 1448) ((treemacs (0 0)) (emacs (26 1))) "Treemacs icons for dired" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-magit . [(20211010 1005) ((emacs (26 1)) (treemacs (0 0)) (pfuture (1 3)) (magit (2 90 0))) "Magit integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-persp . [(20220209 2117) ((emacs (26 1)) (treemacs (0 0)) (persp-mode (2 9 7)) (dash (2 11 0))) "Persp-mode integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-perspective . [(20220209 2117) ((emacs (26 1)) (treemacs (0 0)) (perspective (2 8)) (dash (2 11 0))) "Perspective integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de") ("Jason Dufair" . "jase@dufair.org")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-projectile . [(20211223 1454) ((emacs (26 1)) (projectile (0 14 0)) (treemacs (0 0))) "Projectile integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treemacs-tab-bar . [(20220221 2038) ((emacs (27 1)) (treemacs (0 0)) (dash (2 11 0))) "Tab bar integration for treemacs" single ((:commit . "82ec575b759e68256b359edd8c491bf35f6a4751") (:authors ("Alexander Miller" . "alexanderm@web.de") ("Jason Dufair" . "jase@dufair.org") ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))])
(treepy . [(20191108 2217) ((emacs (25 1))) "Generic tree traversal tools" single ((:commit . "3ac940e97f3d03e48ca9d7fcd74916a9b01c72f3") (:authors ("Daniel Barreto" . "daniel.barreto.n@gmail.com")) (:maintainer "Daniel Barreto" . "daniel.barreto.n@gmail.com") (:keywords "lisp" "maint" "tools") (:url . "https://github.com/volrath/treepy.el"))])
(treeview . [(20210723 2256) ((emacs (24 4))) "A generic tree navigation library" single ((:commit . "09c8c1d045c7c8eace61b10b6df9d2f9079de78e") (:authors ("Tilman Rassy" . "tilman.rassy@googlemail.com")) (:maintainer "Tilman Rassy" . "tilman.rassy@googlemail.com") (:keywords "lisp" "tools" "internal" "convenience") (:url . "https://github.com/tilmanrassy/emacs-treeview"))])
(trident-mode . [(20190410 2036) ((emacs (24)) (slime (20130526)) (skewer-mode (1 5 0)) (dash (1 0 3))) "Live Parenscript interaction" single ((:commit . "109a1bc10bd0c4b47679a6ca5c4cd27c7c8d4ccb") (:authors ("John Mastro" . "john.b.mastro@gmail.com")) (:maintainer "John Mastro" . "john.b.mastro@gmail.com") (:keywords "languages" "lisp" "processes" "tools") (:url . "https://github.com/johnmastro/trident-mode.el"))])
@ -5029,7 +5033,7 @@
(wordel . [(20220225 1907) ((emacs (27 1))) "An Elisp implementation of \"Wordle\" (aka \"Lingo\")" tar ((:commit . "5a1f9a45c3d1fa58c3de5183c4456572ae861d49") (:authors ("Nicholas Vollmer" . "iarchivedmywholelife@gmail.com")) (:maintainer "Nicholas Vollmer" . "iarchivedmywholelife@gmail.com") (:keywords "games") (:url . "https://github.com/progfolio/wordel"))])
(wordgen . [(20170803 1820) ((emacs (24)) (cl-lib (0 5))) "Random word generator" single ((:commit . "aacad928ae99a953e034a831dfd0ebdf7d52ac1d") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/wordgen.el"))])
(wordnut . [(20180313 443) ((emacs (24 4))) "Major mode interface to WordNet" tar ((:commit . "feac531404041855312c1a046bde7ea18c674915"))])
(wordreference . [(20220420 936) ((emacs (27 1)) (s (1 12 0))) "Interface for wordreference.com" single ((:commit . "0809575220ddfb9290829873dacf576f93222d05") (:authors ("Marty Hiatt <martianhiatus AT riseup.net>")) (:maintainer "Marty Hiatt <martianhiatus AT riseup.net>") (:keywords "convenience" "translate") (:url . "https://codeberg.org/martianh/wordreference.el"))])
(wordreference . [(20220424 1712) ((emacs (27 1)) (s (1 12 0))) "Interface for wordreference.com" single ((:commit . "33303dc1ee71bb78b6a9bf96b22b3bd6a62203a8") (:authors ("Marty Hiatt <martianhiatus AT riseup.net>")) (:maintainer "Marty Hiatt <martianhiatus AT riseup.net>") (:keywords "convenience" "translate") (:url . "https://codeberg.org/martianh/wordreference.el"))])
(wordsmith-mode . [(20210715 1517) nil "Syntax analysis and NLP text-processing in Emacs (OSX-only)" single ((:commit . "5d40ceaa2b8d41ab3634ca377ceb6a74deeb2287") (:authors ("istib" . "istib@thebati.net")) (:maintainer "istib" . "istib@thebati.net"))])
(worf . [(20220102 835) ((swiper (0 11 0)) (ace-link (0 1 0)) (hydra (0 13 0)) (zoutline (0 1 0))) "A warrior does not press so many keys! (in org-mode)" tar ((:commit . "8681241e118585824cd256e5b026978bf06c7e58") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:keywords "lisp") (:url . "https://github.com/abo-abo/worf"))])
(workgroups . [(20110726 1641) nil "workgroups for windows (for Emacs)" single ((:commit . "9572b3492ee09054dc329f64ed846c962b395e39") (:authors ("tlh" . "thunkout@gmail.com")) (:maintainer "tlh" . "thunkout@gmail.com") (:keywords "session" "management" "window-configuration" "persistence"))])
@ -5135,8 +5139,8 @@
(zig-mode . [(20211227 1108) ((emacs (24 3))) "A major mode for the Zig programming language" single ((:commit . "aa20d630b8c413dab8d6bd120ec3ed5db5c9da70") (:authors ("Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com")) (:maintainer "Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com") (:keywords "zig" "languages") (:url . "https://github.com/zig-lang/zig-mode"))])
(zim-wiki-mode . [(20211117 2000) ((emacs (25 1)) (helm-ag (0 58)) (helm-projectile (0 14 0)) (dokuwiki-mode (0 1 1)) (link-hint (0 1)) (pretty-hydra (0 2 2))) "Zim Desktop Wiki edit mode" single ((:commit . "aa906931f22c34d77c65bed31121edfef714e4e2") (:authors ("Will Foran" . "willforan+zim-wiki-mode@gmail.com")) (:maintainer "Will Foran" . "willforan+zim-wiki-mode@gmail.com") (:keywords "outlines") (:url . "https://github.com/WillForan/zim-wiki-mode"))])
(zimports . [(20211011 2059) ((emacs (26 1)) (projectile (2 1 0))) "Reformat python imports with zimports" single ((:commit . "76cf76bdc871cb0454a6fc555aeb1aa94f1b6e57") (:url . "https://github.com/schmir/zimports.el"))])
(zk . [(20220422 1230) ((emacs (24 4))) "Functions for working with Zettelkasten-style linked notes" single ((:commit . "609963f989f989dfcf0562bdda565bf2a31b9f66") (:authors ("Grant Rosson <https://github.com/localauthor>")) (:maintainer "Grant Rosson <https://github.com/localauthor>") (:url . "https://github.com/localauthor/zk"))])
(zk-index . [(20220422 1234) ((emacs (26 1)) (zk (0 3))) "Index and Desktop for zk" single ((:commit . "609963f989f989dfcf0562bdda565bf2a31b9f66") (:authors ("Grant Rosson <https://github.com/localauthor>")) (:maintainer "Grant Rosson <https://github.com/localauthor>") (:url . "https://github.com/localauthor/zk"))])
(zk . [(20220423 944) ((emacs (24 4))) "Functions for working with Zettelkasten-style linked notes" single ((:commit . "404b52829ad58155f8ba40e507334267ad95e2a1") (:authors ("Grant Rosson <https://github.com/localauthor>")) (:maintainer "Grant Rosson <https://github.com/localauthor>") (:url . "https://github.com/localauthor/zk"))])
(zk-index . [(20220423 1935) ((emacs (26 1)) (zk (0 3))) "Index and Desktop for zk" single ((:commit . "404b52829ad58155f8ba40e507334267ad95e2a1") (:authors ("Grant Rosson <https://github.com/localauthor>")) (:maintainer "Grant Rosson <https://github.com/localauthor>") (:url . "https://github.com/localauthor/zk"))])
(zlc . [(20151011 157) nil "Provides zsh like completion system to Emacs" single ((:commit . "4dd2ba267ecdeac845a7cbb3147294ee7daa25f4") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:keywords "matching" "convenience"))])
(zmq . [(20210613 343) ((cl-lib (0 5)) (emacs (26))) "ZMQ bindings in elisp" tar ((:commit . "38dc6c4119aee57666caf8f97c8a3d7f678823e0") (:authors ("Nathaniel Nicandro" . "nathanielnicandro@gmail.com")) (:maintainer "Nathaniel Nicandro" . "nathanielnicandro@gmail.com") (:keywords "comm") (:url . "https://github.com/nnicandro/emacs-zmq"))])
(znc . [(20210803 159) ((cl-lib (0 2))) "ZNC + ERC" single ((:commit . "6f0949c393b7778a96033716787d152ada32f705") (:authors ("Yaroslav Shirokov")) (:maintainer "Yaroslav Shirokov") (:url . "https://github.com/sshirokov/ZNC.el"))])

View file

@ -0,0 +1,214 @@
;;; async-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 "async" "async.el" (0 0 0 0))
;;; Generated autoloads from async.el
(autoload 'async-start-process "async" "\
Start the executable PROGRAM asynchronously named NAME. See `async-start'.
PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
process object when done. If FINISH-FUNC is nil, the future
object will return the process object when the program is
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
working directory.
\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil)
(autoload 'async-start "async" "\
Execute START-FUNC (often a lambda) in a subordinate Emacs process.
When done, the return value is passed to FINISH-FUNC. Example:
(async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222)
;; What to do when it finishes
(lambda (result)
(message \"Async process done, result should be 222: %s\"
result)))
If FINISH-FUNC is nil or missing, a future is returned that can
be inspected using `async-get', blocking until the value is
ready. Example:
(let ((proc (async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222))))
(message \"I'm going to do some work here\") ;; ....
(message \"Waiting on async process, result should be 222: %s\"
(async-get proc)))
If you don't want to use a callback, and you don't care about any
return value from the child process, pass the `ignore' symbol as
the second argument (if you don't, and never call `async-get', it
will leave *emacs* process buffers hanging around):
(async-start
(lambda ()
(delete-file \"a remote file on a slow link\" nil))
\\='ignore)
Special case:
If the output of START-FUNC is a string with properties
e.g. (buffer-string) RESULT will be transformed in a list where the
car is the string itself (without props) and the cdr the rest of
properties, this allows using in FINISH-FUNC the string without
properties and then apply the properties in cdr to this string (if
needed).
Properties handling special objects like markers are returned as
list to allow restoring them later.
See <https://github.com/jwiegley/emacs-async/issues/145> for more infos.
Note: Even when FINISH-FUNC is present, a future is still
returned except that it yields no value (since the value is
passed to FINISH-FUNC). Call `async-get' on such a future always
returns nil. It can still be useful, however, as an argument to
`async-ready' or `async-wait'.
\(fn START-FUNC &optional FINISH-FUNC)" nil nil)
(register-definition-prefixes "async" '("async-"))
;;;***
;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (0 0 0
;;;;;; 0))
;;; Generated autoloads from async-bytecomp.el
(autoload 'async-byte-recompile-directory "async-bytecomp" "\
Compile all *.el files in DIRECTORY asynchronously.
All *.elc files are systematically deleted before proceeding.
\(fn DIRECTORY &optional QUIET)" nil nil)
(defvar async-bytecomp-package-mode nil "\
Non-nil if Async-Bytecomp-Package mode is enabled.
See the `async-bytecomp-package-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 `async-bytecomp-package-mode'.")
(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil)
(autoload 'async-bytecomp-package-mode "async-bytecomp" "\
Byte compile asynchronously packages installed with package.el.
Async compilation of packages can be controlled by
`async-bytecomp-allowed-packages'.
This is a minor mode. If called interactively, toggle the
`Async-Bytecomp-Package 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 \\='async-bytecomp-package-mode)'.
The mode's hook is called both when the mode is enabled and when
it is disabled.
\(fn &optional ARG)" t nil)
(autoload 'async-byte-compile-file "async-bytecomp" "\
Byte compile Lisp code FILE asynchronously.
Same as `byte-compile-file' but asynchronous.
\(fn FILE)" t nil)
(register-definition-prefixes "async-bytecomp" '("async-"))
;;;***
;;;### (autoloads nil "dired-async" "dired-async.el" (0 0 0 0))
;;; Generated autoloads from dired-async.el
(defvar dired-async-mode nil "\
Non-nil if Dired-Async mode is enabled.
See the `dired-async-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 `dired-async-mode'.")
(custom-autoload 'dired-async-mode "dired-async" nil)
(autoload 'dired-async-mode "dired-async" "\
Do dired actions asynchronously.
This is a minor mode. If called interactively, toggle the
`Dired-Async 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 \\='dired-async-mode)'.
The mode's hook is called both when the mode is enabled and when
it is disabled.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-copy "dired-async" "\
Run dired-do-copy asynchronously.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-symlink "dired-async" "\
Run dired-do-symlink asynchronously.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-hardlink "dired-async" "\
Run dired-do-hardlink asynchronously.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-rename "dired-async" "\
Run dired-do-rename asynchronously.
\(fn &optional ARG)" t nil)
(register-definition-prefixes "dired-async" '("dired-async-"))
;;;***
;;;### (autoloads nil "smtpmail-async" "smtpmail-async.el" (0 0 0
;;;;;; 0))
;;; Generated autoloads from smtpmail-async.el
(register-definition-prefixes "smtpmail-async" '("async-smtpmail-"))
;;;***
;;;### (autoloads nil nil ("async-pkg.el") (0 0 0 0))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; async-autoloads.el ends here

View file

@ -0,0 +1,210 @@
;;; async-bytecomp.el --- Compile elisp files asynchronously -*- lexical-binding: t -*-
;; Copyright (C) 2014-2019 Free Software Foundation, Inc.
;; Authors: John Wiegley <jwiegley@gmail.com>
;; Thierry Volpiatto <thievol@posteo.net>
;; Keywords: dired async byte-compile
;; X-URL: https://github.com/jwiegley/dired-async
;; 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:
;;
;; This package provide the `async-byte-recompile-directory' function
;; which allows, as the name says to recompile a directory outside of
;; your running emacs.
;; The benefit is your files will be compiled in a clean environment without
;; the old *.el files loaded.
;; Among other things, this fix a bug in package.el which recompile
;; the new files in the current environment with the old files loaded, creating
;; errors in most packages after upgrades.
;;
;; NB: This package is advicing the function `package--compile'.
;;; Code:
(require 'cl-lib)
(require 'async)
(declare-function package-desc-name "package.el")
(declare-function package-desc-dir "package.el")
(defcustom async-bytecomp-allowed-packages 'all
"Packages in this list will be compiled asynchronously by `package--compile'.
All the dependencies of these packages will be compiled async too,
so no need to add dependencies to this list.
The value of this variable can also be the symbol `all' (default), in this case
all packages are always compiled asynchronously."
:group 'async
:type '(choice
(const :tag "All packages" all)
(repeat symbol)))
(defvar async-byte-compile-log-file
(concat user-emacs-directory "async-bytecomp.log"))
(defvar async-bytecomp-load-variable-regexp "\\`load-path\\'"
"The variable used by `async-inject-variables' when (re)compiling async.")
;;;###autoload
(defun async-byte-recompile-directory (directory &optional quiet)
"Compile all *.el files in DIRECTORY asynchronously.
All *.elc files are systematically deleted before proceeding."
(cl-loop with dir = (directory-files directory t "\\.elc\\'")
unless dir return nil
for f in dir
when (file-exists-p f) do (delete-file f))
;; Ensure async is reloaded when async.elc is deleted.
;; This happen when recompiling its own directory.
(load "async")
(let ((call-back
(lambda (&optional _ignore)
(if (file-exists-p async-byte-compile-log-file)
(let ((buf (get-buffer-create byte-compile-log-buffer))
(n 0))
(with-current-buffer buf
(goto-char (point-max))
(let ((inhibit-read-only t))
(insert-file-contents async-byte-compile-log-file)
(compilation-mode))
(display-buffer buf)
(delete-file async-byte-compile-log-file)
(unless quiet
(save-excursion
(goto-char (point-min))
(while (re-search-forward "^.*:Error:" nil t)
(cl-incf n)))
(if (> n 0)
(message "Failed to compile %d files in directory `%s'" n directory)
(message "Directory `%s' compiled asynchronously with warnings" directory)))))
(unless quiet
(message "Directory `%s' compiled asynchronously with success" directory))))))
(async-start
`(lambda ()
(require 'bytecomp)
,(async-inject-variables async-bytecomp-load-variable-regexp)
(let ((default-directory (file-name-as-directory ,directory))
error-data)
(add-to-list 'load-path default-directory)
(byte-recompile-directory ,directory 0 t)
(when (get-buffer byte-compile-log-buffer)
(setq error-data (with-current-buffer byte-compile-log-buffer
(buffer-substring-no-properties (point-min) (point-max))))
(unless (string= error-data "")
(with-temp-file ,async-byte-compile-log-file
(erase-buffer)
(insert error-data))))))
call-back)
(unless quiet (message "Started compiling asynchronously directory %s" directory))))
(defvar package-archive-contents)
(defvar package-alist)
(declare-function package-desc-reqs "package.el" (cl-x))
(defun async-bytecomp--get-package-deps (pkgs)
;; Same as `package--get-deps' but parse instead `package-archive-contents'
;; because PKG is not already installed and not present in `package-alist'.
;; However fallback to `package-alist' in case PKG no more present
;; in `package-archive-contents' due to modification to `package-archives'.
;; See issue #58.
(let ((seen '()))
(while pkgs
(let ((pkg (pop pkgs)))
(unless (memq pkg seen)
(let ((pkg-desc (cadr (or (assq pkg package-archive-contents)
(assq pkg package-alist)))))
(when pkg-desc
(push pkg seen)
(setq pkgs (append (mapcar #'car (package-desc-reqs pkg-desc))
pkgs)))))))
seen))
(defun async--package-compile (orig-fun pkg-desc &rest args)
(let ((cur-package (package-desc-name pkg-desc))
(pkg-dir (package-desc-dir pkg-desc)))
(if (or (member async-bytecomp-allowed-packages '(t all (all)))
(memq cur-package (async-bytecomp--get-package-deps
async-bytecomp-allowed-packages)))
(progn
;; FIXME: Why do we use (eq cur-package 'async) once
;; and (string= cur-package "async") afterwards?
(when (eq cur-package 'async)
(fmakunbound 'async-byte-recompile-directory))
;; Add to `load-path' the latest version of async and
;; reload it when reinstalling async.
(when (string= cur-package "async")
(cl-pushnew pkg-dir load-path)
(load "async-bytecomp"))
;; `async-byte-recompile-directory' will add directory
;; as needed to `load-path'.
(async-byte-recompile-directory (package-desc-dir pkg-desc) t))
(apply orig-fun pkg-desc args))))
;;;###autoload
(define-minor-mode async-bytecomp-package-mode
"Byte compile asynchronously packages installed with package.el.
Async compilation of packages can be controlled by
`async-bytecomp-allowed-packages'."
:group 'async
:global t
(if async-bytecomp-package-mode
(advice-add 'package--compile :around #'async--package-compile)
(advice-remove 'package--compile #'async--package-compile)))
;;;###autoload
(defun async-byte-compile-file (file)
"Byte compile Lisp code FILE asynchronously.
Same as `byte-compile-file' but asynchronous."
(interactive "fFile: ")
(let ((call-back
(lambda (&optional _ignore)
(let ((bn (file-name-nondirectory file)))
(if (file-exists-p async-byte-compile-log-file)
(let ((buf (get-buffer-create byte-compile-log-buffer))
start)
(with-current-buffer buf
(goto-char (setq start (point-max)))
(let ((inhibit-read-only t))
(insert-file-contents async-byte-compile-log-file)
(compilation-mode))
(display-buffer buf)
(delete-file async-byte-compile-log-file)
(save-excursion
(goto-char start)
(if (re-search-forward "^.*:Error:" nil t)
(message "Failed to compile `%s'" bn)
(message "`%s' compiled asynchronously with warnings" bn)))))
(message "`%s' compiled asynchronously with success" bn))))))
(async-start
`(lambda ()
(require 'bytecomp)
,(async-inject-variables async-bytecomp-load-variable-regexp)
(let ((default-directory ,(file-name-directory file)))
(add-to-list 'load-path default-directory)
(byte-compile-file ,file)
(when (get-buffer byte-compile-log-buffer)
(setq error-data (with-current-buffer byte-compile-log-buffer
(buffer-substring-no-properties (point-min) (point-max))))
(unless (string= error-data "")
(with-temp-file ,async-byte-compile-log-file
(erase-buffer)
(insert error-data))))))
call-back)))
(provide 'async-bytecomp)
;;; async-bytecomp.el ends here

View file

@ -0,0 +1,12 @@
(define-package "async" "20220318.1342" "Asynchronous processing in Emacs"
'((emacs "24.4"))
:commit "c78bab7506a70a735d2c3deab13fa87bf44a83d3" :authors
'(("John Wiegley" . "jwiegley@gmail.com"))
:maintainer
'("Thierry Volpiatto" . "thievol@posteo.net")
:keywords
'("async")
:url "https://github.com/jwiegley/emacs-async")
;; Local Variables:
;; no-byte-compile: t
;; End:

View file

@ -0,0 +1,439 @@
;;; async.el --- Asynchronous processing in Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2012-2019 Free Software Foundation, Inc.
;; Author: John Wiegley <jwiegley@gmail.com>
;; Maintainer: Thierry Volpiatto <thievol@posteo.net>
;; Created: 18 Jun 2012
;; Version: 1.9.5
;; Package-Requires: ((emacs "24.4"))
;; Keywords: async
;; X-URL: https://github.com/jwiegley/emacs-async
;; 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:
;; Adds the ability to call asynchronous functions and process with ease. See
;; the documentation for `async-start' and `async-start-process'.
;;; Code:
(eval-when-compile (require 'cl-lib))
(defgroup async nil
"Simple asynchronous processing in Emacs"
:group 'emacs)
(defcustom async-variables-noprops-function #'async--purecopy
"Default function to remove text properties in variables."
:type 'function)
(defvar async-debug nil)
(defvar async-send-over-pipe t)
(defvar async-in-child-emacs nil)
(defvar async-callback nil)
(defvar async-callback-for-process nil)
(defvar async-callback-value nil)
(defvar async-callback-value-set nil)
(defvar async-current-process nil)
(defvar async--procvar nil)
;; For emacs<29 (only exists in emacs-29+).
(defvar print-symbols-bare)
(defun async--purecopy (object)
"Remove text properties in OBJECT.
Argument OBJECT may be a list or a string, if anything else it
is returned unmodified."
(cond ((stringp object)
(substring-no-properties object))
((consp object)
(cl-loop for elm in object
;; A string.
if (stringp elm)
collect (substring-no-properties elm)
else
;; Proper lists.
if (and (consp elm) (null (cdr (last elm))))
collect (async--purecopy elm)
else
;; Dotted lists.
;; We handle here only dotted list where car and cdr
;; are atoms i.e. (x . y) and not (x . (x . y)) or
;; (x . (x y)) which should fit most cases.
if (and (consp elm) (cdr (last elm)))
collect (let ((key (car elm))
(val (cdr elm)))
(cons (if (stringp key)
(substring-no-properties key)
key)
(if (stringp val)
(substring-no-properties val)
val)))
else
collect elm))
(t object)))
(defun async-inject-variables
(include-regexp &optional predicate exclude-regexp noprops)
"Return a `setq' form that replicates part of the calling environment.
It sets the value for every variable matching INCLUDE-REGEXP and
also PREDICATE. It will not perform injection for any variable
matching EXCLUDE-REGEXP (if present) or representing a `syntax-table'
i.e. ending by \"-syntax-table\".
When NOPROPS is non nil it tries to strip out text properties of each
variable's value with `async-variables-noprops-function'.
It is intended to be used as follows:
(async-start
\\=`(lambda ()
(require \\='smtpmail)
(with-temp-buffer
(insert ,(buffer-substring-no-properties (point-min) (point-max)))
;; Pass in the variable environment for smtpmail
,(async-inject-variables \"\\\\=`\\(smtpmail\\|\\(user-\\)?mail\\)-\")
(smtpmail-send-it)))
\\='ignore)"
`(setq
,@(let (bindings)
(mapatoms
(lambda (sym)
(let* ((sname (and (boundp sym) (symbol-name sym)))
(value (and sname (symbol-value sym))))
(when (and sname
(or (null include-regexp)
(string-match include-regexp sname))
(or (null exclude-regexp)
(not (string-match exclude-regexp sname)))
(not (string-match "-syntax-table\\'" sname)))
(unless (or (stringp value)
(memq value '(nil t))
(numberp value)
(vectorp value))
(setq value `(quote ,value)))
(when noprops
(setq value (funcall async-variables-noprops-function
value)))
(when (or (null predicate)
(funcall predicate sym))
(setq bindings (cons value bindings)
bindings (cons sym bindings)))))))
bindings)))
(defalias 'async-inject-environment 'async-inject-variables)
(defun async-handle-result (func result buf)
(if (null func)
(progn
(set (make-local-variable 'async-callback-value) result)
(set (make-local-variable 'async-callback-value-set) t))
(unwind-protect
(if (and (listp result)
(eq 'async-signal (nth 0 result)))
(signal (car (nth 1 result))
(cdr (nth 1 result)))
(funcall func result))
(unless async-debug
(kill-buffer buf)))))
(defun async-when-done (proc &optional _change)
"Process sentinel used to retrieve the value from the child process."
(when (eq 'exit (process-status proc))
(with-current-buffer (process-buffer proc)
(let ((async-current-process proc))
(if (= 0 (process-exit-status proc))
(if async-callback-for-process
(if async-callback
(prog1
(funcall async-callback proc)
(unless async-debug
(kill-buffer (current-buffer))))
(set (make-local-variable 'async-callback-value) proc)
(set (make-local-variable 'async-callback-value-set) t))
;; Maybe strip out unreadable "#"; They are replaced by
;; empty string unless they are prefixing a special
;; object like a marker. See issue #145.
(goto-char (point-min))
(save-excursion
;; Transform markers in list like
;; (marker (moves after insertion) at 2338 in
;; test\.org) so that remap text properties function
;; can parse it to restitute marker.
(while (re-search-forward "#<\\([^>]*\\)>" nil t)
(replace-match (concat "(" (match-string 1) ")") t t)))
(while (re-search-forward "#(" nil t)
(replace-match "(" t t))
(goto-char (point-max))
(backward-sexp)
(async-handle-result async-callback (read (current-buffer))
(current-buffer)))
(set (make-local-variable 'async-callback-value)
(list 'error
(format "Async process '%s' failed with exit code %d"
(process-name proc) (process-exit-status proc))))
(set (make-local-variable 'async-callback-value-set) t))))))
(defun async--receive-sexp (&optional stream)
;; FIXME: Why use `utf-8-auto' instead of `utf-8-unix'? This is
;; a communication channel over which we have complete control,
;; so we get to choose exactly which encoding and EOL we use, isn't it?
(let ((sexp (decode-coding-string (base64-decode-string (read stream))
'utf-8-auto))
;; Parent expects UTF-8 encoded text.
(coding-system-for-write 'utf-8-auto))
(if async-debug
(message "Received sexp {{{%s}}}" (pp-to-string sexp)))
(setq sexp (read sexp))
(if async-debug
(message "Read sexp {{{%s}}}" (pp-to-string sexp)))
(eval sexp t)))
(defun async--insert-sexp (sexp)
(let (print-level
print-length
(print-escape-nonascii t)
(print-circle t)
;; Fix bug#153 in emacs-29 with symbol's positions.
(print-symbols-bare t))
(prin1 sexp (current-buffer))
;; Just in case the string we're sending might contain EOF
(encode-coding-region (point-min) (point-max) 'utf-8-auto)
(base64-encode-region (point-min) (point-max) t)
(goto-char (point-min)) (insert ?\")
(goto-char (point-max)) (insert ?\" ?\n)))
(defun async--transmit-sexp (process sexp)
(with-temp-buffer
(if async-debug
(message "Transmitting sexp {{{%s}}}" (pp-to-string sexp)))
(async--insert-sexp sexp)
(process-send-region process (point-min) (point-max))))
(defun async-batch-invoke ()
"Called from the child Emacs process' command line."
;; Make sure 'message' and 'prin1' encode stuff in UTF-8, as parent
;; process expects.
(let ((coding-system-for-write 'utf-8-auto))
(setq async-in-child-emacs t
debug-on-error async-debug)
(if debug-on-error
(prin1 (funcall
(async--receive-sexp (unless async-send-over-pipe
command-line-args-left))))
(condition-case err
(prin1 (funcall
(async--receive-sexp (unless async-send-over-pipe
command-line-args-left))))
(error
(prin1 (list 'async-signal err)))))))
(defun async-ready (future)
"Query a FUTURE to see if it is ready.
I.e., if no blocking would result from a call to `async-get' on that FUTURE."
(and (memq (process-status future) '(exit signal))
(let ((buf (process-buffer future)))
(if (buffer-live-p buf)
(with-current-buffer buf
async-callback-value-set)
t))))
(defun async-wait (future)
"Wait for FUTURE to become ready."
(while (not (async-ready future))
(sleep-for 0.05)))
(defun async-get (future)
"Get the value from process FUTURE when it is ready.
FUTURE is returned by `async-start' or `async-start-process' when
its FINISH-FUNC is nil."
(and future (async-wait future))
(let ((buf (process-buffer future)))
(when (buffer-live-p buf)
(with-current-buffer buf
(async-handle-result
#'identity async-callback-value (current-buffer))))))
(defun async-message-p (value)
"Return non-nil of VALUE is an async.el message packet."
(and (listp value)
(plist-get value :async-message)))
(defun async-send (&rest args)
"Send the given messages to the asychronous Emacs PROCESS."
(let ((args (append args '(:async-message t))))
(if async-in-child-emacs
(if async-callback
(funcall async-callback args))
(async--transmit-sexp (car args) (list 'quote (cdr args))))))
(defun async-receive ()
"Send the given messages to the asychronous Emacs PROCESS."
(async--receive-sexp))
;;;###autoload
(defun async-start-process (name program finish-func &rest program-args)
"Start the executable PROGRAM asynchronously named NAME. See `async-start'.
PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
process object when done. If FINISH-FUNC is nil, the future
object will return the process object when the program is
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
working directory."
(let* ((buf (generate-new-buffer (concat "*" name "*")))
(proc (let ((process-connection-type nil))
(apply #'start-process name buf program program-args))))
(with-current-buffer buf
(set (make-local-variable 'async-callback) finish-func)
(set-process-sentinel proc #'async-when-done)
(unless (string= name "emacs")
(set (make-local-variable 'async-callback-for-process) t))
proc)))
(defvar async-quiet-switch "-Q"
"The Emacs parameter to use to call emacs without config.
Can be one of \"-Q\" or \"-q\".
Default is \"-Q\" but it is sometimes useful to use \"-q\" to have a
enhanced config or some more variables loaded.")
;;;###autoload
(defun async-start (start-func &optional finish-func)
"Execute START-FUNC (often a lambda) in a subordinate Emacs process.
When done, the return value is passed to FINISH-FUNC. Example:
(async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222)
;; What to do when it finishes
(lambda (result)
(message \"Async process done, result should be 222: %s\"
result)))
If FINISH-FUNC is nil or missing, a future is returned that can
be inspected using `async-get', blocking until the value is
ready. Example:
(let ((proc (async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222))))
(message \"I'm going to do some work here\") ;; ....
(message \"Waiting on async process, result should be 222: %s\"
(async-get proc)))
If you don't want to use a callback, and you don't care about any
return value from the child process, pass the `ignore' symbol as
the second argument (if you don't, and never call `async-get', it
will leave *emacs* process buffers hanging around):
(async-start
(lambda ()
(delete-file \"a remote file on a slow link\" nil))
\\='ignore)
Special case:
If the output of START-FUNC is a string with properties
e.g. (buffer-string) RESULT will be transformed in a list where the
car is the string itself (without props) and the cdr the rest of
properties, this allows using in FINISH-FUNC the string without
properties and then apply the properties in cdr to this string (if
needed).
Properties handling special objects like markers are returned as
list to allow restoring them later.
See <https://github.com/jwiegley/emacs-async/issues/145> for more infos.
Note: Even when FINISH-FUNC is present, a future is still
returned except that it yields no value (since the value is
passed to FINISH-FUNC). Call `async-get' on such a future always
returns nil. It can still be useful, however, as an argument to
`async-ready' or `async-wait'."
(let ((sexp start-func)
;; Subordinate Emacs will send text encoded in UTF-8.
(coding-system-for-read 'utf-8-auto))
(setq async--procvar
(async-start-process
"emacs" (file-truename
(expand-file-name invocation-name
invocation-directory))
finish-func
async-quiet-switch "-l"
;; Using `locate-library' ensure we use the right file
;; when the .elc have been deleted.
(locate-library "async")
"-batch" "-f" "async-batch-invoke"
(if async-send-over-pipe
"<none>"
(with-temp-buffer
(async--insert-sexp (list 'quote sexp))
(buffer-string)))))
(if async-send-over-pipe
(async--transmit-sexp async--procvar (list 'quote sexp)))
async--procvar))
(defmacro async-sandbox(func)
"Evaluate FUNC in a separate Emacs process, synchronously."
`(async-get (async-start ,func)))
(defun async--fold-left (fn forms bindings)
(let ((res forms))
(dolist (binding bindings)
(setq res (funcall fn res
(if (listp binding)
binding
(list binding)))))
res))
(defmacro async-let (bindings &rest forms)
"Implements `let', but each binding is established asynchronously.
For example:
(async-let ((x (foo))
(y (bar)))
(message \"%s %s\" x y))
expands to ==>
(async-start (foo)
(lambda (x)
(async-start (bar)
(lambda (y)
(message \"%s %s\" x y)))))"
(declare (indent 1))
(async--fold-left
(lambda (acc binding)
(let ((fun (pcase (cadr binding)
((and (pred functionp) f) f)
(f `(lambda () ,f)))))
`(async-start ,fun
(lambda (,(car binding))
,acc))))
`(progn ,@forms)
(reverse bindings)))
(provide 'async)
;;; async.el ends here

View file

@ -0,0 +1,385 @@
;;; dired-async.el --- Asynchronous dired actions -*- lexical-binding: t -*-
;; Copyright (C) 2012-2019 Free Software Foundation, Inc.
;; Authors: John Wiegley <jwiegley@gmail.com>
;; Thierry Volpiatto <thievol@posteo.net>
;; Keywords: dired async network
;; X-URL: https://github.com/jwiegley/dired-async
;; 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:
;; This file provide a redefinition of `dired-create-file' function,
;; performs copies, moves and all what is handled by `dired-create-file'
;; in the background using a slave Emacs process,
;; by means of the async.el module.
;; To use it, put this in your .emacs:
;; (dired-async-mode 1)
;; This will enable async copy/rename etc...
;; in dired and helm.
;;; Code:
(require 'cl-lib)
(require 'dired-aux)
(require 'async)
(eval-when-compile
(defvar async-callback))
(defgroup dired-async nil
"Copy rename files asynchronously from dired."
:group 'dired)
(defcustom dired-async-env-variables-regexp
"\\`\\(tramp-\\(default\\|connection\\|remote\\)\\|ange-ftp\\)-.*"
"Variables matching this regexp will be loaded on Child Emacs."
:type 'regexp)
(defcustom dired-async-message-function 'dired-async-mode-line-message
"Function to use to notify result when operation finish.
Should take same args as `message'."
:type 'function)
(defcustom dired-async-log-file "/tmp/dired-async.log"
"File use to communicate errors from Child Emacs to host Emacs."
:type 'string)
(defcustom dired-async-mode-lighter '(:eval
(when (eq major-mode 'dired-mode)
" Async"))
"Mode line lighter used for `dired-async-mode'."
:risky t
:type 'sexp)
(defface dired-async-message
'((t (:foreground "yellow")))
"Face used for mode-line message.")
(defface dired-async-failures
'((t (:foreground "red")))
"Face used for mode-line message.")
(defface dired-async-mode-message
'((t (:foreground "Gold")))
"Face used for `dired-async--modeline-mode' lighter.")
(define-minor-mode dired-async--modeline-mode
"Notify mode-line that an async process run."
:global t
:lighter (:eval (propertize (format " [%s Async job(s) running]"
(length (dired-async-processes)))
'face 'dired-async-mode-message))
(unless dired-async--modeline-mode
(let ((visible-bell t)) (ding))))
(defun dired-async-mode-line-message (text face &rest args)
"Notify end of operation in `mode-line'."
(message nil)
(let ((mode-line-format (concat
" " (propertize
(if args
(apply #'format text args)
text)
'face face))))
(force-mode-line-update)
(sit-for 3)
(force-mode-line-update)))
(defun dired-async-processes ()
(cl-loop for p in (process-list)
when (cl-loop for c in (process-command p) thereis
(string= "async-batch-invoke" c))
collect p))
(defun dired-async-kill-process ()
(interactive)
(let* ((processes (dired-async-processes))
(proc (car (last processes))))
(and proc (delete-process proc))
(unless (> (length processes) 1)
(dired-async--modeline-mode -1))))
(defun dired-async-after-file-create (total operation failures skipped)
"Callback function used for operation handled by `dired-create-file'."
(unless (dired-async-processes)
;; Turn off mode-line notification
;; only when last process end.
(dired-async--modeline-mode -1))
(when operation
(if (file-exists-p dired-async-log-file)
(progn
(pop-to-buffer (get-buffer-create dired-log-buffer))
(goto-char (point-max))
(setq inhibit-read-only t)
(insert "Error: ")
(insert-file-contents dired-async-log-file)
(special-mode)
(shrink-window-if-larger-than-buffer)
(delete-file dired-async-log-file))
(run-with-timer
0.1 nil
(lambda ()
;; First send error messages.
(cond (failures
(funcall dired-async-message-function
"%s failed for %d of %d file%s -- See *Dired log* buffer"
'dired-async-failures
(car operation) (length failures)
total (dired-plural-s total)))
(skipped
(funcall dired-async-message-function
"%s: %d of %d file%s skipped -- See *Dired log* buffer"
'dired-async-failures
(car operation) (length skipped) total
(dired-plural-s total))))
(when dired-buffers
(cl-loop for (_f . b) in dired-buffers
when (buffer-live-p b)
do (with-current-buffer b
(when (and (not (file-remote-p default-directory nil t))
(file-exists-p default-directory))
(revert-buffer nil t)))))
;; Finally send the success message.
(funcall dired-async-message-function
"Asynchronous %s of %s on %s file%s done"
'dired-async-message
(car operation) (cadr operation)
total (dired-plural-s total)))))))
(defun dired-async-maybe-kill-ftp ()
"Return a form to kill ftp process in child emacs."
(quote
(progn
(require 'cl-lib)
(let ((buf (cl-loop for b in (buffer-list)
thereis (and (string-match
"\\`\\*ftp.*"
(buffer-name b)) b))))
(when buf (kill-buffer buf))))))
(defvar overwrite-query)
(defun dired-async-create-files (file-creator operation fn-list name-constructor
&optional _marker-char)
"Same as `dired-create-files' but asynchronous.
See `dired-create-files' for the behavior of arguments."
(setq overwrite-query nil)
(let ((total (length fn-list))
failures async-fn-list skipped callback
async-quiet-switch)
(let (to)
(dolist (from fn-list)
(setq to (funcall name-constructor from))
(if (and (equal to from)
(null (eq file-creator 'backup-file)))
(progn
(setq to nil)
(dired-log "Cannot %s to same file: %s\n"
(downcase operation) from)))
(if (not to)
(setq skipped (cons (dired-make-relative from) skipped))
(let* ((overwrite (and (null (eq file-creator 'backup-file))
(file-exists-p to)))
(dired-overwrite-confirmed ; for dired-handle-overwrite
(and overwrite
(let ((help-form `(format "\
Type SPC or `y' to overwrite file `%s',
DEL or `n' to skip to next,
ESC or `q' to not overwrite any of the remaining files,
`!' to overwrite all remaining files with no more questions." ,to)))
(dired-query 'overwrite-query "Overwrite `%s'?" to)))))
;; Handle the `dired-copy-file' file-creator specially
;; When copying a directory to another directory or
;; possibly to itself or one of its subdirectories.
;; e.g "~/foo/" => "~/test/"
;; or "~/foo/" =>"~/foo/"
;; or "~/foo/ => ~/foo/bar/")
;; In this case the 'name-constructor' have set the destination
;; TO to "~/test/foo" because the old emacs23 behavior
;; of `copy-directory' was to not create the subdirectory
;; and instead copy the contents.
;; With the new behavior of `copy-directory'
;; (similar to the `cp' shell command) we don't
;; need such a construction of the target directory,
;; so modify the destination TO to "~/test/" instead of "~/test/foo/".
(let ((destname (file-name-directory to)))
(when (and (file-directory-p from)
(file-directory-p to)
(eq file-creator 'dired-copy-file))
(setq to destname))
;; If DESTNAME is a subdirectory of FROM, not a symlink,
;; and the method in use is copying, signal an error.
(and (eq t (car (file-attributes destname)))
(eq file-creator 'dired-copy-file)
(file-in-directory-p destname from)
(error "Cannot copy `%s' into its subdirectory `%s'"
from to)))
(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.
(setq async-quiet-switch
(if (and (boundp 'tramp-cache-read-persistent-data)
async-fn-list
(cl-loop for (_from . to) in async-fn-list
thereis (file-remote-p to)))
"-q" "-Q"))
;; When failures have been printed to dired log add the date at bob.
(when (or failures skipped) (dired-log t))
;; When async-fn-list is empty that's mean only one file
;; had to be copied and user finally answer NO.
;; In this case async process will never start and callback
;; will have no chance to run, so notify failures here.
(unless async-fn-list
(cond (failures
(funcall dired-async-message-function
"%s failed for %d of %d file%s -- See *Dired log* buffer"
'dired-async-failures
operation (length failures)
total (dired-plural-s total)))
(skipped
(funcall dired-async-message-function
"%s: %d of %d file%s skipped -- See *Dired log* buffer"
'dired-async-failures
operation (length skipped) total
(dired-plural-s total)))))
;; Setup callback.
(setq callback
(lambda (&optional _ignore)
(dired-async-after-file-create
total (list operation (length async-fn-list)) failures skipped)
(when (string= (downcase operation) "rename")
(cl-loop for (file . to) in async-fn-list
for bf = (get-file-buffer file)
for destp = (file-exists-p to)
do (and bf destp
(with-current-buffer bf
(set-visited-file-name to t t))))))))
;; Start async process.
(when async-fn-list
(async-start `(lambda ()
(require 'cl-lib) (require 'dired-aux) (require 'dired-x)
,(async-inject-variables dired-async-env-variables-regexp)
(let ((dired-recursive-copies (quote always))
(dired-copy-preserve-time
,dired-copy-preserve-time))
(setq overwrite-backup-query nil)
;; Inline `backup-file' as long as it is not
;; available in emacs.
(defalias 'backup-file
;; Same feature as "cp -f --backup=numbered from to"
;; Symlinks are copied as file from source unlike
;; `dired-copy-file' which is same as cp -d.
;; Directories are omitted.
(lambda (from to ok)
(cond ((file-directory-p from) (ignore))
(t (let ((count 0))
(while (let ((attrs (file-attributes to)))
(and attrs (null (nth 0 attrs))))
(cl-incf count)
(setq to (concat (file-name-sans-versions to)
(format ".~%s~" count)))))
(condition-case err
(copy-file from to ok dired-copy-preserve-time)
(file-date-error
(dired-log "Can't set date on %s:\n%s\n" from err)))))))
;; Now run the FILE-CREATOR function on files.
(cl-loop with fn = (quote ,file-creator)
for (from . dest) in (quote ,async-fn-list)
do (condition-case err
(funcall fn from dest t)
(file-error
(dired-log "%s: %s\n" (car err) (cdr err))
nil)))
(when (get-buffer dired-log-buffer)
(dired-log t)
(with-current-buffer dired-log-buffer
(write-region (point-min) (point-max)
,dired-async-log-file))))
,(dired-async-maybe-kill-ftp))
callback)
;; Run mode-line notifications while process running.
(dired-async--modeline-mode 1)
(message "%s proceeding asynchronously..." operation))))
(defvar wdired-use-interactive-rename)
(defun dired-async-wdired-do-renames (old-fn &rest args)
;; Perhaps a better fix would be to ask for renaming BEFORE starting
;; OLD-FN when `wdired-use-interactive-rename' is non-nil. For now
;; just bind it to nil to ensure no questions will be asked between
;; each rename.
(let (wdired-use-interactive-rename)
(apply old-fn args)))
;;;###autoload
(define-minor-mode dired-async-mode
"Do dired actions asynchronously."
:lighter dired-async-mode-lighter
:global t
(if dired-async-mode
(progn
(advice-add 'dired-create-files :override #'dired-async-create-files)
(advice-add 'wdired-do-renames :around #'dired-async-wdired-do-renames))
(progn
(advice-remove 'dired-create-files #'dired-async-create-files)
(advice-remove 'wdired-do-renames #'dired-async-wdired-do-renames))))
(defmacro dired-async--with-async-create-files (&rest body)
"Evaluate BODY with dired-create-files set to dired-async-create-files."
(declare (indent 0))
`(cl-letf (((symbol-function 'dired-create-files) #'dired-async-create-files))
,@body))
;;;###autoload
(defun dired-async-do-copy (&optional arg)
"Run dired-do-copy asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-copy arg)))
;;;###autoload
(defun dired-async-do-symlink (&optional arg)
"Run dired-do-symlink asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-symlink arg)))
;;;###autoload
(defun dired-async-do-hardlink (&optional arg)
"Run dired-do-hardlink asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-hardlink arg)))
;;;###autoload
(defun dired-async-do-rename (&optional arg)
"Run dired-do-rename asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-rename arg)))
(provide 'dired-async)
;;; dired-async.el ends here

View file

@ -0,0 +1,71 @@
;;; smtpmail-async.el --- Send e-mail with smtpmail.el asynchronously -*- lexical-binding: t -*-
;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
;; Author: John Wiegley <jwiegley@gmail.com>
;; Created: 18 Jun 2012
;; Keywords: email async
;; X-URL: https://github.com/jwiegley/emacs-async
;; 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:
;; Send e-mail with smtpmail.el asynchronously. To use:
;;
;; (require 'smtpmail-async)
;;
;; (setq send-mail-function 'async-smtpmail-send-it
;; message-send-mail-function 'async-smtpmail-send-it)
;;
;; This assumes you already have smtpmail.el working.
;;; Code:
(defgroup smtpmail-async nil
"Send e-mail with smtpmail.el asynchronously"
:group 'smptmail)
(require 'async)
(require 'smtpmail)
(require 'message)
(defvar async-smtpmail-before-send-hook nil
"Hook running in the child emacs in `async-smtpmail-send-it'.
It is called just before calling `smtpmail-send-it'.")
(defun async-smtpmail-send-it ()
(let ((to (message-field-value "To"))
(buf-content (buffer-substring-no-properties
(point-min) (point-max))))
(message "Delivering message to %s..." to)
(async-start
`(lambda ()
(require 'smtpmail)
(with-temp-buffer
(insert ,buf-content)
(set-buffer-multibyte nil)
;; Pass in the variable environment for smtpmail
,(async-inject-variables
"\\`\\(smtpmail\\|async-smtpmail\\|\\(user-\\)?mail\\)-\\|auth-sources\\|epg\\|nsm"
nil "\\`\\(mail-header-format-function\\|smtpmail-address-buffer\\|mail-mode-abbrev-table\\)")
(run-hooks 'async-smtpmail-before-send-hook)
(smtpmail-send-it)))
(lambda (&optional _ignore)
(message "Delivering message to %s...done" to)))))
(provide 'smtpmail-async)
;;; smtpmail-async.el ends here

View file

@ -0,0 +1,8 @@
;;; 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 not docstrings))))
(emacs-lisp-mode . ((mode . bug-reference-prog)
(indent-tabs-mode . nil))))

View file

@ -0,0 +1,249 @@
#!/usr/bin/env sh
## Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
##
## 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
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
;;
-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=$(ls -l "$0" | awk '{print $11}')
if [ ! -z "$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)
(defvar bootstrap-version)
(let* ((packages "$LOAD_PACKAGES")
(pkg-list (and packages
(not (equal packages ""))
(split-string packages ",")))
(straight-path (expand-file-name "straight/build/" user-emacs-directory))
(async-path (expand-file-name "straight/build/async" user-emacs-directory))
(bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(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"))
(add-to-list 'package-directory-list (directory-file-name
(file-name-directory
(directory-file-name default-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))
(mapcar (lambda (p) (list (intern p) t)) load-packages)))))
(package-initialize))
(add-to-list 'load-path (file-name-directory (file-truename "$0")))
(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)
(require 'helm-config)
(helm-mode 1)
(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 -Q -l "$CONF_FILE" "$@"

View file

@ -0,0 +1,289 @@
;;; helm-adaptive.el --- Adaptive Sorting of Candidates. -*- lexical-binding: t -*-
;; Original Author: Tamas Patrovics
;; Copyright (C) 2007 Tamas Patrovics
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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
:group 'helm-adapt)
(defcustom helm-adaptive-history-length 50
"Maximum number of candidates stored for a source."
:type 'number
:group 'helm-adapt)
(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."
:group 'helm-adapt
: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."
:group 'helm-adapt
:require 'helm-adaptive
: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
(cl-subseq (cdr selection-info) 0 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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,795 @@
;;; helm-bookmark.el --- Helm for Emacs regular Bookmarks. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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")
(defgroup helm-bookmark nil
"Predefined configurations for `helm.el'."
:group 'helm)
(defcustom helm-bookmark-show-location nil
"Show location of bookmark on display."
:group 'helm-bookmark
: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'."
:group 'helm-bookmark
:type '(repeat (choice symbol)))
(defcustom helm-bookmark-use-icon nil
"Display candidates with an icon with `all-the-icons' when non nil."
:type 'boolean
:group 'helm-bookmark)
(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)
(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)
(defface helm-bookmark-gnus
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "magenta"))
"Face used for Gnus bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-man
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "Orange4"))
"Face used for Woman/man bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-file
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "Deepskyblue2"))
"Face used for file bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-file-not-found
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "Slategray4"))
"Face used for file bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-directory
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:inherit helm-ff-directory))
"Face used for file bookmarks."
:group 'helm-bookmark)
(defface helm-bookmark-addressbook
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "tomato"))
"Face used for addressbook bookmarks."
:group 'helm-bookmark)
(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-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
(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)))))
(defun helm-bookmark-toggle-filename ()
"Toggle bookmark location visibility."
(interactive)
(with-helm-alive-p
(helm-set-attr 'toggle-filename
'(helm-bookmark-toggle-filename-1 . never-split))
(helm-execute-persistent-action 'toggle-filename)))
(put 'helm-bookmark-toggle-filename 'helm-only t)
(defun helm-bookmark-jump (candidate)
"Jump to bookmark action."
(let ((current-prefix-arg helm-current-prefix-arg)
non-essential)
(bookmark-jump candidate)))
(defun helm-bookmark-jump-other-frame (candidate)
"Jump to bookmark in other frame action."
(let ((current-prefix-arg helm-current-prefix-arg)
non-essential)
(bookmark-jump candidate 'switch-to-buffer-other-frame)))
(defun helm-bookmark-jump-other-window (candidate)
"Jump to bookmark in other window action."
(let (non-essential)
(bookmark-jump-other-window candidate)))
;;; 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)))
(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."
(eq (bookmark-get-handler bookmark) 'mu4e-bookmark-jump))
(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)))
(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)))
(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)))
(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 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)
;;;; Filtered bookmark sources
;;
;;
(defclass helm-source-filtered-bookmarks (helm-source-in-buffer helm-type-bookmark)
((filtered-candidate-transformer
:initform '(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))))
;;; W3m bookmarks.
;;
(defun helm-bookmark-w3m-setup-alist ()
"Specialized filter function for bookmarks w3m."
(helm-bookmark-filter-setup-alist 'helm-bookmark-w3m-bookmark-p))
(defvar helm-source-bookmark-w3m
(helm-make-source "Bookmark W3m" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-w3m-setup-alist)))))
;;; Images
;;
(defun helm-bookmark-images-setup-alist ()
"Specialized filter function for images bookmarks."
(helm-bookmark-filter-setup-alist 'helm-bookmark-image-bookmark-p))
(defvar helm-source-bookmark-images
(helm-make-source "Bookmark Images" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-images-setup-alist)))))
;;; 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))
(defvar helm-source-bookmark-man
(helm-make-source "Bookmark Woman&Man" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-man-setup-alist)))))
;;; 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))
(defvar helm-source-bookmark-org
(helm-make-source " Bookmarked Org files" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-org-setup-alist)))))
;;; Gnus
;;
(defun helm-bookmark-gnus-setup-alist ()
"Specialized filter function for bookmarks gnus."
(helm-bookmark-filter-setup-alist 'helm-bookmark-gnus-bookmark-p))
(defvar helm-source-bookmark-gnus
(helm-make-source "Bookmark Gnus" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-gnus-setup-alist)))))
;;; Mu4e
;;
(defun helm-bookmark-mu4e-setup-alist ()
(helm-bookmark-filter-setup-alist 'helm-bookmark-mu4e-bookmark-p))
(defvar helm-source-bookmark-mu4e
(helm-make-source "Bookmark Mu4e" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-mu4e-setup-alist)))))
;;; Info
;;
(defun helm-bookmark-info-setup-alist ()
"Specialized filter function for bookmarks info."
(helm-bookmark-filter-setup-alist 'helm-bookmark-info-bookmark-p))
(defvar helm-source-bookmark-info
(helm-make-source "Bookmark Info" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-info-setup-alist)))))
;;; 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))
(defvar helm-source-bookmark-files&dirs
(helm-make-source "Bookmark Files&Directories" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-local-files-setup-alist)))))
;;; 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)))
(defun helm-bookmark-run-browse-project ()
"Run `helm-bookmark-browse-project' from keyboard."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-bookmark-browse-project)))
(put 'helm-bookmark-run-browse-project 'helm-only t)
(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))
(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
unless (memq action '(helm-bookmark-jump-other-frame
helm-bookmark-jump-other-window))
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)
())
(defvar helm-source-bookmark-helm-find-files
(helm-make-source "Bookmark helm-find-files sessions" 'helm-bookmark-find-files-class
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-helm-find-files-setup-alist)))
:persistent-action (lambda (_candidate) (ignore))
:persistent-help "Do nothing"))
;;; Uncategorized bookmarks
;;
(defun helm-bookmark-uncategorized-setup-alist ()
"Specialized filter function for uncategorized bookmarks."
(helm-bookmark-filter-setup-alist 'helm-bookmark-uncategorized-bookmark-p))
(defvar helm-source-bookmark-uncategorized
(helm-make-source "Bookmark uncategorized" 'helm-source-filtered-bookmarks
:init (lambda ()
(bookmark-maybe-load-default-file)
(helm-init-candidates-in-buffer
'global (helm-bookmark-uncategorized-setup-alist)))))
;;; 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)
(all-the-icons-octicon "file-directory"))
((and isfile isinfo) (all-the-icons-octicon "info"))
(isfile (all-the-icons-icon-for-file isfile))
((or iswoman isman)
(all-the-icons-fileicon "man-page"))
((or isgnus ismu4e)
(all-the-icons-octicon "mail-read"))))
;; 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))
(new-name (read-from-minibuffer "Name: " bookmark-name))
(new-loc (read-from-minibuffer "FileName or Location: "
(or bookmark-fname
(if (consp bookmark-loc)
(car bookmark-loc)
bookmark-loc))))
(docid (and (eq handler 'mu4e-bookmark-jump)
(read-number "Docid: " (cdr bookmark-loc)))))
(when docid
(setq new-loc (cons new-loc docid)))
(when (and (not (equal new-name "")) (not (equal new-loc ""))
(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) 'location new-loc)
(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))
(defun helm-bookmark-run-edit ()
"Run `helm-bookmark-edit-bookmark' from keyboard."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-bookmark-edit-bookmark)))
(put 'helm-bookmark-run-edit 'helm-only t)
(defun helm-bookmark-run-jump-other-frame ()
"Jump to bookmark other frame from keyboard."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-bookmark-jump-other-frame)))
(put 'helm-bookmark-run-jump-other-frame 'helm-only t)
(defun helm-bookmark-run-jump-other-window ()
"Jump to bookmark from keyboard."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-bookmark-jump-other-window)))
(put 'helm-bookmark-run-jump-other-window 'helm-only t)
(defun helm-bookmark-run-delete ()
"Delete bookmark from keyboard."
(interactive)
(with-helm-alive-p
(when (y-or-n-p "Delete bookmark(s)?")
(helm-exit-and-execute-action 'helm-delete-marked-bookmarks))))
(put 'helm-bookmark-run-delete 'helm-only t)
(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."
(cl-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)
(when helm-bookmark-use-icon
(require 'all-the-icons))
(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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,167 @@
;;; helm-color.el --- colors and faces -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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) 'face)
(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)))
(defun helm-color-run-insert-name ()
"Insert name of color from `helm-source-colors'."
(interactive)
(with-helm-alive-p (helm-exit-and-execute-action 'helm-color-insert-name)))
(put 'helm-color-run-insert-name 'helm-only t)
(defun helm-color-run-kill-name ()
"Kill name of color from `helm-source-colors'."
(interactive)
(with-helm-alive-p (helm-exit-and-execute-action 'helm-color-kill-name)))
(put 'helm-color-run-kill-name 'helm-only t)
(defun helm-color-run-insert-rgb ()
"Insert RGB of color from `helm-source-colors'."
(interactive)
(with-helm-alive-p (helm-exit-and-execute-action 'helm-color-insert-rgb)))
(put 'helm-color-run-insert-rgb 'helm-only t)
(defun helm-color-run-kill-rgb ()
"Kill RGB of color from `helm-source-colors'."
(interactive)
(with-helm-alive-p (helm-exit-and-execute-action 'helm-color-kill-rgb)))
(put 'helm-color-run-kill-rgb 'helm-only t)
(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

View file

@ -0,0 +1,230 @@
;;; helm-comint.el --- Comint prompt navigation for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2020 Pierre Neidhardt <mail@ambrevar.xyz>
;; 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:
;;
;; You can bind this as follows in .emacs:
;;
;; (add-hook 'comint-mode-hook
;; (lambda ()
;; (define-key comint-mode-map (kbd "M-s f") 'helm-comint-prompts-all)))
;;; Code:
(require 'cl-lib)
(require 'helm)
(require 'helm-lib)
(require 'helm-help)
(require 'helm-elisp)
;;; Comint prompts
;;
(defface helm-comint-prompts-promptidx
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
(:foreground "cyan")))
"Face used to highlight comint prompt index."
:group 'helm-comint-faces)
(defface helm-comint-prompts-buffer-name
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
(:foreground "green")))
"Face used to highlight comint buffer name."
:group 'helm-comint-faces)
(defcustom helm-comint-prompts-promptidx-p t
"Show prompt number."
:group 'helm-comint
:type 'boolean)
(defcustom helm-comint-mode-list '(comint-mode slime-repl-mode sly-mrepl-mode sql-interactive-mode)
"Supported modes for prompt navigation.
Derived modes (e.g., Geiser's REPL) are automatically supported."
:group 'helm-comint
:type '(repeat (choice symbol)))
(defcustom helm-comint-next-prompt-function '((sly-mrepl-mode . (lambda ()
(sly-mrepl-next-prompt)
(point))))
"Alist of (MODE . NEXT-PROMPT-FUNCTION) to use.
If the current major mode is a key in this list, the associated
function will be used to navigate the prompts.
The function must return the point after the prompt.
Otherwise (comint-next-prompt 1) will be used."
:group 'helm-comint
:type '(alist :key-type symbol :value-type function))
(defcustom helm-comint-max-offset 400
"Max number of chars displayed per candidate in comint-input-ring browser.
When t, don't truncate candidate, show all.
By default it is approximatively the number of bits contained in
five lines of 80 chars each i.e 80*5.
Note that if you set this to nil multiline will be disabled, i.e
you will not have anymore separators between candidates."
:type '(choice (const :tag "Disabled" t)
(integer :tag "Max candidate offset"))
:group 'helm-misc)
(defvar helm-comint-prompts-keymap
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "C-c o") 'helm-comint-prompts-other-window)
(define-key map (kbd "C-c C-o") 'helm-comint-prompts-other-frame)
map)
"Keymap for `helm-comint-prompt-all'.")
(defun helm-comint-prompts-list (mode &optional buffer)
"List the prompts in BUFFER in mode MODE.
Return a list of (\"prompt\" (point) (buffer-name) prompt-index))
E.g. (\"ls\" 162 \"*shell*\" 3).
If BUFFER is nil, use current buffer."
(with-current-buffer (or buffer (current-buffer))
(when (derived-mode-p mode)
(save-excursion
(goto-char (point-min))
(let (result (count 1))
(save-mark-and-excursion
(helm-awhile (and (not (eobp))
(helm-aif (alist-get major-mode helm-comint-next-prompt-function)
(funcall it)
(comint-next-prompt 1)))
(push (list (buffer-substring-no-properties
it (point-at-eol))
it (buffer-name) count)
result)
(setq count (1+ count))))
(nreverse result))))))
(defun helm-comint-prompts-list-all (mode)
"List the prompts of all buffers in mode MODE.
See `helm-comint-prompts-list'."
(cl-loop for b in (buffer-list)
append (helm-comint-prompts-list mode b)))
(defun helm-comint-prompts-transformer (candidates &optional all)
;; ("ls" 162 "*shell*" 3) => ("*shell*:3:ls" . ("ls" 162 "*shell*" 3))
(cl-loop for (prt pos buf id) in candidates
collect `(,(concat
(when all
(concat (propertize
buf
'face 'helm-comint-prompts-buffer-name)
":"))
(when helm-comint-prompts-promptidx-p
(concat (propertize
(number-to-string id)
'face 'helm-comint-prompts-promptidx)
":"))
prt)
. ,(list prt pos buf id))))
(defun helm-comint-prompts-all-transformer (candidates)
(helm-comint-prompts-transformer candidates t))
(cl-defun helm-comint-prompts-goto (candidate &optional (action 'switch-to-buffer))
;; Candidate format: ("ls" 162 "*shell*" 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-comint-prompts-goto-other-window (candidate)
(helm-comint-prompts-goto candidate 'switch-to-buffer-other-window))
(defun helm-comint-prompts-goto-other-frame (candidate)
(helm-comint-prompts-goto candidate 'switch-to-buffer-other-frame))
(defun helm-comint-prompts-other-window ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-comint-prompts-goto-other-window)))
(put 'helm-comint-prompts-other-window 'helm-only t)
(defun helm-comint-prompts-other-frame ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-comint-prompts-goto-other-frame)))
(put 'helm-comint-prompts-other-frame 'helm-only t)
;;;###autoload
(defun helm-comint-prompts ()
"Pre-configured `helm' to browse the prompts of the current comint buffer."
(interactive)
(if (apply 'derived-mode-p helm-comint-mode-list)
(helm :sources
(helm-build-sync-source "Comint prompts"
:candidates (helm-comint-prompts-list major-mode)
:candidate-transformer 'helm-comint-prompts-transformer
:action '(("Go to prompt" . helm-comint-prompts-goto)))
:buffer "*helm comint prompts*")
(message "Current buffer is not a comint buffer")))
;;;###autoload
(defun helm-comint-prompts-all ()
"Pre-configured `helm' to browse the prompts of all comint sessions."
(interactive)
(if (apply 'derived-mode-p helm-comint-mode-list)
(helm :sources
(helm-build-sync-source "All comint prompts"
:candidates (helm-comint-prompts-list-all major-mode)
:candidate-transformer 'helm-comint-prompts-all-transformer
:action (quote (("Go to prompt" . helm-comint-prompts-goto)
("Go to prompt in other window `C-c o`" .
helm-comint-prompts-goto-other-window)
("Go to prompt in other frame `C-c C-o`" .
helm-comint-prompts-goto-other-frame)))
:keymap helm-comint-prompts-keymap)
:buffer "*helm comint all prompts*")
(message "Current buffer is not a comint buffer")))
;;; Comint history
;;
;;
(defun helm-comint-input-ring-action (candidate)
"Default action for comint history."
(with-helm-current-buffer
(delete-region (comint-line-beginning-position) (point-max))
(insert candidate)))
(defvar helm-source-comint-input-ring
(helm-build-sync-source "Comint history"
:candidates (lambda ()
(with-helm-current-buffer
(cl-loop for elm in (ring-elements comint-input-ring)
unless (string= elm "")
collect elm)))
:action 'helm-comint-input-ring-action
;; Multiline does not work for `shell' because of an Emacs bug.
;; It works in other REPLs like Geiser.
:multiline 'helm-comint-max-offset)
"Source that provides Helm completion against `comint-input-ring'.")
;;;###autoload
(defun helm-comint-input-ring ()
"Preconfigured `helm' that provide completion of `comint' history."
(interactive)
(when (or (derived-mode-p 'comint-mode)
(member major-mode helm-comint-mode-list))
(helm :sources 'helm-source-comint-input-ring
:input (buffer-substring-no-properties (comint-line-beginning-position)
(point-at-eol))
:buffer "*helm comint history*")))
(provide 'helm-comint)
;;; helm-comint.el ends here

View file

@ -0,0 +1,413 @@
;;; helm-command.el --- Helm execute-exended-command. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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)
(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."
:group 'helm-command
:type 'boolean)
(defcustom helm-M-x-reverse-history nil
"The history source of `helm-M-x' appear in second position when non-nil."
:group 'helm-command
:type 'boolean)
(defcustom helm-M-x-fuzzy-match t
"Helm-M-x fuzzy matching when non nil."
:group 'helm-command
:type 'boolean)
(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))
(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."
:group 'helm-command
: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-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 max-len = (when helm-M-x-show-short-doc
(buffer-local-value 'helm-candidate-buffer-longest-len
(helm-candidate-buffer)))
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 max-len
(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)
(format "%s%s%s %s"
disp
(if doc (make-string (+ 4 (- max-len (+ (length cand)))) ? ) "")
(if doc (propertize doc 'face 'helm-M-x-short-doc) "")
(propertize
" " 'display
(propertize local-key 'face 'helm-M-x-key))))
((string-match "^M-x" key)
(format "%s%s%s"
disp
(if doc (make-string (+ 4 (- max-len (+ (length cand)))) ? ) "")
(if doc (propertize doc 'face 'helm-M-x-short-doc) "")))
(t (format "%s%s%s %s"
disp
(if doc (make-string (+ 4 (- max-len (+ (length cand)))) ? ) "")
(if doc (propertize doc 'face 'helm-M-x-short-doc) "")
(propertize
" " 'display
(propertize key 'face 'helm-M-x-key)))))
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
(point-at-bol) (point-at-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-no-sort)
(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.
When `helm-M-x-use-completion-styles' is used, Emacs
`completion-styles' mechanism is used, otherwise standard helm
completion and helm fuzzy matching are used together.
Helm completion is not provided when executing or defining kbd
macros.
Arg COLLECTION should be an `obarray' but can be any object
suitable for `try-completion'. Arg PREDICATE is a function that
default to `commandp' see also `try-completion'. 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 (cond
((eq helm-M-x-prefix-argument '-) "- ")
((and (consp helm-M-x-prefix-argument)
(eq (car helm-M-x-prefix-argument) 4)) "C-u ")
((and (consp helm-M-x-prefix-argument)
(integerp (car helm-M-x-prefix-argument)))
(format "%d " (car helm-M-x-prefix-argument)))
((integerp helm-M-x-prefix-argument)
(format "%d " helm-M-x-prefix-argument)))
"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))
(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)
;; 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

View file

@ -0,0 +1,34 @@
;;; helm-config.el --- Applications library for `helm.el' -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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:
;;
;; Requiring this file is not needed when using a package manager to
;; install helm as this one will take care of loading the autoload
;; file.
;;; Code:
;;; Load the autoload file
;; It should have been generated either by
;; the package manager or the make file.
(load "helm-autoloads" nil t)
(provide 'helm-config)
;;; helm-config.el ends here

View file

@ -0,0 +1,396 @@
;;; helm-dabbrev.el --- Helm implementation of dabbrev. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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'."
:group 'helm-dabbrev
: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."
:group 'helm-dabbrev
: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."
:group 'helm-dabbrev
: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'."
:group 'helm-dabbrev
: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)
:group 'helm-dabbrev)
(defcustom helm-dabbrev-lineno-around 30
"Search first in this number of lines before and after point."
:group 'helm-dabbrev
:type 'integer)
(defcustom helm-dabbrev-cycle-threshold 5
"Number of time helm-dabbrev cycle before displaying helm completion.
When nil or 0 disable cycling."
:group 'helm-dabbrev
: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)."
:group 'helm-dabbrev
: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 (point-at-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

View file

@ -0,0 +1,84 @@
;;; helm-easymenu.el --- Helm easymenu definitions. -*- lexical-binding: t -*-
;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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])
("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-list-elisp-packages t]
["Elisp packages no fetch" helm-list-elisp-packages-no-fetch 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

View file

@ -0,0 +1,499 @@
;;; helm-elisp-package.el --- helm interface for package.el -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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 'package)
(defgroup helm-el-package nil
"helm elisp packages."
:group 'helm)
(defcustom helm-el-package-initial-filter 'all
"Show only installed, upgraded or all packages at startup."
:group 'helm-el-package
:type '(radio :tag "Initial filter for elisp packages"
(const :tag "Show all packages" all)
(const :tag "Show installed packages" installed)
(const :tag "Show not installed packages" uninstalled)
(const :tag "Show upgradable packages" upgrade)))
(defcustom helm-el-truncate-lines t
"Truncate lines in `helm-buffer' when non-nil."
:group 'helm-el-package
:type 'boolean)
(defcustom helm-el-package-upgrade-on-start nil
"Show package upgrades on startup when non nil."
:group 'helm-el-package
:type 'boolean)
(defcustom helm-el-package-autoremove-on-start nil
"Try to autoremove no more needed packages on startup.
See `package-autoremove'."
:group 'helm-el-package
:type 'boolean)
;; internals vars
(defvar helm-el-package--show-only 'all)
(defvar helm-el-package--initialized-p nil)
(defvar helm-el-package--tabulated-list nil)
(defvar helm-el-package--upgrades nil)
(defvar helm-el-package--removable-packages nil)
;; Shutup bytecompiler for emacs-24*
(defvar package-menu-async) ; Only available on emacs-25.
(defvar helm-marked-buffer-name)
(declare-function async-byte-recompile-directory "ext:async-bytecomp.el")
(declare-function with-helm-display-marked-candidates "helm-utils.el")
(defun helm-el-package--init ()
;; In emacs-27 package-show-package-list returns an empty buffer
;; until package-initialize have been called.
(unless (or package--initialized
(null (boundp 'package-quickstart)))
(package-initialize))
(let (package-menu-async
(inhibit-read-only t))
(when (null package-alist)
(setq helm-el-package--show-only 'all))
(unless (consp package-selected-packages)
(helm-aif (package--find-non-dependencies)
(setq package-selected-packages it)))
(when (and (setq helm-el-package--removable-packages
(package--removable-packages))
helm-el-package-autoremove-on-start)
(package-autoremove))
(unwind-protect
(progn
(save-selected-window
(if helm-el-package--initialized-p
;; Use this as `list-packages' doesn't work
;; properly (empty buffer) when called from lisp
;; with 'no-fetch (emacs-25 WA).
(package-show-package-list)
(when helm--force-updating-p (message "Refreshing packages list..."))
(list-packages helm-el-package--initialized-p))
(setq helm-el-package--initialized-p t)
(message nil))
(helm-init-candidates-in-buffer
'global
(with-current-buffer (get-buffer "*Packages*")
(setq helm-el-package--tabulated-list tabulated-list-entries)
(remove-text-properties (point-min) (point-max)
'(read-only button follow-link category))
(goto-char (point-min))
(while (re-search-forward "^[ \t]+" nil t)
(replace-match ""))
(buffer-string)))
(setq helm-el-package--upgrades (helm-el-package-menu--find-upgrades))
(if helm--force-updating-p
(if helm-el-package--upgrades
(message "Refreshing packages list done, [%d] package(s) to upgrade"
(length helm-el-package--upgrades))
(message "Refreshing packages list done, no upgrades available"))
(setq helm-el-package--show-only (if (and helm-el-package-upgrade-on-start
helm-el-package--upgrades)
'upgrade
helm-el-package-initial-filter))))
(kill-buffer "*Packages*"))))
(defun helm-el-package-describe (candidate)
(let ((id (get-text-property 0 'tabulated-list-id candidate)))
(describe-package (package-desc-name id))))
(defun helm-el-package-visit-homepage (candidate)
(let* ((id (get-text-property 0 'tabulated-list-id candidate))
(pkg (package-desc-name id))
(desc (cadr (assoc pkg package-archive-contents)))
(extras (package-desc-extras desc))
(url (and (listp extras) (cdr-safe (assoc :url extras)))))
(if (stringp url)
(browse-url url)
(message "Package %s has no homepage"
(propertize (symbol-name pkg)
'face 'font-lock-keyword-face)))))
(defun helm-el-run-visit-homepage ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-el-package-visit-homepage)))
(put 'helm-el-run-visit-homepage 'helm-only t)
(defun helm-elisp-package--pkg-name (pkg)
(if (package-desc-p pkg)
(package-desc-name pkg)
pkg))
(defun helm-el-package-install-1 (pkg-list)
(cl-loop with mkd = pkg-list
for p in mkd
for id = (get-text-property 0 'tabulated-list-id p)
for name = (helm-elisp-package--pkg-name id)
do (package-install id t)
when (helm-aand (assq name package-alist)
(package-desc-dir (cadr it))
(file-exists-p it))
collect id into installed-list and
do (unless (package--user-selected-p name)
(package--save-selected-packages
(cons name package-selected-packages)))
finally do (message (format "%d packages installed:\n(%s)"
(length installed-list)
(mapconcat #'package-desc-full-name
installed-list ", ")))))
(defun helm-el-package-install (_candidate)
(helm-el-package-install-1 (helm-marked-candidates)))
(defun helm-el-run-package-install ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-el-package-install)))
(put 'helm-el-run-package-install 'helm-only t)
(defun helm-el-package-uninstall-1 (pkg-list &optional force)
(cl-loop with mkd = pkg-list
for p in mkd
for id = (get-text-property 0 'tabulated-list-id p)
do
(condition-case-unless-debug err
(package-delete id force)
(error (message (cadr err))))
;; Seems like package-descs are symbols with props instead of
;; vectors in emacs-27, use package-desc-name to ensure
;; compatibility in all emacs versions.
unless (assoc (package-desc-name id) package-alist)
collect id into delete-list
finally do (if delete-list
(message (format "%d packages deleted:\n(%s)"
(length delete-list)
(mapconcat #'package-desc-full-name
delete-list ", ")))
"No package deleted")))
(defun helm-el-package-uninstall (_candidate)
(helm-el-package-uninstall-1 (helm-marked-candidates) helm-current-prefix-arg))
(defun helm-el-run-package-uninstall ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-el-package-uninstall)))
(put 'helm-el-run-package-uninstall 'helm-only t)
(defun helm-el-package-menu--find-upgrades ()
(cl-loop for entry in helm-el-package--tabulated-list
for pkg-desc = (car entry)
for status = (package-desc-status pkg-desc)
;; A dependency.
when (string= status "dependency")
collect pkg-desc into dependencies
;; An installed package used as dependency (user have
;; installed this package explicitely).
when (package--used-elsewhere-p pkg-desc)
collect pkg-desc into installed-as-dep
;; An installed package.
when (member status '("installed" "unsigned"))
collect pkg-desc into installed
when (member status '("available" "new"))
collect (cons (package-desc-name pkg-desc) pkg-desc) into available
finally return
;; Always try to upgrade dependencies before installed.
(cl-loop with all = (append dependencies installed-as-dep installed)
for pkg in all
for name = (package-desc-name pkg)
for avail-pkg = (assq name available)
when (and avail-pkg
(version-list-<
(package-desc-version pkg)
(package-desc-version (cdr avail-pkg))))
collect avail-pkg)))
(defun helm-el-package--user-installed-p (package)
"Return non-nil if PACKAGE is a user-installed package."
(let* ((assoc (assq package package-alist))
(pkg-desc (and assoc (cadr assoc)))
(dir (and pkg-desc (package-desc-dir pkg-desc))))
(when dir
(file-in-directory-p dir package-user-dir))))
(defun helm-el-package-upgrade-1 (pkg-list)
(cl-loop for p in pkg-list
for pkg-desc = (car p)
for pkg-name = (package-desc-name pkg-desc)
for upgrade = (cdr (assq pkg-name
helm-el-package--upgrades))
do
(cond (;; Install.
(equal pkg-desc upgrade)
(message "Installing package `%s'" pkg-name)
(package-install pkg-desc t))
(;; Do nothing.
(or (null upgrade)
;; This may happen when a Elpa version of pkg
;; is installed and need upgrade and pkg is as
;; well a builtin package.
(package-built-in-p pkg-name))
(ignore))
(;; Delete.
t
(message "Deleting package `%s'" pkg-name)
(package-delete pkg-desc t t)))))
(defun helm-el-package-upgrade (_candidate)
(helm-el-package-upgrade-1
(cl-loop with pkgs = (helm-marked-candidates)
for p in helm-el-package--tabulated-list
for pkg = (car p)
if (member (symbol-name (package-desc-name pkg)) pkgs)
collect p)))
(defun helm-el-run-package-upgrade ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-el-package-upgrade)))
(put 'helm-el-run-package-upgrade 'helm-only t)
(defun helm-el-package-upgrade-all ()
(if helm-el-package--upgrades
(with-helm-display-marked-candidates
helm-marked-buffer-name (helm-fast-remove-dups
(mapcar (lambda (x) (symbol-name (car x)))
helm-el-package--upgrades)
:test 'equal)
(when (y-or-n-p "Upgrade all packages? ")
(helm-el-package-upgrade-1 helm-el-package--tabulated-list)))
(message "No packages to upgrade actually!")))
(defun helm-el-package-upgrade-all-action (_candidate)
(helm-el-package-upgrade-all))
(defun helm-el-run-package-upgrade-all ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-el-package-upgrade-all-action)))
(put 'helm-el-run-package-upgrade-all 'helm-only t)
(defun helm-el-package--transformer (candidates _source)
(cl-loop for c in candidates
for disp = (concat " " c)
for id = (get-text-property 0 'tabulated-list-id c)
for name = (and id (package-desc-name id))
for desc = (package-desc-status id)
for built-in-p = (and (package-built-in-p name)
(not (member desc '("available" "new"
"installed" "dependency"))))
for installed-p = (member desc '("installed" "dependency"))
for upgrade-p = (assq name helm-el-package--upgrades)
for user-installed-p = (memq name package-selected-packages)
do (when (and user-installed-p (not upgrade-p))
(put-text-property 0 2 'display "S " disp))
do (when (or (memq name helm-el-package--removable-packages)
(and upgrade-p installed-p))
(put-text-property 0 2 'display "U " disp)
(put-text-property
2 (+ (length (symbol-name name)) 2)
'face 'font-lock-variable-name-face disp))
do (when (and upgrade-p (not installed-p) (not built-in-p))
(put-text-property 0 2 'display "I " disp))
for cand = (cons disp (car (split-string disp)))
when (or (and built-in-p
(eq helm-el-package--show-only 'built-in))
(and upgrade-p
(eq helm-el-package--show-only 'upgrade))
(and installed-p
(eq helm-el-package--show-only 'installed))
(and (not installed-p)
(not built-in-p)
(eq helm-el-package--show-only 'uninstalled))
(eq helm-el-package--show-only 'all))
collect cand))
(defun helm-el-package-show-built-in ()
(interactive)
(with-helm-alive-p
(setq helm-el-package--show-only 'built-in)
(helm-update)))
(put 'helm-el-package-show-built-in 'helm-only t)
(defun helm-el-package-show-upgrade ()
(interactive)
(with-helm-alive-p
(setq helm-el-package--show-only 'upgrade)
(helm-update)))
(put 'helm-el-package-show-upgrade 'helm-only t)
(defun helm-el-package-show-installed ()
(interactive)
(with-helm-alive-p
(setq helm-el-package--show-only 'installed)
(helm-update)))
(put 'helm-el-package-show-installed 'helm-only t)
(defun helm-el-package-show-all ()
(interactive)
(with-helm-alive-p
(setq helm-el-package--show-only 'all)
(helm-update)))
(put 'helm-el-package-show-all 'helm-only t)
(defun helm-el-package-show-uninstalled ()
(interactive)
(with-helm-alive-p
(setq helm-el-package--show-only 'uninstalled)
(helm-update)))
(put 'helm-el-package-show-uninstalled 'helm-only t)
(defvar helm-el-package-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "M-I") 'helm-el-package-show-installed)
(define-key map (kbd "M-O") 'helm-el-package-show-uninstalled)
(define-key map (kbd "M-U") 'helm-el-package-show-upgrade)
(define-key map (kbd "M-B") 'helm-el-package-show-built-in)
(define-key map (kbd "M-A") 'helm-el-package-show-all)
(define-key map (kbd "C-c i") 'helm-el-run-package-install)
(define-key map (kbd "C-c r") 'helm-el-run-package-reinstall)
(define-key map (kbd "C-c d") 'helm-el-run-package-uninstall)
(define-key map (kbd "C-c u") 'helm-el-run-package-upgrade)
(define-key map (kbd "C-c U") 'helm-el-run-package-upgrade-all)
(define-key map (kbd "C-c @") 'helm-el-run-visit-homepage)
map))
(defvar helm-source-list-el-package nil)
(defclass helm-list-el-package-source (helm-source-in-buffer)
((init :initform 'helm-el-package--init)
(get-line :initform 'buffer-substring)
(filtered-candidate-transformer :initform 'helm-el-package--transformer)
(action-transformer :initform 'helm-el-package--action-transformer)
(help-message :initform 'helm-el-package-help-message)
(keymap :initform 'helm-el-package-map)
(update :initform 'helm-el-package--update)
(candidate-number-limit :initform 9999)
(action :initform '(("Describe package" . helm-el-package-describe)
("Visit homepage" . helm-el-package-visit-homepage)))
(find-file-target :initform #'helm-el-package-quit-an-find-file-fn)
(group :initform 'helm-el-package)))
(defun helm-el-package-quit-an-find-file-fn (source)
(let* ((sel (helm-get-selection nil nil source))
(pkg (and (stringp sel)
(get-text-property 0 'tabulated-list-id sel))))
(when (and pkg (package-installed-p pkg))
(expand-file-name (package-desc-dir pkg)))))
(defun helm-el-package--action-transformer (actions candidate)
(let* ((pkg-desc (get-text-property 0 'tabulated-list-id candidate))
(status (package-desc-status pkg-desc))
(pkg-name (package-desc-name pkg-desc))
(built-in (and (package-built-in-p pkg-name)
(not (member status '("available" "new"
"installed" "dependency")))))
(acts (if helm-el-package--upgrades
(append actions '(("Upgrade all packages"
. helm-el-package-upgrade-all-action)))
actions)))
(cond (built-in '(("Describe package" . helm-el-package-describe)))
((and (package-installed-p pkg-name)
(cdr (assq pkg-name helm-el-package--upgrades))
(member status '("installed" "dependency")))
(append '(("Upgrade package(s)" . helm-el-package-upgrade)
("Uninstall package(s)" . helm-el-package-uninstall))
acts))
((and (package-installed-p pkg-name)
(cdr (assq pkg-name helm-el-package--upgrades))
(string= status "available"))
(append '(("Upgrade package(s)" . helm-el-package-upgrade))
acts))
((and (package-installed-p pkg-name)
(or (null (package-built-in-p pkg-name))
(and (package-built-in-p pkg-name)
(assq pkg-name package-alist))))
(append acts '(("Reinstall package(s)" . helm-el-package-reinstall)
("Recompile package(s)" . helm-el-package-recompile)
("Uninstall package(s)" . helm-el-package-uninstall))))
(t (append acts '(("Install packages(s)" . helm-el-package-install)))))))
(defun helm-el-package--update ()
(setq helm-el-package--initialized-p nil))
(defun helm-el-package-recompile (_pkg)
(cl-loop for p in (helm-marked-candidates)
do (helm-el-package-recompile-1 p)))
(defun helm-el-package-recompile-1 (pkg)
(let* ((pkg-desc (get-text-property 0 'tabulated-list-id pkg))
(dir (package-desc-dir pkg-desc)))
(async-byte-recompile-directory dir)))
(defun helm-el-package-reinstall (_pkg)
(cl-loop for p in (helm-marked-candidates)
for pkg-desc = (get-text-property 0 'tabulated-list-id p)
do (helm-el-package-reinstall-1 pkg-desc)))
(defun helm-el-package-reinstall-1 (pkg-desc)
(let ((name (package-desc-name pkg-desc)))
(package-delete pkg-desc 'force 'nosave)
;; pkg-desc contain the description
;; of the installed package just removed
;; and is BTW no more valid.
;; Use the entry in package-archive-content
;; which is the non--installed package entry.
;; For some reason `package-install'
;; need a pkg-desc (package-desc-p) for the build-in
;; packages already installed, the name (as symbol)
;; fails with such packages.
(package-install
(cadr (assq name package-archive-contents)) t)))
(defun helm-el-run-package-reinstall ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-el-package-reinstall)))
(put 'helm-el-run-package-reinstall 'helm-only t)
;;;###autoload
(defun helm-list-elisp-packages (arg)
"Preconfigured `helm' for listing and handling Emacs packages."
(interactive "P")
(when arg (setq helm-el-package--initialized-p nil))
(unless helm-source-list-el-package
(setq helm-source-list-el-package
(helm-make-source "list packages" 'helm-list-el-package-source)))
(helm :sources 'helm-source-list-el-package
:truncate-lines helm-el-truncate-lines
:full-frame t
:buffer "*helm list packages*"))
;;;###autoload
(defun helm-list-elisp-packages-no-fetch (arg)
"Preconfigured Helm for Emacs packages.
Same as `helm-list-elisp-packages' but don't fetch packages on
remote. Called with a prefix ARG always fetch packages on
remote."
(interactive "P")
(let ((helm-el-package--initialized-p (null arg)))
(helm-list-elisp-packages nil)))
(provide 'helm-elisp-package)
;;; helm-elisp-package.el ends here

View file

@ -0,0 +1,980 @@
;;; helm-elisp.el --- Elisp symbols completion for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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 'helm-help)
(require 'helm-types)
(require 'helm-utils)
(require 'helm-info)
(require 'helm-eval)
(require 'helm-files)
(declare-function helm-describe-function "helm-lib")
(declare-function helm-describe-variable "helm-lib")
(declare-function helm-describe-face "helm-lib")
(declare-function helm-read-file-name "helm-mode")
(declare-function helm-comp-read "helm-mode")
(declare-function helm-M-x-transformer-no-sort-no-props "helm-command")
(defvar helm-M-x-show-short-doc)
;;; Customizable values
(defgroup helm-elisp nil
"Elisp related Applications and libraries for Helm."
:group 'helm)
(defcustom helm-turn-on-show-completion t
"Display candidate in `current-buffer' while moving selection when non--nil."
:group 'helm-elisp
:type 'boolean)
(defcustom helm-show-completion-min-window-height 7
"Minimum completion window height used in show completion.
This is used in macro `with-helm-show-completion'."
:group 'helm-elisp
:type 'integer)
(defcustom helm-lisp-quoted-function-list
'(funcall apply mapc cl-mapc mapcar cl-mapcar
callf callf2 cl-callf cl-callf2 fset
fboundp fmakunbound symbol-function)
"List of function where quoted function completion happen.
E.g. give only function names after \(funcall '."
:group 'helm-elisp
:type '(repeat (choice symbol)))
(defcustom helm-lisp-unquoted-function-list
'(function defadvice)
"List of function where unquoted function completion happen.
E.g. give only function names after \(function ."
:group 'helm-elisp
:type '(repeat (choice symbol)))
(defcustom helm-apropos-fuzzy-match nil
"Enable fuzzy matching for `helm-apropos' when non-nil."
:group 'helm-elisp
:type 'boolean)
(defcustom helm-lisp-fuzzy-completion nil
"Enable fuzzy matching in emacs-lisp completion when non-nil.
NOTE: This enables fuzzy matching in Helm native implementation of
elisp completion, but not on helmized elisp completion, i.e. fuzzy
completion is not available in `completion-at-point'."
:group 'helm-elisp
:type 'boolean)
(defcustom helm-apropos-function-list '(helm-def-source--emacs-commands
helm-def-source--emacs-functions
helm-def-source--eieio-classes
helm-def-source--eieio-generic
helm-def-source--emacs-variables
helm-def-source--emacs-faces)
"A list of functions that build helm sources to use in `helm-apropos'."
:group 'helm-elisp
:type '(repeat (choice symbol)))
(defcustom helm-apropos-defaut-info-lookup-sources '(helm-source-info-elisp
helm-source-info-cl
helm-source-info-eieio)
"A list of sources to look into when searching info page of a symbol."
:group 'helm-elisp
:type '(repeat (choice symbol)))
(defcustom helm-show-completion-display-function
(if (display-graphic-p)
#'helm-display-buffer-in-own-frame
#'helm-show-completion-default-display-function)
"The function used to display helm completion buffer.
This function is used by `with-helm-show-completion', when nil
fallback to `helm-default-display-buffer'.
Default is to use a separate frame on graphic display and
`helm-show-completion-default-display-function' on non graphic
display."
:group 'helm-elisp
:type 'function)
;;; Faces
;;
;;
(defgroup helm-elisp-faces nil
"Customize the appearance of helm-elisp."
:prefix "helm-"
:group 'helm-elisp
:group 'helm-faces)
(defface helm-lisp-show-completion
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:background "DarkSlateGray"))
"Face used for showing candidates in `helm-lisp-completion'."
:group 'helm-elisp-faces)
(defface helm-lisp-completion-info
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "red"))
"Face used for showing info in `helm-lisp-completion'."
:group 'helm-elisp-faces)
(defcustom helm-elisp-help-function
'helm-elisp-show-help
"Function for displaying help for Lisp symbols."
:group 'helm-elisp
:type '(choice (function :tag "Open help for the symbol."
helm-elisp-show-help)
(function :tag "Show one liner in modeline."
helm-elisp-show-doc-modeline)))
(defcustom helm-locate-library-fuzzy-match t
"Enable fuzzy-matching in `helm-locate-library' when non--nil."
:type 'boolean
:group 'helm-elisp)
;;; Show completion.
;;
;; Provide show completion with macro `with-helm-show-completion'.
(defvar helm-show-completion-overlay nil)
;; Called each time cursor move in helm-buffer.
(defun helm-show-completion ()
(with-helm-current-buffer
(overlay-put helm-show-completion-overlay
'display (substring-no-properties
(helm-get-selection)))))
(defun helm-show-completion-init-overlay (beg end)
(setq helm-show-completion-overlay (make-overlay beg end))
(overlay-put helm-show-completion-overlay
'face 'helm-lisp-show-completion))
(defun helm-show-completion-default-display-function (buffer &rest _args)
"A special resized Helm window is used depending on position in BUFFER."
(with-selected-window (selected-window)
(if (window-dedicated-p)
(helm-default-display-buffer buffer)
(let* ((screen-size (+ (count-screen-lines (window-start) (point) t)
1 ; mode-line
(if header-line-format 1 0))) ; header-line
(def-size (- (window-height)
helm-show-completion-min-window-height))
(upper-height (max window-min-height (min screen-size def-size)))
split-window-keep-point)
(recenter -1)
(set-window-buffer (if (active-minibuffer-window)
(minibuffer-selected-window)
(split-window nil upper-height
helm-split-window-default-side))
buffer)))))
(defmacro with-helm-show-completion (beg end &rest body)
"Show Helm candidate in an overlay at point.
BEG and END are the beginning and end position of the current
completion in `helm-current-buffer'.
BODY is an Helm call where we want to enable show completion.
If `helm-turn-on-show-completion' is nil do nothing."
(declare (indent 2) (debug t))
`(unwind-protect
(if helm-turn-on-show-completion
(let ((helm-move-selection-after-hook
(append (list 'helm-show-completion)
helm-move-selection-after-hook))
(helm-split-window-default-side
(if (eq helm-split-window-default-side 'same)
'below helm-split-window-default-side))
helm-split-window-inside-p
helm-reuse-last-window-split-state)
(helm-set-local-variable
'helm-display-function
(or helm-show-completion-display-function
'helm-default-display-buffer))
(helm-show-completion-init-overlay ,beg ,end)
,@body)
,@body)
(when (and helm-show-completion-overlay
(overlayp helm-show-completion-overlay))
(delete-overlay helm-show-completion-overlay))))
;;; Lisp symbol completion.
;;
;;
(defun helm-lisp-completion--predicate-at-point (beg)
;; Return a predicate for `all-completions'.
(let ((fn-sym-p (lambda ()
(or
(and (eq (char-before) ?\ )
(save-excursion
(skip-syntax-backward " " (point-at-bol))
(memq (symbol-at-point)
helm-lisp-unquoted-function-list)))
(and (eq (char-before) ?\')
(save-excursion
(forward-char -1)
(eq (char-before) ?\#)))))))
(save-excursion
(goto-char beg)
(if (or
;; Complete on all symbols in non--lisp modes (logs mail etc..)
(not (memq major-mode '(emacs-lisp-mode
lisp-interaction-mode
inferior-emacs-lisp-mode)))
(not (or (funcall fn-sym-p)
(and (eq (char-before) ?\')
(save-excursion
(forward-char (if (funcall fn-sym-p) -2 -1))
(skip-syntax-backward " " (point-at-bol))
(memq (symbol-at-point)
helm-lisp-quoted-function-list)))
(eq (char-before) ?\())) ; no paren before str.
;; Looks like we are in a let statement.
(condition-case nil
(progn (up-list -2) (forward-char 1)
(eq (char-after) ?\())
(error nil)))
(lambda (sym)
(or (boundp sym) (fboundp sym) (symbol-plist sym)))
#'fboundp))))
(defun helm-thing-before-point (&optional limits regexp)
"Return symbol name before point.
If REGEXP is specified return what REGEXP find before point.
By default match the beginning of symbol before point.
With LIMITS arg specified return the beginning and end position
of symbol before point."
(save-excursion
(let (beg
(end (point))
(boundary (field-beginning nil nil (point-at-bol))))
(if (re-search-backward (or regexp "\\_<") boundary t)
(setq beg (match-end 0))
(setq beg boundary))
(unless (= beg end)
(if limits
(cons beg end)
(buffer-substring-no-properties beg end))))))
(defun helm-bounds-of-thing-before-point (&optional regexp)
"Get the beginning and end position of `helm-thing-before-point'.
Return a cons \(beg . end\)."
(helm-thing-before-point 'limits regexp))
(defun helm-insert-completion-at-point (beg end str)
;; When there is no space after point
;; we are completing inside a symbol or
;; after a partial symbol with the next arg aside
;; without space, in this case mark the region.
;; deleting it would remove the
;; next arg which is unwanted.
(delete-region beg end)
(insert str)
(let ((pos (cdr (or (bounds-of-thing-at-point 'symbol)
;; needed for helm-dabbrev.
(bounds-of-thing-at-point 'filename)))))
(when (and pos (< (point) pos))
(push-mark pos t t))))
(defvar helm-lisp-completion--cache nil)
(defvar helm-lgst-len nil)
;;;###autoload
(defun helm-lisp-completion-at-point ()
"Preconfigured Helm for Lisp symbol completion at point."
(interactive)
(setq helm-lgst-len 0)
(let* ((target (helm-thing-before-point))
(beg (car (helm-bounds-of-thing-before-point)))
(end (point))
(pred (and beg (helm-lisp-completion--predicate-at-point beg)))
(loc-vars (and (fboundp 'elisp--local-variables)
(ignore-errors
(mapcar #'symbol-name (elisp--local-variables)))))
(glob-syms (and target pred (all-completions target obarray pred)))
(candidates (append loc-vars glob-syms))
(helm-quit-if-no-candidate t)
(helm-execute-action-at-once-if-one t)
(enable-recursive-minibuffers t))
(setq helm-lisp-completion--cache (cl-loop for sym in candidates
for len = (length sym)
when (> len helm-lgst-len)
do (setq helm-lgst-len len)
collect sym))
(if candidates
(with-helm-show-completion beg end
;; Overlay is initialized now in helm-current-buffer.
(helm
:sources (helm-build-in-buffer-source "Lisp completion"
:data helm-lisp-completion--cache
:persistent-action `(helm-lisp-completion-persistent-action .
,(and (eq helm-elisp-help-function
'helm-elisp-show-doc-modeline)
'never-split))
:nomark t
:match-part (lambda (c) (car (split-string c)))
:fuzzy-match helm-lisp-fuzzy-completion
:persistent-help (helm-lisp-completion-persistent-help)
:filtered-candidate-transformer
'helm-lisp-completion-transformer
:action (lambda (candidate)
(with-helm-current-buffer
(run-with-timer
0.01 nil
'helm-insert-completion-at-point
beg end candidate))))
:input (if helm-lisp-fuzzy-completion
target (concat target " "))
:resume 'noresume
:truncate-lines t
:buffer "*helm lisp completion*"
:allow-nest t))
(message "[No Match]"))))
(defun helm-lisp-completion-persistent-action (candidate &optional name)
"Show documentation for the function.
Documentation is shown briefly in mode-line or completely in
other window according to the value of
`helm-elisp-help-function'."
(funcall helm-elisp-help-function candidate name))
(defun helm-lisp-completion-persistent-help ()
"Return persistent-help according to the value of `helm-elisp-help-function'"
(cl-ecase helm-elisp-help-function
(helm-elisp-show-doc-modeline "Show brief doc in mode-line")
(helm-elisp-show-help "Toggle show help for the symbol")))
(defun helm-elisp--show-help-1 (candidate &optional name)
(let ((sym (intern-soft candidate)))
(cl-typecase sym
((and fboundp boundp)
(if (member name `(,helm-describe-function-function ,helm-describe-variable-function))
(funcall (intern (format "helm-%s" name)) sym)
;; When there is no way to know what to describe
;; prefer describe-function.
(helm-describe-function sym)))
(fbound (helm-describe-function sym))
(bound (helm-describe-variable sym))
(face (helm-describe-face sym)))))
(defun helm-elisp-show-help (candidate &optional name)
"Show full help for the function CANDIDATE.
Arg NAME specifies the name of the top level function calling
Helm generic completion (e.g., \"describe-function\") which
allows calling the right function when CANDIDATE symbol refers at
the same time to variable and a function."
(helm-elisp--persistent-help
candidate 'helm-elisp--show-help-1 name))
(defun helm-elisp-show-doc-modeline (candidate &optional name)
"Show brief documentation for the function in the mode-line."
(let ((cursor-in-echo-area t)
mode-line-in-non-selected-windows)
(helm-show-info-in-mode-line
(propertize
(helm-get-first-line-documentation
(intern candidate) name)
'face 'helm-lisp-completion-info))))
(defun helm-lisp-completion-transformer (candidates _source)
"Helm candidates transformer for Lisp completion."
(cl-loop for c in candidates
for sym = (intern c)
for annot = (cl-typecase sym
(command " (Com)")
(class " (Class)")
(cl-generic " (Gen)")
(fbound " (Fun)")
(bound " (Var)")
(face " (Face)"))
for spaces = (make-string (- helm-lgst-len (length c)) ? )
collect (cons (concat c spaces annot) c) into lst
finally return (sort lst #'helm-generic-sort-fn)))
(defun helm-get-first-line-documentation (sym &optional name)
"Return first line documentation of symbol SYM.
If SYM is not documented, return \"Not documented\"."
(let ((doc (cl-typecase sym
((and fboundp boundp)
(cond ((string= name "describe-function")
(documentation sym t))
((string= name "describe-variable")
(documentation-property sym 'variable-documentation t))
(t (documentation sym t))))
(fbound (documentation sym t))
(bound (documentation-property sym 'variable-documentation t))
(face (face-documentation sym)))))
(if (and doc (not (string= doc ""))
;; `documentation' return "\n\n(args...)"
;; for CL-style functions.
(not (string-match-p "^\n\n" doc)))
;; Some commands specify key bindings in their first line.
(substitute-command-keys (car (split-string doc "\n")))
"Not documented")))
;;; File completion.
;;
;; Complete file name at point.
;;;###autoload
(defun helm-complete-file-name-at-point (&optional force)
"Preconfigured Helm to complete file name at point."
(interactive)
(require 'helm-mode)
(let* ((tap (or (thing-at-point 'filename) ""))
beg
(init (and tap
(or force
(save-excursion
(end-of-line)
(search-backward tap (point-at-bol) t)
(setq beg (point))
(looking-back "[^'`( ]" (1- (point)))))
(expand-file-name
(substring-no-properties tap))))
(end (point))
(helm-quit-if-no-candidate t)
(helm-execute-action-at-once-if-one t)
completion)
(with-helm-show-completion beg end
(setq completion (helm-read-file-name "FileName: "
:initial-input init)))
(when (and completion (not (string= completion "")))
(delete-region beg end) (insert (if (string-match "^~" tap)
(abbreviate-file-name completion)
completion)))))
;;;###autoload
(defun helm-lisp-indent ()
;; It is meant to use with `helm-define-multi-key' which
;; does not support args for functions yet, so use `current-prefix-arg'
;; for now instead of (interactive "P").
(interactive)
(let ((tab-always-indent (or (eq tab-always-indent 'complete)
tab-always-indent)))
(indent-for-tab-command current-prefix-arg)))
;;;###autoload
(defun helm-lisp-completion-or-file-name-at-point ()
"Preconfigured Helm to complete Lisp symbol or filename at point.
Filename completion happens if string start after or between a
double quote."
(interactive)
(let* ((tap (thing-at-point 'filename)))
(if (and tap (save-excursion
(end-of-line)
(search-backward tap (point-at-bol) t)
(looking-back "[^'`( ]" (1- (point)))))
(helm-complete-file-name-at-point)
(helm-lisp-completion-at-point))))
;;; Apropos
;;
;;
(defvar helm-apropos-history nil)
(defun helm-apropos-init (test default)
"Init candidates buffer for `helm-apropos' sources."
(require 'helm-help)
(helm-init-candidates-in-buffer 'global
(let ((default-symbol (and (stringp default)
(intern-soft default)))
(symbols (all-completions "" obarray test)))
(if (and default-symbol (funcall test default-symbol))
(cons default-symbol symbols)
symbols))))
(defun helm-apropos-init-faces (default)
"Init candidates buffer for faces for `helm-apropos'."
(require 'helm-help)
(with-current-buffer (helm-candidate-buffer 'global)
(goto-char (point-min))
(let ((default-symbol (and (stringp default)
(intern-soft default)))
(faces (face-list)))
(when (and default-symbol (facep default-symbol))
(insert (concat default "\n")))
(insert
(mapconcat #'prin1-to-string
(if default
(cl-remove-if (lambda (sym) (string= sym default)) faces)
faces)
"\n")))))
(defun helm-apropos-default-sort-fn (candidates _source)
(if (string= helm-pattern "")
candidates
(sort candidates #'helm-generic-sort-fn)))
(defun helm-apropos-clean-history-variable (candidate)
(with-helm-current-buffer ; var is maybe local
(let* ((sym (intern-soft candidate))
(cands (symbol-value sym))
(mkds (and (listp cands)
(helm-comp-read "Delete entry: "
cands :marked-candidates t))))
(cl-assert (listp mkds) nil "Variable value is not a list")
(cl-loop for elm in mkds do
(if (local-variable-p sym)
(set (make-local-variable sym)
(setq cands (delete elm cands)))
(set sym (setq cands (delete elm cands))))))))
(defun helm-apropos-clean-ring (candidate)
(with-helm-current-buffer ; var is maybe local
(let* ((sym (intern-soft candidate))
(val (symbol-value sym))
(cands (and (ring-p val) (ring-elements val)))
(mkds (and cands (helm-comp-read
"Delete entry: "
cands :marked-candidates t))))
(when mkds
(cl-loop for elm in mkds do
(ring-remove
val (helm-position
elm
(ring-elements val)
:test 'equal))
and do (if (local-variable-p sym)
(set (make-local-variable sym) val)
(set sym val)))))))
(defun helm-apropos-action-transformer (actions candidate)
(let* ((sym (helm-symbolify candidate))
(val (with-helm-current-buffer (symbol-value sym))))
(cond ((custom-variable-p sym)
(append
actions
(let ((standard-value (eval (car (get sym 'standard-value)))))
(unless (equal standard-value (symbol-value sym))
`(("Reset Variable to default value"
. ,(lambda (candidate)
(let ((sym (helm-symbolify candidate)))
(set sym standard-value)))))))
'(("Customize variable" .
(lambda (candidate)
(customize-option (helm-symbolify candidate)))))))
((and val (with-helm-current-buffer (ring-p (symbol-value sym))))
(append actions
'(("Clean ring" . helm-apropos-clean-ring))))
((and (string-match-p "history" candidate) (listp val))
(append actions
'(("Clean variable" .
helm-apropos-clean-history-variable))))
(t actions))))
(defun helm-def-source--emacs-variables (&optional default)
(helm-build-in-buffer-source "Variables"
:init (lambda ()
(helm-apropos-init
(lambda (x) (and (boundp x) (not (keywordp x)))) default))
:fuzzy-match helm-apropos-fuzzy-match
:filtered-candidate-transformer (and (null helm-apropos-fuzzy-match)
'helm-apropos-default-sort-fn)
:nomark t
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate 'helm-describe-variable))
:persistent-help "Toggle describe variable"
:action '(("Describe variable" . helm-describe-variable)
("Find variable" . helm-find-variable)
("Info lookup" . helm-info-lookup-symbol)
("Set variable" . helm-set-variable))
:action-transformer 'helm-apropos-action-transformer))
(defun helm-def-source--emacs-faces (&optional default)
"Create `helm' source for faces to be displayed with
`helm-apropos'."
(helm-build-in-buffer-source "Faces"
:init (lambda () (helm-apropos-init-faces default))
:fuzzy-match helm-apropos-fuzzy-match
:filtered-candidate-transformer
(append (and (null helm-apropos-fuzzy-match)
'(helm-apropos-default-sort-fn))
(list
(lambda (candidates _source)
(cl-loop for c in candidates
collect (propertize c 'face (intern c))))))
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate 'helm-describe-face))
:persistent-help "Toggle describe face"
:action '(("Describe face" . helm-describe-face)
("Find face" . helm-find-face-definition)
("Customize face" . (lambda (candidate)
(customize-face (helm-symbolify candidate)))))))
(defun helm-def-source--emacs-commands (&optional default)
(require 'helm-command)
(helm-build-in-buffer-source "Commands"
:init (lambda ()
(helm-apropos-init 'commandp default))
:fuzzy-match helm-apropos-fuzzy-match
:filtered-candidate-transformer
(append (list #'helm-M-x-transformer-no-sort-no-props)
(and (null helm-apropos-fuzzy-match)
'(helm-apropos-default-sort-fn)))
:display-to-real 'helm-symbolify
:nomark t
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate 'helm-describe-function))
:persistent-help "Toggle describe command"
:action 'helm-type-function-actions))
(defun helm-def-source--emacs-functions (&optional default)
(helm-build-in-buffer-source "Functions"
:init (lambda ()
(helm-apropos-init (lambda (x)
(and (fboundp x)
(not (commandp x))
(not (cl-generic-p x))
(not (class-p x))))
default))
:fuzzy-match helm-apropos-fuzzy-match
:filtered-candidate-transformer (and (null helm-apropos-fuzzy-match)
'helm-apropos-default-sort-fn)
:display-to-real 'helm-symbolify
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate 'helm-describe-function))
:persistent-help "Toggle describe function"
:nomark t
:action 'helm-type-function-actions))
(defun helm-def-source--eieio-classes (&optional default)
(helm-build-in-buffer-source "Classes"
:init (lambda ()
(helm-apropos-init (lambda (x)
(class-p x))
default))
:fuzzy-match helm-apropos-fuzzy-match
:filtered-candidate-transformer (and (null helm-apropos-fuzzy-match)
'helm-apropos-default-sort-fn)
:nomark t
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate 'helm-describe-class))
:persistent-help "Toggle describe class"
:action '(("Describe Class" . helm-describe-class)
("Find Class" . helm-find-function)
("Info lookup" . helm-info-lookup-symbol))))
(defun helm-def-source--eieio-generic (&optional default)
(helm-build-in-buffer-source "Generic functions"
:init (lambda ()
(helm-apropos-init (lambda (x)
(cl-generic-p x))
default))
:fuzzy-match helm-apropos-fuzzy-match
:filtered-candidate-transformer (and (null helm-apropos-fuzzy-match)
'helm-apropos-default-sort-fn)
:nomark t
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate 'helm-describe-function))
:persistent-help "Toggle describe generic function"
:action '(("Describe function" . helm-describe-function)
("Find function" . helm-find-function)
("Info lookup" . helm-info-lookup-symbol))))
(defun helm-info-lookup-fallback-source (candidate)
(let ((sym (helm-symbolify candidate))
src-name fn)
(cond ((class-p sym)
(setq fn #'helm-describe-function
src-name "Describe class"))
((cl-generic-p sym)
(setq fn #'helm-describe-function
src-name "Describe generic function"))
((fboundp sym)
(setq fn #'helm-describe-function
src-name "Describe function"))
((facep sym)
(setq fn #'helm-describe-face
src-name "Describe face"))
(t
(setq fn #'helm-describe-variable
src-name "Describe variable")))
(helm-build-sync-source src-name
:candidates (list candidate)
:persistent-action (lambda (candidate)
(helm-elisp--persistent-help
candidate fn))
:persistent-help src-name
:nomark t
:action fn)))
(defun helm-info-lookup-symbol-1 (c)
(let ((helm-execute-action-at-once-if-one 'current-source))
(helm :sources (append helm-apropos-defaut-info-lookup-sources
(list (helm-info-lookup-fallback-source c)))
:resume 'noresume
:buffer "*helm lookup*"
:input (helm-stringify c))))
(defun helm-info-lookup-symbol (candidate)
;; ???:Running an idle-timer allows not catching RET when exiting
;; with the fallback source.
;; (run-with-idle-timer 0.01 nil #'helm-info-lookup-symbol-1 candidate)
(helm-info-lookup-symbol-1 candidate))
;;;###autoload
(defun helm-apropos (default)
"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."
(interactive (list (with-syntax-table emacs-lisp-mode-syntax-table
(thing-at-point 'symbol))))
(let (helm-M-x-show-short-doc)
(helm :sources
(mapcar (lambda (func)
(funcall func default))
helm-apropos-function-list)
:history 'helm-apropos-history
:buffer "*helm apropos*"
:preselect (and default (concat "\\_<" (regexp-quote default) "\\_>")))))
;;; Advices
;;
;;
(defvar ad-advised-functions)
(defvar ad-advice-classes)
(declare-function ad-make-single-advice-docstring "advice")
(declare-function ad-get-advice-info-field "advice")
(declare-function ad-advice-set-enabled "advice")
(declare-function ad-advice-set-enabled "advice")
(declare-function ad-advice-enabled "advice")
(defvar helm-source-advice
(helm-build-sync-source "Function Advice"
:init (lambda () (require 'advice))
:candidates 'helm-advice-candidates
:action (helm-make-actions "Toggle Enable/Disable" 'helm-advice-toggle)
:persistent-action 'helm-advice-persistent-action
:nomark t
:multiline t
:persistent-help "Toggle describe function / C-u C-j: Toggle advice"))
(defun helm-advice-candidates ()
(cl-loop for (fname) in ad-advised-functions
for function = (intern fname)
append
(cl-loop for class in ad-advice-classes append
(cl-loop for advice in (ad-get-advice-info-field function class)
for enabled = (ad-advice-enabled advice)
collect
(cons (format
"%s %s %s"
(if enabled "Enabled " "Disabled")
(propertize fname 'face 'font-lock-function-name-face)
(ad-make-single-advice-docstring advice class nil))
(list function class advice))))))
(defun helm-advice-persistent-action (func-class-advice)
(if current-prefix-arg
(helm-advice-toggle func-class-advice)
(describe-function (car func-class-advice))))
(defun helm-advice-toggle (func-class-advice)
(cl-destructuring-bind (function _class advice) func-class-advice
(cond ((ad-advice-enabled advice)
(ad-advice-set-enabled advice nil)
(message "Disabled"))
(t
(ad-advice-set-enabled advice t)
(message "Enabled")))
(ad-activate function)
(and helm-in-persistent-action
(helm-advice-update-current-display-string))))
(defun helm-advice-update-current-display-string ()
(helm-edit-current-selection
(let ((newword (cond ((looking-at "Disabled") "Enabled")
((looking-at "Enabled") "Disabled"))))
(when newword
(delete-region (point) (progn (forward-word 1) (point)))
(insert newword)))))
;;;###autoload
(defun helm-manage-advice ()
"Preconfigured `helm' to disable/enable function advices."
(interactive)
(helm-other-buffer 'helm-source-advice "*helm advice*"))
;;; Locate elisp library
;;
;;
(defun helm-locate-library-scan-list ()
(cl-loop for dir in load-path
with load-suffixes = '(".el")
when (file-directory-p dir)
append (directory-files
dir t (concat (regexp-opt (get-load-suffixes))
"\\'"))))
;;;###autoload
(defun helm-locate-library ()
"Preconfigured helm to locate elisp libraries."
(interactive)
(helm :sources (helm-build-in-buffer-source "Elisp libraries (Scan)"
:data #'helm-locate-library-scan-list
:fuzzy-match helm-locate-library-fuzzy-match
:keymap helm-generic-files-map
:search (unless helm-locate-library-fuzzy-match
(lambda (regexp)
(re-search-forward
(if helm-ff-transformer-show-only-basename
(replace-regexp-in-string
"\\`\\^" "" regexp)
regexp)
nil t)))
:match-part (lambda (candidate)
(with-helm-buffer
(if helm-ff-transformer-show-only-basename
(helm-basename candidate) candidate)))
:filter-one-by-one (lambda (c)
(with-helm-buffer
(if helm-ff-transformer-show-only-basename
(cons (helm-basename c) c) c)))
:action (helm-actions-from-type-file))
:ff-transformer-show-only-basename nil
:buffer "*helm locate library*"))
(defun helm-set-variable (var)
"Set VAR value interactively."
(let* ((sym (helm-symbolify var))
(val (default-value sym)))
(set-default sym (eval-minibuffer
(format "Set `%s': " var)
(if (or (stringp val)
(memq val '(nil t))
(numberp val))
(prin1-to-string val)
(format "'%s" (prin1-to-string val)))))))
;;; Elisp Timers.
;;
;;
(defclass helm-absolute-time-timers-class (helm-source-sync helm-type-timers)
((candidates :initform 'timer-list)
(allow-dups :initform t)
(candidate-transformer
:initform
(lambda (candidates)
(cl-loop for timer in candidates
collect (cons (helm-elisp--format-timer timer) timer))))))
(defvar helm-source-absolute-time-timers
(helm-make-source "Absolute Time Timers" 'helm-absolute-time-timers-class))
(defclass helm-idle-time-timers-class (helm-source-sync helm-type-timers)
((candidates :initform 'timer-idle-list)
(allow-dups :initform t)
(candidate-transformer
:initform
(lambda (candidates)
(cl-loop for timer in candidates
collect (cons (helm-elisp--format-timer timer) timer))))))
(defvar helm-source-idle-time-timers
(helm-make-source "Idle Time Timers" 'helm-idle-time-timers-class))
(defun helm-elisp--format-timer (timer)
(format "%s repeat=%s %s(%s)"
(let ((time (timer--time timer)))
(if (timer--idle-delay timer)
(format-time-string "idle-for=%5s" time)
(format-time-string "%m/%d %T" time)))
(or (timer--repeat-delay timer) "nil")
(mapconcat 'identity (split-string
(prin1-to-string (timer--function timer))
"\n") " ")
(mapconcat 'prin1-to-string (timer--args timer) " ")))
;;;###autoload
(defun helm-timers ()
"Preconfigured `helm' for timers."
(interactive)
(helm :sources '(helm-source-absolute-time-timers
helm-source-idle-time-timers)
:buffer "*helm timers*"))
;;; Complex command history
;;
;;
(defvar helm-sexp--last-sexp nil)
;; This wont work compiled.
(defun helm-sexp-eval-1 ()
(interactive)
(unwind-protect
(progn
;; Trick called-interactively-p into thinking that `cand' is
;; an interactive call, See `repeat-complex-command'.
(add-hook 'called-interactively-p-functions
#'helm-complex-command-history--called-interactively-skip)
(eval (read helm-sexp--last-sexp)))
(remove-hook 'called-interactively-p-functions
#'helm-complex-command-history--called-interactively-skip)))
(defun helm-complex-command-history--called-interactively-skip (i _frame1 frame2)
(and (eq 'eval (cadr frame2))
(eq 'helm-sexp-eval-1
(cadr (backtrace-frame (+ i 2) #'called-interactively-p)))
1))
(defun helm-sexp-eval (_candidate)
(call-interactively #'helm-sexp-eval-1))
(defvar helm-source-complex-command-history
(helm-build-sync-source "Complex Command History"
:candidates (lambda ()
;; Use cdr to avoid adding
;; `helm-complex-command-history' here.
(cl-loop for i in command-history
unless (equal i '(helm-complex-command-history))
collect (prin1-to-string i)))
:action (helm-make-actions
"Eval" (lambda (candidate)
(and (boundp 'helm-sexp--last-sexp)
(setq helm-sexp--last-sexp candidate))
(let ((command (read candidate)))
(unless (equal command (car command-history))
(setq command-history (cons command command-history))))
(run-with-timer 0.1 nil #'helm-sexp-eval candidate))
"Edit and eval" (lambda (candidate)
(edit-and-eval-command "Eval: " (read candidate))))
:persistent-action #'helm-sexp-eval
:multiline t))
;;;###autoload
(defun helm-complex-command-history ()
"Preconfigured `helm' for complex command history."
(interactive)
(helm :sources 'helm-source-complex-command-history
:buffer "*helm complex commands*"))
(provide 'helm-elisp)
;;; helm-elisp.el ends here

View file

@ -0,0 +1,254 @@
;;; helm-epa.el --- helm interface for epa/epg
;; Copyright (C) 2012 ~ 2021 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)))
(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)))
:prompt (and prompt (helm-epa--format-prompt prompt))
:buffer "*helm epa*")))
(unless (equal result "")
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

View file

@ -0,0 +1,502 @@
;;; helm-eshell.el --- pcomplete and eshell completion for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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."
:group 'helm-eshell
: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-or-file-name-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."
:group 'helm-eshell-faces)
(defface helm-eshell-prompts-buffer-name
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "green"))
"Face used to highlight Eshell buffer name."
:group 'helm-eshell-faces)
(defcustom helm-eshell-prompts-promptidx-p t
"Show prompt number."
:group 'helm-eshell
: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 (point-at-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))
(defun helm-eshell-prompts-other-window ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-eshell-prompts-goto-other-window)))
(put 'helm-eshell-prompts-other-window 'helm-only t)
(defun helm-eshell-prompts-other-frame ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-eshell-prompts-goto-other-frame)))
(put 'helm-eshell-prompts-other-frame 'helm-only t)
;;;###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

View file

@ -0,0 +1,202 @@
;;; helm-eval.el --- eval expressions from helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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)
(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))
(defun helm-build-evaluation-result-source ()
(helm-build-dummy-source "Evaluation Result"
: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)))))
(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)))
(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* ((sym (save-excursion
(unless (looking-back ")\\|\"" (1- (point)))
(forward-char -1))
(eldoc-current-symbol)))
(info-fn (eldoc-fnsym-in-current-sexp))
(doc (or (eldoc-get-var-docstring sym)
(eldoc-get-fnsym-args-string
(car info-fn) (cadr info-fn)))))
(when doc (funcall helm-eldoc-in-minibuffer-show-fn doc)))))
(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-current-buffer helm-buffer
(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")
(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

View file

@ -0,0 +1,258 @@
;;; helm-external.el --- Run Externals commands within Emacs with helm completion. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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)
;;; 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)
"Returns 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'."
(helm-aif helm-external-commands-list
it
(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)))
(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)
(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

View file

@ -0,0 +1,128 @@
;;; helm-fd.el --- helm interface for fd command line tool. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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")
(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)
(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 (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 "Fd command:\nfd %s" (mapconcat 'identity cmd " "))
(helm-log "VERSION: %s" fd-version)
(prog1
proc
(set-process-sentinel
proc (lambda (_process event)
(if (string= event "finished\n")
(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 in %.2fs - (%s results)] "
,fd-version
,(- (float-time) start-time)
(helm-get-candidate-number))
'face 'helm-fd-finish))))
(force-mode-line-update))
(helm-log "Error: Fd %s"
(replace-regexp-in-string "\n" "" event))))))))
(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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,170 @@
;;; helm-find.el --- helm interface for find command. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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 "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 "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

View file

@ -0,0 +1,344 @@
;;; helm-font --- Font and ucs selection for Helm -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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

View file

@ -0,0 +1,310 @@
;;; helm-for-files.el --- helm-for-files and related. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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 helm-recentf-fuzzy-match)))))
;;; 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-dir-is-dot 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

View file

@ -0,0 +1,96 @@
;;; helm-global-bindings.el --- Bind global helm commands -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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:
;;; Command Keymap
;;
;;
(defcustom helm-command-prefix-key "C-x c"
"The key `helm-command-prefix' is bound to in the global map."
:type '(choice (string :tag "Key") (const :tag "no binding"))
:group 'helm-config
:set
(lambda (var key)
(when (and (boundp var) (symbol-value var))
(define-key (current-global-map)
(read-kbd-macro (symbol-value var)) nil))
(when key
(define-key (current-global-map)
(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 "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-list-elisp-packages)
map))
;; Don't override the keymap we just defined with an empty
;; keymap. This also protect bindings changed by the user.
(defvar helm-command-prefix)
(define-prefix-command 'helm-command-prefix)
(fset 'helm-command-prefix helm-command-map)
(setq helm-command-prefix helm-command-map)
;;; Menu
(require 'helm-easymenu)
;;; Provide
(provide 'helm-global-bindings)
;;; helm-global-bindings.el ends here

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,125 @@
;;; helm-id-utils.el --- Helm interface for id-utils. -*- lexical-binding: t -*-
;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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 "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

View file

@ -0,0 +1,386 @@
;;; helm-imenu.el --- Helm interface for Imenu -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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)
(declare-function which-function "which-func")
(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))
;;; 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)
map))
(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 ()
(car (split-string
(buffer-substring
(point-at-bol) (point-at-eol))
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 (point-at-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))
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-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 (pcase (cdr elm) ; Same as [1].
((and ov (pred overlayp))
(copy-overlay ov))
((and mk (or (pred markerp)
(pred integerp)))
(copy-marker mk))))
(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-transformer (candidates)
(cl-loop for (k . v) in candidates
;; (k . v) == (symbol-name . marker)
for bufname = (buffer-name
(pcase v
((pred overlayp) (overlay-buffer v))
((or (pred markerp) (pred integerp))
(marker-buffer v))))
for types = (or (helm-imenu--get-prop k)
(list (if (with-current-buffer bufname
(derived-mode-p 'prog-mode))
"Function"
"Top level")
k))
for disp1 = (mapconcat
(lambda (x)
(propertize
x 'face
(cl-loop for (p . f) in helm-imenu-type-faces
when (string-match p x) return f
finally return 'default)))
types helm-imenu-delimiter)
for disp = (propertize disp1 'help-echo bufname 'types types)
collect
(cons disp (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

View file

@ -0,0 +1,300 @@
;;; helm-info.el --- Browse info index with helm -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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 'helm-utils)
(require 'info)
(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)
;;; 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-selected-window
(info file " *helm info temp buffer*")
(let ((tobuf (helm-candidate-buffer 'global))
Info-history)
(helm-aif (Info-index-nodes)
(cl-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+ (point-at-eol)) t)
(setq start (point-at-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 (point-at-bol))
(re-search-forward "(line +[0-9]+)" nil t))
(point-at-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."
(Info-goto-node (car node-line))
(helm-goto-line (cdr node-line)))
(defvar helm-info--node-regexp
"^\\* +\\(.+\\):[ \\t]+\\(.*\\)\\(?:[ \\t]*\\)(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 (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"
(helm-get-attr 'info-file)
(replace-regexp-in-string ":\\'" "" nodename))
(string-to-number (or linum "1")))
(cons (format "(%s)%s"
(helm-get-attr '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 (var-value &optional commands)
"Define Helm sources named helm-source-info-<NAME>.
Sources are generated for all entries of
`helm-default-info-index-list'.
If COMMANDS arg is non-nil, also build commands named
`helm-info-<NAME>'.
Where NAME is an element of `helm-default-info-index-list'."
(cl-loop for str in var-value
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

View file

@ -0,0 +1,476 @@
;;; helm-locate.el --- helm interface for locate. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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
:group 'helm-locate)
(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."
:group 'helm-locate
: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 --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\".
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
:group 'helm-locate)
(defcustom helm-locate-create-db-command
"updatedb -l 0 -o '%s' -U '%s'"
"Command used to create a locale locate db file."
:type 'string
:group 'helm-locate)
(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."
:group 'helm-locate
: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."
:group 'helm-locate
:type 'boolean)
(defcustom helm-locate-fuzzy-sort-fn
#'helm-locate-default-fuzzy-sort-fn
"Default fuzzy matching sort function for locate."
:group 'helm-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'."
:group 'helm-locate
: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
(gnu/linux "locate %s -e -A --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-init ()
"Initialize async locate process for `helm-source-locate'."
(let* ((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 "Starting helm-locate process")
(helm-log "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 "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))
(group :initform 'helm-locate)))
;; 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))
(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

View file

@ -0,0 +1,114 @@
;;; helm-man.el --- Man and woman UI -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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

View file

@ -0,0 +1,393 @@
;;; helm-misc.el --- Various functions for helm -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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))
(cl-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))))))
(cl-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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,435 @@
;;; helm-net.el --- helm browse url and search web. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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) or \"-new-window\"."
:group 'helm-net
:type '(radio
(const :tag "New tab" "-new-tab")
(const :tag "New window" "-new-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

View file

@ -0,0 +1,815 @@
;;; helm-occur.el --- Incremental Occur for Helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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")
;;; 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-\\{1\\}\\(.*\\)\\'"
"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."
:group '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."
:group 'helm-occur
: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."
:group 'helm-occur
:type 'boolean)
(defcustom helm-occur-truncate-lines t
"Truncate lines in occur buffer when non nil."
:group 'helm-occur
: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."
:group 'helm-regexp
: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."
:group 'helm-occur
:type 'integer)
(defcustom helm-occur-buffer-substring-fn-for-modes
'((mu4e-headers-mode . buffer-substring))
"Function to use to display buffer contents for major-mode.
Can be one of `buffer-substring' or `buffer-substring-no-properties'.
Note that when using `buffer-substring' initialization will be slower."
:group 'helm-regexp
: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-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'."
:group 'helm-regexp
: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."
:group 'helm-occur)
(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."
:group 'helm-occur)
(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
(point-at-bol) (point-at-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'.
(setq def (save-excursion
(goto-char (setq pos (car mark-ring)))
(helm-aif (thing-at-point 'symbol) (regexp-quote it))))
(narrow-to-region (region-beginning) (region-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 collect
(when (string-match helm-occur--search-buffer-regexp c)
(let ((linum (match-string 1 c))
(disp (match-string 2 c)))
(cons (format "%s:%s"
(propertize
linum 'face 'helm-grep-lineno
'help-echo (buffer-file-name
(get-buffer buf)))
disp)
(string-to-number linum))))))
(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."
(cl-loop for buf in buffers
for bname = (buffer-name buf)
collect
(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)))
:search (lambda (pattern)
(when (string-match "\\`\\^\\([^ ]*\\)" pattern)
(setq pattern (concat "^[0-9]* \\{1\\}" (match-string 1 pattern))))
(condition-case _err
(re-search-forward pattern nil t)
(invalid-regexp nil)))
:init `(lambda ()
(with-current-buffer ,buf
(let* ((bsfn (or (cdr (assq
major-mode
helm-occur-buffer-substring-fn-for-modes))
#'buffer-substring-no-properties))
(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)))
(defun helm-multi-occur-1 (buffers &optional input)
"Run `helm-occur' on a list of buffers.
Each buffer's result is displayed in a separated source."
(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 (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 reg in split-pat
when (save-excursion
(condition-case _err
(if helm-migemo-mode
(helm-mm-migemo-forward reg (point-at-eol) t)
(re-search-forward reg (point-at-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))
(defun helm-occur-run-goto-line-ow ()
"Run goto line other window action from `helm-occur'."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-occur-goto-line-ow)))
(put 'helm-occur-run-goto-line-ow 'helm-only t)
(defun helm-occur-run-goto-line-of ()
"Run goto line new frame action from `helm-occur'."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-occur-goto-line-of)))
(put 'helm-occur-run-goto-line-of 'helm-only t)
(defun helm-occur-run-default-action ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-occur-goto-line)))
(put 'helm-occur-run-default-action 'helm-only t)
(defun helm-occur-run-save-buffer ()
"Run moccur save results action from `helm-moccur'."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-occur-save-results)))
(put 'helm-moccur-run-save-buffer 'helm-only t)
(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)
(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)
(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 (point-at-bol))
(end (point-at-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
(point-at-bol) (point-at-eol)
`(buffer-name ,buf-name))
(add-text-properties
(point-at-bol) (point-at-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)
(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\\}\\(.*\\)$"
(point-at-eol) t))
(setq linum (string-to-number (match-string 1))
mpart (match-string 2)))
;; Match part after line number.
when (and mpart (string-match pattern mpart))
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"))))))
(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))
(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))
((< argp 0) (line-beginning-position))
((> argp 0) (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-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.3) (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

View file

@ -0,0 +1,11 @@
(define-package "helm" "20220423.1712" "Helm is an Emacs incremental and narrowing framework"
'((helm-core "3.8.4")
(popup "0.5.3"))
:commit "dc0c082a451cfe25d35ba3b9b0c0fc2766cc8319" :authors
'(("Thierry Volpiatto" . "thierry.volpiatto@gmail.com"))
:maintainer
'("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")
:url "https://emacs-helm.github.io/helm/")
;; Local Variables:
;; no-byte-compile: t
;; End:

View file

@ -0,0 +1,132 @@
;;; helm-regexp.el --- In buffer regexp searching and replacement for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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-mm-split-pattern "helm-multi-match")
(defgroup helm-regexp nil
"Regexp related Applications and libraries for Helm."
:group 'helm)
;; History vars
(defvar helm-build-regexp-history nil)
(defun helm-query-replace-regexp (_candidate)
"Query replace regexp from `helm-regexp'.
With a prefix arg replace only matches surrounded by word boundaries,
i.e. don't replace inside a word, regexp is surrounded with \\bregexp\\b."
(let ((regexp helm-input))
(apply 'query-replace-regexp
(helm-query-replace-args regexp))))
(defun helm-kill-regexp-as-sexp (_candidate)
"Kill regexp in a format usable in lisp code."
(helm-regexp-kill-new
(prin1-to-string helm-input)))
(defun helm-kill-regexp (_candidate)
"Kill regexp as it is in `helm-pattern'."
(helm-regexp-kill-new helm-input))
(defun helm-query-replace-args (regexp)
"Create arguments of `query-replace-regexp' action in `helm-regexp'."
(let ((region-only (helm-region-active-p)))
(list
regexp
(query-replace-read-to regexp
(format "Query replace %sregexp %s"
(if helm-current-prefix-arg "word " "")
(if region-only "in region " ""))
t)
helm-current-prefix-arg
(when region-only (region-beginning))
(when region-only (region-end)))))
(defvar helm-source-regexp
(helm-build-in-buffer-source "Regexp Builder"
:init (lambda ()
(helm-init-candidates-in-buffer
'global (with-temp-buffer
(insert-buffer-substring helm-current-buffer)
(buffer-string))))
:get-line #'helm-regexp-get-line
:persistent-action #'helm-regexp-persistent-action
:persistent-help "Show this line"
:multiline t
:multimatch nil
:requires-pattern 2
:group 'helm-regexp
:mode-line "Press TAB to select action."
:action '(("Kill Regexp as sexp" . helm-kill-regexp-as-sexp)
("Query Replace Regexp (C-u Not inside word.)"
. helm-query-replace-regexp)
("Kill Regexp" . helm-kill-regexp))))
(defun helm-regexp-get-line (s e)
(let ((matches (match-data))
(line (buffer-substring s e)))
(propertize
(cl-loop with ln = (format "%5d: %s" (1- (line-number-at-pos s)) line)
for i from 0 to (1- (/ (length matches) 2))
if (match-string i)
concat (format "\n%s%s'%s'"
(make-string 10 ? ) (format "Group %d: " i) it)
into ln1
finally return (concat ln ln1))
'helm-realvalue s)))
(defun helm-regexp-persistent-action (pt)
(helm-goto-char pt)
(helm-highlight-current-line))
(defun helm-regexp-kill-new (input)
(kill-new (substring-no-properties input))
(message "Killed: %s" input))
;;; Predefined commands
;;
;;
;;;###autoload
(defun helm-regexp ()
"Preconfigured helm to build regexps.
`query-replace-regexp' can be run from there against found regexp."
(interactive)
(save-restriction
(when (and (helm-region-active-p)
;; Don't narrow to region if buffer is already narrowed.
(not (helm-current-buffer-narrowed-p (current-buffer))))
(narrow-to-region (region-beginning) (region-end)))
(helm :sources helm-source-regexp
:buffer "*helm regexp*"
:prompt "Regexp: "
:history 'helm-build-regexp-history)))
(provide 'helm-regexp)
;;; helm-regexp.el ends here

View file

@ -0,0 +1,604 @@
;;; helm-ring.el --- kill-ring, mark-ring, and register browsers for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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-utils)
(require 'helm-help)
(require 'helm-elisp)
(declare-function undo-tree-restore-state-from-register "ext:undo-tree.el" (register))
(defgroup helm-ring nil
"Ring related Applications and libraries for Helm."
:group 'helm)
(defcustom helm-kill-ring-threshold 3
"Minimum length of a candidate to be listed by `helm-source-kill-ring'."
:type 'integer
:group 'helm-ring)
(defcustom helm-kill-ring-max-offset 400
"Max number of chars displayed per candidate in kill-ring browser.
When `t', don't truncate candidate, show all.
By default it is approximatively the number of bits contained in five lines
of 80 chars each, i.e. 80*5.
Note that if you set this to nil multiline will be disabled, i.e. you
will not have separators between candidates any more."
:type '(choice (const :tag "Disabled" t)
(integer :tag "Max candidate offset"))
:group 'helm-ring)
(defcustom helm-kill-ring-actions
'(("Yank marked" . helm-kill-ring-action-yank)
("Delete marked" . helm-kill-ring-action-delete)
("Search from candidate" . helm-kill-ring-search-from-string))
"List of actions for kill ring source."
:group 'helm-ring
:type '(alist :key-type string :value-type function))
(defcustom helm-kill-ring-separator "\n"
"The separator used to separate marked candidates when yanking."
:group 'helm-ring
:type 'string)
(defcustom helm-register-max-offset 160
"Max size of string register entries before truncating."
:group 'helm-ring
:type 'integer)
;;; Kill ring
;;
;;
(defvar helm-kill-ring-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "M-y") 'helm-next-line)
(define-key map (kbd "M-u") 'helm-previous-line)
(define-key map (kbd "M-D") 'helm-kill-ring-delete)
(define-key map (kbd "C-s") 'helm-kill-ring-run-search-from-string)
(define-key map (kbd "C-]") 'helm-kill-ring-toggle-truncated)
(define-key map (kbd "C-c C-k") 'helm-kill-ring-kill-selection)
(define-key map (kbd "C-c d") 'helm-kill-ring-run-persistent-delete)
map)
"Keymap for `helm-show-kill-ring'.")
(defvar helm-source-kill-ring
(helm-build-sync-source "Kill Ring"
:init (lambda ()
(helm-set-attr 'last-command last-command)
(helm-set-attr 'multiline helm-kill-ring-max-offset))
:candidates #'helm-kill-ring-candidates
:filtered-candidate-transformer #'helm-kill-ring-transformer
:action 'helm-kill-ring-actions
:persistent-action 'ignore
:help-message 'helm-kill-ring-help-message
:persistent-help "DoNothing"
:keymap helm-kill-ring-map
:migemo t
:multiline 'helm-kill-ring-max-offset
:group 'helm-ring)
"Source for browse and insert contents of kill-ring.")
(defun helm-kill-ring-candidates ()
(cl-loop with cands = (helm-fast-remove-dups kill-ring :test 'equal)
for kill in (if (eq (helm-get-attr 'last-command) 'yank)
(cdr cands)
cands)
unless (or (< (length kill) helm-kill-ring-threshold)
(string-match "\\`[\n[:blank:]]+\\'" kill))
collect kill))
(defun helm-kill-ring-transformer (candidates _source)
"Ensure CANDIDATES are not read-only."
(cl-loop for i in candidates
when (get-text-property 0 'read-only i)
do (set-text-properties 0 (length i) '(read-only nil) i)
collect i))
(defvar helm-kill-ring--truncated-flag nil)
(defun helm-kill-ring-toggle-truncated ()
"Toggle truncated view of candidates in helm kill-ring browser."
(interactive)
(with-helm-alive-p
(setq helm-kill-ring--truncated-flag (not helm-kill-ring--truncated-flag))
(let* ((cur-cand (helm-get-selection))
(presel-fn (lambda ()
(helm-kill-ring--preselect-fn cur-cand))))
(helm-set-attr 'multiline
(if helm-kill-ring--truncated-flag
15000000
helm-kill-ring-max-offset))
(helm-update presel-fn))))
(put 'helm-kill-ring-toggle-truncated 'helm-only t)
(defun helm-kill-ring-kill-selection ()
"Store the real value of candidate in kill-ring.
Same as `helm-kill-selection-and-quit' called with a prefix arg."
(interactive)
(helm-kill-selection-and-quit t))
(put 'helm-kill-ring-kill-selection 'helm-only t)
(defun helm-kill-ring--preselect-fn (candidate)
"Internal, used to preselect CANDIDATE when toggling truncated view."
;; Preselection by regexp may not work if candidate is huge, so walk
;; the helm buffer until selection is on CANDIDATE.
(helm-awhile (condition-case-unless-debug nil
(and (not (helm-pos-header-line-p))
(helm-get-selection))
(error nil))
(if (string= it candidate)
(cl-return)
(helm-next-line))))
(defun helm-kill-ring-action-yank (_str)
"Insert concatenated marked candidates in current-buffer.
When two prefix args are given prompt to choose separator, otherwise
use `helm-kill-ring-separator' as default."
(let ((marked (helm-marked-candidates))
(sep (if (equal helm-current-prefix-arg '(16))
(read-string "Separator: ")
helm-kill-ring-separator)))
(helm-kill-ring-action-yank-1
(cl-loop for c in (butlast marked)
concat (concat c sep) into str
finally return (concat str (car (last marked)))))))
(defun helm-kill-ring-action-yank-1 (str)
"Insert STR in `kill-ring' and set STR to the head.
When called with a prefix arg, point and mark are exchanged
without activating region.
If this action is executed just after `yank', replace with STR as
yanked string."
(let ((yank-fn (lambda (&optional before yank-pop)
(insert-for-yank str)
;; Set the window start back where it was in
;; the yank command, if possible.
(when yank-pop
(set-window-start (selected-window) yank-window-start t))
(when (or (equal helm-current-prefix-arg '(4)) before)
;; Same as exchange-point-and-mark but without
;; activating region.
(goto-char (prog1 (mark t)
(set-marker (mark-marker)
(point)
helm-current-buffer)))))))
;; Prevent inserting and saving highlighted items.
(set-text-properties 0 (length str) nil str)
(with-helm-current-buffer
(unwind-protect
(progn
(setq kill-ring (delete str kill-ring))
;; Adding a `delete-selection' property
;; to `helm-kill-ring-action' is not working
;; because `this-command' will be `helm-maybe-exit-minibuffer',
;; so use this workaround (Bug#1520).
(when (and (region-active-p) delete-selection-mode)
(delete-region (region-beginning) (region-end)))
(if (not (eq (helm-get-attr 'last-command helm-source-kill-ring) 'yank))
(progn
;; Ensure mark is at beginning of inserted text.
(push-mark)
;; When yanking in a helm minibuffer we need a small
;; delay to detect the mark in previous minibuffer. [1]
(run-with-timer 0.01 nil yank-fn))
;; from `yank-pop'
(let ((inhibit-read-only t)
(before (< (point) (mark t))))
(if before
(funcall (or yank-undo-function 'delete-region) (point) (mark t))
(funcall (or yank-undo-function 'delete-region) (mark t) (point)))
(setq yank-undo-function nil)
(set-marker (mark-marker) (point) helm-current-buffer)
;; Same as [1] but use the same mark and point as in
;; the initial yank according to BEFORE even if no
;; prefix arg is given.
(run-with-timer 0.01 nil yank-fn before 'pop))))
(kill-new str)))))
(define-obsolete-function-alias 'helm-kill-ring-action 'helm-kill-ring-action-yank "2.4.0")
(defun helm-kill-ring-search-from-string (candidate)
(let ((str (car (split-string candidate "\n"))))
(helm-multi-occur-1
(list (current-buffer))
(regexp-quote (substring-no-properties str)))))
(defun helm-kill-ring-run-search-from-string ()
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-kill-ring-search-from-string)))
(put 'helm-kill-ring-run-search-from-string 'helm-only t)
(defun helm-kill-ring-action-delete (_candidate)
"Delete marked candidates from `kill-ring'."
(cl-loop for c in (helm-marked-candidates)
do (setq kill-ring
(delete c kill-ring))))
(defun helm-kill-ring-persistent-delete (_candidate)
(unwind-protect
(cl-loop for c in (helm-marked-candidates)
do (progn
(helm-preselect (format "^%s" (regexp-quote c)))
(setq kill-ring (delete c kill-ring))
(helm-delete-current-selection)
(helm--remove-marked-and-update-mode-line c)))
(with-helm-buffer
(setq helm-marked-candidates nil
helm-visible-mark-overlays nil))
(helm-force-update (helm-aif (helm-get-selection nil t) (regexp-quote it)))))
(defun helm-kill-ring-run-persistent-delete ()
"Delete current candidate without quitting."
(interactive)
(with-helm-alive-p
(helm-set-attr 'quick-delete '(helm-kill-ring-persistent-delete . never-split))
(helm-execute-persistent-action 'quick-delete)))
(put 'helm-kill-ring-run-persistent-delete 'helm-only t)
(defun helm-kill-ring-delete ()
"Delete marked candidates from `kill-ring'.
This is a command for `helm-kill-ring-map'."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-kill-ring-action-delete)))
(put 'helm-kill-ring-delete 'helm-only t)
;;;; <Mark ring>
;; DO NOT use these sources with other sources use
;; the commands `helm-mark-ring', `helm-global-mark-ring' or
;; `helm-all-mark-rings' instead.
(defun helm-mark-ring-line-string-at-pos (pos)
"Return line string at position POS."
(save-excursion
(goto-char pos)
(forward-line 0)
(let ((line (car (split-string (thing-at-point 'line) "[\n\r]"))))
(remove-text-properties 0 (length line) '(read-only) line)
(if (string= "" line)
"<EMPTY LINE>"
line))))
(defun helm-mark-ring-get-candidates ()
(with-helm-current-buffer
(cl-loop with marks = (if (mark t)
(cons (mark-marker) mark-ring)
mark-ring)
for marker in marks
with max-line-number = (line-number-at-pos (point-max))
with width = (length (number-to-string max-line-number))
for m = (format (concat "%" (number-to-string width) "d: %s")
(line-number-at-pos marker)
(helm-mark-ring-line-string-at-pos marker))
unless (and recip (assoc m recip))
collect (cons m marker) into recip
finally return recip)))
(defun helm-mark-ring-default-action (candidate)
(let ((target (copy-marker candidate)))
(helm-aif (marker-buffer candidate)
(progn
(switch-to-buffer it)
(helm-log-run-hook 'helm-goto-line-before-hook)
(helm-match-line-cleanup)
(with-helm-current-buffer
(unless helm-yank-point (setq helm-yank-point (point))))
(helm-goto-char target)
(helm-highlight-current-line))
;; marker points to no buffer, no need to dereference it, just
;; delete it.
(setq mark-ring (delete target mark-ring))
(error "Marker points to no buffer"))))
(defvar helm-source-mark-ring
(helm-build-sync-source "mark-ring"
:candidates #'helm-mark-ring-get-candidates
:action '(("Goto line" . helm-mark-ring-default-action))
:persistent-help "Show this line"
:group 'helm-ring))
;;; Global-mark-ring
(defvar helm-source-global-mark-ring
(helm-build-sync-source "global-mark-ring"
:candidates #'helm-global-mark-ring-get-candidates
:action '(("Goto line" . helm-mark-ring-default-action))
:persistent-help "Show this line"
:group 'helm-ring))
(defun helm-global-mark-ring-format-buffer (marker)
(with-current-buffer (marker-buffer marker)
(goto-char marker)
(forward-line 0)
(let ((line (pcase (thing-at-point 'line)
((and line (pred stringp)
(guard (not (string-match-p "\\`\n?\\'" line))))
(car (split-string line "[\n\r]")))
(_ "<EMPTY LINE>"))))
(remove-text-properties 0 (length line) '(read-only) line)
(format "%7d:%s: %s"
(line-number-at-pos) (marker-buffer marker) line))))
(defun helm-global-mark-ring-get-candidates ()
(let ((marks global-mark-ring))
(when marks
(cl-loop for marker in marks
for mb = (marker-buffer marker)
for gm = (unless (or (string-match "^ " (format "%s" mb))
(null mb))
(helm-global-mark-ring-format-buffer marker))
when (and gm (not (assoc gm recip)))
collect (cons gm marker) into recip
finally return recip))))
;;;; <Register>
;;; Insert from register
(defvar helm-source-register
(helm-build-sync-source "Registers"
:candidates #'helm-register-candidates
:action-transformer #'helm-register-action-transformer
:persistent-help ""
:multiline t
:action '(("Delete Register(s)" .
(lambda (_candidate)
(cl-loop for candidate in (helm-marked-candidates)
for register = (car candidate)
do (setq register-alist
(delq (assoc register register-alist)
register-alist))))))
:group 'helm-ring)
"See (info \"(emacs)Registers\")")
(defun helm-register-candidates ()
"Collecting register contents and appropriate commands."
(cl-loop for (char . rval) in register-alist
for key = (single-key-description char)
for e27 = (registerv-p rval)
for val = (if e27 ; emacs-27
(registerv-data rval)
rval)
for string-actions =
(cond
((numberp val)
(list (int-to-string val)
'insert-register
'increment-register))
((markerp val)
(let ((buf (marker-buffer val)))
(if (null buf)
(list "a marker in no buffer")
(list (concat
"a buffer position:"
(buffer-name buf)
", position "
(int-to-string (marker-position val)))
'jump-to-register
'insert-register))))
((and (consp val) (window-configuration-p (car val)))
(list "window configuration."
'jump-to-register))
((and (vectorp val)
(fboundp 'undo-tree-register-data-p)
(undo-tree-register-data-p (if e27 val (elt val 1))))
(list
"Undo-tree entry."
'undo-tree-restore-state-from-register))
((or (and (vectorp val) (eq 'registerv (aref val 0)))
(and (consp val) (frame-configuration-p (car val))))
(list "frame configuration."
'jump-to-register))
((and (consp val) (eq (car val) 'file))
(list (concat "file:"
(prin1-to-string (cdr val))
".")
'jump-to-register))
((and (consp val) (eq (car val) 'file-query))
(list (concat "file:a file-query reference: file "
(car (cdr val))
", position "
(int-to-string (car (cdr (cdr val))))
".")
'jump-to-register))
((consp val)
(let ((lines (format "%4d" (length val))))
(list (format "%s: %s\n" lines
(truncate-string-to-width
(mapconcat 'identity (list (car val))
"^J")
(- (window-width) 15)))
'insert-register)))
((stringp val)
(list
(concat (substring-no-properties
val 0 (min (length val) helm-register-max-offset))
(if (> (length val) helm-register-max-offset)
"[...]" ""))
'insert-register
'kill-new
'append-to-register
'prepend-to-register)))
unless (null string-actions) ; Fix Bug#1107.
collect (cons (format "Register %3s:\n %s" key (car string-actions))
(cons char (cdr string-actions)))))
(defun helm-register-action-transformer (actions register-and-functions)
"Decide actions by the contents of register."
(cl-loop with func-actions =
'((insert-register
"Insert Register" .
(lambda (c) (insert-register (car c))))
(kill-new
"Kill Register" .
(lambda (c) (with-temp-buffer
(insert-register (car c))
(kill-new (buffer-string)))))
(jump-to-register
"Jump to Register" .
(lambda (c) (jump-to-register (car c))))
(append-to-register
"Append Region to Register" .
(lambda (c) (append-to-register
(car c) (region-beginning) (region-end))))
(prepend-to-register
"Prepend Region to Register" .
(lambda (c) (prepend-to-register
(car c) (region-beginning) (region-end))))
(increment-register
"Increment Prefix Arg to Register" .
(lambda (c) (increment-register
helm-current-prefix-arg (car c))))
(undo-tree-restore-state-from-register
"Restore Undo-tree register" .
(lambda (c) (and (fboundp 'undo-tree-restore-state-from-register)
(undo-tree-restore-state-from-register (car c))))))
for func in (cdr register-and-functions)
when (assq func func-actions)
collect (cdr it) into transformer-actions
finally return (append transformer-actions actions)))
;;;###autoload
(defun helm-mark-ring ()
"Preconfigured `helm' for `helm-source-mark-ring'."
(interactive)
(helm :sources 'helm-source-mark-ring
:resume 'noresume
:buffer "*helm mark*"))
;;;###autoload
(defun helm-global-mark-ring ()
"Preconfigured `helm' for `helm-source-global-mark-ring'."
(interactive)
(helm :sources 'helm-source-global-mark-ring
:resume 'noresume
:buffer "*helm global mark*"))
;;;###autoload
(defun helm-all-mark-rings ()
"Preconfigured `helm' for mark rings.
Source used are `helm-source-global-mark-ring' and
`helm-source-mark-ring'."
(interactive)
(helm :sources '(helm-source-mark-ring
helm-source-global-mark-ring)
:resume 'noresume
:buffer "*helm mark ring*"))
;;;###autoload
(defun helm-register ()
"Preconfigured `helm' for Emacs registers."
(interactive)
(helm :sources 'helm-source-register
:resume 'noresume
:buffer "*helm register*"))
;;;###autoload
(defun helm-show-kill-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."
(interactive)
(setq helm-kill-ring--truncated-flag nil)
(let ((enable-recursive-minibuffers t))
(helm :sources helm-source-kill-ring
:buffer "*helm kill ring*"
:resume 'noresume
:allow-nest t)))
;;;###autoload
(defun helm-execute-kmacro ()
"Preconfigured helm for keyboard macros.
Define your macros with `f3' and `f4'.
See (info \"(emacs) Keyboard Macros\") for detailed infos.
This command is useful when used with persistent action."
(interactive)
(let ((helm-quit-if-no-candidate
(lambda () (message "No kbd macro has been defined"))))
(helm :sources
(helm-build-sync-source "Kmacro"
:candidates (lambda ()
(helm-fast-remove-dups
(cons (kmacro-ring-head)
kmacro-ring)
:test 'equal))
:multiline t
:candidate-transformer
(lambda (candidates)
(cl-loop for c in candidates collect
(propertize (help-key-description (car c) nil)
'helm-realvalue c)))
:persistent-help "Execute kmacro"
:help-message 'helm-kmacro-help-message
:action
(helm-make-actions
"Execute kmacro (`C-u <n>' to execute <n> times)"
'helm-kbd-macro-execute
"Concat marked macros"
'helm-kbd-macro-concat-macros
"Delete marked macros"
'helm-kbd-macro-delete-macro
"Edit marked macro"
'helm-kbd-macro-edit-macro)
:group 'helm-ring)
:buffer "*helm kmacro*")))
(defun helm-kbd-macro-execute (candidate)
;; Move candidate on top of list for next use.
(setq kmacro-ring (delete candidate kmacro-ring))
(kmacro-push-ring)
(kmacro-split-ring-element candidate)
(kmacro-exec-ring-item
candidate helm-current-prefix-arg))
(defun helm-kbd-macro-concat-macros (_candidate)
(let ((mkd (helm-marked-candidates)))
(when (cdr mkd)
(kmacro-push-ring)
(setq last-kbd-macro
(mapconcat 'identity
(cl-loop for km in mkd
if (vectorp km)
append (cl-loop for k across km collect
(key-description (vector k)))
into result
else collect (car km) into result
finally return result)
"")))))
(defun helm-kbd-macro-delete-macro (_candidate)
(let ((mkd (helm-marked-candidates)))
(kmacro-push-ring)
(cl-loop for km in mkd
do (setq kmacro-ring (delete km kmacro-ring)))
(kmacro-pop-ring1)))
(defun helm-kbd-macro-edit-macro (candidate)
(kmacro-push-ring)
(setq kmacro-ring (delete candidate kmacro-ring))
(kmacro-split-ring-element candidate)
(kmacro-edit-macro))
(provide 'helm-ring)
;;; helm-ring.el ends here

View file

@ -0,0 +1,232 @@
;;; helm-semantic.el --- Helm interface for Semantic -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2017 Daniel Hackney <dan@haxney.org>
;; 2012 ~ 2021 Thierry Volpiatto<thierry.volpiatto@gmail.com>
;; Author: Daniel Hackney <dan@haxney.org>
;; 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:
;; Uses `candidates-in-buffer' for speed.
;;; Code:
(require 'cl-lib)
(require 'semantic)
(require 'helm-help)
(require 'helm-imenu)
(declare-function pulse-momentary-highlight-one-line "pulse.el" (point &optional face))
(defgroup helm-semantic nil
"Semantic tags related libraries and applications for helm."
:group 'helm)
(defcustom helm-semantic-display-style
'((python-mode . semantic-format-tag-summarize)
(c-mode . semantic-format-tag-concise-prototype-c-mode)
(emacs-lisp-mode . semantic-format-tag-abbreviate-emacs-lisp-mode))
"Function to present a semantic tag according to `major-mode'.
It is an alist where the `car' of each element is a `major-mode' and
the `cdr' a `semantic-format-tag-*' function.
If no function is found for current `major-mode', fall back to
`semantic-format-tag-summarize' default function.
You can have more or less informations depending of the `semantic-format-tag-*'
function you choose.
All the supported functions are prefixed with \"semantic-format-tag-\",
you have completion on these functions with `C-M i' in the customize interface."
:group 'helm-semantic
:type '(alist :key-type symbol :value-type symbol))
;;; keymap
(defvar helm-semantic-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
map))
(defcustom helm-semantic-lynx-style-map nil
"Use Arrow keys to jump to occurences."
:group 'helm-semantic
:type 'boolean
:set (lambda (var val)
(set var val)
(if val
(progn
(define-key helm-semantic-map (kbd "<right>") 'helm-execute-persistent-action)
(define-key helm-semantic-map (kbd "<left>") 'helm-maybe-exit-minibuffer))
(define-key helm-semantic-map (kbd "<right>") nil)
(define-key helm-semantic-map (kbd "<left>") nil))))
;; Internals vars
(defvar helm-semantic--tags-cache nil)
(defun helm-semantic--fetch-candidates (tags depth &optional class)
"Write the contents of TAGS to the current buffer."
(let ((class class) cur-type
(stylefn (or (with-helm-current-buffer
(assoc-default major-mode helm-semantic-display-style))
#'semantic-format-tag-summarize)))
(cl-dolist (tag tags)
(when (listp tag)
(cl-case (setq cur-type (semantic-tag-class tag))
((function variable type)
(let ((spaces (make-string (* depth 2) ?\s))
(type-p (eq cur-type 'type)))
(unless (and (> depth 0) (not type-p))
(setq class nil))
(insert
(if (and class (not type-p))
(format "%s%s(%s) "
spaces (if (< depth 2) "" "├►") class)
spaces)
;; Save the tag for later
(propertize (funcall stylefn tag nil t)
'semantic-tag tag)
"\n")
(and type-p (setq class (car tag)))
;; Recurse to children
(unless (eq cur-type 'function)
(helm-semantic--fetch-candidates
(semantic-tag-components tag) (1+ depth) class))))
;; Don't do anything with packages or includes for now
((package include)
(insert
(propertize (funcall stylefn tag nil t)
'semantic-tag tag)
"\n")
)
;; Catch-all
(t))))))
(defun helm-semantic-default-action (_candidate &optional persistent)
;; By default, helm doesn't pass on the text properties of the selection.
;; Fix this.
(helm-log-run-hook 'helm-goto-line-before-hook)
(with-current-buffer helm-buffer
(when (looking-at " ")
(goto-char (next-single-property-change
(point-at-bol) 'semantic-tag nil (point-at-eol))))
(let ((tag (get-text-property (point) 'semantic-tag)))
(semantic-go-to-tag tag)
(unless persistent
(pulse-momentary-highlight-one-line (point))))))
(defun helm-semantic--maybe-set-needs-update ()
(with-helm-current-buffer
(when (semantic-parse-tree-needs-update-p)
(semantic-parse-tree-set-needs-update))))
(defvar helm-source-semantic nil)
(defclass helm-semantic-source (helm-source-in-buffer)
((init :initform (lambda ()
(helm-semantic--maybe-set-needs-update)
(setq helm-semantic--tags-cache (semantic-fetch-tags))
(with-current-buffer (helm-candidate-buffer 'global)
(let ((major-mode (with-helm-current-buffer major-mode)))
(helm-semantic--fetch-candidates helm-semantic--tags-cache 0)))))
(get-line :initform 'buffer-substring)
(persistent-help :initform "Show this entry")
(keymap :initform 'helm-semantic-map)
(help-message :initform 'helm-semantic-help-message)
(persistent-action :initform (lambda (elm)
(helm-semantic-default-action elm t)
(helm-highlight-current-line)))
(action :initform 'helm-semantic-default-action)))
(defcustom helm-semantic-fuzzy-match nil
"Enable fuzzy matching in `helm-source-semantic'."
:group 'helm-semantic
:type 'boolean
:set (lambda (var val)
(set var val)
(setq helm-source-semantic
(helm-make-source "Semantic Tags" 'helm-semantic-source
:fuzzy-match helm-semantic-fuzzy-match))))
;;;###autoload
(defun helm-semantic (arg)
"Preconfigured `helm' for `semantic'.
If ARG is supplied, pre-select symbol at point instead of current."
(interactive "P")
(let ((tag (helm-aif (car (semantic-current-tag-parent))
(let ((curtag (car (semantic-current-tag))))
(if (string= it curtag)
(format "\\_<%s\\_>" curtag)
(cons (format "\\_<%s\\_>" it)
(format "\\_<%s\\_>" curtag))))
(format "\\_<%s\\_>" (car (semantic-current-tag)))))
(helm-highlight-matches-around-point-max-lines 'never))
(unless helm-source-semantic
(setq helm-source-semantic
(helm-make-source "Semantic Tags" 'helm-semantic-source
:fuzzy-match helm-semantic-fuzzy-match)))
(helm :sources 'helm-source-semantic
:candidate-number-limit 9999
:preselect (if arg
(thing-at-point 'symbol)
tag)
:buffer "*helm semantic*")))
;;;###autoload
(defun helm-semantic-or-imenu (arg)
"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."
(interactive "P")
(unless helm-source-semantic
(setq helm-source-semantic
(helm-make-source "Semantic Tags" 'helm-semantic-source
:fuzzy-match helm-semantic-fuzzy-match)))
(unless helm-source-imenu
(setq helm-source-imenu
(helm-make-source "Imenu" 'helm-imenu-source
:fuzzy-match helm-imenu-fuzzy-match)))
(let* ((source (if (semantic-active-p)
'helm-source-semantic
'helm-source-imenu))
(helm-highlight-matches-around-point-max-lines 'never)
(imenu-p (eq source 'helm-source-imenu))
(imenu-auto-rescan imenu-p)
(str (thing-at-point 'symbol))
(helm-execute-action-at-once-if-one
(and imenu-p
helm-imenu-execute-action-at-once-if-one))
(tag (helm-aif (car (semantic-current-tag-parent))
(let ((curtag (car (semantic-current-tag))))
(if (string= it curtag)
(format "\\_<%s\\_>" curtag)
(cons (format "\\_<%s\\_>" it)
(format "\\_<%s\\_>" curtag))))
(format "\\_<%s\\_>" (car (semantic-current-tag))))))
(helm :sources source
:candidate-number-limit 9999
:default (and imenu-p (list (concat "\\_<" (and str (regexp-quote str)) "\\_>") str))
:preselect (if (or arg imenu-p) str tag)
:buffer "*helm semantic/imenu*")))
(provide 'helm-semantic)
;;; helm-semantic.el ends here

View file

@ -0,0 +1,38 @@
;;; helm-shell.el --- Shell prompt navigation for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2020 Pierre Neidhardt <mail@ambrevar.xyz>
;; 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:
;;
;; This is superseded by helm-comint.el.
;;; Code:
(require 'cl-lib)
(require 'helm)
(require 'helm-lib)
(require 'helm-help)
(require 'helm-elisp)
(require 'helm-comint)
;;;###autoload
(defalias 'helm-shell-prompts 'helm-comint-prompts)
;;;###autoload
(defalias 'helm-shell-prompts-all 'helm-comint-prompts-all)
(provide 'helm-shell)
;;; helm-shell ends here

View file

@ -0,0 +1,457 @@
;;; helm-sys.el --- System related functions for helm. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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)
(defgroup helm-sys nil
"System related helm library."
:group 'helm)
(defface helm-top-columns
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:inherit helm-header))
"Face for helm help string in minibuffer."
:group 'helm-sys)
(defcustom helm-top-command
(cl-case system-type
(darwin "env COLUMNS=%s ps -axo pid,user,pri,nice,ucomm,tty,start_time,vsz,%%cpu,%%mem,etime,command")
(t "env COLUMNS=%s top -b -n 1"))
"Top command used to display output of top.
A format string where %s will be replaced with `frame-width'.
To use 'top' command, a version supporting batch mode (-b option)
is needed. On Mac OSX 'top' command doesn't support this, so the
'ps' command is used instead by default.
Normally 'top' command output have 12 columns, but in some
versions you may have less than this, so you can either customize
top to use 12 columns with the interactives 'f' and 'W' commands
of top, or modify `helm-top-sort-columns-alist' to fit with the
number of columns your 'top' command is using.
If you modify 'ps' command be sure that 'pid' comes in first and
\"env COLUMNS=%s\" is specified at beginning of command. Ensure
also that no elements contain spaces (e.g., use start_time and
not start). Same as for 'top': you can customize
`helm-top-sort-columns-alist' to make sort commands working
properly according to your settings."
:group 'helm-sys
:type 'string)
(defcustom helm-top-sort-columns-alist '((com . 11)
(mem . 9)
(cpu . 8)
(user . 1))
"Allow defining which column to use when sorting output of top/ps command.
Only com, mem, cpu and user are sorted, so no need to put something
else there,it will have no effect.
Note that column numbers are counted from zero, i.e. column 1 is the
nth 0 column."
:group 'helm-sys
:type '(alist :key-type symbol :value-type (integer :tag "Column number")))
(defcustom helm-top-poll-delay 1.5
"Helm top poll after this delay when `helm-top-poll-mode' is enabled.
The minimal delay allowed is 1.5, if less than this helm-top will use 1.5."
:group 'helm-sys
:type 'float)
(defcustom helm-top-poll-delay-post-command 1.0
"Helm top stop polling during this delay.
This delay is added to `helm-top-poll-delay' after Emacs stops
being idle."
:group 'helm-sys
:type 'float)
(defcustom helm-top-poll-preselection 'linum
"Stay on same line or follow candidate when `helm-top-poll' updates display.
Possible values are 'candidate or 'linum.
This affects also sorting functions in the same way."
:group'helm-sys
:type '(radio :tag "Preferred preselection action for helm-top"
(const :tag "Follow candidate" candidate)
(const :tag "Stay on same line" linum)))
;;; Top (process)
;;
;;
(defvar helm-top-sort-fn nil)
(defvar helm-top-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "M-P") 'helm-top-run-sort-by-cpu)
(define-key map (kbd "M-C") 'helm-top-run-sort-by-com)
(define-key map (kbd "M-M") 'helm-top-run-sort-by-mem)
(define-key map (kbd "M-U") 'helm-top-run-sort-by-user)
map))
(defvar helm-top-after-init-hook nil
"Local hook for helm-top.")
(defvar helm-top--poll-timer nil)
(defun helm-top-poll (&optional no-update delay)
(when helm-top--poll-timer
(cancel-timer helm-top--poll-timer))
(condition-case nil
(progn
(when (and (helm--alive-p) (null no-update))
;; Fix quitting while process is running
;; by binding `with-local-quit' in init function
;; Bug#1521.
(helm-force-update
(cl-ecase helm-top-poll-preselection
(candidate (replace-regexp-in-string
"[0-9]+" "[0-9]+"
(regexp-quote (helm-get-selection nil t))))
(linum `(lambda ()
(goto-char (point-min))
(forward-line ,(helm-candidate-number-at-point)))))))
(setq helm-top--poll-timer
(run-with-idle-timer
(helm-aif (current-idle-time)
(time-add it (seconds-to-time
(or delay (helm-top--poll-delay))))
(or delay (helm-top--poll-delay)))
nil
'helm-top-poll)))
(quit (cancel-timer helm-top--poll-timer))))
(defun helm-top--poll-delay ()
(max 1.5 helm-top-poll-delay))
(defun helm-top-poll-no-update ()
(helm-top-poll t (+ (helm-top--poll-delay)
helm-top-poll-delay-post-command)))
(defun helm-top-initialize-poll-hooks ()
;; When Emacs is idle during say 20s
;; the idle timer will run in 20+1.5 s.
;; This is fine when Emacs stays idle, because the next timer
;; will run at 21.5+1.5 etc... so the display will be updated
;; at every 1.5 seconds.
;; But as soon as emacs looses its idleness, the next update
;; will occur at say 21+1.5 s, so we have to reinitialize
;; the timer at 0+1.5.
(add-hook 'post-command-hook 'helm-top-poll-no-update)
(add-hook 'focus-in-hook 'helm-top-poll-no-update))
;;;###autoload
(define-minor-mode helm-top-poll-mode
"Refresh automatically helm top buffer once enabled."
:group 'helm-top
:global t
(if helm-top-poll-mode
(progn
(add-hook 'helm-top-after-init-hook 'helm-top-poll-no-update)
(add-hook 'helm-top-after-init-hook 'helm-top-initialize-poll-hooks))
(remove-hook 'helm-top-after-init-hook 'helm-top-poll-no-update)
(remove-hook 'helm-top-after-init-hook 'helm-top-initialize-poll-hooks)))
(defvar helm-source-top
(helm-build-in-buffer-source "Top"
:header-name (lambda (name)
(concat name (if helm-top-poll-mode
" (auto updating)"
" (Press C-c C-u to refresh)")))
:init #'helm-top-init
:after-init-hook 'helm-top-after-init-hook
:cleanup (lambda ()
(when helm-top--poll-timer
(cancel-timer helm-top--poll-timer))
(remove-hook 'post-command-hook 'helm-top-poll-no-update)
(remove-hook 'focus-in-hook 'helm-top-poll-no-update))
:display-to-real #'helm-top-display-to-real
:persistent-action '(helm-top-sh-persistent-action . never-split)
:persistent-help "SIGTERM"
:help-message 'helm-top-help-message
:mode-line 'helm-top-mode-line
:follow 'never
:keymap helm-top-map
:filtered-candidate-transformer #'helm-top-sort-transformer
:action-transformer #'helm-top-action-transformer
:group 'helm-sys))
(defvar helm-top--line nil)
(defun helm-top-transformer (candidates _source)
"Transformer for `helm-top'.
Return empty string for non--valid candidates."
(cl-loop for disp in candidates collect
(cond ((string-match "^ *[0-9]+" disp) disp)
((string-match "^ *PID" disp)
(setq helm-top--line (cons (propertize disp 'face 'helm-top-columns) "")))
(t (cons disp "")))
into lst
finally return (or (member helm-top--line lst)
(cons helm-top--line lst))))
(defun helm-top--skip-top-line ()
(let* ((src (helm-get-current-source))
(src-name (assoc-default 'name src)))
(helm-aif (and (stringp src-name)
(string= src-name "Top")
(helm-get-selection nil t src))
(when (string-match-p "^ *PID" it)
(helm-next-line)))))
(defun helm-top-action-transformer (actions _candidate)
"Action transformer for `top'.
Show actions only on line starting by a PID."
(let ((disp (helm-get-selection nil t)))
(cond ((string-match "\\` *[0-9]+" disp)
(list '("kill (SIGTERM)" . (lambda (_pid)
(helm-top-sh "TERM" (helm-top--marked-pids))))
'("kill (SIGKILL)" . (lambda (_pid)
(helm-top-sh "KILL" (helm-top--marked-pids))))
'("kill (SIGINT)" . (lambda (_pid)
(helm-top-sh "INT" (helm-top--marked-pids))))
'("kill (Choose signal)"
. (lambda (_pid)
(let ((pids (helm-top--marked-pids)))
(helm-top-sh
(helm-comp-read (format "Kill %d pids with signal: "
(length pids))
'("ALRM" "HUP" "INT" "KILL" "PIPE" "POLL"
"PROF" "TERM" "USR1" "USR2" "VTALRM"
"STKFLT" "PWR" "WINCH" "CHLD" "URG"
"TSTP" "TTIN" "TTOU" "STOP" "CONT"
"ABRT" "FPE" "ILL" "QUIT" "SEGV"
"TRAP" "SYS" "EMT" "BUS" "XCPU" "XFSZ")
:must-match t)
pids))))))
(t actions))))
(defun helm-top--marked-pids ()
(helm-remove-if-not-match "\\`[0-9]+\\'" (helm-marked-candidates)))
(defun helm-top-sh (sig pids)
"Run kill shell command with signal SIG on PIDS for `helm-top'."
(message "kill -%s %s exited with status %s"
sig (mapconcat 'identity pids " ")
(apply #'call-process
"kill" nil nil nil (format "-%s" sig) pids)))
(defun helm-top-sh-persistent-action (pid)
(helm-top-sh "TERM" (list pid))
(helm-delete-current-selection))
(defun helm-top-init ()
"Insert output of top command in candidate buffer."
(with-local-quit
(unless helm-top-sort-fn (helm-top-set-mode-line "CPU"))
(with-current-buffer (helm-candidate-buffer 'global)
(call-process-shell-command
(format helm-top-command (frame-width))
nil (current-buffer)))))
(defun helm-top-display-to-real (line)
"Return pid only from LINE."
(car (split-string line)))
;; Sort top command
(defun helm-top-set-mode-line (str)
(if (string-match "Sort:\\[\\(.*\\)\\] " helm-top-mode-line)
(setq helm-top-mode-line (replace-match str nil nil helm-top-mode-line 1))
(setq helm-top-mode-line (concat (format "Sort:[%s] " str) helm-top-mode-line))))
(defun helm-top-sort-transformer (candidates source)
(helm-top-transformer
(if helm-top-sort-fn
(cl-loop for c in candidates
if (string-match "^ *[0-9]+" c)
collect c into pid-cands
else collect c into header-cands
finally return (append
header-cands
(sort pid-cands helm-top-sort-fn)))
candidates)
source))
(defun helm-top-sort-by-com (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
(col (cdr (assq 'com helm-top-sort-columns-alist)))
(com-1 (nth col split-1))
(com-2 (nth col split-2)))
(string< com-1 com-2)))
(defun helm-top-sort-by-mem (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
(col (cdr (assq 'mem helm-top-sort-columns-alist)))
(mem-1 (string-to-number (nth col split-1)))
(mem-2 (string-to-number (nth col split-2))))
(> mem-1 mem-2)))
(defun helm-top-sort-by-cpu (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
(col (cdr (assq 'cpu helm-top-sort-columns-alist)))
(cpu-1 (string-to-number (nth col split-1)))
(cpu-2 (string-to-number (nth col split-2))))
(> cpu-1 cpu-2)))
(defun helm-top-sort-by-user (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
(col (cdr (assq 'user helm-top-sort-columns-alist)))
(user-1 (nth col split-1))
(user-2 (nth col split-2)))
(string< user-1 user-2)))
(defun helm-top--preselect-fn ()
(if (eq helm-top-poll-preselection 'linum)
`(lambda ()
(goto-char (point-min))
(forward-line ,(helm-candidate-number-at-point)))
(replace-regexp-in-string
"[0-9]+" "[0-9]+"
(regexp-quote (helm-get-selection nil t)))))
(defun helm-top-run-sort-by-com ()
(interactive)
(helm-top-set-mode-line "COM")
(setq helm-top-sort-fn 'helm-top-sort-by-com)
(helm-update (helm-top--preselect-fn)))
(defun helm-top-run-sort-by-cpu ()
(interactive)
(helm-top-set-mode-line "CPU")
;; Force sorting by CPU even if some versions of top are using by
;; default CPU sorting (Bug#1908).
(setq helm-top-sort-fn 'helm-top-sort-by-cpu)
(helm-update (helm-top--preselect-fn)))
(defun helm-top-run-sort-by-mem ()
(interactive)
(helm-top-set-mode-line "MEM")
(setq helm-top-sort-fn 'helm-top-sort-by-mem)
(helm-update (helm-top--preselect-fn)))
(defun helm-top-run-sort-by-user ()
(interactive)
(helm-top-set-mode-line "USER")
(setq helm-top-sort-fn 'helm-top-sort-by-user)
(helm-update (helm-top--preselect-fn)))
;;; X RandR resolution change
;;
;;
;;; FIXME I do not care multi-display.
(defun helm-xrandr-info ()
"Return a pair with current X screen number and current X display name."
(with-temp-buffer
(call-process "xrandr" nil (current-buffer) nil
"--current")
(let (screen output)
(goto-char (point-min))
(save-excursion
(when (re-search-forward "\\(^Screen \\)\\([0-9]\\):" nil t)
(setq screen (match-string 2))))
(when (re-search-forward "^\\(.*\\) connected" nil t)
(setq output (match-string 1)))
(list screen output))))
(defun helm-xrandr-screen ()
"Return current X screen number."
(car (helm-xrandr-info)))
(defun helm-xrandr-output ()
"Return current X display name."
(cadr (helm-xrandr-info)))
(defvar helm-source-xrandr-change-resolution
(helm-build-sync-source "Change Resolution"
:candidates
(lambda ()
(with-temp-buffer
(call-process "xrandr" nil (current-buffer) nil
"--screen" (helm-xrandr-screen) "-q")
(goto-char 1)
(cl-loop while (re-search-forward " \\([0-9]+x[0-9]+\\)" nil t)
for mode = (match-string 1)
unless (member mode modes)
collect mode into modes
finally return modes)))
:action
(helm-make-actions "Change Resolution"
(lambda (mode)
(call-process "xrandr" nil nil nil
"--screen" (helm-xrandr-screen)
"--output" (helm-xrandr-output)
"--mode" mode)))))
;;; Emacs process
;;
;;
(defvar helm-source-emacs-process
(helm-build-sync-source "Emacs Process"
:init (lambda ()
(let (tabulated-list-use-header-line)
(list-processes--refresh)))
:candidates (lambda () (mapcar #'process-name (process-list)))
:persistent-action (lambda (elm)
(delete-process (get-process elm))
(helm-delete-current-selection))
:persistent-help "Kill Process"
:action (helm-make-actions "Kill Process"
(lambda (_elm)
(cl-loop for p in (helm-marked-candidates)
do (delete-process (get-process p)))))))
;;;###autoload
(defun helm-top ()
"Preconfigured `helm' for top command."
(interactive)
(add-hook 'helm-after-update-hook 'helm-top--skip-top-line)
(unwind-protect
(helm :sources 'helm-source-top
:buffer "*helm top*" :full-frame t
:candidate-number-limit 9999
:preselect "^\\s-*[0-9]+"
:truncate-lines helm-show-action-window-other-window)
(remove-hook 'helm-after-update-hook 'helm-top--skip-top-line)))
;;;###autoload
(defun helm-list-emacs-process ()
"Preconfigured `helm' for Emacs process."
(interactive)
(helm-other-buffer 'helm-source-emacs-process "*helm process*"))
;;;###autoload
(defun helm-xrandr-set ()
"Preconfigured helm for xrandr."
(interactive)
(helm :sources 'helm-source-xrandr-change-resolution
:buffer "*helm xrandr*"))
(provide 'helm-sys)
;;; helm-sys.el ends here

View file

@ -0,0 +1,348 @@
;;; helm-tags.el --- Helm for Etags. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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)
(require 'helm-grep)
(defvar helm-etags-fuzzy-match)
(declare-function ring-insert "ring")
(defgroup helm-tags nil
"Tags related Applications and libraries for Helm."
:group 'helm)
(defcustom helm-etags-tag-file-name "TAGS"
"Etags tag file name."
:type 'string
:group 'helm-tags)
(defcustom helm-etags-tag-file-search-limit 10
"The limit level of directory to search tag file.
Don't search tag file deeply if outside this value."
:type 'number
:group 'helm-tags)
(defcustom helm-etags-match-part-only 'tag
"Allow choosing the tag part of CANDIDATE in `helm-source-etags-select'.
A tag looks like this:
filename: \(defun foo
You can choose matching against the tag part (i.e \"(defun foo\"),
or against the whole candidate (i.e \"(filename:5:(defun foo\")."
:type '(choice
(const :tag "Match only tag" tag)
(const :tag "Match all file+tag" all))
:group 'helm-tags)
(defcustom helm-etags-execute-action-at-once-if-one t
"Whether to jump straight to the selected tag if there's only
one match."
:type 'boolean
:group 'helm-tags)
(defgroup helm-tags-faces nil
"Customize the appearance of helm-tags faces."
:prefix "helm-"
:group 'helm-tags
:group 'helm-faces)
(defface helm-etags-file
`((t ,@(and (>= emacs-major-version 27) '(:extend t))
:foreground "Lightgoldenrod4"
:underline t))
"Face used to highlight etags filenames."
:group 'helm-tags-faces)
;;; Etags
;;
;;
(defun helm-etags-run-switch-other-window ()
"Run switch to other window action from `helm-source-etags-select'."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action
(lambda (c)
(helm-etags-action-goto 'find-file-other-window c)))))
(put 'helm-etags-run-switch-other-window 'helm-only t)
(defun helm-etags-run-switch-other-frame ()
"Run switch to other frame action from `helm-source-etags-select'."
(interactive)
(with-helm-alive-p
(helm-exit-and-execute-action
(lambda (c)
(helm-etags-action-goto 'find-file-other-frame c)))))
(put 'helm-etags-run-switch-other-frame 'helm-only t)
(defvar helm-etags-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "M-<down>") 'helm-goto-next-file)
(define-key map (kbd "M-<up>") 'helm-goto-precedent-file)
(define-key map (kbd "C-c o") 'helm-etags-run-switch-other-window)
(define-key map (kbd "C-c C-o") 'helm-etags-run-switch-other-frame)
map)
"Keymap used in Etags.")
(defvar helm-etags-mtime-alist nil
"Store the last modification time of etags files here.")
(defvar helm-etags-cache (make-hash-table :test 'equal)
"Cache content of etags files used here for faster access.")
(defun helm-etags-get-tag-file (&optional directory)
"Return the path of etags file if found in DIRECTORY.
Look recursively in parents directorys for a
`helm-etags-tag-file-name' file."
;; Get tag file from `default-directory' or upper directory.
(let ((current-dir (helm-etags-find-tag-file-directory
(or directory default-directory))))
;; Return nil if not find tag file.
(when current-dir
(expand-file-name helm-etags-tag-file-name current-dir))))
(defun helm-etags-all-tag-files ()
"Find Etags files.
Return files from the following sources:
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."
(helm-fast-remove-dups
(delq nil
(append (list (helm-etags-get-tag-file)
tags-file-name)
tags-table-list))
:test 'equal))
(defun helm-etags-find-tag-file-directory (current-dir)
"Try to find the directory containing tag file.
If not found in CURRENT-DIR search in upper directory."
(let ((file-exists? (lambda (dir)
(let ((tag-path (expand-file-name
helm-etags-tag-file-name dir)))
(and (stringp tag-path)
(file-regular-p tag-path)
(file-readable-p tag-path))))))
(cl-loop with count = 0
until (funcall file-exists? current-dir)
;; Return nil if outside the value of
;; `helm-etags-tag-file-search-limit'.
if (= count helm-etags-tag-file-search-limit)
do (cl-return nil)
;; Or search upper directories.
else
do (cl-incf count)
(setq current-dir (expand-file-name (concat current-dir "../")))
finally return current-dir)))
(defun helm-etags-get-header-name (_x)
"Create header name for this helm etags session."
(concat "Etags in "
(with-helm-current-buffer
(helm-etags-get-tag-file))))
(defun helm-etags-create-buffer (file)
"Create the `helm-buffer' based on contents of etags tag FILE."
(let* (max
(split (with-temp-buffer
(insert-file-contents file)
(prog1
(split-string (buffer-string) "\n" 'omit-nulls)
(setq max (line-number-at-pos (point-max))))))
(progress-reporter (make-progress-reporter "Loading tag file..." 0 max)))
(cl-loop
with fname
with cand
for i in split for count from 0
for elm = (unless (string-match "^\x0c" i) ;; "^L"
(helm-aif (string-match "\177" i) ;; "^?"
(substring i 0 it)
i))
for linum = (when (string-match "[0-9]+,?[0-9]*$" i)
(car (split-string (match-string 0 i) ",")))
do (cond ((and elm (string-match "^\\([^,]+\\),[0-9]+$" elm))
(setq fname (propertize (match-string 1 elm)
'face 'helm-etags-file)))
(elm (setq cand (format "%s:%s:%s" fname linum elm)))
(t (setq cand nil)))
when cand do (progn
(insert (propertize (concat cand "\n") 'linum linum))
(progress-reporter-update progress-reporter count)))))
(defun helm-etags-init ()
"Feed `helm-buffer' using `helm-etags-cache' or tag file.
If there is no entry in cache, create one."
(let ((tagfiles (helm-etags-all-tag-files)))
(when tagfiles
(with-current-buffer (helm-candidate-buffer 'global)
(dolist (f tagfiles)
(helm-aif (gethash f helm-etags-cache)
;; An entry is present in cache, insert it.
(insert it)
;; No entry, create a new buffer using content of tag file (slower).
(helm-etags-create-buffer f)
;; Store content of buffer in cache.
(puthash f (buffer-string) helm-etags-cache)
;; Store or set the last modification of tag file.
(helm-aif (assoc f helm-etags-mtime-alist)
;; If an entry exists modify it.
(setcdr it (helm-etags-mtime f))
;; No entry create a new one.
(cl-pushnew (cons f (helm-etags-mtime f))
helm-etags-mtime-alist
:test 'equal))))))))
(defvar helm-source-etags-select nil
"Helm source for Etags.")
(defun helm-etags-build-source ()
(helm-build-in-buffer-source "Etags"
:header-name 'helm-etags-get-header-name
:init 'helm-etags-init
:get-line 'buffer-substring
:match-part (lambda (candidate)
;; Match only the tag part of CANDIDATE
;; and not the filename.
(cl-case helm-etags-match-part-only
(tag (cl-caddr (helm-grep-split-line candidate)))
(t candidate)))
:fuzzy-match helm-etags-fuzzy-match
:help-message 'helm-etags-help-message
:keymap helm-etags-map
:action '(("Go to tag" . (lambda (c)
(helm-etags-action-goto 'find-file c)))
("Go to tag in other window" . (lambda (c)
(helm-etags-action-goto
'find-file-other-window
c)))
("Go to tag in other frame" . (lambda (c)
(helm-etags-action-goto
'find-file-other-frame
c))))
:group 'helm-tags
:persistent-help "Go to line"
:persistent-action (lambda (candidate)
(helm-etags-action-goto 'find-file candidate)
(helm-highlight-current-line))))
(defcustom helm-etags-fuzzy-match nil
"Use fuzzy matching in `helm-etags-select'."
:group 'helm-tags
:type 'boolean
:set (lambda (var val)
(set var val)
(setq helm-source-etags-select
(helm-etags-build-source))))
(defvar find-tag-marker-ring)
(defsubst helm-etags--file-from-tag (fname)
(cl-loop for ext in
(cons "" (remove "" tags-compression-info-list))
for file = (concat fname ext)
when (file-exists-p file)
return file))
(defun helm-etags-action-goto (switcher candidate)
"Helm default action to jump to an etags entry in other window."
(require 'etags)
(deactivate-mark t)
(helm-log-run-hook 'helm-goto-line-before-hook)
(let* ((split (helm-grep-split-line candidate))
(fname (cl-loop for tagf being the hash-keys of helm-etags-cache
for f = (expand-file-name
(car split) (file-name-directory tagf))
;; Try to find an existing file, possibly compressed.
when (helm-etags--file-from-tag f)
return it))
(elm (cl-caddr split))
(linum (string-to-number (cadr split))))
(if (null fname)
(error "file %s not found" fname)
(ring-insert find-tag-marker-ring (point-marker))
(funcall switcher fname)
(helm-goto-line linum t)
(when (search-forward elm nil t)
(goto-char (match-beginning 0))))))
(defun helm-etags-mtime (file)
"Last modification time of etags tag FILE."
(cadr (nth 5 (file-attributes file))))
(defun helm-etags-file-modified-p (file)
"Check if tag FILE have been modified in this session.
If FILE is nil return nil."
(let ((last-modif (and file
(assoc-default file helm-etags-mtime-alist))))
(and last-modif
(/= last-modif (helm-etags-mtime file)))))
;;;###autoload
(defun helm-etags-select (reinit)
"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."
(interactive "P")
(let ((tag-files (helm-etags-all-tag-files))
(helm-execute-action-at-once-if-one
helm-etags-execute-action-at-once-if-one)
(str (if (region-active-p)
(buffer-substring-no-properties
(region-beginning) (region-end))
(thing-at-point 'symbol))))
(if (cl-notany 'file-exists-p tag-files)
(message "Error: No tag file found.\
Create with etags shell command, or visit with `find-tag' or `visit-tags-table'.")
(cl-loop for k being the hash-keys of helm-etags-cache
unless (member k tag-files)
do (remhash k helm-etags-cache))
(mapc (lambda (f)
(when (or (equal reinit '(4))
(and helm-etags-mtime-alist
(helm-etags-file-modified-p f)))
(remhash f helm-etags-cache)))
tag-files)
(unless helm-source-etags-select
(setq helm-source-etags-select
(helm-etags-build-source)))
(helm :sources 'helm-source-etags-select
:keymap helm-etags-map
:default (and (stringp str)
(if (or helm-etags-fuzzy-match
(and (eq major-mode 'haskell-mode)
(string-match "[']\\'" str)))
str
(list (concat "\\_<" str "\\_>") str)))
:buffer "*helm etags*"))))
(provide 'helm-tags)
;;; helm-tags.el ends here

View file

@ -0,0 +1,332 @@
;;; helm-types.el --- Helm types classes and methods. -*- lexical-binding: t -*-
;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; URL: http://github.com/emacs-helm/helm
;; 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 'eieio)
(eval-when-compile (require 'helm-source))
(defvar helm-map)
(defvar helm-mode-line-string)
(defvar helm-bookmark-map)
(declare-function helm-make-actions "helm-lib")
(declare-function helm-ediff-marked-buffers "helm-buffers")
(declare-function helm-make-type "helm-source")
;; Files
(defclass helm-type-file (helm-source) ()
"A class to define helm type file.")
(cl-defmethod helm-source-get-action-from-type ((object helm-type-file))
(slot-value object 'action))
(defun helm-actions-from-type-file ()
(let ((source (make-instance 'helm-type-file)))
(helm--setup-source source)
(helm-source-get-action-from-type source)))
(defvar helm-generic-files-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "C-]") 'helm-ff-run-toggle-basename)
(define-key map (kbd "C-s") 'helm-ff-run-grep)
(define-key map (kbd "M-g s") 'helm-ff-run-grep)
(define-key map (kbd "M-g z") 'helm-ff-run-zgrep)
(define-key map (kbd "M-g p") 'helm-ff-run-pdfgrep)
(define-key map (kbd "M-R") 'helm-ff-run-rename-file)
(define-key map (kbd "M-C") 'helm-ff-run-copy-file)
(define-key map (kbd "M-B") 'helm-ff-run-byte-compile-file)
(define-key map (kbd "M-L") 'helm-ff-run-load-file)
(define-key map (kbd "M-S") 'helm-ff-run-symlink-file)
(define-key map (kbd "M-H") 'helm-ff-run-hardlink-file)
(define-key map (kbd "M-D") 'helm-ff-run-delete-file)
(define-key map (kbd "C-=") 'helm-ff-run-ediff-file)
(define-key map (kbd "C-c =") 'helm-ff-run-ediff-merge-file)
(define-key map (kbd "C-c o") 'helm-ff-run-switch-other-window)
(define-key map (kbd "C-c r") 'helm-ff-run-find-file-as-root)
(define-key map (kbd "C-c C-o") 'helm-ff-run-switch-other-frame)
(define-key map (kbd "M-i") 'helm-ff-properties-persistent)
(define-key map (kbd "C-c C-x") 'helm-ff-run-open-file-externally)
(define-key map (kbd "C-c X") 'helm-ff-run-open-file-with-default-tool)
(define-key map (kbd "C-c @") 'helm-ff-run-insert-org-link)
(define-key map (kbd "C-x C-q") 'helm-ff-run-marked-files-in-dired)
(define-key map (kbd "C-c C-a") 'helm-ff-run-mail-attach-files)
map)
"Generic Keymap for files.")
(defcustom helm-type-file-actions
(helm-make-actions
"Find file" 'helm-find-file-or-marked
"Find file as root" 'helm-find-file-as-root
"Find file other window" 'helm-find-files-other-window
"Find file other frame" 'find-file-other-frame
"Open dired in file's directory" 'helm-open-dired
"Attach file(s) to mail buffer `C-c C-a'" 'helm-ff-mail-attach-files
"Marked files in dired" 'helm-marked-files-in-dired
"Grep File(s) `C-u recurse'" 'helm-find-files-grep
"Zgrep File(s) `C-u Recurse'" 'helm-ff-zgrep
"Pdfgrep File(s)" 'helm-ff-pdfgrep
"Insert as org link" 'helm-files-insert-as-org-link
"Checksum File" 'helm-ff-checksum
"Ediff File" 'helm-find-files-ediff-files
"Ediff Merge File" 'helm-find-files-ediff-merge-files
"View file" 'view-file
"Insert file" 'insert-file
"Add marked files to file-cache" 'helm-ff-cache-add-file
"Delete file(s)" 'helm-ff-delete-files
"Copy file(s) `M-C, C-u to follow'" 'helm-find-files-copy
"Rename file(s) `M-R, C-u to follow'" 'helm-find-files-rename
"Symlink files(s) `M-S, C-u to follow'" 'helm-find-files-symlink
"Relsymlink file(s) `C-u to follow'" 'helm-find-files-relsymlink
"Hardlink file(s) `M-H, C-u to follow'" 'helm-find-files-hardlink
"Open file externally (C-u to choose)" 'helm-open-file-externally
"Open file with default tool" 'helm-open-file-with-default-tool
"Find file in hex dump" 'hexl-find-file)
"Default actions for type files."
:group 'helm-files
:type '(alist :key-type string :value-type function))
(cl-defmethod helm--setup-source ((_source helm-type-file)))
(cl-defmethod helm--setup-source :before ((source helm-type-file))
(setf (slot-value source 'action) 'helm-type-file-actions)
(setf (slot-value source 'persistent-help) "Show this file")
(setf (slot-value source 'action-transformer)
'(helm-transform-file-load-el
helm-transform-file-browse-url
helm-transform-file-cache))
(setf (slot-value source 'candidate-transformer)
'(helm-skip-boring-files
helm-w32-pathname-transformer))
(setf (slot-value source 'filtered-candidate-transformer)
'helm-highlight-files)
(setf (slot-value source 'help-message) 'helm-generic-file-help-message)
(setf (slot-value source 'mode-line) (list "File(s)" helm-mode-line-string))
(setf (slot-value source 'keymap) helm-generic-files-map)
(setf (slot-value source 'group) 'helm-files))
;; Bookmarks
(defclass helm-type-bookmark (helm-source) ()
"A class to define type bookmarks.")
(defcustom helm-type-bookmark-actions
(helm-make-actions
"Jump to bookmark" 'helm-bookmark-jump
"Jump to BM other window" 'helm-bookmark-jump-other-window
"Jump to BM other frame" 'helm-bookmark-jump-other-frame
"Bookmark edit annotation" 'bookmark-edit-annotation
"Bookmark show annotation" 'bookmark-show-annotation
"Delete bookmark(s)" 'helm-delete-marked-bookmarks
"Edit Bookmark" 'helm-bookmark-edit-bookmark
"Rename bookmark" 'helm-bookmark-rename
"Relocate bookmark" 'bookmark-relocate)
"Default actions for type bookmarks."
:group 'helm-bookmark
:type '(alist :key-type string
:value-type function))
(cl-defmethod helm-source-get-action-from-type ((object helm-type-bookmark))
(slot-value object 'action))
(cl-defmethod helm--setup-source ((_source helm-type-bookmark)))
(cl-defmethod helm--setup-source :before ((source helm-type-bookmark))
(setf (slot-value source 'action) 'helm-type-bookmark-actions)
(setf (slot-value source 'keymap) helm-bookmark-map)
(setf (slot-value source 'mode-line) (list "Bookmark(s)" helm-mode-line-string))
(setf (slot-value source 'help-message) 'helm-bookmark-help-message)
(setf (slot-value source 'migemo) t)
(setf (slot-value source 'follow) 'never)
(setf (slot-value source 'group) 'helm-bookmark))
;; Buffers
(defclass helm-type-buffer (helm-source) ()
"A class to define type buffer.")
(defcustom helm-type-buffer-actions
(helm-make-actions
"Switch to buffer(s)" 'helm-buffer-switch-buffers
"Switch to buffer(s) other window `C-c o'"
'helm-buffer-switch-buffers-other-window
"Switch to buffer other frame `C-c C-o'"
'switch-to-buffer-other-frame
(lambda () (and (fboundp 'tab-bar-mode)
"Switch to buffer other tab `C-c C-t'"))
'helm-buffers-switch-to-buffer-other-tab
"Switch to buffer at line number"
'helm-switch-to-buffer-at-linum
"Browse project `C-x C-d'"
'helm-buffers-browse-project
"Query replace regexp `C-M-%'"
'helm-buffer-query-replace-regexp
"Query replace `M-%'" 'helm-buffer-query-replace
"View buffer" 'view-buffer
"Display buffer" 'display-buffer
"Rename buffer `M-R'" 'helm-buffers-rename-buffer
"Grep buffer(s) `M-g s' (C-u grep all buffers)"
'helm-zgrep-buffers
"Multi occur buffer(s) `C-s (C-u search also in current)'"
'helm-multi-occur-as-action
"Revert buffer(s) `M-G'" 'helm-revert-marked-buffers
"Insert buffer" 'insert-buffer
"Kill buffer(s) `M-D'" 'helm-kill-marked-buffers
"Diff with file `C-='" 'diff-buffer-with-file
"Ediff Marked buffers `C-c ='" 'helm-ediff-marked-buffers
"Ediff Merge marked buffers `M-='"
(lambda (candidate)
(helm-ediff-marked-buffers candidate t)))
"Default actions for type buffers."
:group 'helm-buffers
:type '(alist :key-type string :value-type function))
(cl-defmethod helm-source-get-action-from-type ((object helm-type-buffer))
(slot-value object 'action))
(cl-defmethod helm--setup-source ((_source helm-type-buffer)))
(cl-defmethod helm--setup-source :before ((source helm-type-buffer))
(setf (slot-value source 'action) 'helm-type-buffer-actions)
(setf (slot-value source 'persistent-help) "Show this buffer")
(setf (slot-value source 'mode-line)
;; Use default-value of `helm-mode-line-string' in case user
;; starts with a helm buffer as current-buffer otherwise the
;; local value of this helm buffer is used (bug#1517, bug#2377).
(list "Buffer(s)" (default-value 'helm-mode-line-string)))
(setf (slot-value source 'filtered-candidate-transformer)
'(helm-skip-boring-buffers
helm-buffers-sort-transformer
helm-highlight-buffers))
(setf (slot-value source 'group) 'helm-buffers))
;; Functions
(defclass helm-type-function (helm-source) ()
"A class to define helm type function.")
(defcustom helm-type-function-actions
(helm-make-actions
"Describe function" 'helm-describe-function
"Find function" 'helm-find-function
"Info lookup" 'helm-info-lookup-symbol
"Debug on entry" 'debug-on-entry
"Cancel debug on entry" 'cancel-debug-on-entry
"Trace function" 'trace-function
"Trace function (background)" 'trace-function-background
"Untrace function" 'untrace-function)
"Default actions for type functions."
:group 'helm-elisp
;; Use symbol as value type because some functions may not be
;; autoloaded (like untrace-function).
:type '(alist :key-type string :value-type symbol))
(cl-defmethod helm-source-get-action-from-type ((object helm-type-function))
(slot-value object 'action))
(defun helm-actions-from-type-function ()
(let ((source (make-instance 'helm-type-function)))
(helm--setup-source source)
(helm-source-get-action-from-type source)))
(cl-defmethod helm--setup-source ((_source helm-type-function)))
(cl-defmethod helm--setup-source :before ((source helm-type-function))
(setf (slot-value source 'action) 'helm-type-function-actions)
(setf (slot-value source 'action-transformer)
'helm-transform-function-call-interactively)
(setf (slot-value source 'candidate-transformer)
'helm-mark-interactive-functions)
(setf (slot-value source 'coerce) 'helm-symbolify))
;; Commands
(defclass helm-type-command (helm-source) ()
"A class to define helm type command.")
(defun helm-actions-from-type-command ()
(let ((source (make-instance 'helm-type-command)))
(helm--setup-source source)
(helm-source-get-action-from-type source)))
(defcustom helm-type-command-actions
(append (helm-make-actions
"Execute command" 'helm-M-x-execute-command)
(symbol-value
(helm-actions-from-type-function)))
"Default actions for type command."
:group 'helm-command
:type '(alist :key-type string :value-type symbol))
(cl-defmethod helm--setup-source ((_source helm-type-command)))
(cl-defmethod helm--setup-source :before ((source helm-type-command))
(setf (slot-value source 'action) 'helm-type-command-actions)
(setf (slot-value source 'coerce) 'helm-symbolify)
(setf (slot-value source 'persistent-action) 'helm-M-x-persistent-action)
(setf (slot-value source 'persistent-help) "Describe this command")
(setf (slot-value source 'group) 'helm-command))
;; Timers
(defclass helm-type-timers (helm-source) ()
"A class to define helm type timers.")
(defcustom helm-type-timers-actions
'(("Cancel Timer" . (lambda (_timer)
(let ((mkd (helm-marked-candidates)))
(cl-loop for timer in mkd
do (cancel-timer timer)))))
("Describe Function" . (lambda (tm)
(describe-function (timer--function tm))))
("Find Function" . (lambda (tm)
(helm-aif (timer--function tm)
(if (or (byte-code-function-p it)
(helm-subr-native-elisp-p it))
(message "Can't find anonymous function `%s'" it)
(find-function it))))))
"Default actions for type timers."
:group 'helm-elisp
:type '(alist :key-type string :value-type function))
(cl-defmethod helm--setup-source ((_source helm-type-timers)))
(cl-defmethod helm--setup-source :before ((source helm-type-timers))
(setf (slot-value source 'action) 'helm-type-timers-actions)
(setf (slot-value source 'persistent-action)
(lambda (tm)
(describe-function (timer--function tm))))
(setf (slot-value source 'persistent-help) "Describe Function")
(setf (slot-value source 'group) 'helm-elisp))
;; Builders.
(defun helm-build-type-file ()
(helm-make-type 'helm-type-file))
(defun helm-build-type-function ()
(helm-make-type 'helm-type-function))
(defun helm-build-type-command ()
(helm-make-type 'helm-type-command))
(provide 'helm-types)
;;; helm-types.el ends here

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
;;; helm-x-files.el --- helm auxiliary functions and sources. -*- lexical-binding: t -*-
;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; 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:
;;; Code:
(require 'helm-for-files)
;;; List of files gleaned from every dired buffer
;;
;;
(defvar dired-buffers)
(defvar directory-files-no-dot-files-regexp)
(defun helm-files-in-all-dired-candidates ()
"Return a list of files from live `dired' buffers."
(save-excursion
(cl-loop for (f . b) in dired-buffers
when (buffer-live-p b)
append (let ((dir (with-current-buffer b dired-directory)))
(if (listp dir) (cdr dir)
(directory-files f t directory-files-no-dot-files-regexp))))))
;; (dired '("~/" "~/.emacs.d/.emacs-custom.el" "~/.emacs.d/.emacs.bmk"))
(defclass helm-files-dired-source (helm-source-sync helm-type-file)
((candidates :initform #'helm-files-in-all-dired-candidates)))
(defvar helm-source-files-in-all-dired
(helm-make-source "Files in all dired buffer." 'helm-files-dired-source))
;;; session.el files
;;
;; session (http://emacs-session.sourceforge.net/) is an alternative to
;; recentf that saves recent file history and much more.
(defvar session-file-alist)
(defclass helm-source-session-class (helm-source-sync)
((candidates :initform (lambda ()
(cl-delete-if-not
(lambda (f)
(or (string-match helm-tramp-file-name-regexp f)
(file-exists-p f)))
(mapcar 'car session-file-alist))))
(keymap :initform 'helm-generic-files-map)
(help-message :initform 'helm-generic-file-help-message)
(action :initform 'helm-type-file-actions)))
(defvar helm-source-session nil
"File list from emacs-session.")
(defcustom helm-session-fuzzy-match nil
"Enable fuzzy matching in `helm-source-session' when non--nil."
:group 'helm-files
:type 'boolean
:set (lambda (var val)
(set var val)
(setq helm-source-session
(helm-make-source "Session" 'helm-source-session-class
:fuzzy-match val))))
;;; External searching file tools.
;;
;; Tracker desktop search
(defun helm-source-tracker-transformer (candidates _source)
"Return file names from tracker CANDIDATES."
;; loop through tracker candidates selecting out file:// lines
;; then select part after file:// and url decode to get straight filenames
(cl-loop for cand in candidates
when (and (stringp cand)
(string-match "\\`[[:space:]]*file://\\(.*\\)" cand))
collect (url-unhex-string (match-string 1 cand))))
(defvar helm-source-tracker-search
(helm-build-async-source "Tracker Search"
:candidates-process
(lambda ()
;; the tracker-search command has been deprecated, now invoke via tracker
;; also, disable the contextual snippets which we don't currently use
(start-process "tracker-search-process" nil
"tracker" "search"
"--disable-snippets"
"--disable-color"
"--limit=512"
helm-pattern))
;; new simplified transformer of tracker search results
:filtered-candidate-transformer #'helm-source-tracker-transformer
;;(multiline) ; https://github.com/emacs-helm/helm/issues/529
:keymap helm-generic-files-map
:action 'helm-type-file-actions
:action-transformer '(helm-transform-file-load-el
helm-transform-file-browse-url)
:requires-pattern 3)
"Source for the Tracker desktop search engine.")
;; Spotlight (MacOS X desktop search)
(defclass helm-mac-spotlight-source (helm-source-async helm-type-file)
((candidates-process :initform
(lambda ()
(start-process
"mdfind-process" nil "mdfind" helm-pattern)))
(requires-pattern :initform 3)))
(defvar helm-source-mac-spotlight
(helm-make-source "mdfind" 'helm-mac-spotlight-source)
"Source for retrieving files via Spotlight's command line utility mdfind.")
(provide 'helm-x-files)
;;; helm-x-files.el ends here

View file

@ -0,0 +1,42 @@
;;; helm.el --- Helm is an Emacs incremental and narrowing framework -*- lexical-binding: t -*-
;; Copyright (C) 2007 Tamas Patrovics
;; 2008 ~ 2011 rubikitch <rubikitch@ruby-lang.org>
;; 2011 ~ 2021 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; This is a fork of anything.el wrote by Tamas Patrovics.
;; Authors of anything.el: Tamas Patrovics
;; rubikitch <rubikitch@ruby-lang.org>
;; Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; Version: 3.8.5
;; URL: https://emacs-helm.github.io/helm/
;; Package-Requires: ((helm-core "3.8.4") (popup "0.5.3"))
;; 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:
;; This is just a wrapper for helm-core.el and a place holder we
;; currently use only to hold the package's metadata in the header.
;;; Code:
(require 'helm-core)
(provide 'helm)
;;; helm.el ends here

View file

@ -0,0 +1,262 @@
;;; helm-core-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 "helm-core" "helm-core.el" (0 0 0 0))
;;; Generated autoloads from helm-core.el
(autoload 'helm-configuration "helm-core" "\
Customize Helm." t nil)
(autoload 'helm-define-multi-key "helm-core" "\
In KEYMAP, define key sequence KEY for function list FUNCTIONS.
Each function runs sequentially for each KEY press.
If DELAY is specified, switch back to initial function of FUNCTIONS list
after DELAY seconds.
The functions in FUNCTIONS list take no args.
E.g.
(defun foo ()
(interactive)
(message \"Run foo\"))
(defun bar ()
(interactive)
(message \"Run bar\"))
(defun baz ()
(interactive)
(message \"Run baz\"))
\(helm-define-multi-key global-map (kbd \"<f5> q\") '(foo bar baz) 2)
Each time \"<f5> q\" is pressed, the next function is executed.
Waiting more than 2 seconds between key presses switches back to
executing the first function on the next hit.
\(fn KEYMAP KEY FUNCTIONS &optional DELAY)" nil nil)
(autoload 'helm-multi-key-defun "helm-core" "\
Define NAME as a multi-key command running FUNS.
After DELAY seconds, the FUNS list is reinitialized.
See `helm-define-multi-key'.
\(fn NAME DOCSTRING FUNS &optional DELAY)" nil t)
(function-put 'helm-multi-key-defun 'lisp-indent-function '2)
(autoload 'helm-define-key-with-subkeys "helm-core" "\
Define in MAP a KEY and SUBKEY to COMMAND.
This allows typing KEY to call COMMAND the first time and
type only SUBKEY on subsequent calls.
Arg MAP is the keymap to use, SUBKEY is the initial short
key binding to call COMMAND.
Arg OTHER-SUBKEYS is an alist specifying other short key bindings
to use once started, e.g.:
(helm-define-key-with-subkeys global-map
(kbd \"C-x v n\") ?n 'git-gutter:next-hunk
'((?p . git-gutter:previous-hunk)))
In this example, `C-x v n' will run `git-gutter:next-hunk'
subsequent \"n\" will run this command again and subsequent \"p\"
will run `git-gutter:previous-hunk'.
If specified PROMPT can be displayed in minibuffer to describe
SUBKEY and OTHER-SUBKEYS. Arg EXIT-FN specifies a function to run
on exit.
For any other key pressed, run their assigned command as defined
in MAP and then exit the loop running EXIT-FN, if specified.
If DELAY an integer is specified exit after DELAY seconds.
NOTE: SUBKEY and OTHER-SUBKEYS bindings support only char syntax
and vectors, so don't use strings to define them.
\(fn MAP KEY SUBKEY COMMAND &optional OTHER-SUBKEYS PROMPT EXIT-FN DELAY)" nil nil)
(function-put 'helm-define-key-with-subkeys 'lisp-indent-function '1)
(autoload 'helm-debug-open-last-log "helm-core" "\
Open Helm log file or buffer of last Helm session." t nil)
(autoload 'helm "helm-core" "\
Main function to execute helm sources.
PLIST is a list like
\(:key1 val1 :key2 val2 ...)
or
\(&optional sources input prompt resume preselect
buffer keymap default history allow-nest).
** Keywords
Keywords supported:
- :sources
- :input
- :prompt
- :resume
- :preselect
- :buffer
- :keymap
- :default
- :history
- :allow-nest
Extra LOCAL-VARS keywords are supported, see the \"** Other
keywords\" section below.
Basic keywords are the following:
*** :sources
One of the following:
- List of sources
- Symbol whose value is a list of sources
- Alist representing a Helm source.
- In this case the source has no name and is referenced in
`helm-sources' as a whole alist.
*** :input
Initial input of minibuffer (temporary value of `helm-pattern')
*** :prompt
Minibuffer prompt. Default value is `helm--prompt'.
*** :resume
If t, allow resumption of the previous session of this Helm
command, skipping initialization.
If 'noresume, this instance of `helm' cannot be resumed.
*** :preselect
Initially selected candidate (string or regexp).
*** :buffer
Buffer name for this Helm session. `helm-buffer' will take this value.
*** :keymap
\[Obsolete]
Keymap used at the start of this Helm session.
It is overridden by keymaps specified in sources, and is kept
only for backward compatibility.
Keymaps should be specified in sources using the :keymap slot
instead. See `helm-source'.
This keymap is not restored by `helm-resume'.
*** :default
Default value inserted into the minibuffer with
\\<minibuffer-local-map>\\[next-history-element].
It can be a string or a list of strings, in this case
\\<minibuffer-local-map>\\[next-history-element] cycles through
the list items, starting with the first.
If nil, `thing-at-point' is used.
If `helm-maybe-use-default-as-input' is non-nil, display is
updated using this value if this value matches, otherwise it is
ignored. If :input is specified, it takes precedence on :default.
*** :history
Minibuffer input, by default, is pushed to `minibuffer-history'.
When an argument HISTORY is provided, input is pushed to
HISTORY. HISTORY should be a valid symbol.
*** :allow-nest
Allow running this Helm command in a running Helm session.
** Other keywords
Other keywords are interpreted as local variables of this Helm
session. The `helm-' prefix can be omitted. For example,
\(helm :sources 'helm-source-buffers-list
:buffer \"*helm buffers*\"
:candidate-number-limit 10)
Starts a Helm session with the variable
`helm-candidate-number-limit' set to 10.
** Backward compatibility
For backward compatibility, positional parameters are
supported:
\(helm sources input prompt resume preselect
buffer keymap default history allow-nest)
However, the use of non-keyword args is deprecated.
\(fn &key SOURCES INPUT PROMPT RESUME PRESELECT BUFFER KEYMAP DEFAULT HISTORY ALLOW-NEST OTHER-LOCAL-VARS)" nil nil)
(autoload 'helm-cycle-resume "helm-core" "\
Cycle in `helm-buffers' list and resume when waiting more than 1.2s." t nil)
(autoload 'helm-other-buffer "helm-core" "\
Simplified Helm interface with other `helm-buffer'.
Call `helm' only with SOURCES and BUFFER as args.
\(fn SOURCES BUFFER)" nil nil)
(register-definition-prefixes "helm-core" '("helm-" "with-helm-"))
;;;***
;;;### (autoloads nil "helm-lib" "helm-lib.el" (0 0 0 0))
;;; Generated autoloads from helm-lib.el
(register-definition-prefixes "helm-lib" '("helm-" "with-helm-"))
;;;***
;;;### (autoloads nil "helm-multi-match" "helm-multi-match.el" (0
;;;;;; 0 0 0))
;;; Generated autoloads from helm-multi-match.el
(register-definition-prefixes "helm-multi-match" '("helm-m"))
;;;***
;;;### (autoloads nil "helm-source" "helm-source.el" (0 0 0 0))
;;; Generated autoloads from helm-source.el
(register-definition-prefixes "helm-source" '("helm-"))
;;;***
;;;### (autoloads nil nil ("helm-core-pkg.el") (0 0 0 0))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; helm-core-autoloads.el ends here

View file

@ -0,0 +1,11 @@
(define-package "helm-core" "20220423.1804" "Development files for Helm"
'((emacs "25.1")
(async "1.9.4"))
:commit "dc0c082a451cfe25d35ba3b9b0c0fc2766cc8319" :authors
'(("Thierry Volpiatto" . "thierry.volpiatto@gmail.com"))
:maintainer
'("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")
:url "https://emacs-helm.github.io/helm/")
;; Local Variables:
;; no-byte-compile: t
;; End:

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,381 @@
;;; helm-multi-match.el --- Multiple regexp matching methods for helm -*- lexical-binding: t -*-
;; Original Author: rubikitch
;; Copyright (C) 2008 ~ 2011 rubikitch
;; Copyright (C) 2011 ~ 2020 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; URL: http://github.com/emacs-helm/helm
;; 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-lib)
(defgroup helm-multi-match nil
"Helm multi match."
:group 'helm)
(defcustom helm-mm-matching-method 'multi3
"Matching method for helm match plugin.
You can set here different methods to match candidates in helm.
Here are the possible value of this symbol and their meaning:
- multi1: Respect order, prefix of pattern must match.
- multi2: Same but with partial match.
- multi3: The best, multiple regexp match, allow negation.
- multi3p: Same but prefix must match.
Default is multi3, you should keep this for a better experience.
Note that multi1 and multi3p are incompatible with fuzzy matching
in file completion and by the way fuzzy matching will be disabled there
when these options are used."
:type '(radio :tag "Matching methods for helm"
(const :tag "Multiple regexp 1 ordered with prefix match" multi1)
(const :tag "Multiple regexp 2 ordered with partial match" multi2)
(const :tag "Multiple regexp 3 matching no order, partial, best." multi3)
(const :tag "Multiple regexp 3p matching with prefix match" multi3p))
:group 'helm-multi-match)
;; Internal
(defvar helm-mm-default-match-functions
'(helm-mm-exact-match helm-mm-match))
(defvar helm-mm-default-search-functions
'(helm-mm-exact-search helm-mm-search))
;;; Build regexps
;;
;;
(defconst helm-mm-space-regexp "\\s\\\\s-"
"Regexp to represent space itself in multiple regexp match.")
(defun helm-mm-split-pattern (pattern &optional grep-space)
"Split PATTERN if it contains spaces and return resulting list.
If spaces in PATTERN are escaped, don't split at this place.
i.e \"foo bar baz\"=> (\"foo\" \"bar\" \"baz\")
but \"foo\\ bar baz\"=> (\"foo\\s-bar\" \"baz\").
If GREP-SPACE is used translate escaped space to \"\\s\" instead of \"\\s-\"."
(split-string
;; Match spaces litteraly because candidate buffer syntax-table
;; doesn't understand "\s-" properly.
(replace-regexp-in-string
helm-mm-space-regexp
(if grep-space "\\s" "\\s-") pattern nil t)))
(defun helm-mm-1-make-regexp (pattern)
"Replace spaces in PATTERN with \"\.*\"."
(mapconcat 'identity (helm-mm-split-pattern pattern) ".*"))
;;; Exact match.
;;
;;
;; Internal.
(defvar helm-mm-exact-pattern-str nil)
(defvar helm-mm-exact-pattern-real nil)
(defun helm-mm-exact-get-pattern (pattern)
(unless (equal pattern helm-mm-exact-pattern-str)
(setq helm-mm-exact-pattern-str pattern
helm-mm-exact-pattern-real (concat "\n" pattern "\n")))
helm-mm-exact-pattern-real)
(cl-defun helm-mm-exact-match (candidate &optional (pattern helm-pattern))
(if case-fold-search
(progn
(setq candidate (downcase candidate)
pattern (downcase pattern))
(string= candidate pattern))
(string= candidate pattern)))
(defun helm-mm-exact-search (pattern &rest _ignore)
(and (search-forward (helm-mm-exact-get-pattern pattern) nil t)
(forward-line -1)))
;;; Prefix match
;;
;;
;; Internal
(defvar helm-mm-prefix-pattern-str nil)
(defvar helm-mm-prefix-pattern-real nil)
(defun helm-mm-prefix-get-pattern (pattern)
(unless (equal pattern helm-mm-prefix-pattern-str)
(setq helm-mm-prefix-pattern-str pattern
helm-mm-prefix-pattern-real (concat "\n" pattern)))
helm-mm-prefix-pattern-real)
(defun helm-mm-prefix-match (candidate &optional pattern)
;; In filename completion basename and basedir may be
;; quoted, unquote them for string comparison (Bug#1283).
(setq pattern (replace-regexp-in-string
"\\\\" "" (or pattern helm-pattern)))
(let ((len (length pattern)))
(and (<= len (length candidate))
(string= (substring candidate 0 len) pattern ))))
(defun helm-mm-prefix-search (pattern &rest _ignore)
(search-forward (helm-mm-prefix-get-pattern pattern) nil t))
;;; Multiple regexp patterns 1 (order is preserved / prefix).
;;
;;
;; Internal
(defvar helm-mm-1-pattern-str nil)
(defvar helm-mm-1-pattern-real nil)
(defun helm-mm-1-get-pattern (pattern)
(unless (equal pattern helm-mm-1-pattern-str)
(setq helm-mm-1-pattern-str pattern
helm-mm-1-pattern-real
(concat "^" (helm-mm-1-make-regexp pattern))))
helm-mm-1-pattern-real)
(cl-defun helm-mm-1-match (candidate &optional (pattern helm-pattern))
(string-match (helm-mm-1-get-pattern pattern) candidate))
(defun helm-mm-1-search (pattern &rest _ignore)
(re-search-forward (helm-mm-1-get-pattern pattern) nil t))
;;; Multiple regexp patterns 2 (order is preserved / partial).
;;
;;
;; Internal
(defvar helm-mm-2-pattern-str nil)
(defvar helm-mm-2-pattern-real nil)
(defun helm-mm-2-get-pattern (pattern)
(unless (equal pattern helm-mm-2-pattern-str)
(setq helm-mm-2-pattern-str pattern
helm-mm-2-pattern-real
(concat "^.*" (helm-mm-1-make-regexp pattern))))
helm-mm-2-pattern-real)
(cl-defun helm-mm-2-match (candidate &optional (pattern helm-pattern))
(string-match (helm-mm-2-get-pattern pattern) candidate))
(defun helm-mm-2-search (pattern &rest _ignore)
(re-search-forward (helm-mm-2-get-pattern pattern) nil t))
;;; Multiple regexp patterns 3 (permutation).
;;
;;
;; Internal
(defvar helm-mm--3-pattern-str nil)
(defvar helm-mm--3-pattern-list nil)
(defun helm-mm-3-get-patterns (pattern)
"Return a list of predicate/regexp cons cells.
E.g., ((identity . \"foo\") (not . \"bar\")).
If PATTERN is unchanged, don't recompute PATTERN and return the
previous value stored in `helm-mm--3-pattern-list'."
(unless (equal pattern helm-mm--3-pattern-str)
(setq helm-mm--3-pattern-str pattern
helm-mm--3-pattern-list
(helm-mm-3-get-patterns-internal pattern)))
helm-mm--3-pattern-list)
(defun helm-mm-3-get-patterns-internal (pattern)
"Return a list of predicate/regexp cons cells.
E.g., ((identity . \"foo\") (not . \"bar\"))."
(unless (string= pattern "")
(cl-loop for pat in (helm-mm-split-pattern pattern)
collect (if (char-equal ?! (aref pat 0))
(cons 'not (substring pat 1))
(cons 'identity pat)))))
(defun helm-mm-regexp-p (string)
(string-match-p "[[]*+^$.?\\]" string))
(defvar helm-mm--match-on-diacritics nil)
(cl-defun helm-mm-3-match (candidate &optional (pattern helm-pattern))
"Check if PATTERN match CANDIDATE.
When PATTERN contains a space, it is splitted and matching is
done with the several resulting regexps against CANDIDATE.
E.g., \"bar foo\" will match \"foobar\" and \"barfoo\".
Argument PATTERN, a string, is transformed in a list of cons cell
with `helm-mm-3-get-patterns' if it contains a space.
E.g., \"foo bar\"=>((identity . \"foo\") (identity . \"bar\")).
Then each predicate of cons cell(s) is called with the regexp of
the same cons cell against CANDIDATE.
I.e. (identity (string-match \"foo\" \"foo bar\")) => t."
(let ((pat (helm-mm-3-get-patterns pattern)))
(cl-loop for (predicate . regexp) in pat
for re = (if (and (not (helm-mm-regexp-p regexp))
helm-mm--match-on-diacritics)
(char-fold-to-regexp regexp)
regexp)
always (funcall predicate
(condition-case _err
;; FIXME: Probably do nothing when
;; using fuzzy leaving the job
;; to the fuzzy fn.
(string-match re candidate)
(invalid-regexp nil))))))
(defun helm-mm-3-search-base (pattern searchfn1 searchfn2)
"Try to find PATTERN in `helm-buffer' with SEARCHFN1 and SEARCHFN2.
This is the search function for `candidates-in-buffer' enabled sources.
Use the same method as `helm-mm-3-match' except it search in buffer
instead of matching on a string.
i.e (identity (re-search-forward \"foo\" (point-at-eol) t)) => t."
(cl-loop with pat = (if (stringp pattern)
(helm-mm-3-get-patterns pattern)
pattern)
when (eq (caar pat) 'not) return
;; Pass the job to `helm-search-match-part'.
(prog1 (list (point-at-bol) (point-at-eol))
(forward-line 1))
while (condition-case _err
(funcall searchfn1 (or (cdar pat) "") nil t)
(invalid-regexp nil))
for bol = (point-at-bol)
for eol = (point-at-eol)
if (cl-loop for (pred . str) in (cdr pat) always
(progn (goto-char bol)
(funcall pred (condition-case _err
(funcall searchfn2 str eol t)
(invalid-regexp nil)))))
do (goto-char eol) and return t
else do (goto-char eol)
finally return nil))
(defun helm-mm-3-search (pattern &rest _ignore)
(helm-mm-3-search-base
pattern 're-search-forward 're-search-forward))
;;; mp-3 with migemo
;; Needs https://github.com/emacs-jp/migemo
;;
(defvar helm-mm--previous-migemo-info nil
"[Internal] Cache previous migemo query.")
(make-local-variable 'helm-mm--previous-migemo-info)
(declare-function migemo-get-pattern "ext:migemo.el")
(declare-function migemo-search-pattern-get "ext:migemo.el")
(define-minor-mode helm-migemo-mode
"Enable migemo in helm.
It will be available in the sources handling it,
i.e. the sources which have the slot :migemo with non--nil value."
:lighter " Hmio"
:group 'helm
:global t
(cl-assert (featurep 'migemo)
nil "No feature called migemo found, install migemo.el."))
(defun helm-mm-migemo-get-pattern (pattern)
(let ((regex (migemo-get-pattern pattern)))
(if (ignore-errors (string-match regex "") t)
(concat regex "\\|" pattern) pattern)))
(defun helm-mm-migemo-search-pattern-get (pattern)
(let ((regex (migemo-search-pattern-get pattern)))
(if (ignore-errors (string-match regex "") t)
(concat regex "\\|" pattern) pattern)))
(defun helm-mm-migemo-string-match (pattern str)
"Migemo version of `string-match'."
(unless (assoc pattern helm-mm--previous-migemo-info)
(with-helm-buffer
(setq helm-mm--previous-migemo-info
(push (cons pattern (helm-mm-migemo-get-pattern pattern))
helm-mm--previous-migemo-info))))
(string-match (assoc-default pattern helm-mm--previous-migemo-info) str))
(cl-defun helm-mm-3-migemo-match (candidate &optional (pattern helm-pattern))
(and helm-migemo-mode
(cl-loop for (pred . re) in (helm-mm-3-get-patterns pattern)
always (funcall pred (helm-mm-migemo-string-match re candidate)))))
(defun helm-mm-migemo-forward (word &optional bound noerror count)
(with-helm-buffer
(unless (assoc word helm-mm--previous-migemo-info)
(setq helm-mm--previous-migemo-info
(push (cons word (if (delq 'ascii (find-charset-string word))
word
(helm-mm-migemo-search-pattern-get word)))
helm-mm--previous-migemo-info))))
(re-search-forward
(assoc-default word helm-mm--previous-migemo-info) bound noerror count))
(defun helm-mm-3-migemo-search (pattern &rest _ignore)
(and helm-migemo-mode
(helm-mm-3-search-base
pattern 'helm-mm-migemo-forward 'helm-mm-migemo-forward)))
;;; mp-3p- (multiple regexp pattern 3 with prefix search)
;;
;;
(defun helm-mm-3p-match (candidate &optional pattern)
"Check if PATTERN match CANDIDATE.
Same as `helm-mm-3-match' but only for the cdr of patterns, the car of
patterns must always match CANDIDATE prefix.
E.g. \"bar foo baz\" will match \"barfoobaz\" or \"barbazfoo\" but not
\"foobarbaz\" whereas `helm-mm-3-match' would match all."
(let* ((pat (helm-mm-3-get-patterns (or pattern helm-pattern)))
(first (car pat)))
(and (funcall (car first) (helm-mm-prefix-match candidate (cdr first)))
(cl-loop for (predicate . regexp) in (cdr pat)
always (funcall predicate (string-match regexp candidate))))))
(defun helm-mm-3p-search (pattern &rest _ignore)
(helm-mm-3-search-base
pattern 'helm-mm-prefix-search 're-search-forward))
;;; Generic multi-match/search functions
;;
;;
(cl-defun helm-mm-match (candidate &optional (pattern helm-pattern))
"Call `helm-mm-matching-method' function against CANDIDATE."
(let ((fun (cl-ecase helm-mm-matching-method
(multi1 #'helm-mm-1-match)
(multi2 #'helm-mm-2-match)
(multi3 #'helm-mm-3-match)
(multi3p #'helm-mm-3p-match))))
(funcall fun candidate pattern)))
(cl-defun helm-mm-3-match-on-diacritics (candidate &optional (pattern helm-pattern))
"Same as `helm-mm-3-match' but match on diacritics if possible."
(let ((helm-mm--match-on-diacritics t))
(helm-mm-match candidate pattern)))
(defun helm-mm-search (pattern &rest _ignore)
"Search for PATTERN with `helm-mm-matching-method' function."
(let ((fun (cl-ecase helm-mm-matching-method
(multi1 #'helm-mm-1-search)
(multi2 #'helm-mm-2-search)
(multi3 #'helm-mm-3-search)
(multi3p #'helm-mm-3p-search))))
(funcall fun pattern)))
(provide 'helm-multi-match)
;;; helm-multi-match.el ends here

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,22 @@
;;; popup-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 "popup" "popup.el" (0 0 0 0))
;;; Generated autoloads from popup.el
(register-definition-prefixes "popup" '("popup-"))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; popup-autoloads.el ends here

View file

@ -0,0 +1,2 @@
;;; Generated package description from popup.el -*- no-byte-compile: t -*-
(define-package "popup" "20211231.1823" "Visual Popup User Interface" '((emacs "24.3")) :commit "3bf430270c74dad830ab9d776aab23cbf3ea3953" :authors '(("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) :maintainer '("Shen, Jen-Chieh" . "jcs090218@gmail.com") :keywords '("lisp") :url "https://github.com/auto-complete/popup-el")

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,214 @@
;;; async-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 "async" "async.el" (0 0 0 0))
;;; Generated autoloads from async.el
(autoload 'async-start-process "async" "\
Start the executable PROGRAM asynchronously named NAME. See `async-start'.
PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
process object when done. If FINISH-FUNC is nil, the future
object will return the process object when the program is
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
working directory.
\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil)
(autoload 'async-start "async" "\
Execute START-FUNC (often a lambda) in a subordinate Emacs process.
When done, the return value is passed to FINISH-FUNC. Example:
(async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222)
;; What to do when it finishes
(lambda (result)
(message \"Async process done, result should be 222: %s\"
result)))
If FINISH-FUNC is nil or missing, a future is returned that can
be inspected using `async-get', blocking until the value is
ready. Example:
(let ((proc (async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222))))
(message \"I'm going to do some work here\") ;; ....
(message \"Waiting on async process, result should be 222: %s\"
(async-get proc)))
If you don't want to use a callback, and you don't care about any
return value from the child process, pass the `ignore' symbol as
the second argument (if you don't, and never call `async-get', it
will leave *emacs* process buffers hanging around):
(async-start
(lambda ()
(delete-file \"a remote file on a slow link\" nil))
\\='ignore)
Special case:
If the output of START-FUNC is a string with properties
e.g. (buffer-string) RESULT will be transformed in a list where the
car is the string itself (without props) and the cdr the rest of
properties, this allows using in FINISH-FUNC the string without
properties and then apply the properties in cdr to this string (if
needed).
Properties handling special objects like markers are returned as
list to allow restoring them later.
See <https://github.com/jwiegley/emacs-async/issues/145> for more infos.
Note: Even when FINISH-FUNC is present, a future is still
returned except that it yields no value (since the value is
passed to FINISH-FUNC). Call `async-get' on such a future always
returns nil. It can still be useful, however, as an argument to
`async-ready' or `async-wait'.
\(fn START-FUNC &optional FINISH-FUNC)" nil nil)
(register-definition-prefixes "async" '("async-"))
;;;***
;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (0 0 0
;;;;;; 0))
;;; Generated autoloads from async-bytecomp.el
(autoload 'async-byte-recompile-directory "async-bytecomp" "\
Compile all *.el files in DIRECTORY asynchronously.
All *.elc files are systematically deleted before proceeding.
\(fn DIRECTORY &optional QUIET)" nil nil)
(defvar async-bytecomp-package-mode nil "\
Non-nil if Async-Bytecomp-Package mode is enabled.
See the `async-bytecomp-package-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 `async-bytecomp-package-mode'.")
(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil)
(autoload 'async-bytecomp-package-mode "async-bytecomp" "\
Byte compile asynchronously packages installed with package.el.
Async compilation of packages can be controlled by
`async-bytecomp-allowed-packages'.
This is a minor mode. If called interactively, toggle the
`Async-Bytecomp-Package 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 \\='async-bytecomp-package-mode)'.
The mode's hook is called both when the mode is enabled and when
it is disabled.
\(fn &optional ARG)" t nil)
(autoload 'async-byte-compile-file "async-bytecomp" "\
Byte compile Lisp code FILE asynchronously.
Same as `byte-compile-file' but asynchronous.
\(fn FILE)" t nil)
(register-definition-prefixes "async-bytecomp" '("async-"))
;;;***
;;;### (autoloads nil "dired-async" "dired-async.el" (0 0 0 0))
;;; Generated autoloads from dired-async.el
(defvar dired-async-mode nil "\
Non-nil if Dired-Async mode is enabled.
See the `dired-async-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 `dired-async-mode'.")
(custom-autoload 'dired-async-mode "dired-async" nil)
(autoload 'dired-async-mode "dired-async" "\
Do dired actions asynchronously.
This is a minor mode. If called interactively, toggle the
`Dired-Async 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 \\='dired-async-mode)'.
The mode's hook is called both when the mode is enabled and when
it is disabled.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-copy "dired-async" "\
Run dired-do-copy asynchronously.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-symlink "dired-async" "\
Run dired-do-symlink asynchronously.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-hardlink "dired-async" "\
Run dired-do-hardlink asynchronously.
\(fn &optional ARG)" t nil)
(autoload 'dired-async-do-rename "dired-async" "\
Run dired-do-rename asynchronously.
\(fn &optional ARG)" t nil)
(register-definition-prefixes "dired-async" '("dired-async-"))
;;;***
;;;### (autoloads nil "smtpmail-async" "smtpmail-async.el" (0 0 0
;;;;;; 0))
;;; Generated autoloads from smtpmail-async.el
(register-definition-prefixes "smtpmail-async" '("async-smtpmail-"))
;;;***
;;;### (autoloads nil nil ("async-pkg.el") (0 0 0 0))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; async-autoloads.el ends here

View file

@ -0,0 +1,210 @@
;;; async-bytecomp.el --- Compile elisp files asynchronously -*- lexical-binding: t -*-
;; Copyright (C) 2014-2019 Free Software Foundation, Inc.
;; Authors: John Wiegley <jwiegley@gmail.com>
;; Thierry Volpiatto <thievol@posteo.net>
;; Keywords: dired async byte-compile
;; X-URL: https://github.com/jwiegley/dired-async
;; 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:
;;
;; This package provide the `async-byte-recompile-directory' function
;; which allows, as the name says to recompile a directory outside of
;; your running emacs.
;; The benefit is your files will be compiled in a clean environment without
;; the old *.el files loaded.
;; Among other things, this fix a bug in package.el which recompile
;; the new files in the current environment with the old files loaded, creating
;; errors in most packages after upgrades.
;;
;; NB: This package is advicing the function `package--compile'.
;;; Code:
(require 'cl-lib)
(require 'async)
(declare-function package-desc-name "package.el")
(declare-function package-desc-dir "package.el")
(defcustom async-bytecomp-allowed-packages 'all
"Packages in this list will be compiled asynchronously by `package--compile'.
All the dependencies of these packages will be compiled async too,
so no need to add dependencies to this list.
The value of this variable can also be the symbol `all' (default), in this case
all packages are always compiled asynchronously."
:group 'async
:type '(choice
(const :tag "All packages" all)
(repeat symbol)))
(defvar async-byte-compile-log-file
(concat user-emacs-directory "async-bytecomp.log"))
(defvar async-bytecomp-load-variable-regexp "\\`load-path\\'"
"The variable used by `async-inject-variables' when (re)compiling async.")
;;;###autoload
(defun async-byte-recompile-directory (directory &optional quiet)
"Compile all *.el files in DIRECTORY asynchronously.
All *.elc files are systematically deleted before proceeding."
(cl-loop with dir = (directory-files directory t "\\.elc\\'")
unless dir return nil
for f in dir
when (file-exists-p f) do (delete-file f))
;; Ensure async is reloaded when async.elc is deleted.
;; This happen when recompiling its own directory.
(load "async")
(let ((call-back
(lambda (&optional _ignore)
(if (file-exists-p async-byte-compile-log-file)
(let ((buf (get-buffer-create byte-compile-log-buffer))
(n 0))
(with-current-buffer buf
(goto-char (point-max))
(let ((inhibit-read-only t))
(insert-file-contents async-byte-compile-log-file)
(compilation-mode))
(display-buffer buf)
(delete-file async-byte-compile-log-file)
(unless quiet
(save-excursion
(goto-char (point-min))
(while (re-search-forward "^.*:Error:" nil t)
(cl-incf n)))
(if (> n 0)
(message "Failed to compile %d files in directory `%s'" n directory)
(message "Directory `%s' compiled asynchronously with warnings" directory)))))
(unless quiet
(message "Directory `%s' compiled asynchronously with success" directory))))))
(async-start
`(lambda ()
(require 'bytecomp)
,(async-inject-variables async-bytecomp-load-variable-regexp)
(let ((default-directory (file-name-as-directory ,directory))
error-data)
(add-to-list 'load-path default-directory)
(byte-recompile-directory ,directory 0 t)
(when (get-buffer byte-compile-log-buffer)
(setq error-data (with-current-buffer byte-compile-log-buffer
(buffer-substring-no-properties (point-min) (point-max))))
(unless (string= error-data "")
(with-temp-file ,async-byte-compile-log-file
(erase-buffer)
(insert error-data))))))
call-back)
(unless quiet (message "Started compiling asynchronously directory %s" directory))))
(defvar package-archive-contents)
(defvar package-alist)
(declare-function package-desc-reqs "package.el" (cl-x))
(defun async-bytecomp--get-package-deps (pkgs)
;; Same as `package--get-deps' but parse instead `package-archive-contents'
;; because PKG is not already installed and not present in `package-alist'.
;; However fallback to `package-alist' in case PKG no more present
;; in `package-archive-contents' due to modification to `package-archives'.
;; See issue #58.
(let ((seen '()))
(while pkgs
(let ((pkg (pop pkgs)))
(unless (memq pkg seen)
(let ((pkg-desc (cadr (or (assq pkg package-archive-contents)
(assq pkg package-alist)))))
(when pkg-desc
(push pkg seen)
(setq pkgs (append (mapcar #'car (package-desc-reqs pkg-desc))
pkgs)))))))
seen))
(defun async--package-compile (orig-fun pkg-desc &rest args)
(let ((cur-package (package-desc-name pkg-desc))
(pkg-dir (package-desc-dir pkg-desc)))
(if (or (member async-bytecomp-allowed-packages '(t all (all)))
(memq cur-package (async-bytecomp--get-package-deps
async-bytecomp-allowed-packages)))
(progn
;; FIXME: Why do we use (eq cur-package 'async) once
;; and (string= cur-package "async") afterwards?
(when (eq cur-package 'async)
(fmakunbound 'async-byte-recompile-directory))
;; Add to `load-path' the latest version of async and
;; reload it when reinstalling async.
(when (string= cur-package "async")
(cl-pushnew pkg-dir load-path)
(load "async-bytecomp"))
;; `async-byte-recompile-directory' will add directory
;; as needed to `load-path'.
(async-byte-recompile-directory (package-desc-dir pkg-desc) t))
(apply orig-fun pkg-desc args))))
;;;###autoload
(define-minor-mode async-bytecomp-package-mode
"Byte compile asynchronously packages installed with package.el.
Async compilation of packages can be controlled by
`async-bytecomp-allowed-packages'."
:group 'async
:global t
(if async-bytecomp-package-mode
(advice-add 'package--compile :around #'async--package-compile)
(advice-remove 'package--compile #'async--package-compile)))
;;;###autoload
(defun async-byte-compile-file (file)
"Byte compile Lisp code FILE asynchronously.
Same as `byte-compile-file' but asynchronous."
(interactive "fFile: ")
(let ((call-back
(lambda (&optional _ignore)
(let ((bn (file-name-nondirectory file)))
(if (file-exists-p async-byte-compile-log-file)
(let ((buf (get-buffer-create byte-compile-log-buffer))
start)
(with-current-buffer buf
(goto-char (setq start (point-max)))
(let ((inhibit-read-only t))
(insert-file-contents async-byte-compile-log-file)
(compilation-mode))
(display-buffer buf)
(delete-file async-byte-compile-log-file)
(save-excursion
(goto-char start)
(if (re-search-forward "^.*:Error:" nil t)
(message "Failed to compile `%s'" bn)
(message "`%s' compiled asynchronously with warnings" bn)))))
(message "`%s' compiled asynchronously with success" bn))))))
(async-start
`(lambda ()
(require 'bytecomp)
,(async-inject-variables async-bytecomp-load-variable-regexp)
(let ((default-directory ,(file-name-directory file)))
(add-to-list 'load-path default-directory)
(byte-compile-file ,file)
(when (get-buffer byte-compile-log-buffer)
(setq error-data (with-current-buffer byte-compile-log-buffer
(buffer-substring-no-properties (point-min) (point-max))))
(unless (string= error-data "")
(with-temp-file ,async-byte-compile-log-file
(erase-buffer)
(insert error-data))))))
call-back)))
(provide 'async-bytecomp)
;;; async-bytecomp.el ends here

View file

@ -0,0 +1,12 @@
(define-package "async" "20220318.1342" "Asynchronous processing in Emacs"
'((emacs "24.4"))
:commit "c78bab7506a70a735d2c3deab13fa87bf44a83d3" :authors
'(("John Wiegley" . "jwiegley@gmail.com"))
:maintainer
'("Thierry Volpiatto" . "thievol@posteo.net")
:keywords
'("async")
:url "https://github.com/jwiegley/emacs-async")
;; Local Variables:
;; no-byte-compile: t
;; End:

View file

@ -0,0 +1,439 @@
;;; async.el --- Asynchronous processing in Emacs -*- lexical-binding: t -*-
;; Copyright (C) 2012-2019 Free Software Foundation, Inc.
;; Author: John Wiegley <jwiegley@gmail.com>
;; Maintainer: Thierry Volpiatto <thievol@posteo.net>
;; Created: 18 Jun 2012
;; Version: 1.9.5
;; Package-Requires: ((emacs "24.4"))
;; Keywords: async
;; X-URL: https://github.com/jwiegley/emacs-async
;; 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:
;; Adds the ability to call asynchronous functions and process with ease. See
;; the documentation for `async-start' and `async-start-process'.
;;; Code:
(eval-when-compile (require 'cl-lib))
(defgroup async nil
"Simple asynchronous processing in Emacs"
:group 'emacs)
(defcustom async-variables-noprops-function #'async--purecopy
"Default function to remove text properties in variables."
:type 'function)
(defvar async-debug nil)
(defvar async-send-over-pipe t)
(defvar async-in-child-emacs nil)
(defvar async-callback nil)
(defvar async-callback-for-process nil)
(defvar async-callback-value nil)
(defvar async-callback-value-set nil)
(defvar async-current-process nil)
(defvar async--procvar nil)
;; For emacs<29 (only exists in emacs-29+).
(defvar print-symbols-bare)
(defun async--purecopy (object)
"Remove text properties in OBJECT.
Argument OBJECT may be a list or a string, if anything else it
is returned unmodified."
(cond ((stringp object)
(substring-no-properties object))
((consp object)
(cl-loop for elm in object
;; A string.
if (stringp elm)
collect (substring-no-properties elm)
else
;; Proper lists.
if (and (consp elm) (null (cdr (last elm))))
collect (async--purecopy elm)
else
;; Dotted lists.
;; We handle here only dotted list where car and cdr
;; are atoms i.e. (x . y) and not (x . (x . y)) or
;; (x . (x y)) which should fit most cases.
if (and (consp elm) (cdr (last elm)))
collect (let ((key (car elm))
(val (cdr elm)))
(cons (if (stringp key)
(substring-no-properties key)
key)
(if (stringp val)
(substring-no-properties val)
val)))
else
collect elm))
(t object)))
(defun async-inject-variables
(include-regexp &optional predicate exclude-regexp noprops)
"Return a `setq' form that replicates part of the calling environment.
It sets the value for every variable matching INCLUDE-REGEXP and
also PREDICATE. It will not perform injection for any variable
matching EXCLUDE-REGEXP (if present) or representing a `syntax-table'
i.e. ending by \"-syntax-table\".
When NOPROPS is non nil it tries to strip out text properties of each
variable's value with `async-variables-noprops-function'.
It is intended to be used as follows:
(async-start
\\=`(lambda ()
(require \\='smtpmail)
(with-temp-buffer
(insert ,(buffer-substring-no-properties (point-min) (point-max)))
;; Pass in the variable environment for smtpmail
,(async-inject-variables \"\\\\=`\\(smtpmail\\|\\(user-\\)?mail\\)-\")
(smtpmail-send-it)))
\\='ignore)"
`(setq
,@(let (bindings)
(mapatoms
(lambda (sym)
(let* ((sname (and (boundp sym) (symbol-name sym)))
(value (and sname (symbol-value sym))))
(when (and sname
(or (null include-regexp)
(string-match include-regexp sname))
(or (null exclude-regexp)
(not (string-match exclude-regexp sname)))
(not (string-match "-syntax-table\\'" sname)))
(unless (or (stringp value)
(memq value '(nil t))
(numberp value)
(vectorp value))
(setq value `(quote ,value)))
(when noprops
(setq value (funcall async-variables-noprops-function
value)))
(when (or (null predicate)
(funcall predicate sym))
(setq bindings (cons value bindings)
bindings (cons sym bindings)))))))
bindings)))
(defalias 'async-inject-environment 'async-inject-variables)
(defun async-handle-result (func result buf)
(if (null func)
(progn
(set (make-local-variable 'async-callback-value) result)
(set (make-local-variable 'async-callback-value-set) t))
(unwind-protect
(if (and (listp result)
(eq 'async-signal (nth 0 result)))
(signal (car (nth 1 result))
(cdr (nth 1 result)))
(funcall func result))
(unless async-debug
(kill-buffer buf)))))
(defun async-when-done (proc &optional _change)
"Process sentinel used to retrieve the value from the child process."
(when (eq 'exit (process-status proc))
(with-current-buffer (process-buffer proc)
(let ((async-current-process proc))
(if (= 0 (process-exit-status proc))
(if async-callback-for-process
(if async-callback
(prog1
(funcall async-callback proc)
(unless async-debug
(kill-buffer (current-buffer))))
(set (make-local-variable 'async-callback-value) proc)
(set (make-local-variable 'async-callback-value-set) t))
;; Maybe strip out unreadable "#"; They are replaced by
;; empty string unless they are prefixing a special
;; object like a marker. See issue #145.
(goto-char (point-min))
(save-excursion
;; Transform markers in list like
;; (marker (moves after insertion) at 2338 in
;; test\.org) so that remap text properties function
;; can parse it to restitute marker.
(while (re-search-forward "#<\\([^>]*\\)>" nil t)
(replace-match (concat "(" (match-string 1) ")") t t)))
(while (re-search-forward "#(" nil t)
(replace-match "(" t t))
(goto-char (point-max))
(backward-sexp)
(async-handle-result async-callback (read (current-buffer))
(current-buffer)))
(set (make-local-variable 'async-callback-value)
(list 'error
(format "Async process '%s' failed with exit code %d"
(process-name proc) (process-exit-status proc))))
(set (make-local-variable 'async-callback-value-set) t))))))
(defun async--receive-sexp (&optional stream)
;; FIXME: Why use `utf-8-auto' instead of `utf-8-unix'? This is
;; a communication channel over which we have complete control,
;; so we get to choose exactly which encoding and EOL we use, isn't it?
(let ((sexp (decode-coding-string (base64-decode-string (read stream))
'utf-8-auto))
;; Parent expects UTF-8 encoded text.
(coding-system-for-write 'utf-8-auto))
(if async-debug
(message "Received sexp {{{%s}}}" (pp-to-string sexp)))
(setq sexp (read sexp))
(if async-debug
(message "Read sexp {{{%s}}}" (pp-to-string sexp)))
(eval sexp t)))
(defun async--insert-sexp (sexp)
(let (print-level
print-length
(print-escape-nonascii t)
(print-circle t)
;; Fix bug#153 in emacs-29 with symbol's positions.
(print-symbols-bare t))
(prin1 sexp (current-buffer))
;; Just in case the string we're sending might contain EOF
(encode-coding-region (point-min) (point-max) 'utf-8-auto)
(base64-encode-region (point-min) (point-max) t)
(goto-char (point-min)) (insert ?\")
(goto-char (point-max)) (insert ?\" ?\n)))
(defun async--transmit-sexp (process sexp)
(with-temp-buffer
(if async-debug
(message "Transmitting sexp {{{%s}}}" (pp-to-string sexp)))
(async--insert-sexp sexp)
(process-send-region process (point-min) (point-max))))
(defun async-batch-invoke ()
"Called from the child Emacs process' command line."
;; Make sure 'message' and 'prin1' encode stuff in UTF-8, as parent
;; process expects.
(let ((coding-system-for-write 'utf-8-auto))
(setq async-in-child-emacs t
debug-on-error async-debug)
(if debug-on-error
(prin1 (funcall
(async--receive-sexp (unless async-send-over-pipe
command-line-args-left))))
(condition-case err
(prin1 (funcall
(async--receive-sexp (unless async-send-over-pipe
command-line-args-left))))
(error
(prin1 (list 'async-signal err)))))))
(defun async-ready (future)
"Query a FUTURE to see if it is ready.
I.e., if no blocking would result from a call to `async-get' on that FUTURE."
(and (memq (process-status future) '(exit signal))
(let ((buf (process-buffer future)))
(if (buffer-live-p buf)
(with-current-buffer buf
async-callback-value-set)
t))))
(defun async-wait (future)
"Wait for FUTURE to become ready."
(while (not (async-ready future))
(sleep-for 0.05)))
(defun async-get (future)
"Get the value from process FUTURE when it is ready.
FUTURE is returned by `async-start' or `async-start-process' when
its FINISH-FUNC is nil."
(and future (async-wait future))
(let ((buf (process-buffer future)))
(when (buffer-live-p buf)
(with-current-buffer buf
(async-handle-result
#'identity async-callback-value (current-buffer))))))
(defun async-message-p (value)
"Return non-nil of VALUE is an async.el message packet."
(and (listp value)
(plist-get value :async-message)))
(defun async-send (&rest args)
"Send the given messages to the asychronous Emacs PROCESS."
(let ((args (append args '(:async-message t))))
(if async-in-child-emacs
(if async-callback
(funcall async-callback args))
(async--transmit-sexp (car args) (list 'quote (cdr args))))))
(defun async-receive ()
"Send the given messages to the asychronous Emacs PROCESS."
(async--receive-sexp))
;;;###autoload
(defun async-start-process (name program finish-func &rest program-args)
"Start the executable PROGRAM asynchronously named NAME. See `async-start'.
PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
process object when done. If FINISH-FUNC is nil, the future
object will return the process object when the program is
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
working directory."
(let* ((buf (generate-new-buffer (concat "*" name "*")))
(proc (let ((process-connection-type nil))
(apply #'start-process name buf program program-args))))
(with-current-buffer buf
(set (make-local-variable 'async-callback) finish-func)
(set-process-sentinel proc #'async-when-done)
(unless (string= name "emacs")
(set (make-local-variable 'async-callback-for-process) t))
proc)))
(defvar async-quiet-switch "-Q"
"The Emacs parameter to use to call emacs without config.
Can be one of \"-Q\" or \"-q\".
Default is \"-Q\" but it is sometimes useful to use \"-q\" to have a
enhanced config or some more variables loaded.")
;;;###autoload
(defun async-start (start-func &optional finish-func)
"Execute START-FUNC (often a lambda) in a subordinate Emacs process.
When done, the return value is passed to FINISH-FUNC. Example:
(async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222)
;; What to do when it finishes
(lambda (result)
(message \"Async process done, result should be 222: %s\"
result)))
If FINISH-FUNC is nil or missing, a future is returned that can
be inspected using `async-get', blocking until the value is
ready. Example:
(let ((proc (async-start
;; What to do in the child process
(lambda ()
(message \"This is a test\")
(sleep-for 3)
222))))
(message \"I'm going to do some work here\") ;; ....
(message \"Waiting on async process, result should be 222: %s\"
(async-get proc)))
If you don't want to use a callback, and you don't care about any
return value from the child process, pass the `ignore' symbol as
the second argument (if you don't, and never call `async-get', it
will leave *emacs* process buffers hanging around):
(async-start
(lambda ()
(delete-file \"a remote file on a slow link\" nil))
\\='ignore)
Special case:
If the output of START-FUNC is a string with properties
e.g. (buffer-string) RESULT will be transformed in a list where the
car is the string itself (without props) and the cdr the rest of
properties, this allows using in FINISH-FUNC the string without
properties and then apply the properties in cdr to this string (if
needed).
Properties handling special objects like markers are returned as
list to allow restoring them later.
See <https://github.com/jwiegley/emacs-async/issues/145> for more infos.
Note: Even when FINISH-FUNC is present, a future is still
returned except that it yields no value (since the value is
passed to FINISH-FUNC). Call `async-get' on such a future always
returns nil. It can still be useful, however, as an argument to
`async-ready' or `async-wait'."
(let ((sexp start-func)
;; Subordinate Emacs will send text encoded in UTF-8.
(coding-system-for-read 'utf-8-auto))
(setq async--procvar
(async-start-process
"emacs" (file-truename
(expand-file-name invocation-name
invocation-directory))
finish-func
async-quiet-switch "-l"
;; Using `locate-library' ensure we use the right file
;; when the .elc have been deleted.
(locate-library "async")
"-batch" "-f" "async-batch-invoke"
(if async-send-over-pipe
"<none>"
(with-temp-buffer
(async--insert-sexp (list 'quote sexp))
(buffer-string)))))
(if async-send-over-pipe
(async--transmit-sexp async--procvar (list 'quote sexp)))
async--procvar))
(defmacro async-sandbox(func)
"Evaluate FUNC in a separate Emacs process, synchronously."
`(async-get (async-start ,func)))
(defun async--fold-left (fn forms bindings)
(let ((res forms))
(dolist (binding bindings)
(setq res (funcall fn res
(if (listp binding)
binding
(list binding)))))
res))
(defmacro async-let (bindings &rest forms)
"Implements `let', but each binding is established asynchronously.
For example:
(async-let ((x (foo))
(y (bar)))
(message \"%s %s\" x y))
expands to ==>
(async-start (foo)
(lambda (x)
(async-start (bar)
(lambda (y)
(message \"%s %s\" x y)))))"
(declare (indent 1))
(async--fold-left
(lambda (acc binding)
(let ((fun (pcase (cadr binding)
((and (pred functionp) f) f)
(f `(lambda () ,f)))))
`(async-start ,fun
(lambda (,(car binding))
,acc))))
`(progn ,@forms)
(reverse bindings)))
(provide 'async)
;;; async.el ends here

View file

@ -0,0 +1,385 @@
;;; dired-async.el --- Asynchronous dired actions -*- lexical-binding: t -*-
;; Copyright (C) 2012-2019 Free Software Foundation, Inc.
;; Authors: John Wiegley <jwiegley@gmail.com>
;; Thierry Volpiatto <thievol@posteo.net>
;; Keywords: dired async network
;; X-URL: https://github.com/jwiegley/dired-async
;; 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:
;; This file provide a redefinition of `dired-create-file' function,
;; performs copies, moves and all what is handled by `dired-create-file'
;; in the background using a slave Emacs process,
;; by means of the async.el module.
;; To use it, put this in your .emacs:
;; (dired-async-mode 1)
;; This will enable async copy/rename etc...
;; in dired and helm.
;;; Code:
(require 'cl-lib)
(require 'dired-aux)
(require 'async)
(eval-when-compile
(defvar async-callback))
(defgroup dired-async nil
"Copy rename files asynchronously from dired."
:group 'dired)
(defcustom dired-async-env-variables-regexp
"\\`\\(tramp-\\(default\\|connection\\|remote\\)\\|ange-ftp\\)-.*"
"Variables matching this regexp will be loaded on Child Emacs."
:type 'regexp)
(defcustom dired-async-message-function 'dired-async-mode-line-message
"Function to use to notify result when operation finish.
Should take same args as `message'."
:type 'function)
(defcustom dired-async-log-file "/tmp/dired-async.log"
"File use to communicate errors from Child Emacs to host Emacs."
:type 'string)
(defcustom dired-async-mode-lighter '(:eval
(when (eq major-mode 'dired-mode)
" Async"))
"Mode line lighter used for `dired-async-mode'."
:risky t
:type 'sexp)
(defface dired-async-message
'((t (:foreground "yellow")))
"Face used for mode-line message.")
(defface dired-async-failures
'((t (:foreground "red")))
"Face used for mode-line message.")
(defface dired-async-mode-message
'((t (:foreground "Gold")))
"Face used for `dired-async--modeline-mode' lighter.")
(define-minor-mode dired-async--modeline-mode
"Notify mode-line that an async process run."
:global t
:lighter (:eval (propertize (format " [%s Async job(s) running]"
(length (dired-async-processes)))
'face 'dired-async-mode-message))
(unless dired-async--modeline-mode
(let ((visible-bell t)) (ding))))
(defun dired-async-mode-line-message (text face &rest args)
"Notify end of operation in `mode-line'."
(message nil)
(let ((mode-line-format (concat
" " (propertize
(if args
(apply #'format text args)
text)
'face face))))
(force-mode-line-update)
(sit-for 3)
(force-mode-line-update)))
(defun dired-async-processes ()
(cl-loop for p in (process-list)
when (cl-loop for c in (process-command p) thereis
(string= "async-batch-invoke" c))
collect p))
(defun dired-async-kill-process ()
(interactive)
(let* ((processes (dired-async-processes))
(proc (car (last processes))))
(and proc (delete-process proc))
(unless (> (length processes) 1)
(dired-async--modeline-mode -1))))
(defun dired-async-after-file-create (total operation failures skipped)
"Callback function used for operation handled by `dired-create-file'."
(unless (dired-async-processes)
;; Turn off mode-line notification
;; only when last process end.
(dired-async--modeline-mode -1))
(when operation
(if (file-exists-p dired-async-log-file)
(progn
(pop-to-buffer (get-buffer-create dired-log-buffer))
(goto-char (point-max))
(setq inhibit-read-only t)
(insert "Error: ")
(insert-file-contents dired-async-log-file)
(special-mode)
(shrink-window-if-larger-than-buffer)
(delete-file dired-async-log-file))
(run-with-timer
0.1 nil
(lambda ()
;; First send error messages.
(cond (failures
(funcall dired-async-message-function
"%s failed for %d of %d file%s -- See *Dired log* buffer"
'dired-async-failures
(car operation) (length failures)
total (dired-plural-s total)))
(skipped
(funcall dired-async-message-function
"%s: %d of %d file%s skipped -- See *Dired log* buffer"
'dired-async-failures
(car operation) (length skipped) total
(dired-plural-s total))))
(when dired-buffers
(cl-loop for (_f . b) in dired-buffers
when (buffer-live-p b)
do (with-current-buffer b
(when (and (not (file-remote-p default-directory nil t))
(file-exists-p default-directory))
(revert-buffer nil t)))))
;; Finally send the success message.
(funcall dired-async-message-function
"Asynchronous %s of %s on %s file%s done"
'dired-async-message
(car operation) (cadr operation)
total (dired-plural-s total)))))))
(defun dired-async-maybe-kill-ftp ()
"Return a form to kill ftp process in child emacs."
(quote
(progn
(require 'cl-lib)
(let ((buf (cl-loop for b in (buffer-list)
thereis (and (string-match
"\\`\\*ftp.*"
(buffer-name b)) b))))
(when buf (kill-buffer buf))))))
(defvar overwrite-query)
(defun dired-async-create-files (file-creator operation fn-list name-constructor
&optional _marker-char)
"Same as `dired-create-files' but asynchronous.
See `dired-create-files' for the behavior of arguments."
(setq overwrite-query nil)
(let ((total (length fn-list))
failures async-fn-list skipped callback
async-quiet-switch)
(let (to)
(dolist (from fn-list)
(setq to (funcall name-constructor from))
(if (and (equal to from)
(null (eq file-creator 'backup-file)))
(progn
(setq to nil)
(dired-log "Cannot %s to same file: %s\n"
(downcase operation) from)))
(if (not to)
(setq skipped (cons (dired-make-relative from) skipped))
(let* ((overwrite (and (null (eq file-creator 'backup-file))
(file-exists-p to)))
(dired-overwrite-confirmed ; for dired-handle-overwrite
(and overwrite
(let ((help-form `(format "\
Type SPC or `y' to overwrite file `%s',
DEL or `n' to skip to next,
ESC or `q' to not overwrite any of the remaining files,
`!' to overwrite all remaining files with no more questions." ,to)))
(dired-query 'overwrite-query "Overwrite `%s'?" to)))))
;; Handle the `dired-copy-file' file-creator specially
;; When copying a directory to another directory or
;; possibly to itself or one of its subdirectories.
;; e.g "~/foo/" => "~/test/"
;; or "~/foo/" =>"~/foo/"
;; or "~/foo/ => ~/foo/bar/")
;; In this case the 'name-constructor' have set the destination
;; TO to "~/test/foo" because the old emacs23 behavior
;; of `copy-directory' was to not create the subdirectory
;; and instead copy the contents.
;; With the new behavior of `copy-directory'
;; (similar to the `cp' shell command) we don't
;; need such a construction of the target directory,
;; so modify the destination TO to "~/test/" instead of "~/test/foo/".
(let ((destname (file-name-directory to)))
(when (and (file-directory-p from)
(file-directory-p to)
(eq file-creator 'dired-copy-file))
(setq to destname))
;; If DESTNAME is a subdirectory of FROM, not a symlink,
;; and the method in use is copying, signal an error.
(and (eq t (car (file-attributes destname)))
(eq file-creator 'dired-copy-file)
(file-in-directory-p destname from)
(error "Cannot copy `%s' into its subdirectory `%s'"
from to)))
(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.
(setq async-quiet-switch
(if (and (boundp 'tramp-cache-read-persistent-data)
async-fn-list
(cl-loop for (_from . to) in async-fn-list
thereis (file-remote-p to)))
"-q" "-Q"))
;; When failures have been printed to dired log add the date at bob.
(when (or failures skipped) (dired-log t))
;; When async-fn-list is empty that's mean only one file
;; had to be copied and user finally answer NO.
;; In this case async process will never start and callback
;; will have no chance to run, so notify failures here.
(unless async-fn-list
(cond (failures
(funcall dired-async-message-function
"%s failed for %d of %d file%s -- See *Dired log* buffer"
'dired-async-failures
operation (length failures)
total (dired-plural-s total)))
(skipped
(funcall dired-async-message-function
"%s: %d of %d file%s skipped -- See *Dired log* buffer"
'dired-async-failures
operation (length skipped) total
(dired-plural-s total)))))
;; Setup callback.
(setq callback
(lambda (&optional _ignore)
(dired-async-after-file-create
total (list operation (length async-fn-list)) failures skipped)
(when (string= (downcase operation) "rename")
(cl-loop for (file . to) in async-fn-list
for bf = (get-file-buffer file)
for destp = (file-exists-p to)
do (and bf destp
(with-current-buffer bf
(set-visited-file-name to t t))))))))
;; Start async process.
(when async-fn-list
(async-start `(lambda ()
(require 'cl-lib) (require 'dired-aux) (require 'dired-x)
,(async-inject-variables dired-async-env-variables-regexp)
(let ((dired-recursive-copies (quote always))
(dired-copy-preserve-time
,dired-copy-preserve-time))
(setq overwrite-backup-query nil)
;; Inline `backup-file' as long as it is not
;; available in emacs.
(defalias 'backup-file
;; Same feature as "cp -f --backup=numbered from to"
;; Symlinks are copied as file from source unlike
;; `dired-copy-file' which is same as cp -d.
;; Directories are omitted.
(lambda (from to ok)
(cond ((file-directory-p from) (ignore))
(t (let ((count 0))
(while (let ((attrs (file-attributes to)))
(and attrs (null (nth 0 attrs))))
(cl-incf count)
(setq to (concat (file-name-sans-versions to)
(format ".~%s~" count)))))
(condition-case err
(copy-file from to ok dired-copy-preserve-time)
(file-date-error
(dired-log "Can't set date on %s:\n%s\n" from err)))))))
;; Now run the FILE-CREATOR function on files.
(cl-loop with fn = (quote ,file-creator)
for (from . dest) in (quote ,async-fn-list)
do (condition-case err
(funcall fn from dest t)
(file-error
(dired-log "%s: %s\n" (car err) (cdr err))
nil)))
(when (get-buffer dired-log-buffer)
(dired-log t)
(with-current-buffer dired-log-buffer
(write-region (point-min) (point-max)
,dired-async-log-file))))
,(dired-async-maybe-kill-ftp))
callback)
;; Run mode-line notifications while process running.
(dired-async--modeline-mode 1)
(message "%s proceeding asynchronously..." operation))))
(defvar wdired-use-interactive-rename)
(defun dired-async-wdired-do-renames (old-fn &rest args)
;; Perhaps a better fix would be to ask for renaming BEFORE starting
;; OLD-FN when `wdired-use-interactive-rename' is non-nil. For now
;; just bind it to nil to ensure no questions will be asked between
;; each rename.
(let (wdired-use-interactive-rename)
(apply old-fn args)))
;;;###autoload
(define-minor-mode dired-async-mode
"Do dired actions asynchronously."
:lighter dired-async-mode-lighter
:global t
(if dired-async-mode
(progn
(advice-add 'dired-create-files :override #'dired-async-create-files)
(advice-add 'wdired-do-renames :around #'dired-async-wdired-do-renames))
(progn
(advice-remove 'dired-create-files #'dired-async-create-files)
(advice-remove 'wdired-do-renames #'dired-async-wdired-do-renames))))
(defmacro dired-async--with-async-create-files (&rest body)
"Evaluate BODY with dired-create-files set to dired-async-create-files."
(declare (indent 0))
`(cl-letf (((symbol-function 'dired-create-files) #'dired-async-create-files))
,@body))
;;;###autoload
(defun dired-async-do-copy (&optional arg)
"Run dired-do-copy asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-copy arg)))
;;;###autoload
(defun dired-async-do-symlink (&optional arg)
"Run dired-do-symlink asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-symlink arg)))
;;;###autoload
(defun dired-async-do-hardlink (&optional arg)
"Run dired-do-hardlink asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-hardlink arg)))
;;;###autoload
(defun dired-async-do-rename (&optional arg)
"Run dired-do-rename asynchronously."
(interactive "P")
(dired-async--with-async-create-files
(dired-do-rename arg)))
(provide 'dired-async)
;;; dired-async.el ends here

View file

@ -0,0 +1,71 @@
;;; smtpmail-async.el --- Send e-mail with smtpmail.el asynchronously -*- lexical-binding: t -*-
;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
;; Author: John Wiegley <jwiegley@gmail.com>
;; Created: 18 Jun 2012
;; Keywords: email async
;; X-URL: https://github.com/jwiegley/emacs-async
;; 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:
;; Send e-mail with smtpmail.el asynchronously. To use:
;;
;; (require 'smtpmail-async)
;;
;; (setq send-mail-function 'async-smtpmail-send-it
;; message-send-mail-function 'async-smtpmail-send-it)
;;
;; This assumes you already have smtpmail.el working.
;;; Code:
(defgroup smtpmail-async nil
"Send e-mail with smtpmail.el asynchronously"
:group 'smptmail)
(require 'async)
(require 'smtpmail)
(require 'message)
(defvar async-smtpmail-before-send-hook nil
"Hook running in the child emacs in `async-smtpmail-send-it'.
It is called just before calling `smtpmail-send-it'.")
(defun async-smtpmail-send-it ()
(let ((to (message-field-value "To"))
(buf-content (buffer-substring-no-properties
(point-min) (point-max))))
(message "Delivering message to %s..." to)
(async-start
`(lambda ()
(require 'smtpmail)
(with-temp-buffer
(insert ,buf-content)
(set-buffer-multibyte nil)
;; Pass in the variable environment for smtpmail
,(async-inject-variables
"\\`\\(smtpmail\\|async-smtpmail\\|\\(user-\\)?mail\\)-\\|auth-sources\\|epg\\|nsm"
nil "\\`\\(mail-header-format-function\\|smtpmail-address-buffer\\|mail-mode-abbrev-table\\)")
(run-hooks 'async-smtpmail-before-send-hook)
(smtpmail-send-it)))
(lambda (&optional _ignore)
(message "Delivering message to %s...done" to)))))
(provide 'smtpmail-async)
;;; smtpmail-async.el ends here

View file

@ -0,0 +1,22 @@
;;; popup-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 "popup" "popup.el" (0 0 0 0))
;;; Generated autoloads from popup.el
(register-definition-prefixes "popup" '("popup-"))
;;;***
;; Local Variables:
;; version-control: never
;; no-byte-compile: t
;; no-update-autoloads: t
;; coding: utf-8
;; End:
;;; popup-autoloads.el ends here

View file

@ -0,0 +1,2 @@
;;; Generated package description from popup.el -*- no-byte-compile: t -*-
(define-package "popup" "20211231.1823" "Visual Popup User Interface" '((emacs "24.3")) :commit "3bf430270c74dad830ab9d776aab23cbf3ea3953" :authors '(("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) :maintainer '("Shen, Jen-Chieh" . "jcs090218@gmail.com") :keywords '("lisp") :url "https://github.com/auto-complete/popup-el")

File diff suppressed because it is too large Load diff